@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 @@
1
+ import{jsx as n,jsxs as l,Fragment as S}from"react/jsx-runtime";import t from"@visulima/tui/components/box";import o from"@visulima/tui/components/text";import{Spinner as w}from"./spinner.js";const C={completed:"green",error:"red",pending:"gray",running:"cyan",skipped:"yellow"},k={completed:"✔",error:"✖",pending:"○",skipped:"⊘"},y=e=>{if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;const r=Math.round(e/1e3),i=Math.floor(r/60),d=r%60;return`${i}m ${d}s`},h=({isLast:e,node:r,prefix:i,showSpinner:d})=>{const p=C[r.status],c=e?"└─ ":"├─ ",u=i.length===0?"":c,s=i+(e?" ":"│ "),m=d?n(w,{type:"dots"}):"…",f=r.status==="running"?m:k[r.status];return l(S,{children:[l(t,{children:[n(o,{dimColor:!0,children:i}),n(o,{dimColor:!0,children:u}),n(t,{flexShrink:0,children:n(o,{color:p,children:f})}),n(o,{children:" "}),n(t,{flexGrow:1,flexShrink:1,minWidth:0,children:n(o,{bold:r.status==="running",color:r.status==="pending"?"gray":void 0,dimColor:r.status==="skipped",wrap:"truncate-end",children:r.label})}),r.durationMs===void 0?void 0:n(t,{flexShrink:0,children:l(o,{dimColor:!0,children:[" ",y(r.durationMs)]})})]}),r.details===void 0?void 0:l(t,{children:[n(o,{dimColor:!0,children:s}),n(o,{dimColor:!0,children:r.details})]}),r.children?.map((a,g,x)=>n(h,{isLast:g===x.length-1,node:a,prefix:s,showSpinner:d},a.id))]})};function b({nodes:e,showSpinner:r=!0}){return n(t,{flexDirection:"column",children:e.map((i,d)=>n(h,{isLast:d===e.length-1,node:i,prefix:"",showSpinner:r},i.id))})}export{b as OperationTree,b as default};
@@ -0,0 +1,47 @@
1
+ import { AnsiColors } from '@visulima/colorize';
2
+ import { ReactNode, ReactElement } from 'react';
3
+ import { LiteralUnion } from 'type-fest';
4
+ type OptionListEntry = {
5
+ readonly description?: string;
6
+ readonly icon?: ReactNode;
7
+ readonly id: string;
8
+ readonly label: ReactNode;
9
+ readonly trailing?: ReactNode;
10
+ };
11
+ type Props = {
12
+ /**
13
+ * Highlight color for the row marked as current.
14
+ */
15
+ readonly accentColor?: LiteralUnion<AnsiColors, string>;
16
+ /**
17
+ * Render the list with a border.
18
+ */
19
+ readonly bordered?: boolean;
20
+ /**
21
+ * Id of the row to highlight. No visual change if omitted.
22
+ */
23
+ readonly currentId?: string;
24
+ /**
25
+ * Icon width in characters for column alignment.
26
+ * @default 2
27
+ */
28
+ readonly iconColumnWidth?: number;
29
+ /**
30
+ * Entries to render.
31
+ */
32
+ readonly options: ReadonlyArray<OptionListEntry>;
33
+ };
34
+ /**
35
+ * Read-only presentational option list. Like `SelectInput` but without focus,
36
+ * input handling, or scrolling — just a styled list of rows. Useful inside
37
+ * modals, sidebars, or summary panels.
38
+ * @returns A `ReactElement` rendering the list; bordered when requested.
39
+ */
40
+ declare function OptionList({
41
+ accentColor,
42
+ bordered,
43
+ currentId,
44
+ iconColumnWidth,
45
+ options
46
+ }: Props): ReactElement;
47
+ export { OptionList, OptionListEntry, type Props as OptionListProps, Props, OptionList as default };
@@ -0,0 +1 @@
1
+ import{jsx as i,jsxs as c}from"react/jsx-runtime";import r from"@visulima/tui/components/box";import e from"@visulima/tui/components/text";function x({accentColor:h="blue",bordered:a=!1,currentId:f,iconColumnWidth:d=2,options:m}){const l=i(r,{flexDirection:"column",children:m.map(n=>{const o=n.id===f,t=o?h:void 0;return c(r,{flexDirection:"column",children:[c(r,{children:[i(r,{flexShrink:0,width:d,children:i(e,{color:t,children:n.icon??(o?"▸":" ")})}),i(r,{flexGrow:1,flexShrink:1,minWidth:0,children:i(e,{bold:o,color:t,wrap:"truncate-end",children:n.label})}),n.trailing===void 0?void 0:i(r,{flexShrink:0,children:n.trailing})]}),n.description===void 0?void 0:i(r,{marginLeft:d,children:i(e,{dimColor:!0,wrap:"truncate-end",children:n.description})})]},n.id)})});return a?i(r,{borderStyle:"round",paddingX:1,children:l}):l}export{x as OptionList,x as default};
@@ -0,0 +1,24 @@
1
+ import { ReactNode, ReactElement } from 'react';
2
+ type OrderedListEntry = {
3
+ /**
4
+ * Nested sub-items, rendered as a sub-list with hierarchical numbering.
5
+ */
6
+ readonly children?: ReadonlyArray<OrderedListEntry>;
7
+ /**
8
+ * Display text for this item.
9
+ */
10
+ readonly label: ReactNode;
11
+ };
12
+ type Props = {
13
+ /**
14
+ * Entries to render as a numbered list.
15
+ */
16
+ readonly items: ReadonlyArray<OrderedListEntry>;
17
+ };
18
+ /**
19
+ * Renders a numbered list with hierarchical nesting support.
20
+ */
21
+ declare function OrderedList({
22
+ items
23
+ }: Props): ReactElement;
24
+ export { OrderedList, OrderedListEntry, type Props as OrderedListProps, Props, OrderedList as default };
@@ -0,0 +1 @@
1
+ import{jsx as t,jsxs as l}from"react/jsx-runtime";import e from"@visulima/tui/components/box";import c from"@visulima/tui/components/text";const d=(r,m)=>{const s=String(r.length).length;return t(e,{flexDirection:"column",children:r.map((i,n)=>{const h=`${String(n+1).padStart(s)}.`,o=`${m}${h}`;return l(e,{gap:1,children:[t(c,{dimColor:!0,children:o}),l(e,{flexDirection:"column",children:[t(c,{children:i.label}),i.children?d(i.children,o):void 0]})]},n)})})};function f({items:r}){return d(r,"")}export{f as OrderedList,f as default};
@@ -0,0 +1 @@
1
+ import"react/jsx-runtime";import"@visulima/tui";import"@visulima/tui/components/box";import"react";import{C as l}from"./controlled-scroll-view-DerVKKv6.js";export{l as ControlledScrollView};
@@ -0,0 +1 @@
1
+ import{jsxs as h,jsx as y}from"react/jsx-runtime";import z from"@visulima/tui/components/box";import m from"@visulima/tui/components/text";import R from"@visulima/tui/hooks/use-input";import{useState as g,useRef as B,useEffect as G,useCallback as $}from"react";import{Spinner as W}from"../spinner.js";import{readdir as q,stat as I}from"node:fs/promises";import{resolve as A,join as H,dirname as K,extname as N}from"node:path";function _(r){const o=d=>`${d&4?"r":"-"}${d&2?"w":"-"}${d&1?"x":"-"}`;return`${o(r>>6&7)}${o(r>>3&7)}${o(r&7)}`}function J(r,o){if(!(o.showHidden??!1)&&r.isHidden||!(o.showDirectories??!0)&&r.isDirectory||!(o.showFiles??!0)&&!r.isDirectory)return!1;if(o.extensions&&o.extensions.length>0&&!r.isDirectory){const d=N(r.name);if(!o.extensions.includes(d))return!1}return!0}function O(r){const{filter:o,initialPath:d}=r,[u,w]=g(()=>A(d)),[b,c]=g([]),[x,D]=g(!0),[F,C]=g(),[P,t]=g(0),M=B(o);M.current=o,G(()=>{let n=!1;return(async()=>{D(!0),C(void 0);try{const s=await q(u,{withFileTypes:!0}),v=await Promise.all(s.map(async e=>{try{return await I(H(u,e.name))}catch{return}})),S=s.map((e,i)=>{const E=H(u,e.name),L=e.isDirectory(),T=e.name.startsWith("."),U=v[i],j=U?.size??0,k=U?_(U.mode):"---------";return{isDirectory:L,isHidden:T,name:e.name,path:E,permissions:k,size:j}});if(n)return;const a=S.filter(e=>J(e,M.current));a.sort((e,i)=>e.isDirectory!==i.isDirectory?e.isDirectory?-1:1:e.name.localeCompare(i.name,void 0,{sensitivity:"base"})),c(a)}catch(s){n||(C(s instanceof Error?s.message:String(s)),c([]))}finally{n||D(!1)}})().catch(()=>{}),()=>{n=!0}},[u,P]);const l=$(n=>{w(A(n))},[]),f=$(()=>{w(n=>{const s=K(n);return s===n?n:s})},[]),p=$(()=>{t(n=>n+1)},[]);return{currentPath:u,entries:b,error:F,goUp:f,isLoading:x,navigateTo:l,refresh:p}}function Q(r){return r<1024?`${r}B`:r<1024*1024?`${(r/1024).toFixed(1)}K`:r<1024*1024*1024?`${(r/(1024*1024)).toFixed(1)}M`:`${(r/(1024*1024*1024)).toFixed(1)}G`}const V={},X=()=>process.cwd(),se=({accentColor:r="cyan",directoryColor:o="blue",fileColor:d="white",filter:u=V,initialPath:w,isFocused:b=!0,limit:c=10,onCancel:x,onSelect:D,showPermissions:F=!1,showSize:C=!1})=>{const P=w??X(),t=O({filter:u,initialPath:P}),[M,l]=g(0),f=Math.max(0,t.entries.length-1),p=Math.min(M,f);R($((a,e)=>{if(e.upArrow)l(i=>Math.max(0,i-1));else if(e.downArrow)l(i=>Math.min(f,i+1));else if(e.return){const i=t.entries[p];i&&(i.isDirectory?(t.navigateTo(i.path),l(0)):D?.(i))}else e.backspace||e.leftArrow?(t.goUp(),l(0)):e.escape?x?.():a==="."?t.refresh():e.pageUp?l(i=>Math.max(0,i-c)):e.pageDown?l(i=>Math.min(f,i+c)):e.home?l(0):e.end&&l(f)},[f,p,t,c,D,x]),{isActive:b});const n=Math.floor(c/2);let s=Math.max(0,p-n);const v=Math.min(t.entries.length,s+c);s=Math.max(0,v-c);const S=t.entries.slice(s,v);return h(z,{flexDirection:"column",children:[y(m,{bold:!0,dimColor:!0,children:t.currentPath}),t.isLoading&&h(z,{children:[y(W,{}),y(m,{children:" Loading..."})]}),t.error&&h(m,{color:"red",children:["Error:",t.error]}),!t.isLoading&&!t.error&&t.entries.length===0&&y(m,{dimColor:!0,children:"(empty directory)"}),S.map((a,e)=>{const i=s+e===p,E=a.isDirectory?"📁 ":"📄 ",L=a.isDirectory?o:d;return h(z,{children:[y(m,{color:i?r:void 0,children:i?"▸ ":" "}),y(m,{children:E}),h(m,{bold:a.isDirectory,color:i?r:L,children:[a.name,a.isDirectory?"/":""]}),C&&!a.isDirectory&&h(m,{dimColor:!0,children:[" ",Q(a.size)]}),F&&h(m,{dimColor:!0,children:[" ",a.permissions]})]},a.name)}),t.entries.length>c&&h(m,{dimColor:!0,children:[p+1,"/",t.entries.length]})]})};export{se as default};
@@ -0,0 +1 @@
1
+ import{jsx as i,jsxs as I}from"react/jsx-runtime";import H from"@visulima/tui/components/box";import p from"@visulima/tui/components/text";import{useMemo as N}from"react";const S={arrow:{lowerThumb:"╽",thumb:"┃",track:"|",upperThumb:"╿"},block:{thumb:"█",track:"░"},bold:{lowerThumb:"╿",thumb:"│",track:"┃",upperThumb:"╽"},classic:{thumb:"┃",track:"|"},dots:{thumb:"●",track:"·"},double:{thumb:"┃",track:"║"},doubleSingle:{lowerThumb:"╽",thumb:"┃",track:"│",upperThumb:"╿"},line:{thumb:"│",track:" "},round:{lowerThumb:"╽",thumb:"┃",track:"│",upperThumb:"╿"},single:{lowerThumb:"╽",thumb:"┃",track:"│",upperThumb:"╿"},singleDouble:{thumb:"┃",track:"║"},thick:{thumb:"┃",track:"╏"}},j={arrow:{bottomLeft:"└",bottomRight:"┘",topLeft:"┌",topRight:"┐"},bold:{bottomLeft:"┗",bottomRight:"┛",topLeft:"┏",topRight:"┓"},classic:{bottomLeft:"+",bottomRight:"+",topLeft:"+",topRight:"+"},double:{bottomLeft:"╚",bottomRight:"╝",topLeft:"╔",topRight:"╗"},doubleSingle:{bottomLeft:"╘",bottomRight:"╛",topLeft:"╒",topRight:"╕"},round:{bottomLeft:"╰",bottomRight:"╯",topLeft:"╭",topRight:"╮"},single:{bottomLeft:"└",bottomRight:"┘",topLeft:"┌",topRight:"┐"},singleDouble:{bottomLeft:"╙",bottomRight:"╜",topLeft:"╓",topRight:"╖"}},Y=t=>S[typeof t=="string"?t:"single"]??S.single??{thumb:"┃",track:"│"},_=t=>j[typeof t=="string"?t:"single"]??j.single??{bottomLeft:"└",bottomRight:"┘",topLeft:"┌",topRight:"┐"},J=({autoHide:t=!1,color:m,contentHeight:L,dimColor:l,placement:c="right",scrollOffset:R,style:n,thumbChar:k,trackChar:w,viewportHeight:e})=>{const f=N(()=>{const r=Math.max(L,e);if(t&&r<=e)return null;const o=Y(n),a=k??o.thumb,q=w??o.track,x=e*2,v=Math.min(e/r,1),T=Math.max(2,Math.round(x*v)),M=r-e,A=M>0?Math.min(Math.max(R/M,0),1):0,E=x-T,g=Math.round(A*E),C=g+T,h=[];for(let b=0;b<e;b+=1){const D=b*2,y=b*2+1,s=D>=g&&D<C,d=y>=g&&y<C;s&&d?h.push(a):s&&!d?h.push(o.lowerThumb??a):!s&&d?h.push(o.upperThumb??a):h.push(q)}return h},[L,e,R,n,k,w,t]);if(f===null)return null;if(c==="inset")return i(H,{flexDirection:"column",flexShrink:0,width:1,children:f.map((r,o)=>i(p,{color:m,dimColor:l,children:r},o))});const u=_(n),B=c==="left"?u.topLeft:u.topRight,O=c==="left"?u.bottomLeft:u.bottomRight;return I(H,{flexDirection:"column",flexShrink:0,width:1,children:[i(p,{color:m,dimColor:l,children:B}),f.map((r,o)=>i(p,{color:m,dimColor:l,children:r},o)),i(p,{color:m,dimColor:l,children:O})]})};export{J as ScrollBar};
@@ -0,0 +1 @@
1
+ import{jsxs as D,jsx as l}from"react/jsx-runtime";import b from"@visulima/tui/components/box";import{ScrollBar as g}from"./ScrollBar-C9i3z3Ft.js";const S=({borderColor:r,borderDimColor:e,borderLeftColor:a,borderLeftDimColor:C,borderRightColor:p,borderRightDimColor:H,borderStyle:t="single",children:u,contentHeight:i,height:w,scrollBarAutoHide:h=!1,scrollBarPosition:x="right",scrollOffset:d,thumbChar:c,viewportHeight:f,...B})=>{const o=x==="left",s=o?"left":"right",m=o?a??r:p??r,n=o?C??e:H??e;return D(b,{flexDirection:"row",height:w,...B,children:[o&&l(g,{autoHide:h,color:m,contentHeight:i,dimColor:n,placement:s,scrollOffset:d,style:t,thumbChar:c,viewportHeight:f}),l(b,{borderColor:r,borderDimColor:e,borderLeft:!o,borderRight:o,borderStyle:t,flexGrow:1,overflow:"hidden",children:u}),!o&&l(g,{autoHide:h,color:m,contentHeight:i,dimColor:n,placement:s,scrollOffset:d,style:t,thumbChar:c,viewportHeight:f})]})};export{S as ScrollBarBox};
@@ -0,0 +1 @@
1
+ import{jsx as X}from"react/jsx-runtime";import Y from"@visulima/tui/hooks/use-scroll-input";import{useRef as d,useState as N,useEffect as y,useCallback as g,useImperativeHandle as Q}from"react";import{C as U}from"./controlled-scroll-view-DerVKKv6.js";const et=O=>{const{children:P,keyboard:A=!1,onContentHeightChange:V,onItemHeightChange:B,onScroll:T,onViewportSizeChange:b,overscan:E,ref:L,scrollAlignment:h="auto",selectedIndex:p,vimBindings:R=!1,virtualize:j,...q}=O,n=d(null),[s,D]=N(0),C=d(0);y(()=>{C.current=s},[s]);const o=g(t=>{t!==C.current&&(D(t),T?.(t))},[T]),a=d(p);a.current=p;const S=g(()=>{const t=a.current;if(t===void 0||t<0)return null;const e=n.current?.getItemPosition(t);if(!e)return null;const i=n.current?.getViewportHeight()??0,l=n.current?.getContentHeight()??0;let r=e.top+e.height-i,c=e.top;r>c&&([r,c]=[c,r]);const M=Math.max(0,l-i);return{max:Math.min(M,c),min:Math.max(0,r)}},[]),u=g(t=>{const e=n.current?.getContentHeight()??0,i=n.current?.getViewportHeight()??0,l=Math.max(0,e-i);let r=Math.max(0,Math.min(t,l));const c=S();return c&&(r=Math.max(c.min,Math.min(r,c.max))),r},[S]),m=g((t,e,i,l)=>{const r=n.current?.getItemPosition(t);if(!r)return e;const c=l??n.current?.getViewportHeight()??0,M=n.current?.getContentHeight()??0;let f=e;switch(i){case"bottom":{f=r.top+r.height-c;break}case"center":{f=r.top+r.height/2-c/2;break}case"top":{f=r.top;break}default:{const w=r.top+r.height;r.top<=e&&w>=e+c?f=e:r.top<e?f=r.top:w>e+c&&(f=w-c)}}const W=Math.max(0,M-c);return Math.max(0,Math.min(f,W))},[]);let H=s;p!==void 0&&p>=0&&(H=m(p,s,h)),y(()=>{H!==s&&o(H)},[H,s,o]);const k=g((t,e)=>{if(a.current!==void 0&&a.current>=0){const i=m(a.current,s,h,t.height);o(i)}b?.(t,e)},[b,m,s,h,o]),F=g((t,e,i)=>{const l=a.current;if(l!==void 0&&l>=0){if(t<l){const r=u(s+(e-i));o(r)}else if(t===l){const r=m(t,s,h);o(r)}}B?.(t,e,i)},[B,m,h,s,u,o]),G=g((t,e)=>{if(a.current!==void 0&&a.current>=0){const i=m(a.current,s,h);o(i)}V?.(t,e)},[V,m,s,h,o]),z=d(0),x=g(t=>{const e=C.current,i=u(e+t);o(i)},[u,o]),v=g(()=>{const t=n.current?.getContentHeight()??0,e=n.current?.getViewportHeight()??0,i=Math.max(0,t-e),l=u(i);o(l)},[u,o]),I=g(()=>{const t=u(0);o(t)},[u,o]),J=g(()=>z.current,[]);Y({getViewportHeight:J,isActive:A,scrollBy:x,scrollToBottom:v,scrollToTop:I,vimBindings:R}),Q(L,()=>({getBottomOffset:()=>n.current?.getBottomOffset()??0,getContentHeight:()=>n.current?.getContentHeight()??0,getItemHeight:t=>n.current?.getItemHeight(t)??0,getItemPosition:t=>n.current?.getItemPosition(t)??null,getScrollOffset:()=>C.current,getViewportHeight:()=>n.current?.getViewportHeight()??0,remeasure:()=>n.current?.remeasure(),remeasureItem:t=>n.current?.remeasureItem(t),scrollBy:x,scrollTo:t=>{const e=u(t);o(e)},scrollToBottom:v,scrollToTop:I}),[u,o,x,v,I]);const K=g((t,e)=>{z.current=t.height,k(t,e)},[k]);return X(U,{onContentHeightChange:G,onItemHeightChange:F,onViewportSizeChange:K,overscan:E,ref:n,scrollOffset:H,virtualize:j,...q,children:P})};export{et as ScrollList};
@@ -0,0 +1 @@
1
+ import{jsxs as X,jsx as v}from"react/jsx-runtime";import _ from"@visulima/tui/components/box";import $ from"@visulima/tui/hooks/use-scroll-input";import{useRef as h,useState as q,useCallback as o,useImperativeHandle as ee}from"react";import{f as re,C as E}from"./controlled-scroll-view-DerVKKv6.js";import{ScrollBar as te}from"./ScrollBar-C9i3z3Ft.js";const se=({children:I,debug:M=!1,followOutput:T=!1,followThreshold:z=3,keyboard:F=!1,onContentHeightChange:B,onItemHeightChange:y,onReachEnd:g,onReachStart:p,onScroll:V,onViewportSizeChange:N,overscan:O,reachThreshold:a=5,ref:K,scrollbar:W=!1,scrollbarColor:Y,scrollbarStyle:Z="line",vimBindings:J=!1,virtualize:G,...m})=>{const[d,k,n]=re(0),c=h(null),s=h(0),l=h(0),[P,L]=q(0),[x,Q]=q(0),C=h(!1),w=h(!1),i=o(()=>Math.max(0,s.current-l.current),[]),j=o(e=>{const t=i();g&&e>=t-a&&!C.current?(C.current=!0,g()):e<t-a&&(C.current=!1),p&&e<=a&&!w.current?(w.current=!0,p()):e>a&&(w.current=!1)},[g,p,a,i]),r=o(e=>{e!==n()&&(k(e),V?.(e),j(e))},[n,k,V,j]),A=o((e,t)=>{const u=n()>=i()-z;if(s.current=e,L(e),B?.(e,t),T&&u&&e>t){const f=Math.max(0,e-l.current);r(f)}else{const f=Math.max(0,e-l.current);n()>f&&r(f)}},[B,T,z,n,i,r]),D=o((e,t)=>{l.current=e.height,Q(e.height),N?.(e,t)},[N]),H=o(e=>{if(typeof e!="number"||Number.isNaN(e))return;const t=Math.max(0,s.current-l.current),u=Math.max(0,Math.min(n()+e,t));r(u)},[n,r]),R=o(e=>{if(typeof e!="number"||Number.isNaN(e))return;const t=Math.max(0,s.current-l.current),u=Math.max(0,Math.min(e,t));r(u)},[r]),b=o(()=>{const e=i();r(e)},[i,r]),S=o(()=>{r(0)},[r]),U=o(()=>l.current,[]);return $({getViewportHeight:U,isActive:F,scrollBy:H,scrollToBottom:b,scrollToTop:S,vimBindings:J}),ee(K,()=>({getBottomOffset:i,getContentHeight:()=>s.current,getItemHeight:e=>c.current?.getItemHeight(e)??0,getItemPosition:e=>c.current?.getItemPosition(e)??null,getScrollOffset:n,getViewportHeight:()=>l.current,remeasure:()=>c.current?.remeasure(),remeasureItem:e=>c.current?.remeasureItem(e),scrollBy:H,scrollTo:R,scrollToBottom:b,scrollToTop:S}),[i,n,H,R,b,S]),W&&P>x&&x>0?X(_,{flexDirection:"row",flexGrow:m.flexGrow,flexShrink:m.flexShrink,overflow:"hidden",children:[v(E,{children:I,debug:M,onContentHeightChange:A,onItemHeightChange:y,onViewportSizeChange:D,overscan:O,ref:c,scrollOffset:d,virtualize:G,...m,flexGrow:1}),v(te,{color:Y,contentHeight:P,placement:"inset",scrollOffset:d,style:Z,viewportHeight:x})]}):v(E,{children:I,debug:M,onContentHeightChange:A,onItemHeightChange:y,onViewportSizeChange:D,overscan:O,ref:c,scrollOffset:d,virtualize:G,...m})};export{se as ScrollView};
@@ -0,0 +1 @@
1
+ class g{orderedIds;rootIds;map;constructor(i){this.map=new Map,this.orderedIds=[],this.rootIds=[],this.buildFromData(i)}entries(){return this.map.entries()}get(i){return this.map.get(i)}get size(){return this.map.size}getVisibleIds(i){const d=[],n=[];for(let e=this.rootIds.length-1;e>=0;e--)n.push(this.rootIds[e]);for(;n.length>0;){const e=n.pop();d.push(e);const s=this.map.get(e);if(s&&i.has(e)&&s.childrenIds.length>0)for(let t=s.childrenIds.length-1;t>=0;t--)n.push(s.childrenIds[t])}return d}isDescendantOf(i,d){let n=i;for(;n!==void 0;){const e=this.map.get(n);if(!e)return!1;if(e.parentId===d)return!0;n=e.parentId}return!1}withChildren(i,d){if(!this.map.get(i))return this;const n=s=>{const t=this.map.get(s);return s===i?{...t.node,children:d}:t.childrenIds.length>0?{...t.node,children:t.childrenIds.map(p=>n(p))}:t.node},e=this.rootIds.map(s=>n(s));return new g(e)}buildFromData(i){const d=[];for(let e=i.length-1;e>=0;e--)d.push({depth:0,node:i[e],parentId:void 0,siblingIndex:e,siblings:i});for(const e of i)this.rootIds.push(e.id);let n=0;for(;d.length>0;){const e=d.pop(),{depth:s,node:t,parentId:p,siblingIndex:o,siblings:l}=e;if(this.map.has(t.id))throw new Error(`TreeView: Duplicate node id '${t.id}' found. All node ids must be unique.`);const h=t.children??[],a=h.length>0||t.isParent===!0,u=h.map(r=>r.id),I=o>0?l[o-1].id:void 0,c=o<l.length-1?l[o+1].id:void 0,f={childrenIds:u,depth:s,flatIndex:n,hasChildren:a,nextSiblingId:c,node:t,parentId:p,previousSiblingId:I,siblingCount:l.length,siblingIndex:o};if(this.map.set(t.id,f),this.orderedIds.push(t.id),n++,a)for(let r=h.length-1;r>=0;r--)d.push({depth:s+1,node:h[r],parentId:t.id,siblingIndex:r,siblings:h})}}}export{g as TreeNodeMap};
@@ -0,0 +1 @@
1
+ import{jsxs as b,jsx as a}from"react/jsx-runtime";import v from"@visulima/tui/components/box";import n from"@visulima/tui/components/text";import L from"@visulima/tui/hooks/use-is-screen-reader-enabled";import{theme as M}from"./treeViewTheme-Dq3ekRAC.js";import{useTreeView as y}from"./useTreeView-D0JEqT6W.js";import{useTreeViewState as j}from"./useTreeViewState-BiTJakkh.js";const V="❯",D="▾",A="▸",P="☒",R="☐",$="✔",k="⟳";function T(t,r,i,l){const{depth:c,hasChildren:m,isExpanded:o,isLoading:u,isSelected:C}=r,d=[t,`item ${i} of ${l}`];return c>0&&d.push(`depth ${c}`),m&&d.push(o?"expanded":"collapsed"),u&&d.push("loading"),C&&d.push("selected"),d.join(", ")}function F(t,r){const i={};return t.hasChildren&&(i.expanded=t.isExpanded),r!=="none"&&(i.selected=t.isSelected),Object.keys(i).length>0?i:void 0}function O({isScreenReaderEnabled:t,node:r,nodeState:i,selectionMode:l,siblingCount:c,siblingPosition:m,styles:o}){const{depth:u,hasChildren:C,isExpanded:d,isFocused:h,isLoading:s,isSelected:f}=i;let e=" ";s?e=k:C&&(e=d?D:A);const g=t?T(r.label,i,m,c):void 0;return b(v,{...o.node({isFocused:h}),"aria-role":"listitem","aria-state":F(i,l),children:[g&&a(n,{"aria-label":g}),h&&a(n,{...o.focusIndicator(),"aria-hidden":!0,children:V}),u>0&&a(v,{...o.indent({depth:u}),"aria-hidden":!0}),l==="multiple"&&a(n,{...o.selectedIndicator(),"aria-hidden":!0,children:f?P:R}),a(n,{...s?o.loadingIndicator():o.expandIndicator({isExpanded:d}),"aria-hidden":!0,children:e}),a(n,{...o.label({isFocused:h,isSelected:f}),children:r.label}),l==="single"&&f&&b(n,{...o.selectedIndicator(),"aria-hidden":!0,children:[" ",$]})]})}function K({ariaLabel:t="Tree view",data:r,defaultExpanded:i,defaultSelected:l,isDisabled:c=!1,loadChildren:m,onExpandChange:o,onFocusChange:u,onLoadError:C,onSelectChange:d,renderNode:h,selectionMode:s="none",visibleNodeCount:f}){const e=j({data:r,defaultExpanded:i,defaultSelected:l,onExpandChange:o,onFocusChange:u,onSelectChange:d,selectionMode:s,visibleNodeCount:f});y({isDisabled:c,loadChildren:m,onLoadError:C,selectionMode:s,state:e});const{styles:g}=M,w=L();return b(v,{...g.container(),"aria-role":"list",children:[w&&a(n,{"aria-label":t}),e.hasScrollUp&&b(n,{"aria-label":`${e.viewportFromIndex} more items above`,dimColor:!0,children:[" ","↑",e.viewportFromIndex," ","more above"]}),e.viewportNodes.map(({node:p,state:x})=>{const S=e.nodeMap.get(p.id),E=S?S.siblingIndex+1:1,I=S?S.siblingCount:1;if(h){const N=w?T(p.label,x,E,I):void 0;return b(v,{"aria-role":"listitem","aria-state":F(x,s),children:[N&&a(n,{"aria-label":N}),h({node:p,state:x})]},p.id)}return a(O,{isScreenReaderEnabled:w,node:p,nodeState:x,selectionMode:s,siblingCount:I,siblingPosition:E,styles:g},p.id)}),e.hasScrollDown&&b(n,{"aria-label":`${e.visibleCount-e.viewportToIndex} more items below`,dimColor:!0,children:[" ","↓",e.visibleCount-e.viewportToIndex," ","more below"]})]})}export{K as TreeView};
@@ -0,0 +1 @@
1
+ import{jsx as E,jsxs as rr}from"react/jsx-runtime";import{measureElement as K}from"@visulima/tui";import H from"@visulima/tui/components/box";import{useState as N,useRef as d,useCallback as j,useLayoutEffect as T,isValidElement as z,useImperativeHandle as tr,Fragment as G}from"react";const J=u=>{const[g,m]=N(u),l=d(u),M=j(v=>{const k=typeof v=="function"?v(l.current):v;l.current=k,m(k)},[]),y=j(()=>l.current,[]);return[g,M,y]},er=({children:u,index:g,measureKey:m,onMeasure:l,width:M})=>{const y=d(null);return T(()=>{if(y.current){const{height:v}=K(y.current);l(g,v)}},[g,l,M,m,u]),E(H,{flexDirection:"column",flexShrink:0,ref:y,width:"100%",children:u})},D=u=>{if(u==null)return[];if(Array.isArray(u)){const g=[];for(let m=0;m<u.length;m+=1){const l=u[m];z(l)&&l.type===G?g.push(...D(l.props.children)):g.push(l)}return g}return z(u)&&u.type===G?D(u.props.children):[u]},hr=({children:u,debug:g=!1,onContentHeightChange:m,onItemHeightChange:l,onViewportSizeChange:M,overscan:y=3,ref:v,scrollOffset:k,virtualize:Q=!1,...U})=>{const O=d(!1),[$,q,V]=J({height:0,width:0}),[I,b,S]=J(0),[W,X]=N({}),A=d(null),B=d(0);T(()=>{I!==B.current&&(m?.(I,B.current),B.current=I)},[I,m]);const o=d({}),i=d([]),p=d([]),f=d(0),Y=j((r,t)=>{const e=i.current[r]??r;if(o.current[e]!==t){const h=o.current[e]??0;o.current={...o.current,[e]:t};let n=0;for(let s=0;s<i.current.length;s+=1){const x=i.current[s];x!=null&&(n+=o.current[x]??0)}const c=S();n!==c&&b(n),l?.(r,t,h),f.current=Math.min(f.current,r+1)}},[l,S,b]),F=j(()=>{if(A.current){const{height:r,width:t}=K(A.current),e=V();(t!==e.width||r!==e.height)&&(M?.({height:r,width:t},e),q({height:r,width:t}))}},[A,M,V,q]);T(()=>{F()});const Z=d(null);if(Z.current!==u){Z.current=u;const r=[],t={};D(u).forEach((n,c)=>{if(!n)return;const s=(z(n)?n.key:null)??c;r[c]=s;const x=o.current[s]??0;t[s]=x}),o.current=t,i.current=r,p.current=Array.from({length:r.length}).fill(0),f.current=0;let e=0;r.forEach(n=>{e+=t[n]??0});const h=S();e!==h&&b(e)}tr(v,()=>({getBottomOffset:()=>Math.max(0,S()-V().height),getContentHeight:S,getItemHeight:r=>{const t=i.current[r]??r;return o.current[t]??0},getItemPosition:r=>{if(r<0||r>=i.current.length)return null;if(r>=f.current){let h=0,n=0;if(f.current>0){n=f.current;const c=n-1,s=i.current[c]??c,x=o.current[s]??0;h=(p.current[c]??0)+x}for(let c=n;c<=r;c+=1){p.current[c]=h;const s=i.current[c]??c,x=o.current[s]??0;h+=x}f.current=r+1}const t=p.current[r]??0,e=i.current[r]??r;return{height:o.current[e]??0,top:t}},getViewportHeight:()=>V().height,remeasure:F,remeasureItem:r=>{X(t=>({...t,[r]:(t[r]??0)+1}))}}),[F,S,V,X]);const C=D(u);!O.current&&I>0&&(O.current=!0);let w=0,a=C.length-1,L=0,P=0;const _=C.length>0&&C.every((r,t)=>{const e=i.current[t]??t;return(o.current[e]??0)>0}),R=Q&&O.current&&_;if(R){const r=i.current.length;if(f.current<r){let e=0,h=0;if(f.current>0){h=f.current;const n=h-1,c=i.current[n]??n,s=o.current[c]??0;e=(p.current[n]??0)+s}for(let n=h;n<r;n+=1){p.current[n]=e;const c=i.current[n]??n;e+=o.current[c]??0}f.current=r}const t=k+$.height;w=C.length,a=-1;for(let e=0;e<r;e+=1){const h=p.current[e]??0,n=i.current[e]??e,c=o.current[n]??0;h+c>k&&h<t&&(e<w&&(w=e),a=e)}if(w>a&&(w=0,a=-1),w=Math.max(0,w-y),a=Math.min(C.length-1,Math.max(-1,a)+y),L=p.current[w]??0,a<C.length-1){const e=i.current[a]??a,h=(p.current[a]??0)+(o.current[e]??0);P=I-h}}return E(H,{...U,children:E(H,{ref:A,width:"100%",children:E(H,{overflow:g?void 0:"hidden",width:"100%",children:rr(H,{flexDirection:"column",marginTop:-k,width:"100%",children:[R&&L>0&&E(H,{height:L}),C.map((r,t)=>!r||R&&(t<w||t>a)?null:E(er,{index:t,measureKey:W[t],onMeasure:Y,width:$.width,children:r},z(r)?r.key??t:t)),R&&P>0&&E(H,{height:P})]})})})})};export{hr as C,J as f};
@@ -0,0 +1,54 @@
1
+ import { Props } from '@visulima/tui/components/box';
2
+ import React, { ReactNode, Ref } from 'react';
3
+ interface ControlledScrollViewProps extends Props {
4
+ children?: ReactNode;
5
+ debug?: boolean;
6
+ onContentHeightChange?: (height: number, previousHeight: number) => void;
7
+ onItemHeightChange?: (index: number, height: number, previousHeight: number) => void;
8
+ onViewportSizeChange?: (size: {
9
+ height: number;
10
+ width: number;
11
+ }, previousSize: {
12
+ height: number;
13
+ width: number;
14
+ }) => void;
15
+ /**
16
+ * Number of extra items to render above/below the viewport when virtualized.
17
+ * @default 3
18
+ */
19
+ overscan?: number;
20
+ scrollOffset: number;
21
+ /**
22
+ * Only render items visible in the viewport plus overscan.
23
+ * Items must be measured first (first render always renders all items).
24
+ * @default false
25
+ */
26
+ virtualize?: boolean;
27
+ }
28
+ interface ControlledScrollViewRef {
29
+ getBottomOffset: () => number;
30
+ getContentHeight: () => number;
31
+ getItemHeight: (index: number) => number;
32
+ getItemPosition: (index: number) => {
33
+ height: number;
34
+ top: number;
35
+ } | null;
36
+ getViewportHeight: () => number;
37
+ remeasure: () => void;
38
+ remeasureItem: (index: number) => void;
39
+ }
40
+ declare const ControlledScrollView: ({
41
+ children,
42
+ debug,
43
+ onContentHeightChange,
44
+ onItemHeightChange,
45
+ onViewportSizeChange,
46
+ overscan,
47
+ ref,
48
+ scrollOffset,
49
+ virtualize,
50
+ ...boxProps
51
+ }: ControlledScrollViewProps & {
52
+ ref?: Ref<ControlledScrollViewRef>;
53
+ }) => React.JSX.Element;
54
+ export { ControlledScrollView as C, ControlledScrollViewProps as a, ControlledScrollViewRef as b };
@@ -0,0 +1,104 @@
1
+ import { ReactElement } from 'react';
2
+ /**
3
+ * A single entry (file or directory) returned by the file system hook.
4
+ */
5
+ type FileEntry = {
6
+ readonly isDirectory: boolean;
7
+ readonly isHidden: boolean;
8
+ readonly name: string;
9
+ readonly path: string;
10
+ readonly permissions: string;
11
+ readonly size: number;
12
+ };
13
+ /**
14
+ * Filter options for the file picker.
15
+ */
16
+ type FilePickerFilter = {
17
+ /**
18
+ * Allowed file extensions (e.g. `[".ts", ".tsx"]`). Empty or omitted means all.
19
+ */
20
+ readonly extensions?: ReadonlyArray<string>;
21
+ /**
22
+ * Whether to include directories in the list.
23
+ * @default true
24
+ */
25
+ readonly showDirectories?: boolean;
26
+ /**
27
+ * Whether to include regular files in the list.
28
+ * @default true
29
+ */
30
+ readonly showFiles?: boolean;
31
+ /**
32
+ * Whether to include hidden files (names starting with `.`).
33
+ * @default false
34
+ */
35
+ readonly showHidden?: boolean;
36
+ };
37
+ type Props = {
38
+ /**
39
+ * Color for the focused item highlight.
40
+ * @default "cyan"
41
+ */
42
+ readonly accentColor?: string;
43
+ /**
44
+ * Color for directory entries.
45
+ * @default "blue"
46
+ */
47
+ readonly directoryColor?: string;
48
+ /**
49
+ * Color for file entries.
50
+ * @default "white"
51
+ */
52
+ readonly fileColor?: string;
53
+ /**
54
+ * File filter options.
55
+ */
56
+ readonly filter?: FilePickerFilter;
57
+ /**
58
+ * Starting directory path.
59
+ * @default process.cwd()
60
+ */
61
+ readonly initialPath?: string;
62
+ /**
63
+ * Whether keyboard navigation is active.
64
+ * @default true
65
+ */
66
+ readonly isFocused?: boolean;
67
+ /**
68
+ * Maximum number of visible items (viewport height).
69
+ * @default 10
70
+ */
71
+ readonly limit?: number;
72
+ /**
73
+ * Called when escape is pressed.
74
+ */
75
+ readonly onCancel?: () => void;
76
+ /**
77
+ * Called when a file is selected (enter on a file entry).
78
+ */
79
+ readonly onSelect?: (entry: FileEntry) => void;
80
+ /**
81
+ * Show file permissions column.
82
+ * @default false
83
+ */
84
+ readonly showPermissions?: boolean;
85
+ /**
86
+ * Show file size column.
87
+ * @default false
88
+ */
89
+ readonly showSize?: boolean;
90
+ };
91
+ declare const FilePicker: ({
92
+ accentColor,
93
+ directoryColor,
94
+ fileColor,
95
+ filter,
96
+ initialPath,
97
+ isFocused,
98
+ limit,
99
+ onCancel,
100
+ onSelect,
101
+ showPermissions,
102
+ showSize
103
+ }: Props) => ReactElement;
104
+ export { FileEntry as F, Props as P, FilePicker as a, FilePickerFilter as b };
@@ -0,0 +1 @@
1
+ import{jsxs as N,jsx as I}from"react/jsx-runtime";import{createBrailleGrid as u}from"@visulima/tui/canvas";import h from"@visulima/tui/components/box";import d from"@visulima/tui/components/canvas";import y from"@visulima/tui/components/text";import{useMemo as f}from"react";const T=["cyan","magenta","yellow","green","blue","red"],g=e=>e.length===0?[]:typeof e[0]=="number"?e.map((t,o)=>({x:o,y:t})):e,E=(e,t,o)=>e.color??o[t%o.length]??"cyan",b=e=>{let t=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,a=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY;for(const{points:x}of e)for(const n of x)n.x<t&&(t=n.x),n.x>o&&(o=n.x),n.y<a&&(a=n.y),n.y>s&&(s=n.y);return{xMax:o,xMin:t,yMax:s,yMin:a}},Y=T,M=(e,t,o,a)=>{const s=t.xMax-t.xMin||1,x=t.yMax-t.yMin||1,n=(e.x-t.xMin)/s,c=(e.y-t.yMin)/x;return{px:Math.max(0,Math.min(o-1,Math.round(n*(o-1)))),py:Math.max(0,Math.min(a-1,Math.round((1-c)*(a-1))))}},_=(e,t,o)=>{e.clear();const{axisColor:a,seriesList:s}=o,x=Math.max(1,e.width*2),n=Math.max(1,e.height*4);for(let c=0;c<e.width;c+=2)e.setCell(c,e.height-1,"·",{color:a,dim:!0});for(const{color:c,points:m}of s){if(m.length===0)continue;const l=u(e.width,e.height);if(t==="scatter")for(const i of m){const r=M(i,o,x,n);l.plotPoint(r.px,r.py)}else{let i=M(m[0],o,x,n);l.plotPoint(i.px,i.py);for(let r=1;r<m.length;r+=1){const p=M(m[r],o,x,n);l.plotLine(i.px,i.py,p.px,p.py),i=p}}l.flush(e,{color:c})}};function L({axisColor:e="gray",height:t=10,maxY:o,minY:a,palette:s=Y,series:x,showLegend:n=!0,width:c=40}){const m=f(()=>{const l=x.map((r,p)=>({color:E(r,p,s),points:g(r.data),series:r})),i=b(l);return{axisColor:e,palette:s,seriesList:l,xMax:i.xMax===Number.NEGATIVE_INFINITY?1:i.xMax,xMin:i.xMin===Number.POSITIVE_INFINITY?0:i.xMin,yMax:o??(i.yMax===Number.NEGATIVE_INFINITY?1:i.yMax),yMin:a??(i.yMin===Number.POSITIVE_INFINITY?0:i.yMin)}},[x,e,s,a,o]);return N(h,{flexDirection:"column",children:[I(d,{draw:l=>{_(l,"line",m)},height:t,version:[x,c,t,a,o,e,s],width:c}),n?I(h,{gap:2,marginTop:1,children:m.seriesList.map(({color:l,series:i},r)=>N(h,{gap:1,children:[I(y,{color:l,children:"●"}),I(y,{children:i.label??`Series ${r+1}`})]},`${r}:${i.label??""}`))}):void 0]})}export{T as D,M as a,b as c,_ as d,L as h,E as p,g as t};
@@ -0,0 +1,30 @@
1
+ import { Props } from '@visulima/tui/components/box';
2
+ import React from 'react';
3
+ interface ScrollBarBoxProps extends Props {
4
+ children?: React.ReactNode;
5
+ contentHeight: number;
6
+ scrollBarAutoHide?: boolean;
7
+ scrollBarPosition?: "left" | "right";
8
+ scrollOffset: number;
9
+ thumbChar?: string;
10
+ viewportHeight: number;
11
+ }
12
+ declare const ScrollBarBox: ({
13
+ borderColor,
14
+ borderDimColor,
15
+ borderLeftColor,
16
+ borderLeftDimColor,
17
+ borderRightColor,
18
+ borderRightDimColor,
19
+ borderStyle,
20
+ children,
21
+ contentHeight,
22
+ height,
23
+ scrollBarAutoHide,
24
+ scrollBarPosition,
25
+ scrollOffset,
26
+ thumbChar,
27
+ viewportHeight,
28
+ ...boxProps
29
+ }: ScrollBarBoxProps) => React.JSX.Element;
30
+ export { ScrollBarBox as S, ScrollBarBoxProps as a };
@@ -0,0 +1,18 @@
1
+ import { Props } from '@visulima/tui/components/box';
2
+ import React from 'react';
3
+ type ScrollBarPlacement = "inset" | "left" | "right";
4
+ type ScrollBarStyle = Props["borderStyle"] | "block" | "line" | "thick" | "dots";
5
+ interface ScrollBarProps {
6
+ autoHide?: boolean;
7
+ color?: string;
8
+ contentHeight: number;
9
+ dimColor?: boolean;
10
+ placement?: ScrollBarPlacement;
11
+ scrollOffset: number;
12
+ style?: ScrollBarStyle;
13
+ thumbChar?: string;
14
+ trackChar?: string;
15
+ viewportHeight: number;
16
+ }
17
+ declare const ScrollBar: React.FC<ScrollBarProps>;
18
+ export { ScrollBar as S, ScrollBarPlacement as a, ScrollBarProps as b, ScrollBarStyle as c };
@@ -0,0 +1,12 @@
1
+ import React, { Ref } from 'react';
2
+ import { a as ScrollViewProps, b as ScrollViewRef } from "./scroll-view.d-BqKpI-F-.js";
3
+ type ScrollAlignment = "auto" | "bottom" | "center" | "top";
4
+ interface ScrollListProps extends ScrollViewProps {
5
+ readonly scrollAlignment?: ScrollAlignment;
6
+ readonly selectedIndex?: number;
7
+ }
8
+ type ScrollListRef = ScrollViewRef;
9
+ declare const ScrollList: (props: ScrollListProps & {
10
+ ref?: Ref<ScrollListRef>;
11
+ }) => React.JSX.Element;
12
+ export { ScrollAlignment as S, ScrollList as a, ScrollListProps as b, ScrollListRef as c };
@@ -0,0 +1,119 @@
1
+ import { Props } from '@visulima/tui/components/box';
2
+ import React, { ReactNode, Ref } from 'react';
3
+ interface ScrollViewProps extends Props {
4
+ children?: ReactNode;
5
+ debug?: boolean;
6
+ /**
7
+ * Auto-scroll to bottom when content grows and user is at/near the bottom.
8
+ * Pauses when user scrolls away from bottom; resumes when they return.
9
+ * @default false
10
+ */
11
+ followOutput?: boolean;
12
+ /**
13
+ * Number of lines from bottom that still counts as "at bottom" for followOutput.
14
+ * @default 3
15
+ */
16
+ followThreshold?: number;
17
+ /**
18
+ * Enable built-in keyboard navigation (arrows, page up/down, home/end, ctrl+u/d).
19
+ * When enabled, the component becomes focusable.
20
+ * @default false
21
+ */
22
+ keyboard?: boolean;
23
+ onContentHeightChange?: (height: number, previousHeight: number) => void;
24
+ onItemHeightChange?: (index: number, height: number, previousHeight: number) => void;
25
+ /**
26
+ * Fires when scrolled within `reachThreshold` lines of the end.
27
+ * Only fires once per entry into the threshold zone.
28
+ */
29
+ onReachEnd?: () => void;
30
+ /**
31
+ * Fires when scrolled within `reachThreshold` lines of the start.
32
+ * Only fires once per entry into the threshold zone.
33
+ */
34
+ onReachStart?: () => void;
35
+ onScroll?: (scrollOffset: number) => void;
36
+ onViewportSizeChange?: (size: {
37
+ height: number;
38
+ width: number;
39
+ }, previousSize: {
40
+ height: number;
41
+ width: number;
42
+ }) => void;
43
+ /**
44
+ * Number of extra items to render above/below the viewport when virtualized.
45
+ * @default 3
46
+ */
47
+ overscan?: number;
48
+ /**
49
+ * Distance in lines from the edge to trigger onReachEnd/onReachStart.
50
+ * @default 5
51
+ */
52
+ reachThreshold?: number;
53
+ /**
54
+ * Show a scrollbar track when content overflows the viewport.
55
+ * @default false
56
+ */
57
+ scrollbar?: boolean;
58
+ /**
59
+ * Color of the scrollbar thumb and track.
60
+ */
61
+ scrollbarColor?: string;
62
+ /**
63
+ * Scrollbar visual style.
64
+ * @default "line"
65
+ */
66
+ scrollbarStyle?: "arrow" | "block" | "bold" | "classic" | "dots" | "double" | "doubleSingle" | "line" | "round" | "single" | "singleDouble" | "thick";
67
+ /**
68
+ * Enable vim-style keybindings (j/k/g/G/u/d). Requires `keyboard` to be true.
69
+ * @default false
70
+ */
71
+ vimBindings?: boolean;
72
+ /**
73
+ * Only render items visible in the viewport plus overscan. Requires items to be measured first.
74
+ * @default false
75
+ */
76
+ virtualize?: boolean;
77
+ }
78
+ interface ScrollViewRef {
79
+ getBottomOffset: () => number;
80
+ getContentHeight: () => number;
81
+ getItemHeight: (index: number) => number;
82
+ getItemPosition: (index: number) => {
83
+ height: number;
84
+ top: number;
85
+ } | null;
86
+ getScrollOffset: () => number;
87
+ getViewportHeight: () => number;
88
+ remeasure: () => void;
89
+ remeasureItem: (index: number) => void;
90
+ scrollBy: (delta: number) => void;
91
+ scrollTo: (offset: number) => void;
92
+ scrollToBottom: () => void;
93
+ scrollToTop: () => void;
94
+ }
95
+ declare const ScrollView: ({
96
+ children,
97
+ debug,
98
+ followOutput,
99
+ followThreshold,
100
+ keyboard,
101
+ onContentHeightChange,
102
+ onItemHeightChange,
103
+ onReachEnd,
104
+ onReachStart,
105
+ onScroll,
106
+ onViewportSizeChange,
107
+ overscan,
108
+ reachThreshold,
109
+ ref,
110
+ scrollbar,
111
+ scrollbarColor,
112
+ scrollbarStyle: scrollbarStyleProp,
113
+ vimBindings,
114
+ virtualize,
115
+ ...boxProps
116
+ }: ScrollViewProps & {
117
+ ref?: Ref<ScrollViewRef>;
118
+ }) => React.JSX.Element;
119
+ export { ScrollView as S, ScrollViewProps as a, ScrollViewRef as b };
@@ -0,0 +1 @@
1
+ const c={styles:{container:()=>({flexDirection:"column"}),expandIndicator:e=>({color:"gray"}),focusIndicator:()=>({color:"blue"}),indent:({depth:e})=>({width:(e??0)*2}),label:({isFocused:e,isSelected:n})=>{let o;return n&&(o="green"),e&&(o="blue"),{color:o}},loadingIndicator:()=>({color:"yellow"}),node:({isFocused:e})=>({gap:1,paddingLeft:e?0:2}),selectedIndicator:()=>({color:"green"})}};export{c as theme};