@visulima/tui-kit 0.0.0 → 1.0.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 (371) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE.md +2095 -0
  3. package/README.md +115 -29
  4. package/dist/accordion.d.ts +59 -0
  5. package/dist/accordion.js +1 -0
  6. package/dist/alert.d.ts +26 -0
  7. package/dist/alert.js +1 -0
  8. package/dist/animate-presence.d.ts +18 -0
  9. package/dist/animate-presence.js +1 -0
  10. package/dist/approval-prompt.d.ts +65 -0
  11. package/dist/approval-prompt.js +1 -0
  12. package/dist/area-chart.d.ts +66 -0
  13. package/dist/area-chart.js +1 -0
  14. package/dist/badge.d.ts +22 -0
  15. package/dist/badge.js +1 -0
  16. package/dist/bar-chart.d.ts +67 -0
  17. package/dist/bar-chart.js +1 -0
  18. package/dist/big-text.d.ts +81 -0
  19. package/dist/big-text.js +1 -0
  20. package/dist/blink-dot.d.ts +36 -0
  21. package/dist/blink-dot.js +1 -0
  22. package/dist/breadcrumb.d.ts +33 -0
  23. package/dist/breadcrumb.js +1 -0
  24. package/dist/button.d.ts +45 -0
  25. package/dist/button.js +1 -0
  26. package/dist/calendar.d.ts +72 -0
  27. package/dist/calendar.js +1 -0
  28. package/dist/card.d.ts +57 -0
  29. package/dist/card.js +1 -0
  30. package/dist/checkbox-group.d.ts +59 -0
  31. package/dist/checkbox-group.js +1 -0
  32. package/dist/checkbox.d.ts +48 -0
  33. package/dist/checkbox.js +1 -0
  34. package/dist/code.d.ts +48 -0
  35. package/dist/code.js +2 -0
  36. package/dist/collapsible.d.ts +53 -0
  37. package/dist/collapsible.js +1 -0
  38. package/dist/color-picker.d.ts +71 -0
  39. package/dist/color-picker.js +1 -0
  40. package/dist/command-block.d.ts +47 -0
  41. package/dist/command-block.js +4 -0
  42. package/dist/command-palette.d.ts +82 -0
  43. package/dist/command-palette.js +1 -0
  44. package/dist/confirm-dialog.d.ts +75 -0
  45. package/dist/confirm-dialog.js +1 -0
  46. package/dist/confirm-input.d.ts +38 -0
  47. package/dist/confirm-input.js +1 -0
  48. package/dist/console-overlay.d.ts +54 -0
  49. package/dist/console-overlay.js +1 -0
  50. package/dist/content-switcher.d.ts +57 -0
  51. package/dist/content-switcher.js +1 -0
  52. package/dist/controlled-scroll-view.d.ts +3 -0
  53. package/dist/controlled-scroll-view.js +1 -0
  54. package/dist/data-grid.d.ts +49 -0
  55. package/dist/data-grid.js +1 -0
  56. package/dist/date-picker.d.ts +65 -0
  57. package/dist/date-picker.js +1 -0
  58. package/dist/definition-list.d.ts +44 -0
  59. package/dist/definition-list.js +1 -0
  60. package/dist/dialog.d.ts +110 -0
  61. package/dist/dialog.js +1 -0
  62. package/dist/diff-view.d.ts +85 -0
  63. package/dist/diff-view.js +1 -0
  64. package/dist/digits.d.ts +30 -0
  65. package/dist/digits.js +1 -0
  66. package/dist/directory-tree.d.ts +51 -0
  67. package/dist/directory-tree.js +1 -0
  68. package/dist/divider.d.ts +49 -0
  69. package/dist/divider.js +1 -0
  70. package/dist/drawer.d.ts +53 -0
  71. package/dist/drawer.js +1 -0
  72. package/dist/file-change.d.ts +40 -0
  73. package/dist/file-change.js +1 -0
  74. package/dist/file-picker-entry.d.ts +2 -0
  75. package/dist/file-picker-entry.js +1 -0
  76. package/dist/form.d.ts +81 -0
  77. package/dist/form.js +1 -0
  78. package/dist/gauge.d.ts +87 -0
  79. package/dist/gauge.js +1 -0
  80. package/dist/gradient.d.ts +42 -0
  81. package/dist/gradient.js +1 -0
  82. package/dist/grid.d.ts +40 -0
  83. package/dist/grid.js +1 -0
  84. package/dist/heading.d.ts +33 -0
  85. package/dist/heading.js +1 -0
  86. package/dist/heatmap.d.ts +62 -0
  87. package/dist/heatmap.js +1 -0
  88. package/dist/help.d.ts +52 -0
  89. package/dist/help.js +1 -0
  90. package/dist/histogram.d.ts +62 -0
  91. package/dist/histogram.js +1 -0
  92. package/dist/image.d.ts +26 -0
  93. package/dist/image.js +1 -0
  94. package/dist/index.d.ts +125 -0
  95. package/dist/index.js +1 -0
  96. package/dist/json.d.ts +58 -0
  97. package/dist/json.js +1 -0
  98. package/dist/kbd.d.ts +31 -0
  99. package/dist/kbd.js +1 -0
  100. package/dist/line-chart.d.ts +109 -0
  101. package/dist/line-chart.js +1 -0
  102. package/dist/link.d.ts +38 -0
  103. package/dist/link.js +1 -0
  104. package/dist/loading-indicator.d.ts +29 -0
  105. package/dist/loading-indicator.js +1 -0
  106. package/dist/log.d.ts +38 -0
  107. package/dist/log.js +1 -0
  108. package/dist/markdown.d.ts +40 -0
  109. package/dist/markdown.js +1 -0
  110. package/dist/masked-input.d.ts +50 -0
  111. package/dist/masked-input.js +1 -0
  112. package/dist/menu.d.ts +78 -0
  113. package/dist/menu.js +1 -0
  114. package/dist/message-bubble.d.ts +43 -0
  115. package/dist/message-bubble.js +1 -0
  116. package/dist/model-badge.d.ts +39 -0
  117. package/dist/model-badge.js +1 -0
  118. package/dist/model-selector.d.ts +52 -0
  119. package/dist/model-selector.js +1 -0
  120. package/dist/multi-progress.d.ts +55 -0
  121. package/dist/multi-progress.js +1 -0
  122. package/dist/multi-select.d.ts +65 -0
  123. package/dist/multi-select.js +1 -0
  124. package/dist/notification-badge.d.ts +47 -0
  125. package/dist/notification-badge.js +1 -0
  126. package/dist/number-input.d.ts +85 -0
  127. package/dist/number-input.js +1 -0
  128. package/dist/operation-tree.d.ts +49 -0
  129. package/dist/operation-tree.js +1 -0
  130. package/dist/option-list.d.ts +47 -0
  131. package/dist/option-list.js +1 -0
  132. package/dist/ordered-list.d.ts +24 -0
  133. package/dist/ordered-list.js +1 -0
  134. package/dist/packem_shared/ControlledScrollView-BzlbIUph.js +1 -0
  135. package/dist/packem_shared/FilePicker-V5H2fb-v.js +1 -0
  136. package/dist/packem_shared/ScrollBar-C9i3z3Ft.js +1 -0
  137. package/dist/packem_shared/ScrollBarBox-DZEC8YnV.js +1 -0
  138. package/dist/packem_shared/ScrollList-Djtb2vVy.js +1 -0
  139. package/dist/packem_shared/ScrollView-ESxpl6Hy.js +1 -0
  140. package/dist/packem_shared/TreeNodeMap-cJlYqckB.js +1 -0
  141. package/dist/packem_shared/TreeView-q0l446NV.js +1 -0
  142. package/dist/packem_shared/controlled-scroll-view-DerVKKv6.js +1 -0
  143. package/dist/packem_shared/controlled-scroll-view.d-vF4wevEJ.d.ts +54 -0
  144. package/dist/packem_shared/file-picker.d-Cie6aAMD.d.ts +104 -0
  145. package/dist/packem_shared/line-chart-BbhMhcZg.js +1 -0
  146. package/dist/packem_shared/scroll-bar-box.d-DSBbBsRc.d.ts +30 -0
  147. package/dist/packem_shared/scroll-bar.d-B4sD1hBR.d.ts +18 -0
  148. package/dist/packem_shared/scroll-list.d-BP0UZSY4.d.ts +12 -0
  149. package/dist/packem_shared/scroll-view.d-BqKpI-F-.d.ts +119 -0
  150. package/dist/packem_shared/treeViewTheme-Dq3ekRAC.js +1 -0
  151. package/dist/packem_shared/use-tree-view.d-dXTKoDPM.d.ts +350 -0
  152. package/dist/packem_shared/useTreeView-D0JEqT6W.js +1 -0
  153. package/dist/packem_shared/useTreeViewState-BiTJakkh.js +1 -0
  154. package/dist/packem_shared/variant-config-BJqpNo7H.js +1 -0
  155. package/dist/packem_shared/variant-config.d-D5NnrrQK.d.ts +2 -0
  156. package/dist/paginator.d.ts +69 -0
  157. package/dist/paginator.js +1 -0
  158. package/dist/paragraph.d.ts +38 -0
  159. package/dist/paragraph.js +1 -0
  160. package/dist/path-input.d.ts +67 -0
  161. package/dist/path-input.js +1 -0
  162. package/dist/pie-chart.d.ts +50 -0
  163. package/dist/pie-chart.js +1 -0
  164. package/dist/placeholder.d.ts +55 -0
  165. package/dist/placeholder.js +1 -0
  166. package/dist/popover.d.ts +46 -0
  167. package/dist/popover.js +1 -0
  168. package/dist/progress-bar.d.ts +51 -0
  169. package/dist/progress-bar.js +1 -0
  170. package/dist/progress-circle.d.ts +59 -0
  171. package/dist/progress-circle.js +1 -0
  172. package/dist/qr-code.d.ts +45 -0
  173. package/dist/qr-code.js +1 -0
  174. package/dist/r/accordion.json +24 -0
  175. package/dist/r/alert.json +24 -0
  176. package/dist/r/animate-presence.json +22 -0
  177. package/dist/r/approval-prompt.json +24 -0
  178. package/dist/r/area-chart.json +27 -0
  179. package/dist/r/badge.json +24 -0
  180. package/dist/r/bar-chart.json +24 -0
  181. package/dist/r/big-text.json +23 -0
  182. package/dist/r/blink-dot.json +24 -0
  183. package/dist/r/breadcrumb.json +24 -0
  184. package/dist/r/button.json +24 -0
  185. package/dist/r/calendar.json +24 -0
  186. package/dist/r/card.json +26 -0
  187. package/dist/r/chart-utils.json +24 -0
  188. package/dist/r/checkbox-group.json +24 -0
  189. package/dist/r/checkbox.json +24 -0
  190. package/dist/r/code.json +23 -0
  191. package/dist/r/collapsible.json +24 -0
  192. package/dist/r/color-picker.json +24 -0
  193. package/dist/r/command-block.json +26 -0
  194. package/dist/r/command-palette.json +24 -0
  195. package/dist/r/confirm-dialog.json +24 -0
  196. package/dist/r/confirm-input.json +22 -0
  197. package/dist/r/console-overlay.json +22 -0
  198. package/dist/r/content-switcher.json +24 -0
  199. package/dist/r/controlled-scroll-view.json +24 -0
  200. package/dist/r/data-grid.json +24 -0
  201. package/dist/r/date-picker.json +26 -0
  202. package/dist/r/definition-list.json +24 -0
  203. package/dist/r/dialog.json +24 -0
  204. package/dist/r/diff-view.json +24 -0
  205. package/dist/r/digits.json +24 -0
  206. package/dist/r/directory-tree.json +24 -0
  207. package/dist/r/divider.json +24 -0
  208. package/dist/r/drawer.json +24 -0
  209. package/dist/r/file-change.json +24 -0
  210. package/dist/r/file-picker.json +44 -0
  211. package/dist/r/form.json +24 -0
  212. package/dist/r/gauge.json +24 -0
  213. package/dist/r/gradient.json +24 -0
  214. package/dist/r/grid.json +22 -0
  215. package/dist/r/heading.json +24 -0
  216. package/dist/r/heatmap.json +24 -0
  217. package/dist/r/help.json +22 -0
  218. package/dist/r/histogram.json +26 -0
  219. package/dist/r/image.json +24 -0
  220. package/dist/r/json.json +24 -0
  221. package/dist/r/kbd.json +24 -0
  222. package/dist/r/line-chart.json +26 -0
  223. package/dist/r/link.json +23 -0
  224. package/dist/r/loading-indicator.json +27 -0
  225. package/dist/r/log.json +24 -0
  226. package/dist/r/markdown.json +29 -0
  227. package/dist/r/masked-input.json +22 -0
  228. package/dist/r/menu.json +24 -0
  229. package/dist/r/message-bubble.json +24 -0
  230. package/dist/r/model-badge.json +24 -0
  231. package/dist/r/model-selector.json +24 -0
  232. package/dist/r/multi-progress.json +24 -0
  233. package/dist/r/multi-select.json +24 -0
  234. package/dist/r/notification-badge.json +24 -0
  235. package/dist/r/number-input.json +24 -0
  236. package/dist/r/operation-tree.json +26 -0
  237. package/dist/r/option-list.json +24 -0
  238. package/dist/r/ordered-list.json +22 -0
  239. package/dist/r/paginator.json +22 -0
  240. package/dist/r/paragraph.json +24 -0
  241. package/dist/r/path-input.json +26 -0
  242. package/dist/r/pie-chart.json +24 -0
  243. package/dist/r/placeholder.json +24 -0
  244. package/dist/r/popover.json +24 -0
  245. package/dist/r/progress-bar.json +22 -0
  246. package/dist/r/progress-circle.json +24 -0
  247. package/dist/r/qr-code.json +24 -0
  248. package/dist/r/radio-group.json +24 -0
  249. package/dist/r/registry.json +1051 -0
  250. package/dist/r/scatter-plot.json +27 -0
  251. package/dist/r/scroll-bar-box.json +24 -0
  252. package/dist/r/scroll-bar.json +24 -0
  253. package/dist/r/scroll-list.json +24 -0
  254. package/dist/r/scroll-view.json +24 -0
  255. package/dist/r/scroll.json +58 -0
  256. package/dist/r/search-input.json +26 -0
  257. package/dist/r/select-input-indicator.json +24 -0
  258. package/dist/r/select-input-item.json +24 -0
  259. package/dist/r/select-input.json +28 -0
  260. package/dist/r/shimmer-text.json +24 -0
  261. package/dist/r/sidebar.json +24 -0
  262. package/dist/r/slider.json +24 -0
  263. package/dist/r/sparkline.json +24 -0
  264. package/dist/r/spinner.json +23 -0
  265. package/dist/r/status-line.json +24 -0
  266. package/dist/r/status-message.json +24 -0
  267. package/dist/r/stepper.json +24 -0
  268. package/dist/r/stopwatch.json +22 -0
  269. package/dist/r/streaming-text.json +24 -0
  270. package/dist/r/switch.json +24 -0
  271. package/dist/r/tab.json +22 -0
  272. package/dist/r/table.json +23 -0
  273. package/dist/r/tabs.json +26 -0
  274. package/dist/r/tag-input.json +24 -0
  275. package/dist/r/tag.json +24 -0
  276. package/dist/r/text-input.json +22 -0
  277. package/dist/r/textarea.json +22 -0
  278. package/dist/r/thinking-block.json +24 -0
  279. package/dist/r/time-picker.json +24 -0
  280. package/dist/r/timer.json +22 -0
  281. package/dist/r/toast.json +24 -0
  282. package/dist/r/token-usage.json +24 -0
  283. package/dist/r/tool-call.json +24 -0
  284. package/dist/r/tooltip.json +24 -0
  285. package/dist/r/transition.json +22 -0
  286. package/dist/r/tree-select.json +24 -0
  287. package/dist/r/tree-view.json +64 -0
  288. package/dist/r/unordered-list.json +22 -0
  289. package/dist/r/use-linked-scroll.json +24 -0
  290. package/dist/r/variant-config.json +22 -0
  291. package/dist/radio-group.d.ts +74 -0
  292. package/dist/radio-group.js +1 -0
  293. package/dist/scatter-plot.d.ts +35 -0
  294. package/dist/scatter-plot.js +1 -0
  295. package/dist/scroll-bar-box.d.ts +3 -0
  296. package/dist/scroll-bar-box.js +1 -0
  297. package/dist/scroll-bar.d.ts +3 -0
  298. package/dist/scroll-bar.js +1 -0
  299. package/dist/scroll-list.d.ts +4 -0
  300. package/dist/scroll-list.js +1 -0
  301. package/dist/scroll-view.d.ts +3 -0
  302. package/dist/scroll-view.js +1 -0
  303. package/dist/search-input.d.ts +55 -0
  304. package/dist/search-input.js +1 -0
  305. package/dist/select-input-indicator.d.ts +32 -0
  306. package/dist/select-input-indicator.js +1 -0
  307. package/dist/select-input-item.d.ts +41 -0
  308. package/dist/select-input-item.js +1 -0
  309. package/dist/select-input.d.ts +110 -0
  310. package/dist/select-input.js +1 -0
  311. package/dist/shimmer-text.d.ts +47 -0
  312. package/dist/shimmer-text.js +1 -0
  313. package/dist/sidebar.d.ts +47 -0
  314. package/dist/sidebar.js +1 -0
  315. package/dist/slider.d.ts +103 -0
  316. package/dist/slider.js +1 -0
  317. package/dist/sparkline.d.ts +42 -0
  318. package/dist/sparkline.js +1 -0
  319. package/dist/spinner.d.ts +17 -0
  320. package/dist/spinner.js +1 -0
  321. package/dist/status-line.d.ts +37 -0
  322. package/dist/status-line.js +1 -0
  323. package/dist/status-message.d.ts +21 -0
  324. package/dist/status-message.js +1 -0
  325. package/dist/stepper.d.ts +48 -0
  326. package/dist/stepper.js +1 -0
  327. package/dist/stopwatch.d.ts +49 -0
  328. package/dist/stopwatch.js +1 -0
  329. package/dist/streaming-text.d.ts +46 -0
  330. package/dist/streaming-text.js +1 -0
  331. package/dist/switch.d.ts +55 -0
  332. package/dist/switch.js +1 -0
  333. package/dist/tab.d.ts +19 -0
  334. package/dist/tab.js +1 -0
  335. package/dist/table.d.ts +119 -0
  336. package/dist/table.js +1 -0
  337. package/dist/tabs.d.ts +107 -0
  338. package/dist/tabs.js +1 -0
  339. package/dist/tag-input.d.ts +71 -0
  340. package/dist/tag-input.js +1 -0
  341. package/dist/tag.d.ts +35 -0
  342. package/dist/tag.js +1 -0
  343. package/dist/text-input.d.ts +48 -0
  344. package/dist/text-input.js +1 -0
  345. package/dist/textarea.d.ts +68 -0
  346. package/dist/textarea.js +2 -0
  347. package/dist/thinking-block.d.ts +57 -0
  348. package/dist/thinking-block.js +1 -0
  349. package/dist/time-picker.d.ts +67 -0
  350. package/dist/time-picker.js +1 -0
  351. package/dist/timer.d.ts +59 -0
  352. package/dist/timer.js +1 -0
  353. package/dist/toast.d.ts +49 -0
  354. package/dist/toast.js +1 -0
  355. package/dist/token-usage.d.ts +50 -0
  356. package/dist/token-usage.js +1 -0
  357. package/dist/tool-call.d.ts +33 -0
  358. package/dist/tool-call.js +1 -0
  359. package/dist/tooltip.d.ts +43 -0
  360. package/dist/tooltip.js +1 -0
  361. package/dist/transition.d.ts +74 -0
  362. package/dist/transition.js +1 -0
  363. package/dist/tree-select.d.ts +65 -0
  364. package/dist/tree-select.js +1 -0
  365. package/dist/tree-view-entry.d.ts +4 -0
  366. package/dist/tree-view-entry.js +1 -0
  367. package/dist/unordered-list.d.ts +30 -0
  368. package/dist/unordered-list.js +1 -0
  369. package/dist/use-linked-scroll.d.ts +42 -0
  370. package/dist/use-linked-scroll.js +1 -0
  371. package/package.json +553 -7
@@ -0,0 +1,30 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type Props = {
5
+ /**
6
+ * Color of the digits.
7
+ * @default "cyan"
8
+ */
9
+ readonly color?: LiteralUnion<AnsiColors, string>;
10
+ /**
11
+ * Number of spaces between glyphs.
12
+ * @default 1
13
+ */
14
+ readonly gap?: number;
15
+ /**
16
+ * The value to render. Numbers are stringified; unsupported characters
17
+ * render as `?`.
18
+ */
19
+ readonly value: number | string;
20
+ };
21
+ /**
22
+ * A large seven-segment-style numeric readout. Supports digits, space, minus,
23
+ * dot and colon — enough for counters, clocks and timers.
24
+ */
25
+ declare function Digits({
26
+ color,
27
+ gap,
28
+ value
29
+ }: Props): ReactElement;
30
+ export { Digits, type Props as DigitsProps, Props, Digits as default };
package/dist/digits.js ADDED
@@ -0,0 +1 @@
1
+ import{jsx as n}from"react/jsx-runtime";import f from"@visulima/tui/components/box";import l from"@visulima/tui/components/text";const s={" ":[" "," "," "],0:[" ▄ ","█ █","▀▄▀"],1:[" ▄ "," █ "," ▪ "],2:["▄▄ "," ▄▀","▀▄▄"],3:["▄▄ "," ▄▀","▄▄▀"],4:[" ","█▄█"," █"],5:["▄▄▄","█▄ ","▄▄▀"],6:[" ▄ ","█▄ ","▀▄▀"],7:["▄▄▄"," █"," █ "],8:[" ▄ ","▄▀▄","▀▄▀"],9:[" ▄ ","▀▄█"," ▄▀"],"-":[" "," ─ "," "],".":[" "," "," ▪ "],":":[" "," ▪ "," ▪ "]},u=[" "," ? "," "];function g({color:a="cyan",gap:c=1,value:i}){const m=String(i),e=" ".repeat(Math.max(0,c)),t=[];for(const o of m)t.push(o);const p=[0,1,2].map(o=>t.map(r=>(s[r]??u)[o]).join(e));return n(f,{flexDirection:"column",children:p.map((o,r)=>n(l,{color:a,children:o},r))})}export{g as Digits,g as default};
@@ -0,0 +1,51 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type DirectoryNode = {
5
+ readonly children?: ReadonlyArray<DirectoryNode>;
6
+ readonly name: string;
7
+ readonly type: "directory" | "file";
8
+ };
9
+ type Props = {
10
+ /**
11
+ * Accent color for the focused row.
12
+ * @default "blue"
13
+ */
14
+ readonly accentColor?: LiteralUnion<AnsiColors, string>;
15
+ /**
16
+ * Auto-focus for keyboard navigation.
17
+ */
18
+ readonly autoFocus?: boolean;
19
+ /**
20
+ * Start with every directory expanded.
21
+ * @default false
22
+ */
23
+ readonly defaultExpanded?: boolean;
24
+ /**
25
+ * Color used for directory names.
26
+ * @default "cyan"
27
+ */
28
+ readonly directoryColor?: LiteralUnion<AnsiColors, string>;
29
+ /**
30
+ * The tree to render.
31
+ */
32
+ readonly nodes: ReadonlyArray<DirectoryNode>;
33
+ /**
34
+ * Fires with the path segments when Enter is pressed on a file.
35
+ */
36
+ readonly onSelect?: (path: ReadonlyArray<string>) => void;
37
+ };
38
+ /**
39
+ * A read-only filesystem tree. Directories show a ▸/▾ toggle and a folder
40
+ * glyph; files show a document glyph. Arrow keys navigate, →/← and Space
41
+ * expand/collapse directories, and Enter fires `onSelect` with a file's path.
42
+ */
43
+ declare function DirectoryTree({
44
+ accentColor,
45
+ autoFocus,
46
+ defaultExpanded,
47
+ directoryColor,
48
+ nodes,
49
+ onSelect
50
+ }: Props): ReactElement;
51
+ export { DirectoryNode, DirectoryTree, type Props as DirectoryTreeProps, Props, DirectoryTree as default };
@@ -0,0 +1 @@
1
+ import{jsx as y,jsxs as x}from"react/jsx-runtime";import S from"@visulima/tui/components/box";import w from"@visulima/tui/components/text";import B from"@visulima/tui/hooks/use-focus";import k from"@visulima/tui/hooks/use-input";import{useState as g,useMemo as E,useCallback as $}from"react";function F(i,e){return e===0?0:(i%e+e)%e}function M(i,e){return i?e?"▾ 📁":"▸ 📁":" 📄"}const b=(i,e,u,l,s,f)=>{for(const d of i){const a=`${l}/${d.name}`,m=[...s,d.name];f.push({depth:u,id:a,node:d,path:m}),d.type==="directory"&&d.children!==void 0&&e.has(a)&&b(d.children,e,u+1,a,m,f)}},C=(i,e,u)=>{for(const l of i){const s=`${e}/${l.name}`;l.type==="directory"&&l.children!==void 0&&(u.add(s),C(l.children,s,u))}};function H({accentColor:i="blue",autoFocus:e=!1,defaultExpanded:u=!1,directoryColor:l="cyan",nodes:s,onSelect:f}){const{isFocused:d}=B({autoFocus:e}),[a,m]=g(()=>{if(!u)return new Set;const r=new Set;return C(s,"",r),r}),[p,v]=g(0),h=E(()=>{const r=[];return b(s,a,0,"",[],r),r},[a,s]),A=$((r,t)=>{m(o=>{const n=new Set(o);return t??!n.has(r)?n.add(r):n.delete(r),n})},[]),D=$((r,t)=>{const o=h[p];if(t.upArrow){v(c=>F(c-1,h.length));return}if(t.downArrow){v(c=>F(c+1,h.length));return}if(o===void 0)return;const n=o.node.type==="directory";if(n&&o.node.children!==void 0&&(r===" "||t.rightArrow||t.leftArrow)){let c;t.rightArrow?c=!0:t.leftArrow&&(c=!1),A(o.id,c);return}t.return&&!n&&f?.(o.path)},[p,f,h,A]);return k(D,{isActive:d}),y(S,{flexDirection:"column",children:h.map((r,t)=>{const o=d&&t===p,n=r.node.type==="directory",c=a.has(r.id),j=M(n,c);return x(S,{children:[y(w,{color:o?i:void 0,children:o?"❯":" "}),y(w,{children:" ".repeat(r.depth)}),x(w,{color:n?l:void 0,children:[j," ",r.node.name]})]},r.id)})})}export{H as DirectoryTree,H as default};
@@ -0,0 +1,49 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type Props = {
5
+ /**
6
+ * Custom character to use instead of the default line character.
7
+ */
8
+ readonly character?: string;
9
+ /**
10
+ * Color of the divider line.
11
+ */
12
+ readonly color?: LiteralUnion<AnsiColors, string>;
13
+ /**
14
+ * Render the divider with dim color.
15
+ */
16
+ readonly dimColor?: boolean;
17
+ /**
18
+ * Optional label rendered in the middle of a horizontal divider.
19
+ */
20
+ readonly label?: string;
21
+ /**
22
+ * Padding around the label.
23
+ * @default 1
24
+ */
25
+ readonly labelPadding?: number;
26
+ /**
27
+ * Total length of the divider. When omitted, horizontal dividers stretch to
28
+ * fill the available space and vertical dividers default to one row.
29
+ */
30
+ readonly length?: number;
31
+ /**
32
+ * Orientation of the divider.
33
+ * @default "horizontal"
34
+ */
35
+ readonly orientation?: "horizontal" | "vertical";
36
+ };
37
+ /**
38
+ * Horizontal or vertical divider line, optionally with a centered label.
39
+ */
40
+ declare function Divider({
41
+ character,
42
+ color,
43
+ dimColor,
44
+ label,
45
+ labelPadding,
46
+ length,
47
+ orientation
48
+ }: Props): ReactElement;
49
+ export { Divider, type Props as DividerProps, Props, Divider as default };
@@ -0,0 +1 @@
1
+ import{jsx as r,jsxs as f}from"react/jsx-runtime";import e from"@visulima/tui/components/box";import t from"@visulima/tui/components/text";import w from"@visulima/tui/hooks/use-window-size";function S({character:x,color:i,dimColor:l=!1,label:a,labelPadding:p=1,length:o,orientation:d="horizontal"}){const{columns:s}=w(),n=x??(d==="horizontal"?"─":"│");if(d==="vertical"){const m=o??1;return r(e,{flexDirection:"column",height:m,children:Array.from({length:m},(v,u)=>r(t,{color:i,dimColor:l,children:n},`divider-row-${u}`))})}const c=Math.min(500,o??Math.max(s,1));if(a===void 0)return r(e,{flexGrow:o===void 0?1:0,width:o,children:r(t,{color:i,dimColor:l,wrap:"truncate",children:n.repeat(c)})});const h=" ".repeat(p);return f(e,{flexGrow:o===void 0?1:0,width:o,children:[r(e,{flexGrow:1,flexShrink:1,children:r(t,{color:i,dimColor:l,wrap:"truncate",children:n.repeat(c)})}),r(e,{flexShrink:0,children:f(t,{color:i,dimColor:l,children:[h,a,h]})}),r(e,{flexGrow:1,flexShrink:1,children:r(t,{color:i,dimColor:l,wrap:"truncate",children:n.repeat(c)})})]})}export{S as Divider,S as default};
@@ -0,0 +1,53 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactNode, ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type Props = {
5
+ /**
6
+ * Accent color for the border and title.
7
+ * @default "blue"
8
+ */
9
+ readonly accentColor?: LiteralUnion<AnsiColors, string>;
10
+ /**
11
+ * Drawer body.
12
+ */
13
+ readonly children: ReactNode;
14
+ /**
15
+ * Whether the drawer is open. When false, nothing is rendered.
16
+ */
17
+ readonly isOpen: boolean;
18
+ /**
19
+ * Fires when Escape is pressed while open.
20
+ */
21
+ readonly onClose?: () => void;
22
+ /**
23
+ * Edge the drawer is anchored to. Left/right drawers take a fixed `size`
24
+ * as width; top/bottom take it as height.
25
+ * @default "right"
26
+ */
27
+ readonly side?: "bottom" | "left" | "right" | "top";
28
+ /**
29
+ * Fixed extent (width for left/right, height for top/bottom) in cells.
30
+ * @default 32
31
+ */
32
+ readonly size?: number;
33
+ /**
34
+ * Optional title shown in the drawer header.
35
+ */
36
+ readonly title?: string;
37
+ };
38
+ /**
39
+ * A slide-over panel anchored to a terminal edge. Rendered as a bordered box
40
+ * sized along one axis; Escape fires `onClose`, and nothing renders while
41
+ * closed. Terminals have no true overlay layer, so place the drawer where it
42
+ * should appear in your layout.
43
+ */
44
+ declare function Drawer({
45
+ accentColor,
46
+ children,
47
+ isOpen,
48
+ onClose,
49
+ side,
50
+ size,
51
+ title
52
+ }: Props): ReactElement | null;
53
+ export { Drawer, type Props as DrawerProps, Props, Drawer as default };
package/dist/drawer.js ADDED
@@ -0,0 +1 @@
1
+ import{jsxs as s,jsx as r}from"react/jsx-runtime";import e from"@visulima/tui/components/box";import m from"@visulima/tui/components/text";import a from"@visulima/tui/hooks/use-input";import{useCallback as h}from"react";function j({accentColor:i="blue",children:u,isOpen:t,onClose:n,side:l="right",size:c=32,title:o}){const f=h((b,p)=>{p.escape&&n?.()},[n]);if(a(f,{isActive:t}),!t)return null;const d=l==="left"||l==="right";return s(e,{borderColor:i,borderStyle:"round",flexDirection:"column",height:d?void 0:c,paddingX:1,width:d?c:void 0,children:[o===void 0?void 0:s(e,{justifyContent:"space-between",children:[r(m,{bold:!0,color:i,children:o}),r(m,{dimColor:!0,children:"esc"})]}),r(e,{flexDirection:"column",marginTop:o===void 0?0:1,children:u})]})}export{j as Drawer,j as default};
@@ -0,0 +1,40 @@
1
+ import { ReactElement } from 'react';
2
+ type FileChangeStatus = "added" | "deleted" | "modified" | "renamed";
3
+ type Props = {
4
+ /**
5
+ * Number of added lines.
6
+ * @default 0
7
+ */
8
+ readonly additions?: number;
9
+ /**
10
+ * Total width of the +/- change bar in cells.
11
+ * @default 10
12
+ */
13
+ readonly barWidth?: number;
14
+ /**
15
+ * Number of removed lines.
16
+ * @default 0
17
+ */
18
+ readonly deletions?: number;
19
+ /**
20
+ * The file path.
21
+ */
22
+ readonly path: string;
23
+ /**
24
+ * Change status, shown as a colored one-letter badge.
25
+ * @default "modified"
26
+ */
27
+ readonly status?: FileChangeStatus;
28
+ };
29
+ /**
30
+ * A single git-style diff-stat row: a status badge, the path, the numeric
31
+ * add/remove counts, and a proportional ▰/▱ change bar.
32
+ */
33
+ declare function FileChange({
34
+ additions,
35
+ barWidth,
36
+ deletions,
37
+ path,
38
+ status
39
+ }: Props): ReactElement;
40
+ export { FileChange, type Props as FileChangeProps, FileChangeStatus, Props, FileChange as default };
@@ -0,0 +1 @@
1
+ import{jsxs as c,jsx as r}from"react/jsx-runtime";import m from"@visulima/tui/components/box";import e from"@visulima/tui/components/text";const u={added:{color:"green",mark:"A"},deleted:{color:"red",mark:"D"},modified:{color:"yellow",mark:"M"},renamed:{color:"blue",mark:"R"}};function k({additions:l=0,barWidth:o=10,deletions:t=0,path:h,status:s="modified"}){const n=u[s],d=l+t,i=d===0?0:Math.round(l/d*o),a=d===0?0:Math.min(o-i,Math.round(t/d*o));return c(m,{gap:1,children:[r(e,{bold:!0,color:n.color,children:n.mark}),r(e,{children:h}),r(e,{color:"green",children:`+${l}`}),r(e,{color:"red",children:`-${t}`}),c(m,{children:[r(e,{color:"green",children:"▰".repeat(i)}),r(e,{color:"red",children:"▰".repeat(a)}),r(e,{dimColor:!0,children:"▱".repeat(Math.max(0,o-i-a))})]})]})}export{k as FileChange,k as default};
@@ -0,0 +1,2 @@
1
+ export { type F as FileEntry, a as FilePicker, type b as FilePickerFilter, type P as FilePickerProps, a as default } from "./packem_shared/file-picker.d-Cie6aAMD.js";
2
+ import 'react';
@@ -0,0 +1 @@
1
+ import{default as f,default as l}from"./packem_shared/FilePicker-V5H2fb-v.js";export{f as FilePicker,l as default};
package/dist/form.d.ts ADDED
@@ -0,0 +1,81 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactNode, ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type FormFieldProps = {
5
+ /**
6
+ * The input element (TextInput, Checkbox, Select, …).
7
+ */
8
+ readonly children: ReactNode;
9
+ /**
10
+ * Optional helper text rendered beneath the input.
11
+ */
12
+ readonly description?: string;
13
+ /**
14
+ * Validation error — dimmed red below the input.
15
+ */
16
+ readonly error?: string;
17
+ /**
18
+ * When true, the field's label and description are dim.
19
+ */
20
+ readonly isDisabled?: boolean;
21
+ /**
22
+ * Label rendered above the input.
23
+ */
24
+ readonly label: string;
25
+ /**
26
+ * Mark the field as required (adds a trailing `*`).
27
+ */
28
+ readonly required?: boolean;
29
+ };
30
+ /**
31
+ * Standard form field wrapper: label + input + helper/error.
32
+ */
33
+ declare const FormField: ({
34
+ children,
35
+ description,
36
+ error,
37
+ isDisabled,
38
+ label,
39
+ required
40
+ }: FormFieldProps) => ReactElement;
41
+ type Props = {
42
+ /**
43
+ * Accent color for the form chrome.
44
+ * @default "blue"
45
+ */
46
+ readonly accentColor?: LiteralUnion<AnsiColors, string>;
47
+ /**
48
+ * Render a border around the form.
49
+ * @default true
50
+ */
51
+ readonly bordered?: boolean;
52
+ /**
53
+ * Fields composed via `&lt;FormField />`.
54
+ */
55
+ readonly children: ReactNode;
56
+ /**
57
+ * Optional description rendered under the title.
58
+ */
59
+ readonly description?: string;
60
+ /**
61
+ * Optional footer rendered below the fields (buttons, hints, summary).
62
+ */
63
+ readonly footer?: ReactNode;
64
+ /**
65
+ * Optional heading rendered at the top.
66
+ */
67
+ readonly title?: string;
68
+ /**
69
+ * Fixed width.
70
+ */
71
+ readonly width?: number;
72
+ };
73
+ type FormComponent = ((props: Props) => ReactElement) & {
74
+ Field: typeof FormField;
75
+ };
76
+ /**
77
+ * Stateless form layout. Pair with the `useForm` hook for state management
78
+ * and `FormField` for consistent label/error styling.
79
+ */
80
+ declare const Form: FormComponent;
81
+ export { Form, FormField, FormFieldProps, type Props as FormProps, Props, Form as default };
package/dist/form.js ADDED
@@ -0,0 +1 @@
1
+ import{jsxs as m,jsx as r}from"react/jsx-runtime";import o from"@visulima/tui/components/box";import i from"@visulima/tui/components/text";const a=({children:e,description:d,error:l,isDisabled:n=!1,label:c,required:t=!1})=>m(o,{flexDirection:"column",marginBottom:1,children:[m(o,{children:[r(i,{bold:!0,dimColor:n,children:c}),t?r(i,{color:"red",children:" *"}):void 0]}),r(o,{marginTop:0,children:e}),l===void 0?d===void 0?void 0:r(i,{dimColor:!0,children:d}):r(i,{color:"red",children:l})]}),b=Object.assign(({accentColor:e="blue",bordered:d=!0,children:l,description:n,footer:c,title:t,width:h})=>{const s=m(o,{flexDirection:"column",children:[t===void 0?void 0:r(o,{marginBottom:1,children:r(i,{bold:!0,color:e,children:t})}),n===void 0?void 0:r(o,{marginBottom:1,children:r(i,{dimColor:!0,children:n})}),r(o,{flexDirection:"column",children:l}),c===void 0?void 0:r(o,{marginTop:1,children:c})]});return d?r(o,{borderColor:e,borderStyle:"round",flexDirection:"column",paddingX:1,paddingY:1,width:h,children:s}):r(o,{flexDirection:"column",width:h,children:s})},{Field:a});export{b as Form,a as FormField,b as default};
@@ -0,0 +1,87 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type GaugeThreshold = {
5
+ /**
6
+ * Color used for the arc segment and, when the current value falls into
7
+ * this segment, for the value readout.
8
+ */
9
+ readonly color: LiteralUnion<AnsiColors, string>;
10
+ /**
11
+ * Optional label used by the legend under the gauge.
12
+ */
13
+ readonly label?: string;
14
+ /**
15
+ * Upper bound of this threshold segment (inclusive). Segments are sorted
16
+ * ascending and painted in order.
17
+ */
18
+ readonly max: number;
19
+ };
20
+ type GaugeSize = "large" | "medium" | "small";
21
+ type Props = {
22
+ /**
23
+ * Color of the arc background (the portion beyond `value`).
24
+ * @default "gray"
25
+ */
26
+ readonly backgroundColor?: LiteralUnion<AnsiColors, string>;
27
+ /**
28
+ * Format for the numeric readout. Defaults to rounding to an integer.
29
+ */
30
+ readonly formatValue?: (value: number) => string;
31
+ /**
32
+ * Optional label rendered above the readout.
33
+ */
34
+ readonly label?: string;
35
+ /**
36
+ * Upper bound of the range.
37
+ * @default 100
38
+ */
39
+ readonly max?: number;
40
+ /**
41
+ * Lower bound of the range.
42
+ * @default 0
43
+ */
44
+ readonly min?: number;
45
+ /**
46
+ * Show a legend listing thresholds below the gauge.
47
+ * @default false
48
+ */
49
+ readonly showLegend?: boolean;
50
+ /**
51
+ * Show a numeric readout in the middle of the gauge.
52
+ * @default true
53
+ */
54
+ readonly showValue?: boolean;
55
+ /**
56
+ * Overall dimension preset.
57
+ * @default "medium"
58
+ */
59
+ readonly size?: GaugeSize;
60
+ /**
61
+ * Color threshold ramp. When provided, segments of the arc are painted in
62
+ * the corresponding colors and the value readout picks up the color for
63
+ * the segment `value` lands in.
64
+ */
65
+ readonly thresholds?: ReadonlyArray<GaugeThreshold>;
66
+ /**
67
+ * Current value. Clamped into the `[min, max]` range.
68
+ */
69
+ readonly value: number;
70
+ };
71
+ /**
72
+ * Semi-circular gauge rendered at 2x4 sub-cell resolution. Supports colored
73
+ * threshold segments and an optional needle.
74
+ */
75
+ declare function Gauge({
76
+ backgroundColor,
77
+ formatValue,
78
+ label,
79
+ max,
80
+ min,
81
+ showLegend,
82
+ showValue,
83
+ size,
84
+ thresholds,
85
+ value
86
+ }: Props): ReactElement;
87
+ export { Gauge, type Props as GaugeProps, GaugeSize, GaugeThreshold, Props, Gauge as default };
package/dist/gauge.js ADDED
@@ -0,0 +1 @@
1
+ import{jsxs as j,jsx as l}from"react/jsx-runtime";import{createBrailleGrid as U}from"@visulima/tui/canvas";import c from"@visulima/tui/components/box";import W from"@visulima/tui/components/canvas";import p from"@visulima/tui/components/text";import{useMemo as q}from"react";const X={large:{cols:40,rows:10},medium:{cols:24,rows:6},small:{cols:16,rows:4}},_=.9,T=2,Y=r=>String(Math.round(r)),z=(r,u,d,e)=>{const t=u+(d-u)*e;for(const f of r)if(t<=f.max)return f;return r[r.length-1]};function io({backgroundColor:r="gray",formatValue:u=Y,label:d,max:e=100,min:t=0,showLegend:f=!1,showValue:C=!0,size:b="medium",thresholds:i,value:P}){const{cols:A,rows:E}=X[b],I=Math.max(t,Math.min(e,P)),F=e-t||1,M=(I-t)/F,s=q(()=>{if(!(i===void 0||i.length===0))return[...i].toSorted((o,h)=>o.max-h.max)},[i]),D=q(()=>{if(s!==void 0)return z(s,t,e,M)},[s,t,e,M]),G=u(I);return j(c,{flexDirection:"column",children:[l(W,{draw:o=>{o.clear();const h=o.width*2,L=o.height*4,x=h/2,v=L-1,H=h/2-1,J=L-1,g=Math.max(1,Math.min(H,J)),y=new Map,S=n=>{const a=y.get(n);if(a!==void 0)return a;const m=U(o.width,o.height);return y.set(n,m),m},V=Math.max(32,Math.round(Math.PI*g)*T);for(let n=0;n<=V;n+=1){const a=n/V,m=Math.PI*(1-a),Q=Math.round(x+g*Math.cos(m)),R=Math.round(v-g*Math.sin(m));let w;a>M?w=r:s?w=z(s,t,e,a)?.color??"cyan":w="cyan",S(w).plotPoint(Q,R)}const k=g*_,B=Math.PI*(1-M),K=Math.round(x+k*Math.cos(B)),N=Math.round(v-k*Math.sin(B)),O=D?.color??"white";S(O).plotLine(Math.round(x),Math.round(v),K,N);for(const[n,a]of y)a.flush(o,{color:n})},height:E,version:[P,t,e,b,i,r],width:A}),C||d?j(c,{flexDirection:"column",children:[d===void 0?void 0:l(c,{justifyContent:"center",children:l(p,{dimColor:!0,children:d})}),C?l(c,{justifyContent:"center",children:l(p,{bold:!0,color:D?.color??"white",children:G})}):void 0]}):void 0,f&&i&&i.length>0?l(c,{gap:2,justifyContent:"center",marginTop:1,children:i.map((o,h)=>j(c,{gap:1,children:[l(p,{color:o.color,children:"●"}),l(p,{dimColor:!0,children:o.label??`≤ ${o.max}`})]},h))}):void 0]})}export{io as Gauge,io as default};
@@ -0,0 +1,42 @@
1
+ import { multilineGradient } from '@visulima/colorize/gradient';
2
+ import { ReactNode, ReactElement } from 'react';
3
+ /**
4
+ * A color stop for the gradient — hex string, CSS color name, RGB tuple, RGB object, or positioned stop.
5
+ */
6
+ type GradientStop = Parameters<typeof multilineGradient>[0][number];
7
+ /**
8
+ * Built-in gradient presets.
9
+ */
10
+ type GradientName = "atlas" | "cristal" | "fruit" | "instagram" | "mind" | "morning" | "pastel" | "passion" | "rainbow" | "retro" | "summer" | "teen" | "vice";
11
+ /**
12
+ * Custom gradient colors — an array of color stops accepted by `@visulima/colorize`'s gradient API.
13
+ */
14
+ type GradientColors = GradientStop[];
15
+ type Props = {
16
+ /**
17
+ * The content to colorize.
18
+ *
19
+ * Multiple `&lt;Text>` children are treated as separate nodes, which preserves layout when `&lt;Gradient>` is placed inside a `&lt;Box flexDirection="column">`.
20
+ *
21
+ * If you want a continuous gradient across multiple lines, pass a single string or a single `&lt;Text>` with `\n`.
22
+ */
23
+ readonly children: ReactNode;
24
+ /**
25
+ * [Colors to use to make the gradient.](https://visulima.com/packages/colorize)
26
+ *
27
+ * Mutually exclusive with `name`.
28
+ */
29
+ readonly colors?: GradientColors;
30
+ /**
31
+ * The name of a built-in gradient preset.
32
+ *
33
+ * Mutually exclusive with `colors`.
34
+ */
35
+ readonly name?: GradientName;
36
+ };
37
+ declare function Gradient({
38
+ children,
39
+ colors,
40
+ name
41
+ }: Props): ReactElement | null;
42
+ export { Gradient, type GradientColors, type GradientName, type Props as GradientProps, Props, Gradient as default };
@@ -0,0 +1 @@
1
+ import{jsx as s,Fragment as B}from"react/jsx-runtime";import{strip as F}from"@visulima/ansi";import{multilineGradient as k}from"@visulima/colorize/gradient";import C from"@visulima/tui/components/box";import S from"@visulima/tui/components/text";import b from"@visulima/tui/components/transform";import{useMemo as M,Children as g,isValidElement as T,cloneElement as y}from"react";const O={atlas:{colors:["#feac5e","#c779d0","#4bc0c8"]},cristal:{colors:["#bdfff3","#4ac29a"]},fruit:{colors:["#ff4e50","#f9d423"]},instagram:{colors:["#833ab4","#fd1d1d","#fcb045"]},mind:{colors:["#473b7b","#3584a7","#30d2be"]},morning:{colors:["#ff5f6d","#ffc371"],options:{interpolation:"hsv"}},passion:{colors:["#f43b47","#453a94"]},pastel:{colors:["#74ebd5","#74ecd5"],options:{hsvSpin:"long",interpolation:"hsv"}},rainbow:{colors:["#ff0000","#ff0100"],options:{hsvSpin:"long",interpolation:"hsv"}},retro:{colors:["#3f51b1","#5a55ae","#7b5fac","#8f6aae","#a86aa4","#cc6b8e","#f18271","#f3a469","#f7c978"]},summer:{colors:["#fdbb2d","#22c1c3"]},teen:{colors:["#77a1d3","#79cbca","#e684ae"]},vice:{colors:["#5ee7df","#b490ca"],options:{interpolation:"hsv"}}},j=o=>{let t=!1;const n=u=>{g.forEach(u,i=>{if(t||!T(i))return;if(i.type===C){t=!0;return}const f=i.props;Object.hasOwn(f,"children")&&n(f.children)})};return n(o),t},x=o=>Object.hasOwn(o,"children"),G=o=>typeof o=="string"||typeof o=="number",N=o=>o==null||typeof o=="boolean";function J({children:o,colors:t,name:n}){if(n&&t)throw new Error("The `name` and `colors` props are mutually exclusive");if(!n&&!t)throw new Error("Either `name` or `colors` prop must be provided");const u=M(()=>n?k(O[n].colors,O[n].options):k(t??[]),[n,t]),i=h=>u(F(h)),f=g.count(o);if(G(o))return s(b,{transform:i,children:o});if(f===1&&!j(o))return s(b,{transform:i,children:o});const m=h=>{const c=[];let l="",v=0;const w=()=>{const r=`gradient-node-${String(v)}`;return v+=1,r},a=(r,e)=>{c.push(s(b,{transform:i,children:r},e))},E=()=>{if(l==="")return;const r=l;l="",a(s(S,{children:r}),w())};return g.forEach(h,r=>{if(!N(r)){if(G(r)){l+=String(r);return}if(E(),T(r)){const e=r.key??w(),p=r.props;if(r.type===S){a(r,e);return}if(r.type===C){if(x(p)){const d=p.children;c.push(y(r,{key:e},m(d)));return}c.push(y(r,{key:e}));return}if(x(p)){const d=p.children;if(!j(d)){a(r,e);return}c.push(y(r,{key:e},m(d)));return}a(r,e);return}c.push(r)}}),E(),c};return s(B,{children:m(o)})}export{J as Gradient,J as default};
package/dist/grid.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { ReactNode, ReactElement } from 'react';
2
+ type Props = {
3
+ /**
4
+ * The grid cells, filled left-to-right, top-to-bottom.
5
+ */
6
+ readonly children: ReactNode;
7
+ /**
8
+ * Horizontal gap between columns, in cells.
9
+ * @default 1
10
+ */
11
+ readonly columnGap?: number;
12
+ /**
13
+ * Number of columns. Children wrap into as many rows as needed.
14
+ * @default 2
15
+ */
16
+ readonly columns?: number;
17
+ /**
18
+ * Fixed width for every column, in cells. Omit to let columns size to
19
+ * their content.
20
+ */
21
+ readonly columnWidth?: number;
22
+ /**
23
+ * Vertical gap between rows, in cells.
24
+ * @default 0
25
+ */
26
+ readonly rowGap?: number;
27
+ };
28
+ /**
29
+ * A simple 2D grid: children flow left-to-right into a fixed number of columns,
30
+ * wrapping to new rows. Column and row gaps are configurable, and columns can
31
+ * be given a fixed width for uniform cells.
32
+ */
33
+ declare function Grid({
34
+ children,
35
+ columnGap,
36
+ columns,
37
+ columnWidth,
38
+ rowGap
39
+ }: Props): ReactElement;
40
+ export { Grid, type Props as GridProps, Props, Grid as default };
package/dist/grid.js ADDED
@@ -0,0 +1 @@
1
+ import{jsx as o}from"react/jsx-runtime";import n from"@visulima/tui/components/box";import{Children as u}from"react";function G({children:e,columnGap:a=1,columns:m=2,columnWidth:c,rowGap:h=0}){const i=u.toArray(e),l=[],t=Math.max(1,m);for(let r=0;r<i.length;r+=t)l.push(i.slice(r,r+t));return o(n,{flexDirection:"column",gap:h,children:l.map((r,p)=>o(n,{gap:a,children:r.map((d,f)=>o(n,{flexShrink:0,width:c,children:d},f))},p))})}export{G as Grid,G as default};
@@ -0,0 +1,33 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactNode, ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
5
+ type Props = {
6
+ /**
7
+ * Heading content.
8
+ */
9
+ readonly children: ReactNode;
10
+ /**
11
+ * Explicit color. By default the color is derived from the level.
12
+ */
13
+ readonly color?: LiteralUnion<AnsiColors, string>;
14
+ /**
15
+ * Heading level controls decoration and color.
16
+ * @default 1
17
+ */
18
+ readonly level?: HeadingLevel;
19
+ /**
20
+ * When true, renders an underline on a second line.
21
+ */
22
+ readonly underline?: boolean;
23
+ };
24
+ /**
25
+ * Semantic heading with level-based styling.
26
+ */
27
+ declare function Heading({
28
+ children,
29
+ color,
30
+ level,
31
+ underline
32
+ }: Props): ReactElement;
33
+ export { Heading, HeadingLevel, type Props as HeadingProps, Props, Heading as default };
@@ -0,0 +1 @@
1
+ import{jsx as l,jsxs as t}from"react/jsx-runtime";import c from"@visulima/tui/components/box";import d from"@visulima/tui/components/text";const a={1:"blueBright",2:"cyanBright",3:"magentaBright",4:"yellowBright",5:"green",6:"white"},h={1:"# ",2:"## ",3:"### ",4:"#### ",5:"##### ",6:"###### "};function g({children:e,color:o,level:r=1,underline:i=!1}){const n=o??a[r];return l(c,{flexDirection:"column",children:t(d,{bold:r<=2,color:n,underline:i,children:[h[r],e]})})}export{g as Heading,g as default};
@@ -0,0 +1,62 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type HeatmapProps = {
5
+ /**
6
+ * Width of each cell in character columns.
7
+ * @default 2
8
+ */
9
+ readonly cellWidth?: number;
10
+ /**
11
+ * Glyph used to paint each heatmap cell. Defaults to `█` so the
12
+ * background color fills the cell.
13
+ * @default "█" (full block)
14
+ */
15
+ readonly character?: string;
16
+ /**
17
+ * Column labels rendered below the grid.
18
+ */
19
+ readonly columnLabels?: ReadonlyArray<string>;
20
+ /**
21
+ * 2D matrix, rows × cols.
22
+ */
23
+ readonly data: ReadonlyArray<ReadonlyArray<number>>;
24
+ /**
25
+ * Fixed maximum (for consistent scales across multiple heatmaps).
26
+ */
27
+ readonly max?: number;
28
+ /**
29
+ * Fixed minimum.
30
+ */
31
+ readonly min?: number;
32
+ /**
33
+ * Color palette, lowest-to-highest intensity. Values are mapped into the
34
+ * palette by their position in the [min, max] range.
35
+ * @default ["#0b1e4f", "#1f3b96", "#3258c8", "#4e84ec", "#78b0ff"]
36
+ */
37
+ readonly palette?: ReadonlyArray<string>;
38
+ /**
39
+ * Row labels rendered to the left of the grid.
40
+ */
41
+ readonly rowLabels?: ReadonlyArray<string>;
42
+ /**
43
+ * Foreground color override (rarely needed since the character is a full block).
44
+ */
45
+ readonly textColor?: LiteralUnion<AnsiColors, string>;
46
+ };
47
+ /**
48
+ * 2D heatmap. Each cell's background color is derived from its value's
49
+ * position in the [min, max] range mapped into `palette`.
50
+ */
51
+ declare function Heatmap({
52
+ cellWidth,
53
+ character,
54
+ columnLabels,
55
+ data,
56
+ max: maxOverride,
57
+ min: minOverride,
58
+ palette,
59
+ rowLabels,
60
+ textColor
61
+ }: HeatmapProps): ReactElement;
62
+ export { Heatmap, HeatmapProps, Heatmap as default };
@@ -0,0 +1 @@
1
+ import{jsxs as M,jsx as c}from"react/jsx-runtime";import m from"@visulima/tui/components/box";import k from"@visulima/tui/components/canvas";import C from"@visulima/tui/components/text";import{useMemo as A}from"react";const E=["#0b1e4f","#1f3b96","#3258c8","#4e84ec","#78b0ff"];function I({cellWidth:s=2,character:L="█",columnLabels:p,data:t,max:l,min:d,palette:x=E,rowLabels:g,textColor:W}){const{cols:w,colWidth:f,extent:j,rows:u}=A(()=>{const e=t.length,r=t.reduce((n,o)=>Math.max(n,o.length),0);let i=d??1/0,a=l??-1/0;if(d===void 0||l===void 0)for(const n of t)for(const o of n)d===void 0&&o<i&&(i=o),l===void 0&&o>a&&(a=o);return{cols:r,colWidth:s,extent:{max:a,min:i},rows:e}},[t,d,l,s]),D=w*f,H=u;return M(m,{children:[g===void 0?void 0:c(m,{flexDirection:"column",marginRight:1,children:Array.from({length:u},(e,r)=>c(C,{dimColor:!0,children:g[r]??""},r))}),M(m,{flexDirection:"column",children:[c(k,{draw:e=>{e.clear();const{max:r,min:i}=j,a=r-i||1,n=x.length-1;for(let o=0;o<u;o+=1)for(let h=0;h<w;h+=1){const b=t[o]?.[h],R=b===void 0?void 0:x[Math.max(0,Math.min(n,Math.round((b-i)/a*n)))];for(let v=0;v<f;v+=1)e.setCell(h*f+v,o,L,{background:R,color:W})}},height:H,version:[t,x,s,d,l],width:D}),p===void 0?void 0:c(m,{children:p.map((e,r)=>c(m,{width:f,children:c(C,{dimColor:!0,wrap:"truncate-end",children:e})},r))})]})]})}export{I as Heatmap,I as default};