@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.
Files changed (235) hide show
  1. package/README.md +250 -0
  2. package/dist/borders/index.d.ts +3 -0
  3. package/dist/borders/index.js +13 -0
  4. package/dist/box/index.d.ts +4 -0
  5. package/dist/box/index.js +10 -0
  6. package/dist/confirm.d.ts +37 -0
  7. package/dist/confirm.js +36 -0
  8. package/dist/demo/index.d.ts +77 -0
  9. package/dist/demo/index.js +142 -0
  10. package/dist/demo/registry.d.ts +6 -0
  11. package/dist/demo/registry.js +28 -0
  12. package/dist/demo/renderers/borders.d.ts +7 -0
  13. package/dist/demo/renderers/borders.js +14 -0
  14. package/dist/demo/renderers/box.d.ts +7 -0
  15. package/dist/demo/renderers/box.js +15 -0
  16. package/dist/demo/renderers/colors.d.ts +7 -0
  17. package/dist/demo/renderers/colors.js +15 -0
  18. package/dist/demo/renderers/indicators.d.ts +7 -0
  19. package/dist/demo/renderers/indicators.js +14 -0
  20. package/dist/demo/renderers/list.d.ts +7 -0
  21. package/dist/demo/renderers/list.js +16 -0
  22. package/dist/demo/renderers/markdown.d.ts +7 -0
  23. package/dist/demo/renderers/markdown.js +15 -0
  24. package/dist/demo/renderers/progress.d.ts +7 -0
  25. package/dist/demo/renderers/progress.js +14 -0
  26. package/dist/demo/renderers/spinner.d.ts +7 -0
  27. package/dist/demo/renderers/spinner.js +16 -0
  28. package/dist/demo/renderers/table.d.ts +7 -0
  29. package/dist/demo/renderers/table.js +16 -0
  30. package/dist/demo/renderers/text.d.ts +7 -0
  31. package/dist/demo/renderers/text.js +13 -0
  32. package/dist/demo/renderers/tree.d.ts +7 -0
  33. package/dist/demo/renderers/tree.js +15 -0
  34. package/dist/demo/section.d.ts +4 -0
  35. package/dist/demo/section.js +20 -0
  36. package/dist/demo/templates.d.ts +3 -0
  37. package/dist/demo/templates.js +10 -0
  38. package/dist/demo/types.d.ts +2 -0
  39. package/dist/demo/types.js +8 -0
  40. package/dist/index.d.ts +31 -0
  41. package/dist/index.js +77 -0
  42. package/dist/list/index.d.ts +3 -0
  43. package/dist/list/index.js +9 -0
  44. package/dist/preset/full.d.ts +12 -0
  45. package/dist/preset/full.js +37 -0
  46. package/dist/preset/standard.d.ts +9 -0
  47. package/dist/preset/standard.js +26 -0
  48. package/dist/prompt/confirm.d.ts +4 -0
  49. package/dist/prompt/confirm.js +9 -0
  50. package/dist/prompt/group.d.ts +4 -0
  51. package/dist/prompt/group.js +9 -0
  52. package/dist/prompt/index.d.ts +7 -0
  53. package/dist/prompt/index.js +32 -0
  54. package/dist/prompt/select.d.ts +4 -0
  55. package/dist/prompt/select.js +11 -0
  56. package/dist/prompt/text.d.ts +4 -0
  57. package/dist/prompt/text.js +11 -0
  58. package/dist/prompt/types.d.ts +3 -0
  59. package/dist/prompt/types.js +8 -0
  60. package/dist/prompt/validators.d.ts +2 -0
  61. package/dist/prompt/validators.js +8 -0
  62. package/dist/render/borders.d.ts +2 -0
  63. package/dist/render/borders.js +15 -0
  64. package/dist/render/box.d.ts +3 -0
  65. package/dist/render/box.js +20 -0
  66. package/dist/render/date.d.ts +2 -0
  67. package/dist/render/date.js +12 -0
  68. package/dist/render/format-relative.d.ts +2 -0
  69. package/dist/render/format-relative.js +8 -0
  70. package/dist/render/format.d.ts +2 -0
  71. package/dist/render/format.js +10 -0
  72. package/dist/render/heading.d.ts +3 -0
  73. package/dist/render/heading.js +11 -0
  74. package/dist/render/index.d.ts +31 -0
  75. package/dist/render/index.js +222 -0
  76. package/dist/render/indicators.d.ts +2 -0
  77. package/dist/render/indicators.js +16 -0
  78. package/dist/render/json.d.ts +2 -0
  79. package/dist/render/json.js +10 -0
  80. package/dist/render/layout.d.ts +5 -0
  81. package/dist/render/layout.js +22 -0
  82. package/dist/render/list.d.ts +2 -0
  83. package/dist/render/list.js +8 -0
  84. package/dist/render/markdown.d.ts +2 -0
  85. package/dist/render/markdown.js +8 -0
  86. package/dist/render/progress.d.ts +2 -0
  87. package/dist/render/progress.js +8 -0
  88. package/dist/render/separator.d.ts +3 -0
  89. package/dist/render/separator.js +11 -0
  90. package/dist/render/shapes.d.ts +2 -0
  91. package/dist/render/shapes.js +32 -0
  92. package/dist/render/spinner.d.ts +2 -0
  93. package/dist/render/spinner.js +12 -0
  94. package/dist/render/stack.d.ts +3 -0
  95. package/dist/render/stack.js +35 -0
  96. package/dist/render/table.d.ts +3 -0
  97. package/dist/render/table.js +9 -0
  98. package/dist/render/tree.d.ts +2 -0
  99. package/dist/render/tree.js +10 -0
  100. package/dist/render/types.d.ts +2 -0
  101. package/dist/render/types.js +1 -0
  102. package/dist/shared/@outfitter/tui-011579t8.d.ts +24 -0
  103. package/dist/shared/@outfitter/tui-06dntkse.js +146 -0
  104. package/dist/shared/@outfitter/tui-0awf316b.js +71 -0
  105. package/dist/shared/@outfitter/tui-0b85rht7.js +1 -0
  106. package/dist/shared/@outfitter/tui-0mpqnyc1.js +55 -0
  107. package/dist/shared/@outfitter/tui-1qh888th.d.ts +106 -0
  108. package/dist/shared/@outfitter/tui-1tk0kxa6.js +94 -0
  109. package/dist/shared/@outfitter/tui-1wggw2zj.d.ts +56 -0
  110. package/dist/shared/@outfitter/tui-2pwhzg55.js +123 -0
  111. package/dist/shared/@outfitter/tui-2tkva96b.d.ts +20 -0
  112. package/dist/shared/@outfitter/tui-2wfat6jb.js +22 -0
  113. package/dist/shared/@outfitter/tui-34q2aenf.d.ts +24 -0
  114. package/dist/shared/@outfitter/tui-37hjcqhb.d.ts +3 -0
  115. package/dist/shared/@outfitter/tui-3dyxg62j.d.ts +97 -0
  116. package/dist/shared/@outfitter/tui-3kza6p9k.d.ts +132 -0
  117. package/dist/shared/@outfitter/tui-43bnfxv9.js +30 -0
  118. package/dist/shared/@outfitter/tui-4yz7jcyq.js +214 -0
  119. package/dist/shared/@outfitter/tui-52ndmswq.js +23 -0
  120. package/dist/shared/@outfitter/tui-53ms1ba4.d.ts +41 -0
  121. package/dist/shared/@outfitter/tui-5dsn6d6d.js +86 -0
  122. package/dist/shared/@outfitter/tui-5pb72vf9.js +51 -0
  123. package/dist/shared/@outfitter/tui-6605wa2j.js +127 -0
  124. package/dist/shared/@outfitter/tui-6ptks7jj.js +19 -0
  125. package/dist/shared/@outfitter/tui-6svngg69.js +126 -0
  126. package/dist/shared/@outfitter/tui-733asbd8.js +37 -0
  127. package/dist/shared/@outfitter/tui-75bztyfp.d.ts +50 -0
  128. package/dist/shared/@outfitter/tui-83zaah9b.d.ts +17 -0
  129. package/dist/shared/@outfitter/tui-8ejx8gq5.d.ts +71 -0
  130. package/dist/shared/@outfitter/tui-8j1gbehy.d.ts +164 -0
  131. package/dist/shared/@outfitter/tui-8mypsnva.d.ts +74 -0
  132. package/dist/shared/@outfitter/tui-997aapz0.js +61 -0
  133. package/dist/shared/@outfitter/tui-9dbykt4g.d.ts +42 -0
  134. package/dist/shared/@outfitter/tui-9h1kdd98.d.ts +119 -0
  135. package/dist/shared/@outfitter/tui-9rj9yesd.js +118 -0
  136. package/dist/shared/@outfitter/tui-a65efhsk.d.ts +23 -0
  137. package/dist/shared/@outfitter/tui-a8nkrbds.js +1 -0
  138. package/dist/shared/@outfitter/tui-ajp1153q.d.ts +59 -0
  139. package/dist/shared/@outfitter/tui-ay1fv41j.d.ts +30 -0
  140. package/dist/shared/@outfitter/tui-azh1w4ak.js +67 -0
  141. package/dist/shared/@outfitter/tui-b14ry1j1.d.ts +53 -0
  142. package/dist/shared/@outfitter/tui-c56sxcm8.d.ts +87 -0
  143. package/dist/shared/@outfitter/tui-c6ft5w6q.d.ts +91 -0
  144. package/dist/shared/@outfitter/tui-cq7za0cz.js +62 -0
  145. package/dist/shared/@outfitter/tui-dh15zwg0.js +95 -0
  146. package/dist/shared/@outfitter/tui-esc46z2v.js +20 -0
  147. package/dist/shared/@outfitter/tui-f1mj6h6p.d.ts +2 -0
  148. package/dist/shared/@outfitter/tui-gcpz529w.js +122 -0
  149. package/dist/shared/@outfitter/tui-gqsdhmk9.d.ts +42 -0
  150. package/dist/shared/@outfitter/tui-hescagw2.js +32 -0
  151. package/dist/shared/@outfitter/tui-j2kd7eej.js +126 -0
  152. package/dist/shared/@outfitter/tui-j3bkjt2g.js +7 -0
  153. package/dist/shared/@outfitter/tui-jnn9d8cd.js +8 -0
  154. package/dist/shared/@outfitter/tui-jz5nws55.d.ts +51 -0
  155. package/dist/shared/@outfitter/tui-k3mby2kk.js +70 -0
  156. package/dist/shared/@outfitter/tui-kc4nxak0.js +20 -0
  157. package/dist/shared/@outfitter/tui-kcxv8txp.js +7 -0
  158. package/dist/shared/@outfitter/tui-kydbggmj.js +39 -0
  159. package/dist/shared/@outfitter/tui-mch672g9.js +30 -0
  160. package/dist/shared/@outfitter/tui-n9kxkdrh.js +82 -0
  161. package/dist/shared/@outfitter/tui-na4dnjpw.js +348 -0
  162. package/dist/shared/@outfitter/tui-ncaatp4j.js +25 -0
  163. package/dist/shared/@outfitter/tui-nce7fgtf.js +48 -0
  164. package/dist/shared/@outfitter/tui-ngz2fbdw.js +144 -0
  165. package/dist/shared/@outfitter/tui-nprd7g0d.js +52 -0
  166. package/dist/shared/@outfitter/tui-nr580mbv.js +272 -0
  167. package/dist/shared/@outfitter/tui-nr93tf31.d.ts +64 -0
  168. package/dist/shared/@outfitter/tui-pdwbbzwr.js +179 -0
  169. package/dist/shared/@outfitter/tui-qb07rtct.js +19 -0
  170. package/dist/shared/@outfitter/tui-qkyazctw.d.ts +36 -0
  171. package/dist/shared/@outfitter/tui-qn1rgz9v.d.ts +93 -0
  172. package/dist/shared/@outfitter/tui-qs3fhwp8.js +43 -0
  173. package/dist/shared/@outfitter/tui-r8hywf9m.d.ts +48 -0
  174. package/dist/shared/@outfitter/tui-rbbcc034.js +20 -0
  175. package/dist/shared/@outfitter/tui-rgkerz72.js +85 -0
  176. package/dist/shared/@outfitter/tui-rh52sycm.d.ts +45 -0
  177. package/dist/shared/@outfitter/tui-rr924x4z.d.ts +59 -0
  178. package/dist/shared/@outfitter/tui-rwpdjrt3.js +20 -0
  179. package/dist/shared/@outfitter/tui-rx9xq9s7.d.ts +26 -0
  180. package/dist/shared/@outfitter/tui-sk05ye6g.js +1 -0
  181. package/dist/shared/@outfitter/tui-sv2xmh3w.d.ts +26 -0
  182. package/dist/shared/@outfitter/tui-t1a9xgbd.js +111 -0
  183. package/dist/shared/@outfitter/tui-t9vd88jr.js +273 -0
  184. package/dist/shared/@outfitter/tui-tq1z78x0.js +11 -0
  185. package/dist/shared/@outfitter/tui-ts1f957s.d.ts +128 -0
  186. package/dist/shared/@outfitter/tui-ve0083wa.d.ts +61 -0
  187. package/dist/shared/@outfitter/tui-vt0wg6c4.js +54 -0
  188. package/dist/shared/@outfitter/tui-wfnnq0zq.d.ts +328 -0
  189. package/dist/shared/@outfitter/tui-x3yg0887.d.ts +223 -0
  190. package/dist/shared/@outfitter/tui-x9vvtfkk.js +20 -0
  191. package/dist/shared/@outfitter/tui-xbvz707j.js +20 -0
  192. package/dist/shared/@outfitter/tui-xbx6d4t7.js +1 -0
  193. package/dist/shared/@outfitter/tui-xph95b7h.js +67 -0
  194. package/dist/shared/@outfitter/tui-xqjx7d1f.js +135 -0
  195. package/dist/shared/@outfitter/tui-xrgrp99k.d.ts +112 -0
  196. package/dist/shared/@outfitter/tui-xzjv96ps.d.ts +300 -0
  197. package/dist/shared/@outfitter/tui-ykzs6v4v.d.ts +66 -0
  198. package/dist/shared/@outfitter/tui-yw9n5h6q.d.ts +54 -0
  199. package/dist/shared/@outfitter/tui-ywmakc6b.js +30 -0
  200. package/dist/shared/@outfitter/tui-z6nf9b9h.js +7 -0
  201. package/dist/shared/@outfitter/tui-zcspg6z6.d.ts +190 -0
  202. package/dist/shared/@outfitter/tui-zhbsnj7w.js +1 -0
  203. package/dist/streaming/ansi.d.ts +2 -0
  204. package/dist/streaming/ansi.js +8 -0
  205. package/dist/streaming/index.d.ts +4 -0
  206. package/dist/streaming/index.js +17 -0
  207. package/dist/streaming/spinner.d.ts +3 -0
  208. package/dist/streaming/spinner.js +10 -0
  209. package/dist/streaming/writer.d.ts +2 -0
  210. package/dist/streaming/writer.js +9 -0
  211. package/dist/table/index.d.ts +4 -0
  212. package/dist/table/index.js +10 -0
  213. package/dist/theme/context.d.ts +9 -0
  214. package/dist/theme/context.js +12 -0
  215. package/dist/theme/create.d.ts +8 -0
  216. package/dist/theme/create.js +10 -0
  217. package/dist/theme/index.d.ts +17 -0
  218. package/dist/theme/index.js +40 -0
  219. package/dist/theme/presets/bold.d.ts +8 -0
  220. package/dist/theme/presets/bold.js +10 -0
  221. package/dist/theme/presets/default.d.ts +8 -0
  222. package/dist/theme/presets/default.js +9 -0
  223. package/dist/theme/presets/index.d.ts +12 -0
  224. package/dist/theme/presets/index.js +22 -0
  225. package/dist/theme/presets/minimal.d.ts +8 -0
  226. package/dist/theme/presets/minimal.js +10 -0
  227. package/dist/theme/presets/rounded.d.ts +8 -0
  228. package/dist/theme/presets/rounded.js +10 -0
  229. package/dist/theme/resolve.d.ts +8 -0
  230. package/dist/theme/resolve.js +11 -0
  231. package/dist/theme/types.d.ts +7 -0
  232. package/dist/theme/types.js +1 -0
  233. package/dist/tree/index.d.ts +3 -0
  234. package/dist/tree/index.js +11 -0
  235. package/package.json +263 -0
@@ -0,0 +1,135 @@
1
+ // @bun
2
+ import {
3
+ renderTree
4
+ } from "./tui-kydbggmj.js";
5
+ import {
6
+ renderJson,
7
+ renderText
8
+ } from "./tui-tq1z78x0.js";
9
+ import {
10
+ renderMarkdown
11
+ } from "./tui-vt0wg6c4.js";
12
+ import {
13
+ renderList
14
+ } from "./tui-5dsn6d6d.js";
15
+ import {
16
+ renderTable
17
+ } from "./tui-t1a9xgbd.js";
18
+
19
+ // packages/tui/src/render/shapes.ts
20
+ function isCollection(shape) {
21
+ return shape.type === "collection";
22
+ }
23
+ function isHierarchy(shape) {
24
+ return shape.type === "hierarchy";
25
+ }
26
+ function isKeyValue(shape) {
27
+ return shape.type === "keyvalue";
28
+ }
29
+ function isResource(shape) {
30
+ return shape.type === "resource";
31
+ }
32
+ function treeNodeToRecord(node) {
33
+ if (node.children.length === 0) {
34
+ return { [node.name]: null };
35
+ }
36
+ const childRecord = {};
37
+ for (const child of node.children) {
38
+ const childObj = treeNodeToRecord(child);
39
+ Object.assign(childRecord, childObj);
40
+ }
41
+ return { [node.name]: childRecord };
42
+ }
43
+ function isPlainObject(item) {
44
+ return item !== null && typeof item === "object" && !Array.isArray(item);
45
+ }
46
+ var customRenderers = new Map;
47
+ function registerRenderer(shapeType, renderer) {
48
+ customRenderers.set(shapeType, renderer);
49
+ }
50
+ function unregisterRenderer(shapeType) {
51
+ return customRenderers.delete(shapeType);
52
+ }
53
+ function clearRenderers() {
54
+ customRenderers.clear();
55
+ }
56
+ function render(shape, options) {
57
+ const customRenderer = customRenderers.get(shape.type);
58
+ if (customRenderer) {
59
+ return customRenderer(shape, options);
60
+ }
61
+ const format = options?.format;
62
+ if (format === "json") {
63
+ if (isCollection(shape)) {
64
+ return renderJson(shape.items);
65
+ }
66
+ if (isHierarchy(shape)) {
67
+ return renderJson(treeNodeToRecord(shape.root));
68
+ }
69
+ if (isKeyValue(shape)) {
70
+ return renderJson(shape.entries);
71
+ }
72
+ if (isResource(shape)) {
73
+ return renderJson(shape.data);
74
+ }
75
+ }
76
+ if (format === "list" && isCollection(shape)) {
77
+ const listItems = shape.items.map((item) => {
78
+ if (typeof item === "string") {
79
+ return item;
80
+ }
81
+ if (isPlainObject(item)) {
82
+ const name = item.name;
83
+ if (typeof name === "string") {
84
+ return name;
85
+ }
86
+ return JSON.stringify(item);
87
+ }
88
+ return String(item);
89
+ });
90
+ return renderList(listItems);
91
+ }
92
+ if (format === "table" && isCollection(shape)) {
93
+ const items = shape.items.filter(isPlainObject);
94
+ return renderTable(items, shape.headers ? { headers: shape.headers } : undefined);
95
+ }
96
+ if (format === "tree" && isHierarchy(shape)) {
97
+ return renderTree(treeNodeToRecord(shape.root));
98
+ }
99
+ if (format === "text" && isResource(shape)) {
100
+ return renderText(String(shape.data));
101
+ }
102
+ if (isCollection(shape)) {
103
+ const hasObjectItems = shape.items.every(isPlainObject);
104
+ if (hasObjectItems) {
105
+ const items = shape.items;
106
+ return renderTable(items, shape.headers ? { headers: shape.headers } : undefined);
107
+ }
108
+ const listItems = shape.items.map((item) => {
109
+ if (typeof item === "string") {
110
+ return item;
111
+ }
112
+ return String(item);
113
+ });
114
+ return renderList(listItems);
115
+ }
116
+ if (isHierarchy(shape)) {
117
+ return renderTree(treeNodeToRecord(shape.root));
118
+ }
119
+ if (isKeyValue(shape)) {
120
+ return renderJson(shape.entries);
121
+ }
122
+ if (isResource(shape)) {
123
+ const resourceFormat = shape.format ?? "json";
124
+ if (resourceFormat === "markdown") {
125
+ return renderMarkdown(String(shape.data));
126
+ }
127
+ if (resourceFormat === "text") {
128
+ return renderText(String(shape.data));
129
+ }
130
+ return renderJson(shape.data);
131
+ }
132
+ return renderJson(shape);
133
+ }
134
+
135
+ export { isCollection, isHierarchy, isKeyValue, isResource, treeNodeToRecord, isPlainObject, registerRenderer, unregisterRenderer, clearRenderers, render };
@@ -0,0 +1,112 @@
1
+ import { Theme } from "@outfitter/cli/colors";
2
+ /**
3
+ * Available primitive types for demos.
4
+ */
5
+ type PrimitiveId = "colors" | "borders" | "spinner" | "list" | "box" | "table" | "progress" | "tree" | "text" | "markdown" | "indicators";
6
+ /**
7
+ * Categorization for theme methods.
8
+ */
9
+ type ThemeMethodCategory = "semantic" | "utility";
10
+ /**
11
+ * Metadata for a theme method.
12
+ */
13
+ interface ThemeMethodMeta {
14
+ /** Method category (semantic or utility) */
15
+ category: ThemeMethodCategory;
16
+ /** Human-readable description */
17
+ description: string;
18
+ /** Default example text */
19
+ defaultExample: string;
20
+ }
21
+ /**
22
+ * Metadata for a primitive variant (spinner styles, border styles, etc).
23
+ */
24
+ interface VariantMeta<T extends string> {
25
+ /** The variant value */
26
+ value: T;
27
+ /** Human-readable label */
28
+ label: string;
29
+ /** Description of the variant */
30
+ description: string;
31
+ }
32
+ /**
33
+ * Metadata describing a primitive for demo generation.
34
+ */
35
+ interface PrimitiveMeta {
36
+ /** Primitive identifier */
37
+ id: PrimitiveId;
38
+ /** Human-readable name */
39
+ name: string;
40
+ /** Brief description */
41
+ description: string;
42
+ /** Import statement example */
43
+ importExample: string;
44
+ }
45
+ /**
46
+ * Customizable example texts for demos.
47
+ *
48
+ * Keys correspond to theme method names and other example contexts.
49
+ */
50
+ interface ExampleTexts {
51
+ success: string;
52
+ warning: string;
53
+ error: string;
54
+ info: string;
55
+ primary: string;
56
+ secondary: string;
57
+ muted: string;
58
+ accent: string;
59
+ highlight: string;
60
+ link: string;
61
+ destructive: string;
62
+ subtle: string;
63
+ bold: string;
64
+ italic: string;
65
+ underline: string;
66
+ dim: string;
67
+ boxContent: string;
68
+ boxTitle: string;
69
+ spinnerMessage: string;
70
+ progressLabel: string;
71
+ listItems: string[];
72
+ tableData: Record<string, unknown>[];
73
+ treeData: Record<string, unknown>;
74
+ markdownSample: string;
75
+ }
76
+ /**
77
+ * Configuration for demo rendering.
78
+ */
79
+ interface DemoConfig {
80
+ /**
81
+ * Override default example texts.
82
+ */
83
+ examples?: Partial<ExampleTexts>;
84
+ /**
85
+ * Whether to show import statements.
86
+ * @default true
87
+ */
88
+ showCode?: boolean;
89
+ /**
90
+ * Whether to show method/variant descriptions.
91
+ * @default true
92
+ */
93
+ showDescriptions?: boolean;
94
+ }
95
+ /**
96
+ * Function that renders a demo section for a primitive.
97
+ */
98
+ type DemoRenderer = (config: DemoConfig, theme: Theme) => string;
99
+ /**
100
+ * Registry entry for a primitive demo.
101
+ */
102
+ interface DemoRegistryEntry {
103
+ /** Primitive metadata */
104
+ meta: PrimitiveMeta;
105
+ /** Render function */
106
+ render: DemoRenderer;
107
+ }
108
+ /**
109
+ * Checks if a string is a valid PrimitiveId.
110
+ */
111
+ declare function isPrimitiveId(value: string): value is PrimitiveId;
112
+ export { PrimitiveId, ThemeMethodCategory, ThemeMethodMeta, VariantMeta, PrimitiveMeta, ExampleTexts, DemoConfig, DemoRenderer, DemoRegistryEntry, isPrimitiveId };
@@ -0,0 +1,300 @@
1
+ /**
2
+ * A tree node for hierarchical data structures.
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * const tree: TreeNode = {
7
+ * name: "src",
8
+ * children: [
9
+ * { name: "index.ts", children: [] },
10
+ * { name: "utils", children: [{ name: "helpers.ts", children: [] }] },
11
+ * ],
12
+ * };
13
+ * ```
14
+ */
15
+ interface TreeNode {
16
+ /** The name/label of this node */
17
+ name: string;
18
+ /** Child nodes (empty array for leaf nodes) */
19
+ children: TreeNode[];
20
+ }
21
+ /**
22
+ * A collection of items, rendered as table (objects) or list (primitives).
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // Table rendering (array of objects)
27
+ * const users: Collection = {
28
+ * type: "collection",
29
+ * items: [{ name: "Alice", age: 30 }, { name: "Bob", age: 25 }],
30
+ * headers: { name: "Name", age: "Age" },
31
+ * };
32
+ *
33
+ * // List rendering (array of primitives)
34
+ * const tasks: Collection = {
35
+ * type: "collection",
36
+ * items: ["Task 1", "Task 2", "Task 3"],
37
+ * };
38
+ * ```
39
+ */
40
+ interface Collection {
41
+ /** Discriminant for Collection type */
42
+ type: "collection";
43
+ /** Array of items to render */
44
+ items: unknown[];
45
+ /** Optional custom headers for table rendering */
46
+ headers?: Record<string, string>;
47
+ }
48
+ /**
49
+ * A hierarchical tree structure.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * const fileTree: Hierarchy = {
54
+ * type: "hierarchy",
55
+ * root: {
56
+ * name: "project",
57
+ * children: [
58
+ * { name: "src", children: [{ name: "index.ts", children: [] }] },
59
+ * { name: "package.json", children: [] },
60
+ * ],
61
+ * },
62
+ * };
63
+ * ```
64
+ */
65
+ interface Hierarchy {
66
+ /** Discriminant for Hierarchy type */
67
+ type: "hierarchy";
68
+ /** Root node of the tree */
69
+ root: TreeNode;
70
+ }
71
+ /**
72
+ * Key-value pairs for displaying configuration or metadata.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const config: KeyValue = {
77
+ * type: "keyvalue",
78
+ * entries: {
79
+ * name: "my-app",
80
+ * version: "1.0.0",
81
+ * debug: true,
82
+ * },
83
+ * };
84
+ * ```
85
+ */
86
+ interface KeyValue {
87
+ /** Discriminant for KeyValue type */
88
+ type: "keyvalue";
89
+ /** Key-value entries to display */
90
+ entries: Record<string, unknown>;
91
+ }
92
+ /**
93
+ * A resource with content in a specific format.
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const jsonResource: Resource = {
98
+ * type: "resource",
99
+ * data: { name: "test", value: 42 },
100
+ * format: "json",
101
+ * };
102
+ *
103
+ * const markdownResource: Resource = {
104
+ * type: "resource",
105
+ * data: "# Heading\n\nSome **bold** text",
106
+ * format: "markdown",
107
+ * };
108
+ * ```
109
+ */
110
+ interface Resource {
111
+ /** Discriminant for Resource type */
112
+ type: "resource";
113
+ /** The content to render */
114
+ data: unknown;
115
+ /** Output format (defaults to "json") */
116
+ format?: "json" | "markdown" | "text";
117
+ }
118
+ /**
119
+ * Discriminated union of all output shape types.
120
+ *
121
+ * Use the type guards {@link isCollection}, {@link isHierarchy},
122
+ * {@link isKeyValue}, and {@link isResource} for type narrowing.
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * function processShape(shape: Shape) {
127
+ * if (isCollection(shape)) {
128
+ * console.log(`Collection with ${shape.items.length} items`);
129
+ * } else if (isHierarchy(shape)) {
130
+ * console.log(`Tree rooted at ${shape.root.name}`);
131
+ * }
132
+ * }
133
+ * ```
134
+ */
135
+ type Shape = Collection | Hierarchy | KeyValue | Resource;
136
+ /**
137
+ * Options for the unified {@link render} function.
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const options: RenderOptions = {
142
+ * width: 80,
143
+ * color: true,
144
+ * format: "json",
145
+ * };
146
+ * ```
147
+ */
148
+ interface RenderOptions {
149
+ /** Maximum width for output (used by some renderers) */
150
+ width?: number;
151
+ /** Whether to use ANSI colors in output */
152
+ color?: boolean;
153
+ /** Force a specific output format, overriding auto-selection */
154
+ format?: "table" | "list" | "tree" | "json" | "text";
155
+ }
156
+ /**
157
+ * Type guard for {@link Collection} shapes.
158
+ *
159
+ * @param shape - Shape to check
160
+ * @returns `true` if the shape is a Collection
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * if (isCollection(shape)) {
165
+ * console.log(`Has ${shape.items.length} items`);
166
+ * }
167
+ * ```
168
+ */
169
+ declare function isCollection(shape: Shape): shape is Collection;
170
+ /**
171
+ * Type guard for {@link Hierarchy} shapes.
172
+ *
173
+ * @param shape - Shape to check
174
+ * @returns `true` if the shape is a Hierarchy
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * if (isHierarchy(shape)) {
179
+ * console.log(`Root: ${shape.root.name}`);
180
+ * }
181
+ * ```
182
+ */
183
+ declare function isHierarchy(shape: Shape): shape is Hierarchy;
184
+ /**
185
+ * Type guard for {@link KeyValue} shapes.
186
+ *
187
+ * @param shape - Shape to check
188
+ * @returns `true` if the shape is a KeyValue
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * if (isKeyValue(shape)) {
193
+ * console.log(`Keys: ${Object.keys(shape.entries).join(", ")}`);
194
+ * }
195
+ * ```
196
+ */
197
+ declare function isKeyValue(shape: Shape): shape is KeyValue;
198
+ /**
199
+ * Type guard for {@link Resource} shapes.
200
+ *
201
+ * @param shape - Shape to check
202
+ * @returns `true` if the shape is a Resource
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * if (isResource(shape)) {
207
+ * console.log(`Format: ${shape.format ?? "json"}`);
208
+ * }
209
+ * ```
210
+ */
211
+ declare function isResource(shape: Shape): shape is Resource;
212
+ /**
213
+ * Converts a TreeNode to the Record format expected by renderTree.
214
+ */
215
+ declare function treeNodeToRecord(node: TreeNode): Record<string, unknown>;
216
+ /**
217
+ * Checks if an item is a plain object (not null, not array, not primitive).
218
+ */
219
+ declare function isPlainObject(item: unknown): item is Record<string, unknown>;
220
+ /**
221
+ * A function that renders a shape to a string.
222
+ *
223
+ * @typeParam S - The specific shape type this renderer handles
224
+ */
225
+ type ShapeRenderer<S extends Shape = Shape> = (shape: S, options?: RenderOptions) => string;
226
+ /**
227
+ * Registers a custom renderer for a shape type.
228
+ * Custom renderers take precedence over built-in renderers.
229
+ *
230
+ * @param shapeType - The shape type to register (e.g., "collection", "hierarchy")
231
+ * @param renderer - The renderer function to use for this shape type
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * registerRenderer("collection", (shape, opts) => {
236
+ * return shape.items.map(item => `- ${item}`).join("\n");
237
+ * });
238
+ * ```
239
+ */
240
+ declare function registerRenderer<S extends Shape>(shapeType: S["type"], renderer: ShapeRenderer<S>): void;
241
+ /**
242
+ * Removes a custom renderer, reverting to built-in behavior.
243
+ *
244
+ * @param shapeType - The shape type to unregister
245
+ * @returns `true` if a renderer was removed, `false` if none existed
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * unregisterRenderer("collection"); // Reverts to built-in table/list rendering
250
+ * ```
251
+ */
252
+ declare function unregisterRenderer(shapeType: string): boolean;
253
+ /**
254
+ * Clears all custom renderers, reverting to built-in behavior.
255
+ * Useful for testing to ensure clean state between tests.
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * afterEach(() => {
260
+ * clearRenderers();
261
+ * });
262
+ * ```
263
+ */
264
+ declare function clearRenderers(): void;
265
+ /**
266
+ * Unified render function that auto-selects the appropriate renderer based on shape type.
267
+ *
268
+ * Auto-selection logic:
269
+ * - **Collection**: Uses {@link renderTable} for object items, {@link renderList} for primitives
270
+ * - **Hierarchy**: Uses {@link renderTree}
271
+ * - **KeyValue**: Renders as formatted key-value pairs (JSON-like)
272
+ * - **Resource**: Uses {@link renderJson}, {@link renderMarkdown}, or {@link renderText} based on format
273
+ *
274
+ * The `options.format` parameter can override auto-selection.
275
+ *
276
+ * @param shape - The shape to render
277
+ * @param options - Rendering options
278
+ * @returns Rendered string output
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * // Collection auto-selects table or list
283
+ * render({ type: "collection", items: [{ name: "Alice" }] });
284
+ * render({ type: "collection", items: ["item1", "item2"] });
285
+ *
286
+ * // Hierarchy uses tree rendering
287
+ * render({ type: "hierarchy", root: { name: "src", children: [] } });
288
+ *
289
+ * // KeyValue renders formatted pairs
290
+ * render({ type: "keyvalue", entries: { key: "value" } });
291
+ *
292
+ * // Resource respects format option
293
+ * render({ type: "resource", data: obj, format: "json" });
294
+ *
295
+ * // Override with options.format
296
+ * render({ type: "collection", items: [{ a: 1 }] }, { format: "json" });
297
+ * ```
298
+ */
299
+ declare function render(shape: Shape, options?: RenderOptions): string;
300
+ export { TreeNode, Collection, Hierarchy, KeyValue, Resource, Shape, RenderOptions, isCollection, isHierarchy, isKeyValue, isResource, treeNodeToRecord, isPlainObject, ShapeRenderer, registerRenderer, unregisterRenderer, clearRenderers, render };
@@ -0,0 +1,66 @@
1
+ import { WritableStream } from "./tui-b14ry1j1";
2
+ /**
3
+ * Spinner frame sets.
4
+ */
5
+ declare const SPINNER_FRAMES: {
6
+ readonly dots: readonly ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
7
+ readonly line: readonly ["-", "\\", "|", "/"];
8
+ readonly simple: readonly ["◐", "◓", "◑", "◒"];
9
+ };
10
+ /**
11
+ * Available spinner styles.
12
+ */
13
+ type SpinnerStyle = keyof typeof SPINNER_FRAMES;
14
+ /**
15
+ * Options for creating a spinner.
16
+ */
17
+ interface SpinnerOptions {
18
+ /** Spinner style */
19
+ style?: SpinnerStyle;
20
+ /** Target stream */
21
+ stream?: WritableStream;
22
+ /** Frame interval in ms */
23
+ interval?: number;
24
+ }
25
+ /**
26
+ * Spinner interface for animated progress indication.
27
+ */
28
+ interface Spinner {
29
+ /** Start the spinner */
30
+ start(): void;
31
+ /** Update the spinner message */
32
+ update(message: string): void;
33
+ /** Stop with success state */
34
+ succeed(message?: string): void;
35
+ /** Stop with failure state */
36
+ fail(message?: string): void;
37
+ /** Stop the spinner */
38
+ stop(): void;
39
+ }
40
+ /**
41
+ * Creates an animated spinner for indicating progress.
42
+ *
43
+ * In TTY mode, shows an animated spinner. In non-TTY mode,
44
+ * falls back to static output.
45
+ *
46
+ * @param message - Initial spinner message
47
+ * @param options - Spinner configuration
48
+ * @returns Spinner instance
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { createSpinner } from "@outfitter/tui/streaming";
53
+ *
54
+ * const spinner = createSpinner("Installing dependencies");
55
+ * spinner.start();
56
+ *
57
+ * try {
58
+ * await install();
59
+ * spinner.succeed("Dependencies installed");
60
+ * } catch (error) {
61
+ * spinner.fail("Installation failed");
62
+ * }
63
+ * ```
64
+ */
65
+ declare function createSpinner(message: string, options?: SpinnerOptions): Spinner;
66
+ export { SpinnerStyle, SpinnerOptions, Spinner, createSpinner };
@@ -0,0 +1,54 @@
1
+ /**
2
+ * ANSI escape sequences for terminal control.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ /**
7
+ * ANSI escape sequences for cursor and screen control.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { ANSI } from "@outfitter/tui/streaming";
12
+ *
13
+ * // Move cursor up 2 lines and clear
14
+ * process.stdout.write(ANSI.cursorUp(2) + ANSI.clearLine);
15
+ *
16
+ * // Hide cursor during animation
17
+ * process.stdout.write(ANSI.hideCursor);
18
+ * // ... do animation ...
19
+ * process.stdout.write(ANSI.showCursor);
20
+ * ```
21
+ */
22
+ declare const ANSI: {
23
+ /** Move cursor up n lines */
24
+ readonly cursorUp: (n: number) => string;
25
+ /** Move cursor down n lines */
26
+ readonly cursorDown: (n: number) => string;
27
+ /** Move cursor right n columns */
28
+ readonly cursorRight: (n: number) => string;
29
+ /** Move cursor left n columns */
30
+ readonly cursorLeft: (n: number) => string;
31
+ /** Move cursor to beginning of line */
32
+ readonly cursorToStart: "\x1B[G";
33
+ /** Clear entire line */
34
+ readonly clearLine: "\x1B[2K";
35
+ /** Clear from cursor to end of screen */
36
+ readonly clearToEnd: "\x1B[0J";
37
+ /** Clear from cursor to beginning of screen */
38
+ readonly clearToStart: "\x1B[1J";
39
+ /** Clear entire screen */
40
+ readonly clearScreen: "\x1B[2J";
41
+ /** Hide cursor */
42
+ readonly hideCursor: "\x1B[?25l";
43
+ /** Show cursor */
44
+ readonly showCursor: "\x1B[?25h";
45
+ /** Save cursor position */
46
+ readonly saveCursor: "\x1B[s";
47
+ /** Restore cursor position */
48
+ readonly restoreCursor: "\x1B[u";
49
+ /** Carriage return (move to start of line) */
50
+ readonly carriageReturn: "\r";
51
+ /** New line */
52
+ readonly newLine: "\n";
53
+ };
54
+ export { ANSI };
@@ -0,0 +1,30 @@
1
+ // @bun
2
+ // packages/tui/src/render/format.ts
3
+ function formatDuration(ms) {
4
+ if (ms < 1000)
5
+ return `${ms}ms`;
6
+ const seconds = Math.floor(ms / 1000) % 60;
7
+ const minutes = Math.floor(ms / 60000) % 60;
8
+ const hours = Math.floor(ms / 3600000);
9
+ const parts = [];
10
+ if (hours > 0)
11
+ parts.push(`${hours}h`);
12
+ if (minutes > 0)
13
+ parts.push(`${minutes}m`);
14
+ if (seconds > 0 || parts.length === 0)
15
+ parts.push(`${seconds}s`);
16
+ return parts.join(" ");
17
+ }
18
+ function formatBytes(bytes) {
19
+ const units = ["B", "KB", "MB", "GB", "TB"];
20
+ let unitIndex = 0;
21
+ let size = bytes;
22
+ while (size >= 1024 && unitIndex < units.length - 1) {
23
+ size /= 1024;
24
+ unitIndex++;
25
+ }
26
+ const formatted = unitIndex === 0 ? size.toString() : size.toFixed(1).replace(/\.0$/, "");
27
+ return `${formatted} ${units[unitIndex]}`;
28
+ }
29
+
30
+ export { formatDuration, formatBytes };
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ import {
3
+ init_borders
4
+ } from "./tui-2pwhzg55.js";
5
+
6
+ // packages/tui/src/borders/index.ts
7
+ init_borders();