@textui/widgets 0.1.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 (423) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +69 -0
  3. package/dist/chart/area-chart.d.ts +4 -0
  4. package/dist/chart/area-chart.d.ts.map +1 -0
  5. package/dist/chart/area-chart.js +3 -0
  6. package/dist/chart/bar-chart.d.ts +32 -0
  7. package/dist/chart/bar-chart.d.ts.map +1 -0
  8. package/dist/chart/bar-chart.js +32 -0
  9. package/dist/chart/gauge.d.ts +26 -0
  10. package/dist/chart/gauge.d.ts.map +1 -0
  11. package/dist/chart/gauge.js +26 -0
  12. package/dist/chart/heatmap.d.ts +13 -0
  13. package/dist/chart/heatmap.d.ts.map +1 -0
  14. package/dist/chart/heatmap.js +27 -0
  15. package/dist/chart/histogram.d.ts +12 -0
  16. package/dist/chart/histogram.d.ts.map +1 -0
  17. package/dist/chart/histogram.js +22 -0
  18. package/dist/chart/index.d.ts +20 -0
  19. package/dist/chart/index.d.ts.map +1 -0
  20. package/dist/chart/index.js +32 -0
  21. package/dist/chart/line-chart.d.ts +7 -0
  22. package/dist/chart/line-chart.d.ts.map +1 -0
  23. package/dist/chart/line-chart.js +75 -0
  24. package/dist/chart/shared.d.ts +34 -0
  25. package/dist/chart/shared.d.ts.map +1 -0
  26. package/dist/chart/shared.js +78 -0
  27. package/dist/chart/sparkline.d.ts +15 -0
  28. package/dist/chart/sparkline.d.ts.map +1 -0
  29. package/dist/chart/sparkline.js +22 -0
  30. package/dist/control/button.d.ts +27 -0
  31. package/dist/control/button.d.ts.map +1 -0
  32. package/dist/control/button.js +130 -0
  33. package/dist/control/checkbox.d.ts +10 -0
  34. package/dist/control/checkbox.d.ts.map +1 -0
  35. package/dist/control/checkbox.js +31 -0
  36. package/dist/control/index.d.ts +20 -0
  37. package/dist/control/index.d.ts.map +1 -0
  38. package/dist/control/index.js +36 -0
  39. package/dist/control/radio-group.d.ts +17 -0
  40. package/dist/control/radio-group.d.ts.map +1 -0
  41. package/dist/control/radio-group.js +32 -0
  42. package/dist/control/search-box.d.ts +7 -0
  43. package/dist/control/search-box.d.ts.map +1 -0
  44. package/dist/control/search-box.js +3 -0
  45. package/dist/control/select.d.ts +42 -0
  46. package/dist/control/select.d.ts.map +1 -0
  47. package/dist/control/select.js +166 -0
  48. package/dist/control/shared.d.ts +41 -0
  49. package/dist/control/shared.d.ts.map +1 -0
  50. package/dist/control/shared.js +1 -0
  51. package/dist/control/slider.d.ts +14 -0
  52. package/dist/control/slider.d.ts.map +1 -0
  53. package/dist/control/slider.js +45 -0
  54. package/dist/control/switch.d.ts +10 -0
  55. package/dist/control/switch.d.ts.map +1 -0
  56. package/dist/control/switch.js +32 -0
  57. package/dist/control/text-area.d.ts +87 -0
  58. package/dist/control/text-area.d.ts.map +1 -0
  59. package/dist/control/text-area.js +299 -0
  60. package/dist/control/text-input.d.ts +10 -0
  61. package/dist/control/text-input.d.ts.map +1 -0
  62. package/dist/control/text-input.js +129 -0
  63. package/dist/data/code-viewer.d.ts +71 -0
  64. package/dist/data/code-viewer.d.ts.map +1 -0
  65. package/dist/data/code-viewer.js +232 -0
  66. package/dist/data/feed.d.ts +43 -0
  67. package/dist/data/feed.d.ts.map +1 -0
  68. package/dist/data/feed.js +178 -0
  69. package/dist/data/index.d.ts +54 -0
  70. package/dist/data/index.d.ts.map +1 -0
  71. package/dist/data/index.js +187 -0
  72. package/dist/data/list.d.ts +31 -0
  73. package/dist/data/list.d.ts.map +1 -0
  74. package/dist/data/list.js +104 -0
  75. package/dist/data/log-viewer.d.ts +26 -0
  76. package/dist/data/log-viewer.d.ts.map +1 -0
  77. package/dist/data/log-viewer.js +69 -0
  78. package/dist/data/markdown-view.d.ts +31 -0
  79. package/dist/data/markdown-view.d.ts.map +1 -0
  80. package/dist/data/markdown-view.js +139 -0
  81. package/dist/data/pagination.d.ts +9 -0
  82. package/dist/data/pagination.d.ts.map +1 -0
  83. package/dist/data/pagination.js +18 -0
  84. package/dist/data/scroll-thumb.d.ts +15 -0
  85. package/dist/data/scroll-thumb.d.ts.map +1 -0
  86. package/dist/data/scroll-thumb.js +32 -0
  87. package/dist/data/shared.d.ts +12 -0
  88. package/dist/data/shared.d.ts.map +1 -0
  89. package/dist/data/shared.js +17 -0
  90. package/dist/data/tree.d.ts +35 -0
  91. package/dist/data/tree.d.ts.map +1 -0
  92. package/dist/data/tree.js +158 -0
  93. package/dist/decorations.d.ts +88 -0
  94. package/dist/decorations.d.ts.map +1 -0
  95. package/dist/decorations.js +135 -0
  96. package/dist/display/alert.d.ts +8 -0
  97. package/dist/display/alert.d.ts.map +1 -0
  98. package/dist/display/alert.js +12 -0
  99. package/dist/display/badge.d.ts +10 -0
  100. package/dist/display/badge.d.ts.map +1 -0
  101. package/dist/display/badge.js +21 -0
  102. package/dist/display/card.d.ts +8 -0
  103. package/dist/display/card.d.ts.map +1 -0
  104. package/dist/display/card.js +12 -0
  105. package/dist/display/empty-state.d.ts +10 -0
  106. package/dist/display/empty-state.d.ts.map +1 -0
  107. package/dist/display/empty-state.js +5 -0
  108. package/dist/display/error-state.d.ts +9 -0
  109. package/dist/display/error-state.d.ts.map +1 -0
  110. package/dist/display/error-state.js +7 -0
  111. package/dist/display/heading.d.ts +6 -0
  112. package/dist/display/heading.d.ts.map +1 -0
  113. package/dist/display/heading.js +8 -0
  114. package/dist/display/index.d.ts +25 -0
  115. package/dist/display/index.d.ts.map +1 -0
  116. package/dist/display/index.js +52 -0
  117. package/dist/display/key-value.d.ts +14 -0
  118. package/dist/display/key-value.d.ts.map +1 -0
  119. package/dist/display/key-value.js +11 -0
  120. package/dist/display/label.d.ts +6 -0
  121. package/dist/display/label.d.ts.map +1 -0
  122. package/dist/display/label.js +3 -0
  123. package/dist/display/marquee.d.ts +36 -0
  124. package/dist/display/marquee.d.ts.map +1 -0
  125. package/dist/display/marquee.js +55 -0
  126. package/dist/display/progress.d.ts +39 -0
  127. package/dist/display/progress.d.ts.map +1 -0
  128. package/dist/display/progress.js +46 -0
  129. package/dist/display/skeleton.d.ts +20 -0
  130. package/dist/display/skeleton.d.ts.map +1 -0
  131. package/dist/display/skeleton.js +20 -0
  132. package/dist/display/spinner.d.ts +7 -0
  133. package/dist/display/spinner.d.ts.map +1 -0
  134. package/dist/display/spinner.js +9 -0
  135. package/dist/display/status-dot.d.ts +8 -0
  136. package/dist/display/status-dot.d.ts.map +1 -0
  137. package/dist/display/status-dot.js +13 -0
  138. package/dist/display/timeline.d.ts +12 -0
  139. package/dist/display/timeline.d.ts.map +1 -0
  140. package/dist/display/timeline.js +22 -0
  141. package/dist/find.d.ts +74 -0
  142. package/dist/find.d.ts.map +1 -0
  143. package/dist/find.js +102 -0
  144. package/dist/form/danger-zone.d.ts +11 -0
  145. package/dist/form/danger-zone.d.ts.map +1 -0
  146. package/dist/form/danger-zone.js +15 -0
  147. package/dist/form/field.d.ts +19 -0
  148. package/dist/form/field.d.ts.map +1 -0
  149. package/dist/form/field.js +35 -0
  150. package/dist/form/form-actions.d.ts +11 -0
  151. package/dist/form/form-actions.d.ts.map +1 -0
  152. package/dist/form/form-actions.js +16 -0
  153. package/dist/form/form-section.d.ts +7 -0
  154. package/dist/form/form-section.d.ts.map +1 -0
  155. package/dist/form/form-section.js +5 -0
  156. package/dist/form/form.d.ts +7 -0
  157. package/dist/form/form.d.ts.map +1 -0
  158. package/dist/form/form.js +3 -0
  159. package/dist/form/index.d.ts +42 -0
  160. package/dist/form/index.d.ts.map +1 -0
  161. package/dist/form/index.js +140 -0
  162. package/dist/form/shared.d.ts +25 -0
  163. package/dist/form/shared.d.ts.map +1 -0
  164. package/dist/form/shared.js +9 -0
  165. package/dist/index.d.ts +26 -0
  166. package/dist/index.d.ts.map +1 -0
  167. package/dist/index.js +62 -0
  168. package/dist/layout/center.d.ts +7 -0
  169. package/dist/layout/center.d.ts.map +1 -0
  170. package/dist/layout/center.js +8 -0
  171. package/dist/layout/column.d.ts +3 -0
  172. package/dist/layout/column.d.ts.map +1 -0
  173. package/dist/layout/column.js +2 -0
  174. package/dist/layout/divider.d.ts +11 -0
  175. package/dist/layout/divider.d.ts.map +1 -0
  176. package/dist/layout/divider.js +13 -0
  177. package/dist/layout/grid.d.ts +10 -0
  178. package/dist/layout/grid.d.ts.map +1 -0
  179. package/dist/layout/grid.js +22 -0
  180. package/dist/layout/index.d.ts +19 -0
  181. package/dist/layout/index.d.ts.map +1 -0
  182. package/dist/layout/index.js +36 -0
  183. package/dist/layout/panel.d.ts +37 -0
  184. package/dist/layout/panel.d.ts.map +1 -0
  185. package/dist/layout/panel.js +71 -0
  186. package/dist/layout/row.d.ts +7 -0
  187. package/dist/layout/row.d.ts.map +1 -0
  188. package/dist/layout/row.js +2 -0
  189. package/dist/layout/scroll-view.d.ts +27 -0
  190. package/dist/layout/scroll-view.d.ts.map +1 -0
  191. package/dist/layout/scroll-view.js +93 -0
  192. package/dist/layout/splitter.d.ts +10 -0
  193. package/dist/layout/splitter.d.ts.map +1 -0
  194. package/dist/layout/splitter.js +9 -0
  195. package/dist/layout/stack.d.ts +7 -0
  196. package/dist/layout/stack.d.ts.map +1 -0
  197. package/dist/layout/stack.js +5 -0
  198. package/dist/navigation/breadcrumb.d.ts +14 -0
  199. package/dist/navigation/breadcrumb.d.ts.map +1 -0
  200. package/dist/navigation/breadcrumb.js +24 -0
  201. package/dist/navigation/index.d.ts +17 -0
  202. package/dist/navigation/index.d.ts.map +1 -0
  203. package/dist/navigation/index.js +30 -0
  204. package/dist/navigation/key-hints.d.ts +11 -0
  205. package/dist/navigation/key-hints.d.ts.map +1 -0
  206. package/dist/navigation/key-hints.js +13 -0
  207. package/dist/navigation/menu.d.ts +35 -0
  208. package/dist/navigation/menu.d.ts.map +1 -0
  209. package/dist/navigation/menu.js +88 -0
  210. package/dist/navigation/status-bar.d.ts +18 -0
  211. package/dist/navigation/status-bar.d.ts.map +1 -0
  212. package/dist/navigation/status-bar.js +12 -0
  213. package/dist/navigation/tabs.d.ts +20 -0
  214. package/dist/navigation/tabs.d.ts.map +1 -0
  215. package/dist/navigation/tabs.js +41 -0
  216. package/dist/navigation/toolbar.d.ts +14 -0
  217. package/dist/navigation/toolbar.d.ts.map +1 -0
  218. package/dist/navigation/toolbar.js +10 -0
  219. package/dist/navigation/wizard.d.ts +15 -0
  220. package/dist/navigation/wizard.d.ts.map +1 -0
  221. package/dist/navigation/wizard.js +17 -0
  222. package/dist/overlay/command-palette.d.ts +63 -0
  223. package/dist/overlay/command-palette.d.ts.map +1 -0
  224. package/dist/overlay/command-palette.js +415 -0
  225. package/dist/overlay/dialog.d.ts +16 -0
  226. package/dist/overlay/dialog.d.ts.map +1 -0
  227. package/dist/overlay/dialog.js +44 -0
  228. package/dist/overlay/index.d.ts +84 -0
  229. package/dist/overlay/index.d.ts.map +1 -0
  230. package/dist/overlay/index.js +157 -0
  231. package/dist/overlay/layer-scope.d.ts +21 -0
  232. package/dist/overlay/layer-scope.d.ts.map +1 -0
  233. package/dist/overlay/layer-scope.js +5 -0
  234. package/dist/overlay/path-picker.d.ts +14 -0
  235. package/dist/overlay/path-picker.d.ts.map +1 -0
  236. package/dist/overlay/path-picker.js +200 -0
  237. package/dist/overlay/prompt-dialog.d.ts +12 -0
  238. package/dist/overlay/prompt-dialog.d.ts.map +1 -0
  239. package/dist/overlay/prompt-dialog.js +29 -0
  240. package/dist/overlay/shared.d.ts +17 -0
  241. package/dist/overlay/shared.d.ts.map +1 -0
  242. package/dist/overlay/shared.js +17 -0
  243. package/dist/overlay/toast-host.d.ts +8 -0
  244. package/dist/overlay/toast-host.d.ts.map +1 -0
  245. package/dist/overlay/toast-host.js +19 -0
  246. package/dist/overlay/toast.d.ts +9 -0
  247. package/dist/overlay/toast.d.ts.map +1 -0
  248. package/dist/overlay/toast.js +20 -0
  249. package/dist/overlay/tooltip.d.ts +6 -0
  250. package/dist/overlay/tooltip.d.ts.map +1 -0
  251. package/dist/overlay/tooltip.js +11 -0
  252. package/dist/panel/index.d.ts +79 -0
  253. package/dist/panel/index.d.ts.map +1 -0
  254. package/dist/panel/index.js +256 -0
  255. package/dist/panel/resource-panel.d.ts +93 -0
  256. package/dist/panel/resource-panel.d.ts.map +1 -0
  257. package/dist/panel/resource-panel.js +213 -0
  258. package/dist/panel/shared.d.ts +6 -0
  259. package/dist/panel/shared.d.ts.map +1 -0
  260. package/dist/panel/shared.js +4 -0
  261. package/dist/shells/console-shell.d.ts +8 -0
  262. package/dist/shells/console-shell.d.ts.map +1 -0
  263. package/dist/shells/console-shell.js +30 -0
  264. package/dist/shells/index.d.ts +20 -0
  265. package/dist/shells/index.d.ts.map +1 -0
  266. package/dist/shells/index.js +61 -0
  267. package/dist/shells/paper-shell.d.ts +9 -0
  268. package/dist/shells/paper-shell.d.ts.map +1 -0
  269. package/dist/shells/paper-shell.js +23 -0
  270. package/dist/shells/plain-shell.d.ts +3 -0
  271. package/dist/shells/plain-shell.d.ts.map +1 -0
  272. package/dist/shells/plain-shell.js +11 -0
  273. package/dist/shells/shared.d.ts +12 -0
  274. package/dist/shells/shared.d.ts.map +1 -0
  275. package/dist/shells/shared.js +21 -0
  276. package/dist/shells/workbench-shell.d.ts +9 -0
  277. package/dist/shells/workbench-shell.d.ts.map +1 -0
  278. package/dist/shells/workbench-shell.js +43 -0
  279. package/dist/surface/bar-layout.d.ts +4 -0
  280. package/dist/surface/bar-layout.d.ts.map +1 -0
  281. package/dist/surface/bar-layout.js +7 -0
  282. package/dist/surface/index.d.ts +58 -0
  283. package/dist/surface/index.d.ts.map +1 -0
  284. package/dist/surface/index.js +48 -0
  285. package/dist/surface/inline-layout.d.ts +4 -0
  286. package/dist/surface/inline-layout.d.ts.map +1 -0
  287. package/dist/surface/inline-layout.js +7 -0
  288. package/dist/surface/mount-view.d.ts +7 -0
  289. package/dist/surface/mount-view.d.ts.map +1 -0
  290. package/dist/surface/mount-view.js +19 -0
  291. package/dist/surface/rail-layout.d.ts +4 -0
  292. package/dist/surface/rail-layout.d.ts.map +1 -0
  293. package/dist/surface/rail-layout.js +19 -0
  294. package/dist/surface/shared.d.ts +7 -0
  295. package/dist/surface/shared.d.ts.map +1 -0
  296. package/dist/surface/shared.js +1 -0
  297. package/dist/surface/single-layout.d.ts +4 -0
  298. package/dist/surface/single-layout.d.ts.map +1 -0
  299. package/dist/surface/single-layout.js +18 -0
  300. package/dist/surface/split-layout.d.ts +4 -0
  301. package/dist/surface/split-layout.d.ts.map +1 -0
  302. package/dist/surface/split-layout.js +7 -0
  303. package/dist/surface/stack-layout.d.ts +4 -0
  304. package/dist/surface/stack-layout.d.ts.map +1 -0
  305. package/dist/surface/stack-layout.js +22 -0
  306. package/dist/surface/surface-area.d.ts +16 -0
  307. package/dist/surface/surface-area.d.ts.map +1 -0
  308. package/dist/surface/surface-area.js +32 -0
  309. package/dist/surface/tabs-layout.d.ts +4 -0
  310. package/dist/surface/tabs-layout.d.ts.map +1 -0
  311. package/dist/surface/tabs-layout.js +24 -0
  312. package/dist/tone.d.ts +16 -0
  313. package/dist/tone.d.ts.map +1 -0
  314. package/dist/tone.js +45 -0
  315. package/dist/viewport.d.ts +30 -0
  316. package/dist/viewport.d.ts.map +1 -0
  317. package/dist/viewport.js +17 -0
  318. package/package.json +54 -0
  319. package/src/chart/area-chart.ts +9 -0
  320. package/src/chart/bar-chart.ts +74 -0
  321. package/src/chart/gauge.ts +60 -0
  322. package/src/chart/heatmap.ts +49 -0
  323. package/src/chart/histogram.ts +36 -0
  324. package/src/chart/index.ts +36 -0
  325. package/src/chart/line-chart.ts +100 -0
  326. package/src/chart/shared.ts +112 -0
  327. package/src/chart/sparkline.ts +46 -0
  328. package/src/control/button.ts +184 -0
  329. package/src/control/checkbox.ts +48 -0
  330. package/src/control/index.ts +40 -0
  331. package/src/control/radio-group.ts +60 -0
  332. package/src/control/search-box.ts +15 -0
  333. package/src/control/select.ts +230 -0
  334. package/src/control/shared.ts +41 -0
  335. package/src/control/slider.ts +63 -0
  336. package/src/control/switch.ts +39 -0
  337. package/src/control/text-area.ts +390 -0
  338. package/src/control/text-input.ts +150 -0
  339. package/src/data/code-viewer.ts +337 -0
  340. package/src/data/feed.ts +204 -0
  341. package/src/data/index.ts +243 -0
  342. package/src/data/list.ts +149 -0
  343. package/src/data/log-viewer.ts +105 -0
  344. package/src/data/markdown-view.ts +182 -0
  345. package/src/data/pagination.ts +31 -0
  346. package/src/data/scroll-thumb.ts +40 -0
  347. package/src/data/shared.ts +23 -0
  348. package/src/data/tree.ts +215 -0
  349. package/src/decorations.ts +176 -0
  350. package/src/display/alert.ts +28 -0
  351. package/src/display/badge.ts +40 -0
  352. package/src/display/card.ts +23 -0
  353. package/src/display/empty-state.ts +21 -0
  354. package/src/display/error-state.ts +23 -0
  355. package/src/display/heading.ts +17 -0
  356. package/src/display/index.ts +55 -0
  357. package/src/display/key-value.ts +32 -0
  358. package/src/display/label.ts +11 -0
  359. package/src/display/marquee.ts +88 -0
  360. package/src/display/progress.ts +92 -0
  361. package/src/display/skeleton.ts +34 -0
  362. package/src/display/spinner.ts +20 -0
  363. package/src/display/status-dot.ts +24 -0
  364. package/src/display/timeline.ts +47 -0
  365. package/src/find.ts +138 -0
  366. package/src/form/danger-zone.ts +34 -0
  367. package/src/form/field.ts +61 -0
  368. package/src/form/form-actions.ts +35 -0
  369. package/src/form/form-section.ts +16 -0
  370. package/src/form/form.ts +13 -0
  371. package/src/form/index.ts +191 -0
  372. package/src/form/shared.ts +36 -0
  373. package/src/index.ts +63 -0
  374. package/src/layout/center.ts +17 -0
  375. package/src/layout/column.ts +6 -0
  376. package/src/layout/divider.ts +31 -0
  377. package/src/layout/grid.ts +34 -0
  378. package/src/layout/index.ts +39 -0
  379. package/src/layout/panel.ts +114 -0
  380. package/src/layout/row.ts +11 -0
  381. package/src/layout/scroll-view.ts +115 -0
  382. package/src/layout/splitter.ts +24 -0
  383. package/src/layout/stack.ts +12 -0
  384. package/src/navigation/breadcrumb.ts +43 -0
  385. package/src/navigation/index.ts +33 -0
  386. package/src/navigation/key-hints.ts +25 -0
  387. package/src/navigation/menu.ts +134 -0
  388. package/src/navigation/status-bar.ts +43 -0
  389. package/src/navigation/tabs.ts +73 -0
  390. package/src/navigation/toolbar.ts +25 -0
  391. package/src/navigation/wizard.ts +43 -0
  392. package/src/overlay/command-palette.ts +485 -0
  393. package/src/overlay/dialog.ts +65 -0
  394. package/src/overlay/index.ts +232 -0
  395. package/src/overlay/layer-scope.ts +26 -0
  396. package/src/overlay/path-picker.ts +215 -0
  397. package/src/overlay/prompt-dialog.ts +45 -0
  398. package/src/overlay/shared.ts +19 -0
  399. package/src/overlay/toast-host.ts +30 -0
  400. package/src/overlay/toast.ts +35 -0
  401. package/src/overlay/tooltip.ts +17 -0
  402. package/src/panel/index.ts +317 -0
  403. package/src/panel/resource-panel.ts +304 -0
  404. package/src/panel/shared.ts +8 -0
  405. package/src/shells/console-shell.ts +47 -0
  406. package/src/shells/index.ts +66 -0
  407. package/src/shells/paper-shell.ts +31 -0
  408. package/src/shells/plain-shell.ts +19 -0
  409. package/src/shells/shared.ts +24 -0
  410. package/src/shells/workbench-shell.ts +62 -0
  411. package/src/surface/bar-layout.ts +11 -0
  412. package/src/surface/index.ts +53 -0
  413. package/src/surface/inline-layout.ts +11 -0
  414. package/src/surface/mount-view.ts +30 -0
  415. package/src/surface/rail-layout.ts +27 -0
  416. package/src/surface/shared.ts +7 -0
  417. package/src/surface/single-layout.ts +25 -0
  418. package/src/surface/split-layout.ts +11 -0
  419. package/src/surface/stack-layout.ts +32 -0
  420. package/src/surface/surface-area.ts +46 -0
  421. package/src/surface/tabs-layout.ts +30 -0
  422. package/src/tone.ts +48 -0
  423. package/src/viewport.ts +45 -0
@@ -0,0 +1,27 @@
1
+ import type { BoxProps, SemanticVariant, SurfaceVariant } from '@textui/core';
2
+ export interface ButtonProps extends BoxProps {
3
+ label: string;
4
+ tone?: SemanticVariant;
5
+ variant?: SurfaceVariant;
6
+ icon?: string;
7
+ /** Shortcut hint rendered after the label. */
8
+ hint?: string;
9
+ onPress?(): void;
10
+ autoFocus?: boolean;
11
+ /**
12
+ * How much of the screen the button takes, and how heavy its edge is.
13
+ *
14
+ * `md` is a button: three rows, the theme's edge. `sm` is one row with no
15
+ * edge at all, for a toolbar or a row of buttons that must not out-weigh
16
+ * the fields beside them. `lg` is three rows with a heavy one.
17
+ *
18
+ * It matters most when filled. A solid `md` draws its edge in half-blocks,
19
+ * so it stands the same height as the outline button next to it without
20
+ * reading as a heavier object; `lg` fills the edge cells too and becomes
21
+ * the whole rectangle, which is what solid used to do at every size - and
22
+ * why one row of buttons looked bigger than the row above it.
23
+ */
24
+ size?: 'sm' | 'md' | 'lg';
25
+ }
26
+ export declare const Button: (props: ButtonProps) => import("@textui/core").RenderOutput;
27
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/control/button.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,QAAQ,EACR,eAAe,EAEf,cAAc,EACf,MAAM,cAAc,CAAC;AAWtB,MAAM,WAAW,WAAY,SAAQ,QAAQ;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,IAAI,IAAI,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,MAAM,6DA6IjB,CAAC"}
@@ -0,0 +1,130 @@
1
+ import { defineComponent, h, useFocus, useInput, useTheme } from '@textui/core';
2
+ import { ON_TONE, TONE } from '../tone.js';
3
+ /** A border that takes up space without drawing anything. */
4
+ const BLANK_BORDER = {
5
+ topLeft: ' ', top: ' ', topRight: ' ', right: ' ',
6
+ bottomRight: ' ', bottom: ' ', bottomLeft: ' ', left: ' ',
7
+ cross: ' ', teeTop: ' ', teeBottom: ' ', teeLeft: ' ', teeRight: ' ',
8
+ };
9
+ export const Button = defineComponent('Button', (props) => {
10
+ const theme = useTheme();
11
+ const { label, tone = 'default', variant = 'outline', icon, hint, onPress, disabled, autoFocus, size = 'md', ...rest } = props;
12
+ const focus = useFocus({ disabled, autoFocus });
13
+ useInput((event) => {
14
+ if (disabled)
15
+ return false;
16
+ if (event.name === 'enter' || event.name === 'space') {
17
+ onPress?.();
18
+ return true;
19
+ }
20
+ return false;
21
+ }, { focusId: focus.id });
22
+ // Selection inverts.
23
+ //
24
+ // At rest a button is a line and a label in its tone; selected, the tone
25
+ // becomes the background and the label flips to the colour written for it.
26
+ // Recolouring only the border was too quiet to find - and next to a filled
27
+ // button it read backwards, because the filled one looked like the selected
28
+ // one however hard the border tried.
29
+ const filled = (focus.focused || props.selected === true) && !disabled;
30
+ const resolvedTone = filled && tone === 'default' ? 'primary' : tone;
31
+ const color = disabled ? 'disabled' : TONE[resolvedTone];
32
+ const onColor = disabled ? 'text' : ON_TONE[resolvedTone];
33
+ // `sm` has no ring, so nothing here reserves one.
34
+ const ringed = size !== 'sm' && theme.border !== 'none';
35
+ // A solid button reserves the same ring an outline one draws, filled with
36
+ // its own background rather than left out. Without it the two are one row
37
+ // and three rows tall, and a dialog's OK sits a line above its Cancel.
38
+ const solidBorder = {
39
+ style: theme.border,
40
+ color: focus.focused ? 'focus' : undefined,
41
+ ...(focus.focused ? {} : { chars: BLANK_BORDER }),
42
+ };
43
+ // The tone fills the inside of the frame, not the frame itself. A cell
44
+ // carries one background, so a background on the button's own box lands on
45
+ // the border glyphs too - rounded corners included - and the button reads as
46
+ // a coloured block rather than a filled button. Hanging the fill on an inner
47
+ // box leaves the ring on whatever is behind it. The wrapper is there whether
48
+ // or not the button is filled, so focusing one does not reshape its tree.
49
+ //
50
+ // A solid button is inset too at `md`, which is the whole of the size fix:
51
+ // hanging the fill on an inner box leaves the ring to be drawn in
52
+ // half-blocks rather than filled through, so it weighs what the outline
53
+ // button beside it weighs. `lg` keeps the fill on the outer box - the ring
54
+ // cells take the tone as well and the button becomes a solid rectangle.
55
+ const inset = variant === 'ghost' || variant === 'link'
56
+ ? false
57
+ : variant !== 'solid' || (ringed && size === 'md');
58
+ // Filled, the frame becomes the fill's own edge.
59
+ //
60
+ // A cell holds one background, so filling the box the ordinary way colours
61
+ // its border glyphs too and the button reads as a block; filling only the
62
+ // inside leaves the border cell on the backdrop, and a gap runs between the
63
+ // frame and the fill. `half` is drawn from block elements whose coloured
64
+ // half faces inward, so the ring meets the inside with nothing between. It
65
+ // measures the same as the line border it replaces - one cell a side - so
66
+ // focus changes how a button looks without changing its size.
67
+ //
68
+ // A theme that asked for no border, or for ascii, is left alone: both are
69
+ // deliberate looks, and `half` degrades to ascii anyway on a terminal that
70
+ // cannot draw block elements.
71
+ const filledBorder = theme.border === 'none' || theme.border === 'ascii' ? theme.border : 'half';
72
+ // The edge, by size. `lg` asks for the heaviest line the theme can draw and
73
+ // falls back to the theme's own where there is none to ask for.
74
+ const edge = size === 'lg' && theme.border !== 'ascii' ? 'bold' : theme.border;
75
+ const style = variant === 'solid'
76
+ ? size === 'sm' || !ringed
77
+ // One row, filled. No ring to reserve and nothing to align to.
78
+ ? { bg: color, fg: onColor }
79
+ : size === 'lg'
80
+ // The fill runs under the ring, so the whole rectangle is the button.
81
+ ? { bg: color, fg: onColor, border: solidBorder }
82
+ // The ring is drawn from block elements whose coloured half faces
83
+ // inward: it meets the fill with no gap and stands half as heavy.
84
+ : { border: { style: filledBorder, color }, fg: color }
85
+ : variant === 'ghost' || variant === 'link'
86
+ ? (filled ? { bg: color, fg: onColor } : { fg: color })
87
+ : size === 'sm' || !ringed
88
+ ? (filled ? { bg: color, fg: onColor } : { fg: color })
89
+ : { border: { style: filled ? filledBorder : edge, color }, fg: color };
90
+ const padding = variant === 'ghost' || variant === 'link' ? 0 : [0, 1];
91
+ const content = [
92
+ icon ? h('text', { content: icon }) : null,
93
+ h('text', { content: label }),
94
+ // On a filled button the hint has to sit on the tone too; `muted` against
95
+ // a solid colour is the one combination that is never readable.
96
+ hint ? h('text', { content: hint, fg: filled ? onColor : 'muted', dim: !filled }) : null,
97
+ ];
98
+ return h('box', {
99
+ id: focus.id,
100
+ role: 'button',
101
+ label,
102
+ direction: 'row',
103
+ // The inner box owns the run of the label - gap, padding and centring -
104
+ // whenever there is one, so the two paths measure the same.
105
+ gap: inset ? 0 : 1,
106
+ // Centred, so a button stretched by the row it sits in keeps its label on
107
+ // the same line as its neighbours' labels.
108
+ align: 'center',
109
+ padding: inset ? 0 : padding,
110
+ bold: inset ? undefined : focus.focused,
111
+ underline: focus.focused && (variant === 'ghost' || variant === 'link'),
112
+ onClick: () => { if (!disabled)
113
+ onPress?.(); },
114
+ ...style,
115
+ ...rest,
116
+ }, inset
117
+ ? h('box', {
118
+ // Grow, so the fill reaches the frame on a button the row stretched.
119
+ flex: 1,
120
+ direction: 'row',
121
+ gap: 1,
122
+ align: 'center',
123
+ padding,
124
+ bold: focus.focused,
125
+ // A solid button is filled whether or not it has focus - that is
126
+ // what solid means. An outline one fills only when it takes focus.
127
+ ...(variant === 'solid' || filled ? { bg: color, fg: onColor } : {}),
128
+ }, ...content)
129
+ : content);
130
+ });
@@ -0,0 +1,10 @@
1
+ import type { BoxProps } from '@textui/core';
2
+ export interface CheckboxProps extends BoxProps {
3
+ label?: string;
4
+ checked?: boolean;
5
+ /** Neither checked nor unchecked - a parent of mixed children. */
6
+ indeterminate?: boolean;
7
+ onChange?(checked: boolean): void;
8
+ }
9
+ export declare const Checkbox: (props: CheckboxProps) => import("@textui/core").RenderOutput;
10
+ //# sourceMappingURL=checkbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../src/control/checkbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,WAAW,aAAc,SAAQ,QAAQ;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,QAAQ,+DAoCnB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { defineComponent, h, useFocus, useInput, useTheme } from '@textui/core';
2
+ export const Checkbox = defineComponent('Checkbox', (props) => {
3
+ const theme = useTheme();
4
+ const { label, checked = false, indeterminate, onChange, disabled, ...rest } = props;
5
+ const focus = useFocus({ disabled });
6
+ useInput((event) => {
7
+ if (disabled)
8
+ return false;
9
+ if (event.name === 'space' || event.name === 'enter') {
10
+ onChange?.(!checked);
11
+ return true;
12
+ }
13
+ return false;
14
+ }, { focusId: focus.id });
15
+ const glyph = indeterminate
16
+ ? theme.glyphs.checkboxMixed
17
+ : checked ? theme.glyphs.checkboxOn : theme.glyphs.checkboxOff;
18
+ return h('box', {
19
+ id: focus.id,
20
+ role: 'checkbox',
21
+ label,
22
+ selected: checked,
23
+ direction: 'row',
24
+ gap: 1,
25
+ fg: disabled ? 'disabled' : focus.focused ? 'accent' : undefined,
26
+ bold: focus.focused,
27
+ onClick: () => { if (!disabled)
28
+ onChange?.(!checked); },
29
+ ...rest,
30
+ }, h('text', { content: glyph }), label ? h('text', { content: label }) : null);
31
+ });
@@ -0,0 +1,20 @@
1
+ import type { ComponentDefinition } from '@textui/core';
2
+ /**
3
+ * Controls.
4
+ *
5
+ * Every control here is focusable, keyboard-first and states its own focus
6
+ * ring, because a terminal has no hover to fall back on: if the focused
7
+ * control is not obvious without moving a mouse, the interface is unusable.
8
+ */
9
+ export * from './button.js';
10
+ export * from './checkbox.js';
11
+ export * from './radio-group.js';
12
+ export * from './search-box.js';
13
+ export * from './select.js';
14
+ export * from './slider.js';
15
+ export * from './switch.js';
16
+ export * from './text-area.js';
17
+ export * from './text-input.js';
18
+ export type { TextInputProps } from './shared.js';
19
+ export declare const CONTROL_COMPONENTS: ComponentDefinition[];
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/control/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAWxD;;;;;;GAMG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,eAAO,MAAM,kBAAkB,EAAE,mBAAmB,EAUnD,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { Button } from './button.js';
2
+ import { Checkbox } from './checkbox.js';
3
+ import { RadioGroup } from './radio-group.js';
4
+ import { SearchBox } from './search-box.js';
5
+ import { Select } from './select.js';
6
+ import { Slider } from './slider.js';
7
+ import { Switch } from './switch.js';
8
+ import { TextArea } from './text-area.js';
9
+ import { TextInput } from './text-input.js';
10
+ /**
11
+ * Controls.
12
+ *
13
+ * Every control here is focusable, keyboard-first and states its own focus
14
+ * ring, because a terminal has no hover to fall back on: if the focused
15
+ * control is not obvious without moving a mouse, the interface is unusable.
16
+ */
17
+ export * from './button.js';
18
+ export * from './checkbox.js';
19
+ export * from './radio-group.js';
20
+ export * from './search-box.js';
21
+ export * from './select.js';
22
+ export * from './slider.js';
23
+ export * from './switch.js';
24
+ export * from './text-area.js';
25
+ export * from './text-input.js';
26
+ export const CONTROL_COMPONENTS = [
27
+ { component: 'Button', category: 'control', renderer: { kind: 'function', render: Button }, role: 'button', variants: ['solid', 'outline', 'ghost', 'link'], description: 'Focusable action.' },
28
+ { component: 'Checkbox', category: 'control', renderer: { kind: 'function', render: Checkbox }, role: 'checkbox', description: 'On, off, or mixed.' },
29
+ { component: 'Switch', category: 'control', renderer: { kind: 'function', render: Switch }, role: 'switch', description: 'Two-state toggle with words, not only colour.' },
30
+ { component: 'RadioGroup', category: 'control', renderer: { kind: 'function', render: RadioGroup }, role: 'radio', description: 'One of several.' },
31
+ { component: 'Slider', category: 'control', renderer: { kind: 'function', render: Slider }, role: 'slider', description: 'A value along a track.' },
32
+ { component: 'TextArea', category: 'control', renderer: { kind: 'function', render: TextArea }, role: 'textbox', description: 'A field that is a paragraph: grows, scrolls, and gives back the keys it does not want.' },
33
+ { component: 'TextInput', category: 'control', renderer: { kind: 'function', render: TextInput }, role: 'textbox', description: 'Single-line text with a real caret.' },
34
+ { component: 'Select', category: 'control', renderer: { kind: 'function', render: Select }, role: 'combobox', description: 'Pick from a list, collapsed or open.' },
35
+ { component: 'SearchBox', category: 'control', renderer: { kind: 'function', render: SearchBox }, role: 'searchbox', description: 'A text field that looks like search.' },
36
+ ];
@@ -0,0 +1,17 @@
1
+ import type { BoxProps } from '@textui/core';
2
+ export interface RadioOption {
3
+ value: string;
4
+ label: string;
5
+ description?: string;
6
+ disabled?: boolean;
7
+ }
8
+ export interface RadioGroupProps extends BoxProps {
9
+ options: RadioOption[];
10
+ value?: string;
11
+ onChange?(value: string): void;
12
+ label?: string;
13
+ /** Lay the options out in a row instead of a column. */
14
+ inline?: boolean;
15
+ }
16
+ export declare const RadioGroup: (props: RadioGroupProps) => import("@textui/core").RenderOutput;
17
+ //# sourceMappingURL=radio-group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group.d.ts","sourceRoot":"","sources":["../../src/control/radio-group.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,UAAU,iEAwCrB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { defineComponent, h, useFocus, useInput, useTheme } from '@textui/core';
2
+ export const RadioGroup = defineComponent('RadioGroup', (props) => {
3
+ const theme = useTheme();
4
+ const { options, value, onChange, label, inline, disabled, ...rest } = props;
5
+ const focus = useFocus({ disabled });
6
+ const index = Math.max(0, options.findIndex((o) => o.value === value));
7
+ useInput((event) => {
8
+ if (disabled)
9
+ return false;
10
+ const step = inline
11
+ ? (event.name === 'right' ? 1 : event.name === 'left' ? -1 : 0)
12
+ : (event.name === 'down' ? 1 : event.name === 'up' ? -1 : 0);
13
+ if (step === 0)
14
+ return false;
15
+ const next = options[(index + step + options.length) % options.length];
16
+ if (next && !next.disabled)
17
+ onChange?.(next.value);
18
+ return true;
19
+ }, { focusId: focus.id });
20
+ return h('box', { id: focus.id, role: 'group', label, direction: 'column', gap: 0, ...rest }, label ? h('text', { content: label, fg: 'muted' }) : null, h('box', { direction: inline ? 'row' : 'column', gap: inline ? 2 : 0 }, ...options.map((option) => {
21
+ const selected = option.value === value;
22
+ return h('box', {
23
+ key: option.value,
24
+ direction: 'row',
25
+ gap: 1,
26
+ fg: option.disabled ? 'disabled' : selected && focus.focused ? 'accent' : undefined,
27
+ bold: selected && focus.focused,
28
+ onClick: () => { if (!option.disabled)
29
+ onChange?.(option.value); },
30
+ }, h('text', { content: selected ? theme.glyphs.radioOn : theme.glyphs.radioOff }), h('text', { content: option.label }), option.description ? h('text', { content: option.description, fg: 'subtle' }) : null);
31
+ })));
32
+ });
@@ -0,0 +1,7 @@
1
+ import type { TextInputProps } from './shared.js';
2
+ export interface SearchBoxProps extends Omit<TextInputProps, 'search'> {
3
+ /** Result count, shown after the field. */
4
+ count?: number;
5
+ }
6
+ export declare const SearchBox: (props: SearchBoxProps) => import("@textui/core").RenderOutput;
7
+ //# sourceMappingURL=search-box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-box.d.ts","sourceRoot":"","sources":["../../src/control/search-box.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC;IACpE,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,SAAS,gEAKrB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { defineComponent, h } from '@textui/core';
2
+ import { TextInput } from './text-input.js';
3
+ export const SearchBox = defineComponent('SearchBox', ({ count, ...props }) => h('box', { direction: 'row', gap: 1 }, h(TextInput, { search: true, flex: 1, ...props }), count !== undefined ? h('text', { content: `${count}`, fg: 'muted' }) : null));
@@ -0,0 +1,42 @@
1
+ import type { BoxProps, RenderOutput } from '@textui/core';
2
+ export interface SelectOption {
3
+ value: string;
4
+ label: string;
5
+ description?: string;
6
+ disabled?: boolean;
7
+ icon?: string;
8
+ }
9
+ export interface SelectProps extends BoxProps {
10
+ options: SelectOption[];
11
+ value?: string;
12
+ onChange?(value: string): void;
13
+ label?: string;
14
+ placeholder?: string;
15
+ /** Show the list inline instead of collapsing to one line. */
16
+ open?: boolean;
17
+ /** Rows shown at once when open. */
18
+ visibleRows?: number;
19
+ /**
20
+ * Where the list goes when it opens.
21
+ *
22
+ * `inline` grows the control: the options appear inside the same border, and
23
+ * everything under it moves down. Honest about the space it takes and the
24
+ * only one that cannot be clipped, which is why it is the default.
25
+ *
26
+ * `floating` puts the list on the floating layer, anchored under the
27
+ * control. Nothing below it moves, which is what you want in a form or a
28
+ * dense row of controls - the layout does not jump as you open and shut it.
29
+ *
30
+ * `modal` puts it in the middle of the screen over a scrim. For a list long
31
+ * enough or a choice consequential enough that the rest of the screen is a
32
+ * distraction.
33
+ *
34
+ * The keys are the same in all three, because the control keeps the keyboard
35
+ * in all three: the layer is somewhere to *draw* the list, not somewhere the
36
+ * focus goes. Arrow keys, enter and escape are answered by the same handler
37
+ * whichever mode it is in.
38
+ */
39
+ mode?: 'inline' | 'floating' | 'modal';
40
+ }
41
+ export declare const Select: (props: SelectProps) => RenderOutput;
42
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/control/select.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAiB,YAAY,EAAE,MAAM,cAAc,CAAC;AAK1E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAY,SAAQ,QAAQ;IAC3C,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;CACxC;AAED,eAAO,MAAM,MAAM,sCAuLjB,CAAC"}
@@ -0,0 +1,166 @@
1
+ import { defineComponent, h, useApp, useEffect, useFocus, useInput, useMeasure, useState, useTheme, } from '@textui/core';
2
+ export const Select = defineComponent('Select', (props) => {
3
+ const theme = useTheme();
4
+ const { options, value, onChange, label, placeholder, open: openProp, visibleRows = 6, disabled, mode = 'inline', ...rest } = props;
5
+ const app = useApp();
6
+ const focus = useFocus({ disabled });
7
+ const measured = useMeasure();
8
+ const empty = placeholder ?? `Select${theme.glyphs.ellipsis}`;
9
+ const [open, setOpen] = useState(openProp ?? false);
10
+ const index = Math.max(0, options.findIndex((o) => o.value === value));
11
+ const [highlight, setHighlight] = useState(index);
12
+ useInput((event) => {
13
+ if (disabled)
14
+ return false;
15
+ if (!open) {
16
+ if (event.name === 'enter' || event.name === 'space' || event.name === 'down') {
17
+ setOpen(true);
18
+ return true;
19
+ }
20
+ return false;
21
+ }
22
+ switch (event.name) {
23
+ case 'up':
24
+ setHighlight((highlight - 1 + options.length) % options.length);
25
+ return true;
26
+ case 'down':
27
+ setHighlight((highlight + 1) % options.length);
28
+ return true;
29
+ case 'enter': {
30
+ const chosen = options[highlight];
31
+ if (chosen && !chosen.disabled)
32
+ onChange?.(chosen.value);
33
+ setOpen(false);
34
+ return true;
35
+ }
36
+ case 'escape':
37
+ setOpen(false);
38
+ return true;
39
+ default: return false;
40
+ }
41
+ }, { focusId: focus.id });
42
+ const selected = options.find((o) => o.value === value);
43
+ const start = Math.max(0, Math.min(highlight - Math.floor(visibleRows / 2), options.length - visibleRows));
44
+ const window = options.slice(start, start + visibleRows);
45
+ /**
46
+ * The options, wherever they are being drawn.
47
+ *
48
+ * One function rather than one per mode: three copies of a highlighted row
49
+ * is three chances for the modes to drift into looking like different
50
+ * controls, and the whole claim here is that they are one control shown in
51
+ * three places.
52
+ */
53
+ function list() {
54
+ return h('box', { direction: 'column' }, ...window.map((option, i) => {
55
+ const active = start + i === highlight;
56
+ return h('box', {
57
+ key: option.value,
58
+ direction: 'row',
59
+ gap: 1,
60
+ // Ink, not a filled row.
61
+ //
62
+ // A background swatch is the heaviest mark available and it has
63
+ // to invert the text to stay readable, so the highlighted option
64
+ // is the one option whose colour tells you nothing about itself.
65
+ // Accent and an underline say "here" without repainting the row.
66
+ fg: option.disabled ? 'disabled' : active ? 'accent' : undefined,
67
+ onClick: () => {
68
+ if (option.disabled)
69
+ return;
70
+ onChange?.(option.value);
71
+ setOpen(false);
72
+ },
73
+ }, h('text', { content: active ? theme.glyphs.chevronRight : ' ' }), option.icon ? h('text', { content: option.icon }) : null, h('text', { content: option.label, underline: active, bold: active }), h('box', { flex: 1 }), option.value === value ? h('text', { content: theme.glyphs.check }) : null);
74
+ }));
75
+ }
76
+ /*
77
+ * Opening a layer, and keeping it in step.
78
+ *
79
+ * Two effects rather than one, because they answer different questions. The
80
+ * first is "is there a layer" and runs when the mode or the open state
81
+ * changes; the second is "what is in it" and runs whenever the highlight
82
+ * moves. Reopening on every arrow key would work and would also mean a new
83
+ * layer entry per keystroke, with whatever a layer manager does on open -
84
+ * ordering, focus bookkeeping, the scrim - done four times to move a cursor
85
+ * four rows.
86
+ *
87
+ * The control keeps the keyboard either way, so `trapFocus` stays off: the
88
+ * layer is a surface to draw the list on, and moving focus into it would
89
+ * take the arrow keys away from the handler that answers them.
90
+ */
91
+ const layerId = `select:${focus.id}`;
92
+ const floating = mode !== 'inline';
93
+ useEffect(() => {
94
+ if (!floating || !open)
95
+ return undefined;
96
+ const handle = app.layers.open({
97
+ id: layerId,
98
+ layer: mode === 'modal' ? 'modal' : 'floating',
99
+ scrim: mode === 'modal',
100
+ // Escape is the control's, and closing it there disposes this. Handled
101
+ // in both places, the layer would close and the control would still
102
+ // think it was open.
103
+ dismissOnEscape: false,
104
+ dismissOnOutsideClick: true,
105
+ position: mode === 'modal'
106
+ ? { kind: 'center' }
107
+ : { kind: 'anchor', targetId: focus.id, side: 'bottom', align: 'start' },
108
+ node: panel(),
109
+ onClose: () => setOpen(false),
110
+ });
111
+ return () => { handle.dispose(); };
112
+ }, [floating, open, mode]);
113
+ useEffect(() => {
114
+ if (!floating || !open)
115
+ return;
116
+ app.layers.update(layerId, { node: panel() });
117
+ }, [highlight, value, options.length]);
118
+ /** The list with something to sit in, which inline gets from the control. */
119
+ function panel() {
120
+ return h('box', {
121
+ direction: 'column',
122
+ // As wide as the control it came out of, so the two line up.
123
+ //
124
+ // `useMeasure` reports the *content* rect, and this panel has a frame
125
+ // and a gutter of its own to pay for - the same two the control is
126
+ // already paying - so it is four cells narrower than the box it is
127
+ // supposed to sit under unless they are added back.
128
+ width: Math.max(20, measured.width + 4),
129
+ border: theme.border,
130
+ bg: 'overlay',
131
+ padding: [0, 1],
132
+ }, list());
133
+ }
134
+ /**
135
+ * One box, open or shut.
136
+ *
137
+ * The list used to be a second bordered box under the first, so opening the
138
+ * control drew two rules back to back and the options read as a separate
139
+ * thing that happened to be nearby. They are the control - the same border
140
+ * holds both, with a rule between them where the two borders used to be.
141
+ */
142
+ return h('box', {
143
+ id: focus.id,
144
+ role: 'combobox',
145
+ label,
146
+ direction: 'column',
147
+ border: { style: theme.border, color: focus.focused ? 'focus' : 'border' },
148
+ padding: [0, 1],
149
+ ...rest,
150
+ }, h('box', {
151
+ direction: 'row',
152
+ gap: 1,
153
+ onClick: () => { if (!disabled)
154
+ setOpen(!open); },
155
+ }, label ? h('text', { content: label, fg: 'muted' }) : null, h('text', {
156
+ content: selected?.label ?? empty,
157
+ fg: selected ? undefined : 'subtle',
158
+ flex: 1,
159
+ truncate: 'end',
160
+ }), h('text', { content: open ? theme.glyphs.chevronUp : theme.glyphs.chevronDown, fg: 'muted' })),
161
+ // A borderless theme has no rule to draw, and a blank row there would be
162
+ // the gap this was meant to close.
163
+ mode === 'inline' && open && theme.border !== 'none'
164
+ ? h('box', { height: 1, fill: theme.borderChars().top, fg: 'borderSubtle' })
165
+ : null, mode === 'inline' && open ? list() : null);
166
+ });
@@ -0,0 +1,41 @@
1
+ import type { BoxProps } from '@textui/core';
2
+ export interface TextInputProps extends BoxProps {
3
+ value: string;
4
+ onChange?(value: string): void;
5
+ onSubmit?(value: string): void;
6
+ placeholder?: string;
7
+ label?: string;
8
+ /**
9
+ * Keep the label as the field's name but do not draw it inside the field -
10
+ * for a form or a dialog that already shows it beside or above the input.
11
+ */
12
+ hideLabel?: boolean;
13
+ /** Replace every character, for secrets. */
14
+ mask?: string;
15
+ /** Stop accepting input past this many characters. */
16
+ maxLength?: number;
17
+ autoFocus?: boolean;
18
+ /** Draw a search glyph before the field. */
19
+ search?: boolean;
20
+ /**
21
+ * A stable focus id, so a command can send the reader here by name.
22
+ *
23
+ * Without one a control's id is derived from its instance, which nothing
24
+ * outside the render can know - so "focus the filter" has nothing to name
25
+ * and the key that would do it cannot be written.
26
+ */
27
+ focusId?: string;
28
+ /**
29
+ * The caret tried to leave the field.
30
+ *
31
+ * A single-line input answers `left` and `right` itself right up to the
32
+ * ends, so a caller that wants those keys past the ends cannot have them
33
+ * from a key handler - the field takes the key and reports nothing. This is
34
+ * how it reports: the palette drills into a command's choices on `right`,
35
+ * and the path picker goes up a folder on `left`. `TextArea` has had this
36
+ * from the start; the two controls disagreeing is what left both of those
37
+ * keys silently doing nothing.
38
+ */
39
+ onEdge?(edge: 'start' | 'end'): void;
40
+ }
41
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/control/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;CACtC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { BoxProps } from '@textui/core';
2
+ export interface SliderProps extends BoxProps {
3
+ value: number;
4
+ min?: number;
5
+ max?: number;
6
+ step?: number;
7
+ label?: string;
8
+ onChange?(value: number): void;
9
+ /** Cells the track occupies. */
10
+ trackWidth?: number;
11
+ format?(value: number): string;
12
+ }
13
+ export declare const Slider: (props: SliderProps) => import("@textui/core").RenderOutput;
14
+ //# sourceMappingURL=slider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slider.d.ts","sourceRoot":"","sources":["../../src/control/slider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,WAAW,WAAY,SAAQ,QAAQ;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED,eAAO,MAAM,MAAM,6DA+CjB,CAAC"}