@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,328 @@
1
+ import { TreeGuideStyle } from "./tui-3dyxg62j";
2
+ /**
3
+ * Delimiter set with unicode and fallback representations.
4
+ */
5
+ interface DelimiterSet {
6
+ /** Unicode character for modern terminals */
7
+ unicode: string;
8
+ /** ASCII fallback for limited terminals */
9
+ fallback: string;
10
+ }
11
+ /**
12
+ * Available delimiter names.
13
+ */
14
+ type DelimiterName = keyof typeof DELIMITERS;
15
+ /**
16
+ * Registry of delimiter characters with unicode and fallback support.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { DELIMITERS, getDelimiter } from "@outfitter/tui/render/stack";
21
+ *
22
+ * // Access directly
23
+ * console.log(DELIMITERS.bullet.unicode); // "•"
24
+ *
25
+ * // Or use helper
26
+ * console.log(getDelimiter("bullet")); // "•" or "*"
27
+ * ```
28
+ */
29
+ declare const DELIMITERS: {
30
+ readonly space: {
31
+ readonly unicode: " ";
32
+ readonly fallback: " ";
33
+ };
34
+ readonly bullet: {
35
+ readonly unicode: "•";
36
+ readonly fallback: "*";
37
+ };
38
+ readonly dot: {
39
+ readonly unicode: "·";
40
+ readonly fallback: ".";
41
+ };
42
+ readonly pipe: {
43
+ readonly unicode: "│";
44
+ readonly fallback: "|";
45
+ };
46
+ readonly arrow: {
47
+ readonly unicode: "→";
48
+ readonly fallback: "->";
49
+ };
50
+ readonly slash: {
51
+ readonly unicode: "/";
52
+ readonly fallback: "/";
53
+ };
54
+ readonly colon: {
55
+ readonly unicode: ":";
56
+ readonly fallback: ":";
57
+ };
58
+ };
59
+ /**
60
+ * Gets a delimiter character with automatic unicode/fallback selection.
61
+ *
62
+ * @param name - The delimiter name
63
+ * @param forceUnicode - Override unicode detection
64
+ * @returns The appropriate delimiter character
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * getDelimiter("bullet"); // "•" (in unicode terminal)
69
+ * getDelimiter("bullet", false); // "*" (force fallback)
70
+ * ```
71
+ */
72
+ declare function getDelimiter(name: DelimiterName, forceUnicode?: boolean): string;
73
+ /**
74
+ * Known marker names from INDICATORS.marker.
75
+ */
76
+ type MarkerName = "circleDot" | "circleOutline" | "circle" | "checkbox" | "checkboxChecked" | "pointer" | "dash";
77
+ /**
78
+ * Gets a marker character, either from INDICATORS or as a custom string.
79
+ *
80
+ * @param nameOrChar - Marker name from INDICATORS.marker or custom string
81
+ * @param forceUnicode - Override unicode detection
82
+ * @returns The marker character
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * getMarker("circleDot"); // "◉"
87
+ * getMarker("circleDot", false); // "(*)"
88
+ * getMarker("★"); // "★" (custom, returned as-is)
89
+ * ```
90
+ */
91
+ declare function getMarker(nameOrChar: MarkerName | string, forceUnicode?: boolean): string;
92
+ /**
93
+ * Vertical stack display modes.
94
+ *
95
+ * - `plain`: Simple newlines, no guides
96
+ * - `guide`: Vertical guide continuation (│)
97
+ * - `tree`: Tree-style with fork/end markers (├/└)
98
+ * - `boxed`: Each item wrapped in a box
99
+ * - `compact`: Single line per item using compact representation
100
+ */
101
+ type VStackMode = "plain" | "guide" | "tree" | "boxed" | "compact";
102
+ /**
103
+ * Semantic states for stack items.
104
+ * Theme maps these to visual markers.
105
+ */
106
+ type ItemState = "default" | "current" | "focused" | "checked" | "disabled";
107
+ /**
108
+ * Theme configuration for stack rendering.
109
+ * Maps semantic states to visual representation.
110
+ */
111
+ interface StackTheme {
112
+ /** Map semantic states to marker names */
113
+ markers: Record<ItemState, MarkerName>;
114
+ /** Default delimiter for compact mode */
115
+ delimiter?: DelimiterName;
116
+ /** Default guide style */
117
+ guide?: TreeGuideStyle;
118
+ }
119
+ /**
120
+ * Default theme for stack rendering.
121
+ */
122
+ declare const DEFAULT_STACK_THEME: StackTheme;
123
+ /**
124
+ * An item in a stack with optional metadata.
125
+ */
126
+ interface StackItem {
127
+ /** Full content (header + body lines) */
128
+ content: string | string[];
129
+ /** Compact single-line representation */
130
+ compact?: string;
131
+ /** Semantic state (resolved via theme) */
132
+ state?: ItemState;
133
+ /** Explicit marker (bypasses theme) */
134
+ marker?: MarkerName | string;
135
+ /** Style function to apply to content */
136
+ style?: (s: string) => string;
137
+ }
138
+ /**
139
+ * A rendered block with metadata for composition.
140
+ * Both Box and StackBox satisfy this interface.
141
+ */
142
+ interface Renderable {
143
+ /** Rendered string representation */
144
+ readonly output: string;
145
+ /** Width in characters */
146
+ readonly width: number;
147
+ /** Height in lines */
148
+ readonly height: number;
149
+ }
150
+ /**
151
+ * A rendered stack with metadata for composition.
152
+ * Alias for Renderable (for semantic clarity when returning from stack functions).
153
+ */
154
+ type StackBox = Renderable;
155
+ /**
156
+ * Type guard to check if a value is a Renderable (Box or StackBox).
157
+ */
158
+ declare function isRenderable(value: unknown): value is Renderable;
159
+ /**
160
+ * Options for horizontal stack.
161
+ */
162
+ interface HStackOptions {
163
+ /** Delimiter between items (name or custom string) */
164
+ delimiter?: DelimiterName | string;
165
+ /** Gap (spaces) around delimiter */
166
+ gap?: number;
167
+ /** Vertical alignment for multi-line items */
168
+ align?: "top" | "center" | "bottom";
169
+ }
170
+ /**
171
+ * Options for vertical stack.
172
+ */
173
+ interface VStackOptions {
174
+ /** Display mode */
175
+ mode?: VStackMode;
176
+ /** Gap (lines) between items */
177
+ gap?: number;
178
+ /** Theme for marker resolution */
179
+ theme?: Partial<StackTheme>;
180
+ /** Shorthand for theme.guide */
181
+ guide?: TreeGuideStyle;
182
+ }
183
+ /**
184
+ * Input type for stack functions.
185
+ * Accepts strings, StackItems, or Renderables (Box/StackBox).
186
+ */
187
+ type StackInput = string | StackItem | Renderable;
188
+ /**
189
+ * Joins items horizontally with a delimiter.
190
+ *
191
+ * @param items - Items to join (strings or StackItems)
192
+ * @param options - Configuration options
193
+ * @returns Joined string
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * // Simple delimiter
198
+ * hstack(["a", "b", "c"], { delimiter: "bullet", gap: 1 });
199
+ * // → "a • b • c"
200
+ *
201
+ * // Multi-line with alignment
202
+ * hstack(["Line1\nLine2", "Single"], { delimiter: "pipe", align: "center" });
203
+ * ```
204
+ */
205
+ declare function hstack(items: StackInput[], options?: HStackOptions): string;
206
+ /**
207
+ * Creates a horizontal stack with metadata for composition.
208
+ *
209
+ * @param items - Items to join
210
+ * @param options - Configuration options
211
+ * @returns StackBox with output, width, and height
212
+ */
213
+ declare function createHStack(items: StackInput[], options?: HStackOptions): StackBox;
214
+ /**
215
+ * Creates a stack item with header and optional body.
216
+ *
217
+ * @param header - Header line
218
+ * @param body - Optional body lines
219
+ * @param options - Item options (state, marker, compact, style)
220
+ * @returns StackItem
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * vstackItem("feature/auth", ["PR #190 (Draft)", "2 hours ago"], {
225
+ * state: "current",
226
+ * compact: "feature/auth • Draft • 2h ago"
227
+ * });
228
+ * ```
229
+ */
230
+ declare function vstackItem(header: string, body?: string[], options?: {
231
+ state?: ItemState;
232
+ marker?: MarkerName | string;
233
+ compact?: string;
234
+ style?: (s: string) => string;
235
+ }): StackItem;
236
+ /**
237
+ * Stacks items vertically with configurable display mode.
238
+ *
239
+ * @param items - Items to stack (strings or StackItems)
240
+ * @param options - Configuration options
241
+ * @returns Formatted string
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * // Guide mode (gt log style)
246
+ * vstack([
247
+ * vstackItem("feature/auth", ["PR #190"], { state: "current" }),
248
+ * vstackItem("feature/api", ["PR #189"]),
249
+ * ], { mode: "guide" });
250
+ * // → ◉ feature/auth
251
+ * // │ PR #190
252
+ * // │
253
+ * // ○ feature/api
254
+ * // │ PR #189
255
+ *
256
+ * // Compact mode
257
+ * vstack(items, { mode: "compact" });
258
+ * // → ◉ feature/auth • Draft • 2h ago
259
+ * // ○ feature/api • 1d ago
260
+ * ```
261
+ */
262
+ declare function vstack(items: StackInput[], options?: VStackOptions): string;
263
+ /**
264
+ * Creates a vertical stack with metadata for composition.
265
+ *
266
+ * @param items - Items to stack
267
+ * @param options - Configuration options
268
+ * @returns StackBox with output, width, and height
269
+ */
270
+ declare function createVStack(items: StackInput[], options?: VStackOptions): StackBox;
271
+ /**
272
+ * Options for boxify helper.
273
+ */
274
+ interface BoxifyOptions {
275
+ /** Box title */
276
+ title?: string;
277
+ /** Border style */
278
+ border?: "single" | "double" | "rounded" | "heavy" | "none";
279
+ /** Padding inside the box */
280
+ padding?: number;
281
+ }
282
+ /**
283
+ * Wraps content in a box for visual grouping.
284
+ *
285
+ * Convenience wrapper around createBox that accepts any Renderable,
286
+ * string, or string array.
287
+ *
288
+ * @param content - Content to wrap (Renderable, string, or string[])
289
+ * @param options - Box options (title, border, padding)
290
+ * @returns Renderable box that can be used in stacks or nested
291
+ *
292
+ * @example
293
+ * ```typescript
294
+ * // Boxify a stack
295
+ * const stack = createVStack([...], { mode: "guide" });
296
+ * const boxed = boxify(stack, { title: "Branches", border: "rounded" });
297
+ *
298
+ * // Boxify plain text
299
+ * const box = boxify("Hello World", { border: "double" });
300
+ *
301
+ * // Use in composition
302
+ * hstack([boxify(stack1), boxify(stack2)], { gap: 2 });
303
+ * ```
304
+ */
305
+ declare function boxify(content: Renderable | string | string[], options?: BoxifyOptions): Renderable;
306
+ /**
307
+ * Extracts the raw output string from a Renderable.
308
+ *
309
+ * Useful when you need the string representation without the metadata,
310
+ * or when passing to functions that only accept strings.
311
+ *
312
+ * @param content - Renderable or string
313
+ * @returns The output string
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * const stack = createVStack([...], { mode: "guide" });
318
+ * const raw = unbox(stack); // Just the string, no metadata
319
+ *
320
+ * // Useful for logging or string manipulation
321
+ * console.log(unbox(boxedContent));
322
+ *
323
+ * // Pass-through for strings
324
+ * unbox("already a string"); // Returns "already a string"
325
+ * ```
326
+ */
327
+ declare function unbox(content: Renderable | string): string;
328
+ export { DelimiterSet, DelimiterName, DELIMITERS, getDelimiter, MarkerName, getMarker, VStackMode, ItemState, StackTheme, DEFAULT_STACK_THEME, StackItem, Renderable, StackBox, isRenderable, HStackOptions, VStackOptions, StackInput, hstack, createHStack, vstackItem, vstack, createVStack, BoxifyOptions, boxify, unbox };
@@ -0,0 +1,223 @@
1
+ import { BorderStyle } from "./tui-1qh888th";
2
+ /**
3
+ * Text alignment options for box content.
4
+ */
5
+ type BoxAlign = "left" | "center" | "right";
6
+ /**
7
+ * Options for customizing box rendering.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * // Box with title and rounded corners
12
+ * renderBox("Content", {
13
+ * title: "Status",
14
+ * border: "rounded",
15
+ * padding: 1,
16
+ * });
17
+ *
18
+ * // Fixed-width centered box
19
+ * renderBox("Centered", {
20
+ * width: 40,
21
+ * align: "center",
22
+ * });
23
+ * ```
24
+ */
25
+ /**
26
+ * Spacing configuration for individual sides.
27
+ */
28
+ interface BoxSpacing {
29
+ top?: number;
30
+ right?: number;
31
+ bottom?: number;
32
+ left?: number;
33
+ }
34
+ /**
35
+ * Border visibility configuration for individual sides.
36
+ */
37
+ interface BoxBorders {
38
+ top?: boolean;
39
+ right?: boolean;
40
+ bottom?: boolean;
41
+ left?: boolean;
42
+ }
43
+ interface BoxOptions {
44
+ /**
45
+ * Border style to use.
46
+ * @default "single"
47
+ */
48
+ border?: BorderStyle;
49
+ /**
50
+ * Control which borders to render.
51
+ * @default { top: true, right: true, bottom: true, left: true }
52
+ */
53
+ borders?: BoxBorders;
54
+ /**
55
+ * Internal padding (spaces between border and content).
56
+ * Can be a single number for all sides or an object for individual sides.
57
+ * @default 1
58
+ */
59
+ padding?: number | BoxSpacing;
60
+ /**
61
+ * External margin (spacing outside the box).
62
+ * Can be a single number for all sides or an object for individual sides.
63
+ */
64
+ margin?: number | BoxSpacing;
65
+ /**
66
+ * Fixed width for the box. If not specified, auto-fits to content.
67
+ */
68
+ width?: number;
69
+ /**
70
+ * Optional title to display in the top border.
71
+ */
72
+ title?: string;
73
+ /**
74
+ * Content alignment within the box.
75
+ * @default "left"
76
+ */
77
+ align?: BoxAlign;
78
+ /**
79
+ * Content sections separated by internal dividers.
80
+ * Each section can be a string or string[].
81
+ * When provided, takes precedence over the content parameter.
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * renderBox("", {
86
+ * sections: [
87
+ * "Header",
88
+ * ["Line 1", "Line 2"],
89
+ * "Footer"
90
+ * ],
91
+ * border: "single"
92
+ * });
93
+ * // ┌─────────────────┐
94
+ * // │ Header │
95
+ * // ├─────────────────┤
96
+ * // │ Line 1 │
97
+ * // │ Line 2 │
98
+ * // ├─────────────────┤
99
+ * // │ Footer │
100
+ * // └─────────────────┘
101
+ * ```
102
+ */
103
+ sections?: Array<string | string[]>;
104
+ }
105
+ /**
106
+ * A rendered box with metadata for composition.
107
+ */
108
+ interface Box {
109
+ /** Rendered string representation */
110
+ readonly output: string;
111
+ /** Width in characters */
112
+ readonly width: number;
113
+ /** Height in lines */
114
+ readonly height: number;
115
+ }
116
+ /**
117
+ * Content that can be rendered inside a box.
118
+ * - string: Plain text content
119
+ * - string[]: Multi-line content
120
+ * - Box: Nested box (rendered string with metadata)
121
+ */
122
+ type BoxContent = string | string[] | Box;
123
+ /**
124
+ * Normalized spacing with all four sides defined.
125
+ */
126
+ interface NormalizedSpacing {
127
+ top: number;
128
+ right: number;
129
+ bottom: number;
130
+ left: number;
131
+ }
132
+ /**
133
+ * Normalized borders with all four sides defined.
134
+ */
135
+ interface NormalizedBorders {
136
+ top: boolean;
137
+ right: boolean;
138
+ bottom: boolean;
139
+ left: boolean;
140
+ }
141
+ /**
142
+ * Normalizes padding input to have all four sides.
143
+ * For backward compatibility, when padding is a number it only applies to horizontal (left/right).
144
+ * When padding is an object, all sides can be specified.
145
+ */
146
+ declare function normalizePadding(padding: number | BoxSpacing | undefined, defaultValue: number): NormalizedSpacing;
147
+ /**
148
+ * Normalizes margin input to have all four sides.
149
+ * When margin is a number, it applies to all sides.
150
+ */
151
+ declare function normalizeMargin(margin: number | BoxSpacing | undefined, defaultValue: number): NormalizedSpacing;
152
+ /**
153
+ * Normalizes borders input to have all four sides.
154
+ */
155
+ declare function normalizeBorders(borders: BoxBorders | undefined): NormalizedBorders;
156
+ /**
157
+ * Renders content within a bordered panel.
158
+ *
159
+ * Creates a box with Unicode borders around the content. Supports multiple
160
+ * border styles, titles, padding, and alignment options.
161
+ *
162
+ * @param content - The content to render (string or array of strings)
163
+ * @param options - Optional configuration for border style, padding, etc.
164
+ * @returns Formatted box string
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * // Simple box
169
+ * console.log(renderBox("Hello, world!"));
170
+ * // ┌───────────────┐
171
+ * // │ Hello, world! │
172
+ * // └───────────────┘
173
+ *
174
+ * // Box with title
175
+ * console.log(renderBox("All systems go", { title: "Status" }));
176
+ * // ┌─ Status ──────┐
177
+ * // │ All systems go │
178
+ * // └────────────────┘
179
+ *
180
+ * // Rounded box with padding
181
+ * console.log(renderBox(["Line 1", "Line 2"], {
182
+ * border: "rounded",
183
+ * padding: 2,
184
+ * }));
185
+ * // ╭──────────────╮
186
+ * // │ │
187
+ * // │ Line 1 │
188
+ * // │ Line 2 │
189
+ * // │ │
190
+ * // ╰──────────────╯
191
+ * ```
192
+ */
193
+ declare function renderBox(content: string | string[], options?: BoxOptions): string;
194
+ /**
195
+ * Creates a Box object that can be composed with other boxes.
196
+ *
197
+ * Unlike `renderBox` which returns a string, `createBox` returns a Box object
198
+ * with metadata (width, height) that enables nested composition.
199
+ *
200
+ * @param content - The content to render (string, string[], Box, or array of mixed)
201
+ * @param options - Optional configuration for border style, padding, etc.
202
+ * @returns Box object with output, width, and height
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * // Simple box
207
+ * const box = createBox("Hello");
208
+ * console.log(box.output);
209
+ * console.log(`Width: ${box.width}, Height: ${box.height}`);
210
+ *
211
+ * // Nested boxes
212
+ * const inner = createBox("Inner", { border: "rounded" });
213
+ * const outer = createBox(inner, { border: "double", title: "Container" });
214
+ * console.log(outer.output);
215
+ * // ╔═ Container ═══════════════╗
216
+ * // ║ ╭───────────────────────╮ ║
217
+ * // ║ │ Inner │ ║
218
+ * // ║ ╰───────────────────────╯ ║
219
+ * // ╚═══════════════════════════╝
220
+ * ```
221
+ */
222
+ declare function createBox(content: BoxContent | BoxContent[], options?: BoxOptions): Box;
223
+ export { BoxAlign, BoxSpacing, BoxBorders, BoxOptions, Box, BoxContent, NormalizedSpacing, NormalizedBorders, normalizePadding, normalizeMargin, normalizeBorders, renderBox, createBox };
@@ -0,0 +1,20 @@
1
+ // @bun
2
+ import {
3
+ getIndicator,
4
+ isUnicodeSupported
5
+ } from "./tui-pdwbbzwr.js";
6
+
7
+ // packages/tui/src/theme/resolve.ts
8
+ function resolveGlyph(glyph, forceUnicode) {
9
+ const useUnicode = forceUnicode ?? isUnicodeSupported();
10
+ return useUnicode ? glyph.unicode : glyph.fallback;
11
+ }
12
+ function resolveStateMarker(theme, state, forceUnicode) {
13
+ const markerSpec = theme.markers[state] ?? theme.markers.default;
14
+ if (markerSpec.type === "indicator") {
15
+ return getIndicator(markerSpec.category, markerSpec.name, forceUnicode);
16
+ }
17
+ return resolveGlyph(markerSpec.glyph, forceUnicode);
18
+ }
19
+
20
+ export { resolveGlyph, resolveStateMarker };
@@ -0,0 +1,20 @@
1
+ // @bun
2
+ import {
3
+ createCancelledError
4
+ } from "./tui-kcxv8txp.js";
5
+
6
+ // packages/tui/src/prompt/group.ts
7
+ import { Result as R } from "better-result";
8
+ async function promptGroup(steps) {
9
+ const result = {};
10
+ for (const [key, step] of Object.entries(steps)) {
11
+ const stepResult = await step();
12
+ if (stepResult.isErr()) {
13
+ return R.err(createCancelledError(stepResult.error.message));
14
+ }
15
+ result[key] = stepResult.value;
16
+ }
17
+ return R.ok(result);
18
+ }
19
+
20
+ export { promptGroup };
@@ -0,0 +1 @@
1
+ // @bun
@@ -0,0 +1,67 @@
1
+ // @bun
2
+ import {
3
+ createCancelledError
4
+ } from "./tui-kcxv8txp.js";
5
+
6
+ // packages/tui/src/prompt/select.ts
7
+ import { isCancel, multiselect, select } from "@clack/prompts";
8
+ import { Result } from "better-result";
9
+ async function promptSelect(options) {
10
+ const clackOptions = options.options.map((opt) => {
11
+ const mapped = {
12
+ value: opt.value,
13
+ label: opt.label
14
+ };
15
+ if (opt.hint !== undefined) {
16
+ mapped.hint = opt.hint;
17
+ }
18
+ return mapped;
19
+ });
20
+ const selectOptions = {
21
+ message: options.message,
22
+ options: clackOptions
23
+ };
24
+ if (options.initialValue !== undefined) {
25
+ selectOptions.initialValue = options.initialValue;
26
+ }
27
+ if (options.pageSize !== undefined) {
28
+ selectOptions.maxItems = options.pageSize;
29
+ }
30
+ const result = await select(selectOptions);
31
+ if (isCancel(result)) {
32
+ return Result.err(createCancelledError());
33
+ }
34
+ return Result.ok(result);
35
+ }
36
+ async function promptMultiSelect(options) {
37
+ const clackOptions = options.options.map((opt) => {
38
+ const mapped = {
39
+ value: opt.value,
40
+ label: opt.label
41
+ };
42
+ if (opt.hint !== undefined) {
43
+ mapped.hint = opt.hint;
44
+ }
45
+ return mapped;
46
+ });
47
+ const multiselectOptions = {
48
+ message: options.message,
49
+ options: clackOptions
50
+ };
51
+ if (options.initialValues !== undefined) {
52
+ multiselectOptions.initialValues = options.initialValues;
53
+ }
54
+ if (options.required !== undefined) {
55
+ multiselectOptions.required = options.required;
56
+ }
57
+ if (options.pageSize !== undefined) {
58
+ multiselectOptions.maxItems = options.pageSize;
59
+ }
60
+ const result = await multiselect(multiselectOptions);
61
+ if (isCancel(result)) {
62
+ return Result.err(createCancelledError());
63
+ }
64
+ return Result.ok(result);
65
+ }
66
+
67
+ export { promptSelect, promptMultiSelect };