@dalcvil/steam-green-react 0.2.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 (348) hide show
  1. package/README.md +20 -5
  2. package/dist/components/Avatar/Avatar.css +136 -0
  3. package/dist/components/Avatar/Avatar.d.ts +22 -0
  4. package/dist/components/Avatar/Avatar.d.ts.map +1 -0
  5. package/dist/components/Avatar/Avatar.js +49 -0
  6. package/dist/components/Avatar/Avatar.js.map +1 -0
  7. package/dist/components/Avatar/index.d.ts +3 -0
  8. package/dist/components/Avatar/index.d.ts.map +1 -0
  9. package/dist/components/Button/Button.css +117 -0
  10. package/dist/components/Button/Button.d.ts +18 -0
  11. package/dist/components/Button/Button.d.ts.map +1 -0
  12. package/dist/components/Button/Button.js +29 -0
  13. package/dist/components/Button/Button.js.map +1 -0
  14. package/dist/components/Button/index.d.ts +3 -0
  15. package/dist/components/Button/index.d.ts.map +1 -0
  16. package/dist/components/Checkbox/Checkbox.css +116 -0
  17. package/dist/components/Checkbox/Checkbox.css.d.ts +1 -0
  18. package/dist/components/Checkbox/Checkbox.d.ts +19 -0
  19. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
  20. package/dist/components/Checkbox/Checkbox.js +51 -0
  21. package/dist/components/Checkbox/Checkbox.js.map +1 -0
  22. package/dist/components/Checkbox/index.d.ts +3 -0
  23. package/dist/components/Checkbox/index.d.ts.map +1 -0
  24. package/dist/components/ColorPicker/ColorPicker.css +331 -0
  25. package/dist/components/ColorPicker/ColorPicker.css.d.ts +1 -0
  26. package/dist/components/ColorPicker/ColorPicker.d.ts +29 -0
  27. package/dist/components/ColorPicker/ColorPicker.d.ts.map +1 -0
  28. package/dist/components/ColorPicker/ColorPicker.js +534 -0
  29. package/dist/components/ColorPicker/ColorPicker.js.map +1 -0
  30. package/dist/components/ColorPicker/index.d.ts +3 -0
  31. package/dist/components/{GreenButton → ColorPicker}/index.d.ts.map +1 -1
  32. package/dist/components/Console/Console.css +96 -0
  33. package/dist/components/Console/Console.css.d.ts +1 -0
  34. package/dist/components/Console/Console.d.ts +26 -0
  35. package/dist/components/Console/Console.d.ts.map +1 -0
  36. package/dist/components/Console/Console.js +59 -0
  37. package/dist/components/Console/Console.js.map +1 -0
  38. package/dist/components/Console/index.d.ts +3 -0
  39. package/dist/components/Console/index.d.ts.map +1 -0
  40. package/dist/components/Dialog/Dialog.css +137 -0
  41. package/dist/components/Dialog/Dialog.css.d.ts +1 -0
  42. package/dist/components/Dialog/Dialog.d.ts +28 -0
  43. package/dist/components/Dialog/Dialog.d.ts.map +1 -0
  44. package/dist/components/Dialog/Dialog.js +151 -0
  45. package/dist/components/Dialog/Dialog.js.map +1 -0
  46. package/dist/components/Dialog/index.d.ts +3 -0
  47. package/dist/components/Dialog/index.d.ts.map +1 -0
  48. package/dist/components/Divider/Divider.css +68 -0
  49. package/dist/components/Divider/Divider.css.d.ts +1 -0
  50. package/dist/components/Divider/Divider.d.ts +12 -0
  51. package/dist/components/Divider/Divider.d.ts.map +1 -0
  52. package/dist/components/Divider/Divider.js +23 -0
  53. package/dist/components/Divider/Divider.js.map +1 -0
  54. package/dist/components/Divider/index.d.ts +3 -0
  55. package/dist/components/Divider/index.d.ts.map +1 -0
  56. package/dist/components/FieldLabel/FieldLabel.css +98 -0
  57. package/dist/components/FieldLabel/FieldLabel.css.d.ts +1 -0
  58. package/dist/components/FieldLabel/FieldLabel.d.ts +29 -0
  59. package/dist/components/FieldLabel/FieldLabel.d.ts.map +1 -0
  60. package/dist/components/FieldLabel/FieldLabel.js +42 -0
  61. package/dist/components/FieldLabel/FieldLabel.js.map +1 -0
  62. package/dist/components/FieldLabel/index.d.ts +3 -0
  63. package/dist/components/{GreenPanel → FieldLabel}/index.d.ts.map +1 -1
  64. package/dist/components/GroupBox/GroupBox.css +101 -0
  65. package/dist/components/GroupBox/GroupBox.css.d.ts +1 -0
  66. package/dist/components/GroupBox/GroupBox.d.ts +14 -0
  67. package/dist/components/GroupBox/GroupBox.d.ts.map +1 -0
  68. package/dist/components/GroupBox/GroupBox.js +25 -0
  69. package/dist/components/GroupBox/GroupBox.js.map +1 -0
  70. package/dist/components/GroupBox/index.d.ts +3 -0
  71. package/dist/components/GroupBox/index.d.ts.map +1 -0
  72. package/dist/components/IconButton/IconButton.css +184 -0
  73. package/dist/components/IconButton/IconButton.css.d.ts +1 -0
  74. package/dist/components/IconButton/IconButton.d.ts +56 -0
  75. package/dist/components/IconButton/IconButton.d.ts.map +1 -0
  76. package/dist/components/IconButton/IconButton.js +77 -0
  77. package/dist/components/IconButton/IconButton.js.map +1 -0
  78. package/dist/components/IconButton/index.d.ts +3 -0
  79. package/dist/components/IconButton/index.d.ts.map +1 -0
  80. package/dist/components/LevelMeter/LevelMeter.css +117 -0
  81. package/dist/components/LevelMeter/LevelMeter.css.d.ts +1 -0
  82. package/dist/components/LevelMeter/LevelMeter.d.ts +20 -0
  83. package/dist/components/LevelMeter/LevelMeter.d.ts.map +1 -0
  84. package/dist/components/LevelMeter/LevelMeter.js +44 -0
  85. package/dist/components/LevelMeter/LevelMeter.js.map +1 -0
  86. package/dist/components/LevelMeter/index.d.ts +3 -0
  87. package/dist/components/LevelMeter/index.d.ts.map +1 -0
  88. package/dist/components/Link/Link.css +127 -0
  89. package/dist/components/Link/Link.css.d.ts +1 -0
  90. package/dist/components/Link/Link.d.ts +26 -0
  91. package/dist/components/Link/Link.d.ts.map +1 -0
  92. package/dist/components/Link/Link.js +60 -0
  93. package/dist/components/Link/Link.js.map +1 -0
  94. package/dist/components/Link/index.d.ts +3 -0
  95. package/dist/components/Link/index.d.ts.map +1 -0
  96. package/dist/components/List/List.css +224 -0
  97. package/dist/components/List/List.css.d.ts +1 -0
  98. package/dist/components/List/List.d.ts +49 -0
  99. package/dist/components/List/List.d.ts.map +1 -0
  100. package/dist/components/List/List.js +300 -0
  101. package/dist/components/List/List.js.map +1 -0
  102. package/dist/components/List/index.d.ts +3 -0
  103. package/dist/components/List/index.d.ts.map +1 -0
  104. package/dist/components/Menu/Menu.css +122 -0
  105. package/dist/components/Menu/Menu.css.d.ts +1 -0
  106. package/dist/components/Menu/Menu.d.ts +46 -0
  107. package/dist/components/Menu/Menu.d.ts.map +1 -0
  108. package/dist/components/Menu/Menu.js +246 -0
  109. package/dist/components/Menu/Menu.js.map +1 -0
  110. package/dist/components/Menu/index.d.ts +3 -0
  111. package/dist/components/Menu/index.d.ts.map +1 -0
  112. package/dist/components/MenuBar/MenuBar.css +94 -0
  113. package/dist/components/MenuBar/MenuBar.css.d.ts +1 -0
  114. package/dist/components/MenuBar/MenuBar.d.ts +34 -0
  115. package/dist/components/MenuBar/MenuBar.d.ts.map +1 -0
  116. package/dist/components/MenuBar/MenuBar.js +129 -0
  117. package/dist/components/MenuBar/MenuBar.js.map +1 -0
  118. package/dist/components/MenuBar/index.d.ts +3 -0
  119. package/dist/components/MenuBar/index.d.ts.map +1 -0
  120. package/dist/components/NavBar/NavBar.css +179 -0
  121. package/dist/components/NavBar/NavBar.css.d.ts +1 -0
  122. package/dist/components/NavBar/NavBar.d.ts +39 -0
  123. package/dist/components/NavBar/NavBar.d.ts.map +1 -0
  124. package/dist/components/NavBar/NavBar.js +198 -0
  125. package/dist/components/NavBar/NavBar.js.map +1 -0
  126. package/dist/components/NavBar/index.d.ts +3 -0
  127. package/dist/components/NavBar/index.d.ts.map +1 -0
  128. package/dist/components/Notification/Notification.css +176 -0
  129. package/dist/components/Notification/Notification.css.d.ts +1 -0
  130. package/dist/components/Notification/Notification.d.ts +26 -0
  131. package/dist/components/Notification/Notification.d.ts.map +1 -0
  132. package/dist/components/Notification/Notification.js +181 -0
  133. package/dist/components/Notification/Notification.js.map +1 -0
  134. package/dist/components/Notification/index.d.ts +3 -0
  135. package/dist/components/Notification/index.d.ts.map +1 -0
  136. package/dist/components/Panel/Panel.css +56 -0
  137. package/dist/components/Panel/Panel.css.d.ts +1 -0
  138. package/dist/components/Panel/Panel.d.ts +14 -0
  139. package/dist/components/Panel/Panel.d.ts.map +1 -0
  140. package/dist/components/Panel/Panel.js +42 -0
  141. package/dist/components/Panel/Panel.js.map +1 -0
  142. package/dist/components/Panel/index.d.ts +3 -0
  143. package/dist/components/Panel/index.d.ts.map +1 -0
  144. package/dist/components/ProgressBar/ProgressBar.css +108 -0
  145. package/dist/components/ProgressBar/ProgressBar.css.d.ts +1 -0
  146. package/dist/components/ProgressBar/ProgressBar.d.ts +22 -0
  147. package/dist/components/ProgressBar/ProgressBar.d.ts.map +1 -0
  148. package/dist/components/ProgressBar/ProgressBar.js +43 -0
  149. package/dist/components/ProgressBar/ProgressBar.js.map +1 -0
  150. package/dist/components/ProgressBar/index.d.ts +3 -0
  151. package/dist/components/ProgressBar/index.d.ts.map +1 -0
  152. package/dist/components/Radio/Radio.css +125 -0
  153. package/dist/components/Radio/Radio.css.d.ts +1 -0
  154. package/dist/components/Radio/Radio.d.ts +40 -0
  155. package/dist/components/Radio/Radio.d.ts.map +1 -0
  156. package/dist/components/Radio/Radio.js +91 -0
  157. package/dist/components/Radio/Radio.js.map +1 -0
  158. package/dist/components/Radio/index.d.ts +3 -0
  159. package/dist/components/Radio/index.d.ts.map +1 -0
  160. package/dist/components/RichText/RichText.css +96 -0
  161. package/dist/components/RichText/RichText.css.d.ts +1 -0
  162. package/dist/components/RichText/RichText.d.ts +25 -0
  163. package/dist/components/RichText/RichText.d.ts.map +1 -0
  164. package/dist/components/RichText/RichText.js +56 -0
  165. package/dist/components/RichText/RichText.js.map +1 -0
  166. package/dist/components/RichText/index.d.ts +3 -0
  167. package/dist/components/RichText/index.d.ts.map +1 -0
  168. package/dist/components/ScrollArea/ScrollArea.css +236 -0
  169. package/dist/components/ScrollArea/ScrollArea.css.d.ts +1 -0
  170. package/dist/components/ScrollArea/ScrollArea.d.ts +25 -0
  171. package/dist/components/ScrollArea/ScrollArea.d.ts.map +1 -0
  172. package/dist/components/ScrollArea/ScrollArea.js +124 -0
  173. package/dist/components/ScrollArea/ScrollArea.js.map +1 -0
  174. package/dist/components/ScrollArea/index.d.ts +3 -0
  175. package/dist/components/ScrollArea/index.d.ts.map +1 -0
  176. package/dist/components/Scrollbar/Scrollbar.css +260 -0
  177. package/dist/components/Scrollbar/Scrollbar.css.d.ts +1 -0
  178. package/dist/components/Scrollbar/Scrollbar.d.ts +31 -0
  179. package/dist/components/Scrollbar/Scrollbar.d.ts.map +1 -0
  180. package/dist/components/Scrollbar/Scrollbar.js +277 -0
  181. package/dist/components/Scrollbar/Scrollbar.js.map +1 -0
  182. package/dist/components/Scrollbar/index.d.ts +3 -0
  183. package/dist/components/Scrollbar/index.d.ts.map +1 -0
  184. package/dist/components/Select/Select.css +299 -0
  185. package/dist/components/Select/Select.css.d.ts +1 -0
  186. package/dist/components/Select/Select.d.ts +52 -0
  187. package/dist/components/Select/Select.d.ts.map +1 -0
  188. package/dist/components/Select/Select.js +281 -0
  189. package/dist/components/Select/Select.js.map +1 -0
  190. package/dist/components/Select/index.d.ts +3 -0
  191. package/dist/components/Select/index.d.ts.map +1 -0
  192. package/dist/components/Slider/Slider.css +158 -0
  193. package/dist/components/Slider/Slider.css.d.ts +1 -0
  194. package/dist/components/Slider/Slider.d.ts +26 -0
  195. package/dist/components/Slider/Slider.d.ts.map +1 -0
  196. package/dist/components/Slider/Slider.js +67 -0
  197. package/dist/components/Slider/Slider.js.map +1 -0
  198. package/dist/components/Slider/index.d.ts +3 -0
  199. package/dist/components/Slider/index.d.ts.map +1 -0
  200. package/dist/components/SpinBox/SpinBox.css +152 -0
  201. package/dist/components/SpinBox/SpinBox.css.d.ts +1 -0
  202. package/dist/components/SpinBox/SpinBox.d.ts +28 -0
  203. package/dist/components/SpinBox/SpinBox.d.ts.map +1 -0
  204. package/dist/components/SpinBox/SpinBox.js +207 -0
  205. package/dist/components/SpinBox/SpinBox.js.map +1 -0
  206. package/dist/components/SpinBox/index.d.ts +3 -0
  207. package/dist/components/SpinBox/index.d.ts.map +1 -0
  208. package/dist/components/Spinner/Spinner.css +137 -0
  209. package/dist/components/Spinner/Spinner.css.d.ts +1 -0
  210. package/dist/components/Spinner/Spinner.d.ts +20 -0
  211. package/dist/components/Spinner/Spinner.d.ts.map +1 -0
  212. package/dist/components/Spinner/Spinner.js +36 -0
  213. package/dist/components/Spinner/Spinner.js.map +1 -0
  214. package/dist/components/Spinner/index.d.ts +3 -0
  215. package/dist/components/Spinner/index.d.ts.map +1 -0
  216. package/dist/components/Splitter/Splitter.css +119 -0
  217. package/dist/components/Splitter/Splitter.css.d.ts +1 -0
  218. package/dist/components/Splitter/Splitter.d.ts +25 -0
  219. package/dist/components/Splitter/Splitter.d.ts.map +1 -0
  220. package/dist/components/Splitter/Splitter.js +212 -0
  221. package/dist/components/Splitter/Splitter.js.map +1 -0
  222. package/dist/components/Splitter/index.d.ts +3 -0
  223. package/dist/components/Splitter/index.d.ts.map +1 -0
  224. package/dist/components/StatusBar/StatusBar.css +97 -0
  225. package/dist/components/StatusBar/StatusBar.css.d.ts +1 -0
  226. package/dist/components/StatusBar/StatusBar.d.ts +22 -0
  227. package/dist/components/StatusBar/StatusBar.d.ts.map +1 -0
  228. package/dist/components/StatusBar/StatusBar.js +56 -0
  229. package/dist/components/StatusBar/StatusBar.js.map +1 -0
  230. package/dist/components/StatusBar/index.d.ts +3 -0
  231. package/dist/components/StatusBar/index.d.ts.map +1 -0
  232. package/dist/components/StatusLabel/StatusLabel.css +93 -0
  233. package/dist/components/StatusLabel/StatusLabel.css.d.ts +1 -0
  234. package/dist/components/StatusLabel/StatusLabel.d.ts +20 -0
  235. package/dist/components/StatusLabel/StatusLabel.d.ts.map +1 -0
  236. package/dist/components/StatusLabel/StatusLabel.js +42 -0
  237. package/dist/components/StatusLabel/StatusLabel.js.map +1 -0
  238. package/dist/components/StatusLabel/index.d.ts +3 -0
  239. package/dist/components/StatusLabel/index.d.ts.map +1 -0
  240. package/dist/components/Table/Table.css +253 -0
  241. package/dist/components/Table/Table.css.d.ts +1 -0
  242. package/dist/components/Table/Table.d.ts +67 -0
  243. package/dist/components/Table/Table.d.ts.map +1 -0
  244. package/dist/components/Table/Table.js +429 -0
  245. package/dist/components/Table/Table.js.map +1 -0
  246. package/dist/components/Table/index.d.ts +3 -0
  247. package/dist/components/Table/index.d.ts.map +1 -0
  248. package/dist/components/Tabs/Tabs.css +138 -0
  249. package/dist/components/Tabs/Tabs.css.d.ts +1 -0
  250. package/dist/components/Tabs/Tabs.d.ts +34 -0
  251. package/dist/components/Tabs/Tabs.d.ts.map +1 -0
  252. package/dist/components/Tabs/Tabs.js +140 -0
  253. package/dist/components/Tabs/Tabs.js.map +1 -0
  254. package/dist/components/Tabs/index.d.ts +3 -0
  255. package/dist/components/Tabs/index.d.ts.map +1 -0
  256. package/dist/components/TextInput/TextInput.css +133 -0
  257. package/dist/components/TextInput/TextInput.css.d.ts +1 -0
  258. package/dist/components/TextInput/TextInput.d.ts +16 -0
  259. package/dist/components/TextInput/TextInput.d.ts.map +1 -0
  260. package/dist/components/TextInput/TextInput.js +38 -0
  261. package/dist/components/TextInput/TextInput.js.map +1 -0
  262. package/dist/components/TextInput/index.d.ts +3 -0
  263. package/dist/components/TextInput/index.d.ts.map +1 -0
  264. package/dist/components/Textarea/Textarea.css +121 -0
  265. package/dist/components/Textarea/Textarea.css.d.ts +1 -0
  266. package/dist/components/Textarea/Textarea.d.ts +21 -0
  267. package/dist/components/Textarea/Textarea.d.ts.map +1 -0
  268. package/dist/components/Textarea/Textarea.js +61 -0
  269. package/dist/components/Textarea/Textarea.js.map +1 -0
  270. package/dist/components/Textarea/index.d.ts +3 -0
  271. package/dist/components/Textarea/index.d.ts.map +1 -0
  272. package/dist/components/TitleBar/TitleBar.css +76 -0
  273. package/dist/components/TitleBar/TitleBar.css.d.ts +1 -0
  274. package/dist/components/TitleBar/TitleBar.d.ts +20 -0
  275. package/dist/components/TitleBar/TitleBar.d.ts.map +1 -0
  276. package/dist/components/TitleBar/TitleBar.js +43 -0
  277. package/dist/components/TitleBar/TitleBar.js.map +1 -0
  278. package/dist/components/TitleBar/index.d.ts +3 -0
  279. package/dist/components/TitleBar/index.d.ts.map +1 -0
  280. package/dist/components/ToggleButton/ToggleButton.css +162 -0
  281. package/dist/components/ToggleButton/ToggleButton.css.d.ts +1 -0
  282. package/dist/components/ToggleButton/ToggleButton.d.ts +27 -0
  283. package/dist/components/ToggleButton/ToggleButton.d.ts.map +1 -0
  284. package/dist/components/ToggleButton/ToggleButton.js +52 -0
  285. package/dist/components/ToggleButton/ToggleButton.js.map +1 -0
  286. package/dist/components/ToggleButton/index.d.ts +3 -0
  287. package/dist/components/ToggleButton/index.d.ts.map +1 -0
  288. package/dist/components/Toolbar/Toolbar.css +202 -0
  289. package/dist/components/Toolbar/Toolbar.css.d.ts +1 -0
  290. package/dist/components/Toolbar/Toolbar.d.ts +46 -0
  291. package/dist/components/Toolbar/Toolbar.d.ts.map +1 -0
  292. package/dist/components/Toolbar/Toolbar.js +102 -0
  293. package/dist/components/Toolbar/Toolbar.js.map +1 -0
  294. package/dist/components/Toolbar/index.d.ts +3 -0
  295. package/dist/components/Toolbar/index.d.ts.map +1 -0
  296. package/dist/components/Tooltip/Tooltip.css +86 -0
  297. package/dist/components/Tooltip/Tooltip.css.d.ts +1 -0
  298. package/dist/components/Tooltip/Tooltip.d.ts +22 -0
  299. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -0
  300. package/dist/components/Tooltip/Tooltip.js +92 -0
  301. package/dist/components/Tooltip/Tooltip.js.map +1 -0
  302. package/dist/components/Tooltip/index.d.ts +3 -0
  303. package/dist/components/Tooltip/index.d.ts.map +1 -0
  304. package/dist/components/TreeView/TreeView.css +191 -0
  305. package/dist/components/TreeView/TreeView.css.d.ts +1 -0
  306. package/dist/components/TreeView/TreeView.d.ts +46 -0
  307. package/dist/components/TreeView/TreeView.d.ts.map +1 -0
  308. package/dist/components/TreeView/TreeView.js +331 -0
  309. package/dist/components/TreeView/TreeView.js.map +1 -0
  310. package/dist/components/TreeView/index.d.ts +3 -0
  311. package/dist/components/TreeView/index.d.ts.map +1 -0
  312. package/dist/components/Window/Window.css +218 -0
  313. package/dist/components/Window/Window.css.d.ts +1 -0
  314. package/dist/components/Window/Window.d.ts +30 -0
  315. package/dist/components/Window/Window.d.ts.map +1 -0
  316. package/dist/components/Window/Window.js +156 -0
  317. package/dist/components/Window/Window.js.map +1 -0
  318. package/dist/components/Window/index.d.ts +3 -0
  319. package/dist/components/Window/index.d.ts.map +1 -0
  320. package/dist/index.d.ts +91 -10
  321. package/dist/index.d.ts.map +1 -1
  322. package/dist/index.js +41 -3
  323. package/dist/styles/scrollbars.css +123 -0
  324. package/dist/styles/scrollbars.css.d.ts +1 -0
  325. package/dist/styles/theme.css +86 -41
  326. package/dist/styles/tokens.css +202 -0
  327. package/dist/styles/tokens.css.d.ts +1 -0
  328. package/dist/test/a11y.d.ts +3 -0
  329. package/dist/test/a11y.d.ts.map +1 -0
  330. package/dist/test/index.d.ts +2 -0
  331. package/dist/test/index.d.ts.map +1 -0
  332. package/dist/test/setup.d.ts +2 -0
  333. package/dist/test/setup.d.ts.map +1 -0
  334. package/package.json +13 -2
  335. package/dist/components/GreenButton/GreenButton.css +0 -47
  336. package/dist/components/GreenButton/GreenButton.d.ts +0 -8
  337. package/dist/components/GreenButton/GreenButton.d.ts.map +0 -1
  338. package/dist/components/GreenButton/GreenButton.js +0 -20
  339. package/dist/components/GreenButton/GreenButton.js.map +0 -1
  340. package/dist/components/GreenButton/index.d.ts +0 -3
  341. package/dist/components/GreenPanel/GreenPanel.css +0 -45
  342. package/dist/components/GreenPanel/GreenPanel.d.ts +0 -12
  343. package/dist/components/GreenPanel/GreenPanel.d.ts.map +0 -1
  344. package/dist/components/GreenPanel/GreenPanel.js +0 -24
  345. package/dist/components/GreenPanel/GreenPanel.js.map +0 -1
  346. package/dist/components/GreenPanel/index.d.ts +0 -3
  347. /package/dist/components/{GreenButton/GreenButton.css.d.ts → Avatar/Avatar.css.d.ts} +0 -0
  348. /package/dist/components/{GreenPanel/GreenPanel.css.d.ts → Button/Button.css.d.ts} +0 -0
@@ -0,0 +1,34 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ import './Tabs.css';
3
+ export interface TabSpec {
4
+ /** Stable identity, used for the id/aria-controls pair. */
5
+ id: string;
6
+ /** Visible tab label. */
7
+ label: string;
8
+ /** Panel content rendered when this tab is selected. */
9
+ content: ReactNode;
10
+ /** Renders a close affordance in the tab. */
11
+ closable?: boolean;
12
+ /** Called when the close affordance is activated. */
13
+ onClose?: () => void;
14
+ /** Renders as disabled and unselectable. */
15
+ disabled?: boolean;
16
+ /** Panel content is not rendered until first activation. */
17
+ lazy?: boolean;
18
+ }
19
+ export interface TabsProps extends HTMLAttributes<HTMLDivElement> {
20
+ /** Tabs in order. The first enabled tab is selected when uncontrolled. */
21
+ tabs: TabSpec[];
22
+ /** Controlled selection. Pair with onValueChange. */
23
+ value?: string;
24
+ /** Initial selection when uncontrolled. */
25
+ defaultValue?: string;
26
+ /** Called with the newly selected tab id. */
27
+ onValueChange?: (id: string) => void;
28
+ /** Selection follows focus, as VGUI's tab strip behaves. Defaults to true. */
29
+ activateOnFocus?: boolean;
30
+ /** Panel surface. 'clay' is the VGUI property-sheet interior. */
31
+ variant?: 'clay' | 'green';
32
+ }
33
+ export declare const Tabs: import("react").ForwardRefExoticComponent<TabsProps & import("react").RefAttributes<HTMLDivElement>>;
34
+ //# sourceMappingURL=Tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../src/components/Tabs/Tabs.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAA6B,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjF,OAAO,YAAY,CAAA;AAEnB,MAAM,WAAW,OAAO;IACtB,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAA;IACV,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,OAAO,EAAE,SAAS,CAAA;IAClB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,cAAc,CAAC;IAC/D,0EAA0E;IAC1E,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,8EAA8E;IAC9E,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAC3B;AAED,eAAO,MAAM,IAAI,sGA+Lf,CAAA"}
@@ -0,0 +1,140 @@
1
+ import { forwardRef, useEffect, useId, useRef, useState } from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import "./Tabs.css";
4
+ //#region src/components/Tabs/Tabs.tsx
5
+ var Tabs = forwardRef(function Tabs({ tabs, value, defaultValue, onValueChange, activateOnFocus = true, variant = "clay", className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...rest }, ref) {
6
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
7
+ const [visited, setVisited] = useState(() => defaultValue ? [defaultValue] : []);
8
+ const baseId = useId();
9
+ const tabNodes = useRef(/* @__PURE__ */ new Map());
10
+ const firstEnabled = tabs.find((tab) => !tab.disabled)?.id;
11
+ const requestedId = value !== void 0 ? value : uncontrolledValue;
12
+ const requested = tabs.find((tab) => tab.id === requestedId);
13
+ const selectedId = requested && !requested.disabled ? requested.id : firstEnabled;
14
+ useEffect(() => {
15
+ if (selectedId && !visited.includes(selectedId)) setVisited((seen) => [...seen, selectedId]);
16
+ }, [selectedId, visited]);
17
+ const setTabNode = (id, node) => {
18
+ if (node) tabNodes.current.set(id, node);
19
+ else tabNodes.current.delete(id);
20
+ };
21
+ const selectTab = (nextId) => {
22
+ const tab = tabs.find((item) => item.id === nextId);
23
+ if (!tab || tab.disabled) return;
24
+ if (value === void 0) setUncontrolledValue(nextId);
25
+ if (nextId !== selectedId) onValueChange?.(nextId);
26
+ };
27
+ const focusTab = (nextId) => {
28
+ if (!nextId) return;
29
+ if (activateOnFocus) selectTab(nextId);
30
+ tabNodes.current.get(nextId)?.focus();
31
+ };
32
+ const handleKeyDown = (event) => {
33
+ const currentId = (event.target?.closest("[role=\"tab\"]"))?.dataset.tabId;
34
+ if (!currentId) return;
35
+ const enabledIds = tabs.filter((tab) => !tab.disabled).map((tab) => tab.id);
36
+ const index = enabledIds.indexOf(currentId);
37
+ if (index === -1) return;
38
+ switch (event.key) {
39
+ case "ArrowRight":
40
+ event.preventDefault();
41
+ focusTab(enabledIds[(index + 1) % enabledIds.length]);
42
+ break;
43
+ case "ArrowLeft":
44
+ event.preventDefault();
45
+ focusTab(enabledIds[(index - 1 + enabledIds.length) % enabledIds.length]);
46
+ break;
47
+ case "Home":
48
+ event.preventDefault();
49
+ focusTab(enabledIds[0]);
50
+ break;
51
+ case "End":
52
+ event.preventDefault();
53
+ focusTab(enabledIds[enabledIds.length - 1]);
54
+ break;
55
+ case "Delete":
56
+ event.preventDefault();
57
+ tabs.find((tab) => tab.id === currentId)?.onClose?.();
58
+ }
59
+ };
60
+ const rootClasses = ["vgui-tabs", `vgui-tabs--${variant}`];
61
+ if (tabs.some((tab) => tab.closable)) rootClasses.push("vgui-tabs--closable");
62
+ if (className) rootClasses.push(className);
63
+ const panelClasses = ["vgui-tabs__panel", `vgui-tabs__panel--${variant}`];
64
+ return /* @__PURE__ */ jsxs("div", {
65
+ className: rootClasses.join(" "),
66
+ ref,
67
+ ...rest,
68
+ children: [/* @__PURE__ */ jsx("div", {
69
+ className: "vgui-tabs__strip",
70
+ role: "tablist",
71
+ "aria-label": ariaLabel,
72
+ "aria-labelledby": ariaLabelledBy,
73
+ onKeyDown: handleKeyDown,
74
+ children: tabs.map((tab) => {
75
+ const isSelected = tab.id === selectedId;
76
+ const tabClasses = ["vgui-tabs__tab"];
77
+ if (isSelected) tabClasses.push("vgui-tabs__tab--selected");
78
+ if (tab.disabled) tabClasses.push("vgui-tabs__tab--disabled");
79
+ const shared = {
80
+ className: tabClasses.join(" "),
81
+ id: `${baseId}-tab-${tab.id}`,
82
+ role: "tab",
83
+ "aria-selected": isSelected,
84
+ "aria-controls": `${baseId}-panel-${tab.id}`,
85
+ "aria-disabled": tab.disabled || void 0,
86
+ "aria-keyshortcuts": tab.closable && !tab.disabled ? "Delete" : void 0,
87
+ tabIndex: isSelected ? 0 : -1,
88
+ "data-tab-id": tab.id,
89
+ onClick: () => selectTab(tab.id)
90
+ };
91
+ const label = /* @__PURE__ */ jsx("span", {
92
+ className: "vgui-tabs__label",
93
+ children: tab.label
94
+ });
95
+ if (!tab.closable) return /* @__PURE__ */ jsx("button", {
96
+ type: "button",
97
+ disabled: tab.disabled,
98
+ ...shared,
99
+ ref: (node) => {
100
+ setTabNode(tab.id, node);
101
+ },
102
+ children: label
103
+ }, tab.id);
104
+ return /* @__PURE__ */ jsxs("div", {
105
+ ...shared,
106
+ ref: (node) => {
107
+ setTabNode(tab.id, node);
108
+ },
109
+ children: [label, tab.disabled ? null : /* @__PURE__ */ jsx("span", {
110
+ className: "vgui-tabs__close",
111
+ "aria-hidden": "true",
112
+ title: `Close ${tab.label} tab`,
113
+ onClick: (event) => {
114
+ event.stopPropagation();
115
+ tab.onClose?.();
116
+ },
117
+ children: "✕"
118
+ })]
119
+ }, tab.id);
120
+ })
121
+ }), tabs.map((tab) => {
122
+ const isSelected = tab.id === selectedId;
123
+ if (!(!tab.lazy || isSelected || visited.includes(tab.id))) return null;
124
+ return /* @__PURE__ */ jsx("div", {
125
+ className: panelClasses.join(" "),
126
+ role: "tabpanel",
127
+ id: `${baseId}-panel-${tab.id}`,
128
+ "aria-labelledby": `${baseId}-tab-${tab.id}`,
129
+ tabIndex: 0,
130
+ hidden: !isSelected,
131
+ children: tab.content
132
+ }, tab.id);
133
+ })]
134
+ });
135
+ });
136
+ Tabs.displayName = "Tabs";
137
+ //#endregion
138
+ export { Tabs };
139
+
140
+ //# sourceMappingURL=Tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tabs.js","names":[],"sources":["../../../src/components/Tabs/Tabs.tsx"],"sourcesContent":["import { forwardRef, useEffect, useId, useRef, useState } from 'react'\nimport type { HTMLAttributes, KeyboardEvent, MouseEvent, ReactNode } from 'react'\n\nimport './Tabs.css'\n\nexport interface TabSpec {\n /** Stable identity, used for the id/aria-controls pair. */\n id: string\n /** Visible tab label. */\n label: string\n /** Panel content rendered when this tab is selected. */\n content: ReactNode\n /** Renders a close affordance in the tab. */\n closable?: boolean\n /** Called when the close affordance is activated. */\n onClose?: () => void\n /** Renders as disabled and unselectable. */\n disabled?: boolean\n /** Panel content is not rendered until first activation. */\n lazy?: boolean\n}\n\nexport interface TabsProps extends HTMLAttributes<HTMLDivElement> {\n /** Tabs in order. The first enabled tab is selected when uncontrolled. */\n tabs: TabSpec[]\n /** Controlled selection. Pair with onValueChange. */\n value?: string\n /** Initial selection when uncontrolled. */\n defaultValue?: string\n /** Called with the newly selected tab id. */\n onValueChange?: (id: string) => void\n /** Selection follows focus, as VGUI's tab strip behaves. Defaults to true. */\n activateOnFocus?: boolean\n /** Panel surface. 'clay' is the VGUI property-sheet interior. */\n variant?: 'clay' | 'green'\n}\n\nexport const Tabs = forwardRef<HTMLDivElement, TabsProps>(function Tabs(\n {\n tabs,\n value,\n defaultValue,\n onValueChange,\n activateOnFocus = true,\n variant = 'clay',\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...rest\n },\n ref,\n) {\n const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue)\n const [visited, setVisited] = useState<string[]>(() => (defaultValue ? [defaultValue] : []))\n const baseId = useId()\n const tabNodes = useRef(new Map<string, HTMLButtonElement | HTMLDivElement>())\n\n const firstEnabled = tabs.find((tab) => !tab.disabled)?.id\n const requestedId = value !== undefined ? value : uncontrolledValue\n const requested = tabs.find((tab) => tab.id === requestedId)\n const selectedId = requested && !requested.disabled ? requested.id : firstEnabled\n\n // A lazy panel stays mounted once it has been shown, so switching away and\n // back does not throw away scroll position or form state.\n useEffect(() => {\n if (selectedId && !visited.includes(selectedId)) {\n setVisited((seen) => [...seen, selectedId])\n }\n }, [selectedId, visited])\n\n const setTabNode = (id: string, node: HTMLButtonElement | HTMLDivElement | null) => {\n if (node) {\n tabNodes.current.set(id, node)\n } else {\n tabNodes.current.delete(id)\n }\n }\n\n const selectTab = (nextId: string) => {\n const tab = tabs.find((item) => item.id === nextId)\n if (!tab || tab.disabled) return\n if (value === undefined) setUncontrolledValue(nextId)\n if (nextId !== selectedId) onValueChange?.(nextId)\n }\n\n const focusTab = (nextId: string | undefined) => {\n if (!nextId) return\n if (activateOnFocus) selectTab(nextId)\n tabNodes.current.get(nextId)?.focus()\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const current = (event.target as HTMLElement | null)?.closest<HTMLElement>('[role=\"tab\"]')\n const currentId = current?.dataset.tabId\n if (!currentId) return\n const enabledIds = tabs.filter((tab) => !tab.disabled).map((tab) => tab.id)\n const index = enabledIds.indexOf(currentId)\n if (index === -1) return\n\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault()\n focusTab(enabledIds[(index + 1) % enabledIds.length])\n break\n case 'ArrowLeft':\n event.preventDefault()\n focusTab(enabledIds[(index - 1 + enabledIds.length) % enabledIds.length])\n break\n case 'Home':\n event.preventDefault()\n focusTab(enabledIds[0])\n break\n case 'End':\n event.preventDefault()\n focusTab(enabledIds[enabledIds.length - 1])\n break\n case 'Delete':\n event.preventDefault()\n tabs.find((tab) => tab.id === currentId)?.onClose?.()\n break\n default:\n break\n }\n }\n\n const rootClasses = ['vgui-tabs', `vgui-tabs--${variant}`]\n if (tabs.some((tab) => tab.closable)) rootClasses.push('vgui-tabs--closable')\n if (className) rootClasses.push(className)\n\n const panelClasses = ['vgui-tabs__panel', `vgui-tabs__panel--${variant}`]\n\n return (\n <div className={rootClasses.join(' ')} ref={ref} {...rest}>\n <div\n className=\"vgui-tabs__strip\"\n role=\"tablist\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n onKeyDown={handleKeyDown}\n >\n {tabs.map((tab) => {\n const isSelected = tab.id === selectedId\n const tabClasses = ['vgui-tabs__tab']\n if (isSelected) tabClasses.push('vgui-tabs__tab--selected')\n if (tab.disabled) tabClasses.push('vgui-tabs__tab--disabled')\n\n const shared = {\n className: tabClasses.join(' '),\n id: `${baseId}-tab-${tab.id}`,\n role: 'tab' as const,\n 'aria-selected': isSelected,\n 'aria-controls': `${baseId}-panel-${tab.id}`,\n 'aria-disabled': tab.disabled || undefined,\n 'aria-keyshortcuts': tab.closable && !tab.disabled ? 'Delete' : undefined,\n tabIndex: isSelected ? 0 : -1,\n 'data-tab-id': tab.id,\n onClick: () => selectTab(tab.id),\n }\n\n const label = <span className=\"vgui-tabs__label\">{tab.label}</span>\n\n if (!tab.closable) {\n return (\n <button\n key={tab.id}\n type=\"button\"\n disabled={tab.disabled}\n {...shared}\n ref={(node) => {\n setTabNode(tab.id, node)\n }}\n >\n {label}\n </button>\n )\n }\n\n // A `role=\"tab\"` element has presentational children, so the close\n // affordance must not be focusable or it breaks the tab's own\n // interaction model (axe `nested-interactive`). Keyboard users close\n // the tab with Delete, announced through `aria-keyshortcuts`.\n return (\n <div\n key={tab.id}\n {...shared}\n ref={(node) => {\n setTabNode(tab.id, node)\n }}\n >\n {label}\n {tab.disabled ? null : (\n <span\n className=\"vgui-tabs__close\"\n aria-hidden=\"true\"\n title={`Close ${tab.label} tab`}\n onClick={(event: MouseEvent<HTMLSpanElement>) => {\n event.stopPropagation()\n tab.onClose?.()\n }}\n >\n ✕\n </span>\n )}\n </div>\n )\n })}\n </div>\n\n {tabs.map((tab) => {\n const isSelected = tab.id === selectedId\n const rendered = !tab.lazy || isSelected || visited.includes(tab.id)\n if (!rendered) return null\n return (\n <div\n key={tab.id}\n className={panelClasses.join(' ')}\n role=\"tabpanel\"\n id={`${baseId}-panel-${tab.id}`}\n aria-labelledby={`${baseId}-tab-${tab.id}`}\n tabIndex={0}\n hidden={!isSelected}\n >\n {tab.content}\n </div>\n )\n })}\n </div>\n )\n})\n\nTabs.displayName = 'Tabs'\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { Tabs } from './Tabs';
2
+ export type { TabSpec, TabsProps } from './Tabs';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Tabs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA"}
@@ -0,0 +1,133 @@
1
+ /*
2
+ * Green Steam text field — VGUI `TextEntry` (docs/components/TextInput.md).
3
+ *
4
+ * Two things define the look and are easy to "improve" away:
5
+ *
6
+ * 1. The interior is genuinely black rather than `--vgui-surface`. It is the
7
+ * darkest surface in the theme, so the value text on it reaches 15.31:1 —
8
+ * the best contrast pairing in the library.
9
+ * 2. The inset is `4 0 4 0`: horizontal padding only, which is what makes a
10
+ * VGUI field feel tight.
11
+ *
12
+ * The black interior is read through `--vgui-field-bg`, the token
13
+ * docs/components/TextInput.md asks the token layer to add. No literal fallback
14
+ * is declared here: components in this library never contain a colour value.
15
+ */
16
+
17
+ .vgui-text-input {
18
+ /* Component-local metrics. The palette is never declared locally. */
19
+ --vgui-text-input-height: 19px;
20
+ --vgui-text-input-icon-inset: 20px;
21
+ --vgui-text-input-suffix-inset: 28px;
22
+
23
+ position: relative;
24
+ display: inline-flex;
25
+ align-items: center;
26
+ min-width: 0;
27
+ font: inherit;
28
+ }
29
+
30
+ .vgui-text-input__field {
31
+ box-sizing: border-box;
32
+ width: 100%;
33
+ min-width: 0;
34
+ min-height: var(--vgui-text-input-height);
35
+ padding: 0 var(--vgui-field-inset);
36
+ font: inherit;
37
+ color: var(--vgui-text);
38
+ background-color: var(--vgui-field-bg);
39
+ /* The UA draws a rounded, inset native field; the bevel replaces it. */
40
+ appearance: none;
41
+ border-top: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
42
+ border-left: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
43
+ border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
44
+ border-right: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
45
+ /* Explicit because `appearance: none` still leaves Safari rounding corners. */
46
+ border-radius: 0;
47
+ caret-color: var(--vgui-text);
48
+ }
49
+
50
+ .vgui-text-input__field::placeholder {
51
+ color: var(--vgui-text-dim);
52
+ /* Firefox dims placeholders to 0.54 by default. */
53
+ opacity: 1;
54
+ }
55
+
56
+ /*
57
+ * Valve's ring for a field is `1px dotted black`, drawn over an interior where
58
+ * it is invisible rather than merely low-contrast. The accent ring is the
59
+ * default; the faithful one stays reachable through `.vgui-crisp`.
60
+ */
61
+ .vgui-text-input__field:focus-visible {
62
+ outline: var(--vgui-focus-ring);
63
+ outline-offset: var(--vgui-focus-ring-offset);
64
+ }
65
+
66
+ .vgui-crisp .vgui-text-input__field:focus-visible {
67
+ outline: var(--vgui-focus-ring-valve);
68
+ outline-offset: var(--vgui-focus-ring-valve-offset);
69
+ }
70
+
71
+ /* `#232421` on the accent is 4.39:1; the theme's body colour is only 2.59:1. */
72
+ .vgui-text-input__field::selection {
73
+ background-color: var(--vgui-selection-bg);
74
+ color: var(--vgui-selection-text);
75
+ }
76
+
77
+ /* Read-only stays legible and selectable; disabled is not submitted at all. */
78
+ .vgui-text-input__field:read-only {
79
+ color: var(--vgui-text-muted);
80
+ }
81
+
82
+ .vgui-text-input__field:disabled {
83
+ color: var(--vgui-text-disabled);
84
+ text-shadow: 1px 1px 0 var(--vgui-text-disabled-shadow);
85
+ cursor: not-allowed;
86
+ }
87
+
88
+ .vgui-text-input--invalid .vgui-text-input__field {
89
+ border-top-color: var(--vgui-danger);
90
+ border-left-color: var(--vgui-danger);
91
+ }
92
+
93
+ .vgui-text-input--large .vgui-text-input__field {
94
+ min-height: var(--vgui-control-height);
95
+ }
96
+
97
+ .vgui-text-input__adornment {
98
+ position: absolute;
99
+ display: flex;
100
+ align-items: center;
101
+ color: var(--vgui-text-dim);
102
+ pointer-events: none;
103
+ }
104
+
105
+ .vgui-text-input__adornment--start {
106
+ left: var(--vgui-field-inset);
107
+ }
108
+
109
+ .vgui-text-input__adornment--end {
110
+ right: var(--vgui-field-inset);
111
+ }
112
+
113
+ .vgui-text-input--with-icon .vgui-text-input__field {
114
+ padding-left: var(--vgui-text-input-icon-inset);
115
+ }
116
+
117
+ .vgui-text-input--with-suffix .vgui-text-input__field {
118
+ padding-right: var(--vgui-text-input-suffix-inset);
119
+ }
120
+
121
+ /*
122
+ * `--clay` is a hook rather than a repaint: the field itself stays black inside
123
+ * a property sheet and only the chrome around it turns grey, so the class
124
+ * declares nothing beyond the adornment glyph colour.
125
+ */
126
+ .vgui-text-input--clay .vgui-text-input__adornment {
127
+ color: var(--vgui-clay-glyph);
128
+ }
129
+
130
+ .vgui-text-input--clay .vgui-text-input__field:disabled {
131
+ color: var(--vgui-clay-glyph-dim);
132
+ text-shadow: none;
133
+ }
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,16 @@
1
+ import type { InputHTMLAttributes, ReactNode } from 'react';
2
+ import './TextInput.css';
3
+ export interface TextInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
4
+ /** Field height: `default` is 19px, `large` is 25px and lines up with a Button. */
5
+ size?: 'default' | 'large';
6
+ /** Glyph shown inside the field's leading edge. */
7
+ icon?: ReactNode | string;
8
+ /** Text shown inside the field's trailing edge, e.g. a unit. */
9
+ suffix?: ReactNode;
10
+ /** Draw the invalid bevel. Does not set aria-invalid. */
11
+ invalid?: boolean;
12
+ /** Grey property-sheet chrome. */
13
+ clay?: boolean;
14
+ }
15
+ export declare const TextInput: import("react").ForwardRefExoticComponent<TextInputProps & import("react").RefAttributes<HTMLInputElement>>;
16
+ //# sourceMappingURL=TextInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextInput.d.ts","sourceRoot":"","sources":["../../../src/components/TextInput/TextInput.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAE3D,OAAO,iBAAiB,CAAA;AAExB,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACzF,mFAAmF;IACnF,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;IAC1B,mDAAmD;IACnD,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACzB,gEAAgE;IAChE,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,kCAAkC;IAClC,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,eAAO,MAAM,SAAS,6GAiCpB,CAAA"}
@@ -0,0 +1,38 @@
1
+ import { forwardRef } from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import "./TextInput.css";
4
+ //#region src/components/TextInput/TextInput.tsx
5
+ var TextInput = forwardRef(function TextInput({ className, size = "default", icon, suffix, invalid = false, clay = false, ...rest }, ref) {
6
+ const classes = ["vgui-text-input"];
7
+ if (size === "large") classes.push("vgui-text-input--large");
8
+ if (icon != null) classes.push("vgui-text-input--with-icon");
9
+ if (suffix != null) classes.push("vgui-text-input--with-suffix");
10
+ if (invalid) classes.push("vgui-text-input--invalid");
11
+ if (clay) classes.push("vgui-text-input--clay");
12
+ if (className) classes.push(className);
13
+ return /* @__PURE__ */ jsxs("span", {
14
+ className: classes.join(" "),
15
+ children: [
16
+ icon != null ? /* @__PURE__ */ jsx("span", {
17
+ className: "vgui-text-input__adornment vgui-text-input__adornment--start",
18
+ "aria-hidden": "true",
19
+ children: icon
20
+ }) : null,
21
+ /* @__PURE__ */ jsx("input", {
22
+ ref,
23
+ className: "vgui-text-input__field",
24
+ ...rest
25
+ }),
26
+ suffix != null ? /* @__PURE__ */ jsx("span", {
27
+ className: "vgui-text-input__adornment vgui-text-input__adornment--end",
28
+ "aria-hidden": "true",
29
+ children: suffix
30
+ }) : null
31
+ ]
32
+ });
33
+ });
34
+ TextInput.displayName = "TextInput";
35
+ //#endregion
36
+ export { TextInput };
37
+
38
+ //# sourceMappingURL=TextInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextInput.js","names":[],"sources":["../../../src/components/TextInput/TextInput.tsx"],"sourcesContent":["import { forwardRef } from 'react'\nimport type { InputHTMLAttributes, ReactNode } from 'react'\n\nimport './TextInput.css'\n\nexport interface TextInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n /** Field height: `default` is 19px, `large` is 25px and lines up with a Button. */\n size?: 'default' | 'large'\n /** Glyph shown inside the field's leading edge. */\n icon?: ReactNode | string\n /** Text shown inside the field's trailing edge, e.g. a unit. */\n suffix?: ReactNode\n /** Draw the invalid bevel. Does not set aria-invalid. */\n invalid?: boolean\n /** Grey property-sheet chrome. */\n clay?: boolean\n}\n\nexport const TextInput = forwardRef<HTMLInputElement, TextInputProps>(function TextInput(\n { className, size = 'default', icon, suffix, invalid = false, clay = false, ...rest },\n ref,\n) {\n const classes = ['vgui-text-input']\n if (size === 'large') classes.push('vgui-text-input--large')\n if (icon != null) classes.push('vgui-text-input--with-icon')\n if (suffix != null) classes.push('vgui-text-input--with-suffix')\n if (invalid) classes.push('vgui-text-input--invalid')\n if (clay) classes.push('vgui-text-input--clay')\n if (className) classes.push(className)\n\n return (\n <span className={classes.join(' ')}>\n {icon != null ? (\n <span\n className=\"vgui-text-input__adornment vgui-text-input__adornment--start\"\n aria-hidden=\"true\"\n >\n {icon}\n </span>\n ) : null}\n <input ref={ref} className=\"vgui-text-input__field\" {...rest} />\n {suffix != null ? (\n <span\n className=\"vgui-text-input__adornment vgui-text-input__adornment--end\"\n aria-hidden=\"true\"\n >\n {suffix}\n </span>\n ) : null}\n </span>\n )\n})\n\nTextInput.displayName = 'TextInput'\n"],"mappings":";;;;AAkBA,IAAa,YAAY,WAA6C,SAAS,UAC7E,EAAE,WAAW,OAAO,WAAW,MAAM,QAAQ,UAAU,OAAO,OAAO,OAAO,GAAG,QAC/E,KACA;CACA,MAAM,UAAU,CAAC,iBAAiB;CAClC,IAAI,SAAS,SAAS,QAAQ,KAAK,wBAAwB;CAC3D,IAAI,QAAQ,MAAM,QAAQ,KAAK,4BAA4B;CAC3D,IAAI,UAAU,MAAM,QAAQ,KAAK,8BAA8B;CAC/D,IAAI,SAAS,QAAQ,KAAK,0BAA0B;CACpD,IAAI,MAAM,QAAQ,KAAK,uBAAuB;CAC9C,IAAI,WAAW,QAAQ,KAAK,SAAS;CAErC,OACE,qBAAC,QAAD;EAAM,WAAW,QAAQ,KAAK,GAAG;EAAjC,UAAA;GACG,QAAQ,OACP,oBAAC,QAAD;IACE,WAAU;IACV,eAAY;IAEX,UAAA;GACG,CAAA,IACJ;GACJ,oBAAC,SAAD;IAAY;IAAK,WAAU;IAAyB,GAAI;GAAO,CAAA;GAC9D,UAAU,OACT,oBAAC,QAAD;IACE,WAAU;IACV,eAAY;IAEX,UAAA;GACG,CAAA,IACJ;EACA;;AAEV,CAAC;AAED,UAAU,cAAc"}
@@ -0,0 +1,3 @@
1
+ export { TextInput } from './TextInput';
2
+ export type { TextInputProps } from './TextInput';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TextInput/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,121 @@
1
+ /*
2
+ * Green Steam multi-line text field — VGUI `TextEntry` with
3
+ * `SetMultiline(true)` (docs/components/Textarea.md).
4
+ *
5
+ * The chrome is identical to TextInput: black interior, inset bevel, 1px caret.
6
+ * Everything else is behavioural, which is why there is no separate VGUI class.
7
+ */
8
+
9
+ .vgui-textarea {
10
+ --vgui-textarea-min-height: 60px;
11
+
12
+ position: relative;
13
+ display: block;
14
+ }
15
+
16
+ .vgui-textarea__field {
17
+ box-sizing: border-box;
18
+ display: block;
19
+ width: 100%;
20
+ /* `rows="1"` on a 200%-zoom browser is a sliver, so a floor is always kept. */
21
+ min-height: var(--vgui-textarea-min-height);
22
+ /* The `4 0 4 0` inset, plus 2px of vertical breathing room. */
23
+ padding: 2px var(--vgui-field-inset);
24
+ font: inherit;
25
+ line-height: var(--vgui-line-height);
26
+ color: var(--vgui-text);
27
+ background-color: var(--vgui-field-bg);
28
+ border-top: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
29
+ border-left: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
30
+ border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
31
+ border-right: var(--vgui-bevel-width) solid var(--vgui-bevel-light);
32
+ border-radius: 0;
33
+ /* Vertical only: a horizontally resizable field reflows the whole page. */
34
+ resize: vertical;
35
+ overflow: auto;
36
+ }
37
+
38
+ .vgui-textarea__field::placeholder {
39
+ color: var(--vgui-text-dim);
40
+ opacity: 1;
41
+ }
42
+
43
+ .vgui-textarea__field::selection {
44
+ background-color: var(--vgui-selection-bg);
45
+ color: var(--vgui-selection-text);
46
+ }
47
+
48
+ /*
49
+ * The worst case for the Valve ring: the dotted black outline is drawn over the
50
+ * field's own black interior, where it is literally invisible. The accent ring
51
+ * is the default and the faithful one is reachable through `.vgui-crisp`.
52
+ */
53
+ .vgui-textarea__field:focus-visible {
54
+ outline: var(--vgui-focus-ring);
55
+ outline-offset: var(--vgui-focus-ring-offset);
56
+ }
57
+
58
+ .vgui-crisp .vgui-textarea__field:focus-visible {
59
+ outline: var(--vgui-focus-ring-valve);
60
+ outline-offset: var(--vgui-focus-ring-valve-offset);
61
+ }
62
+
63
+ .vgui-textarea__field:read-only {
64
+ color: var(--vgui-text-muted);
65
+ }
66
+
67
+ .vgui-textarea__field:disabled {
68
+ color: var(--vgui-text-disabled);
69
+ text-shadow: 1px 1px 0 var(--vgui-text-disabled-shadow);
70
+ cursor: not-allowed;
71
+ }
72
+
73
+ .vgui-textarea--invalid .vgui-textarea__field {
74
+ border-top-color: var(--vgui-danger);
75
+ border-left-color: var(--vgui-danger);
76
+ }
77
+
78
+ /* `--fixed`: height comes from `rows` alone. */
79
+ .vgui-textarea--fixed .vgui-textarea__field {
80
+ resize: none;
81
+ }
82
+
83
+ /*
84
+ * `--auto-grow` height is set by JS from `scrollHeight`; `max-height` and
85
+ * `overflow-y` are the fallback for tall content. `height: auto` is deliberately
86
+ * not declared here — the script needs `auto` only for the measurement pass.
87
+ */
88
+ .vgui-textarea--auto-grow .vgui-textarea__field {
89
+ resize: none;
90
+ overflow: hidden;
91
+ overflow-y: auto;
92
+ }
93
+
94
+ .vgui-textarea--mono .vgui-textarea__field {
95
+ font-family: var(--vgui-font-mono);
96
+ font-size: var(--vgui-font-size-small);
97
+ }
98
+
99
+ /*
100
+ * The counter overlays the field's trailing corner rather than taking a row of
101
+ * its own: a VGUI property sheet has no space for one, and `aria-hidden` means
102
+ * it never has to be read out.
103
+ */
104
+ .vgui-textarea__count {
105
+ position: absolute;
106
+ right: var(--vgui-field-inset);
107
+ bottom: 2px;
108
+ font-size: var(--vgui-font-size-small);
109
+ color: var(--vgui-text-dim);
110
+ pointer-events: none;
111
+ }
112
+
113
+ /* `--clay` has no prop of its own; callers opt in through `className`. */
114
+ .vgui-textarea--clay .vgui-textarea__field:disabled {
115
+ color: var(--vgui-clay-glyph-dim);
116
+ text-shadow: none;
117
+ }
118
+
119
+ .vgui-textarea--clay .vgui-textarea__count {
120
+ color: var(--vgui-clay-glyph-dim);
121
+ }
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,21 @@
1
+ import type { TextareaHTMLAttributes } from 'react';
2
+ import './Textarea.css';
3
+ import '../../styles/scrollbars.css';
4
+ export interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'children'> {
5
+ /** Visible rows. Sets `rows`; the 60px `min-height` still applies. */
6
+ rows?: number;
7
+ /** Grow to fit content instead of scrolling, up to `maxHeight`. */
8
+ autoGrow?: boolean;
9
+ /** Cap for `autoGrow`, in pixels. Defaults to 240. */
10
+ maxHeight?: number;
11
+ /** Prevent the user from resizing the field. Defaults to `vertical`. */
12
+ resize?: 'none' | 'vertical';
13
+ /** Monospaced text, for console and config content. */
14
+ mono?: boolean;
15
+ /** Show a live character count, expressed against `maxLength` when given. */
16
+ showCount?: boolean;
17
+ /** Render the invalid border. Does not set aria-invalid. */
18
+ invalid?: boolean;
19
+ }
20
+ export declare const Textarea: import("react").ForwardRefExoticComponent<TextareaProps & import("react").RefAttributes<HTMLTextAreaElement>>;
21
+ //# sourceMappingURL=Textarea.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.d.ts","sourceRoot":"","sources":["../../../src/components/Textarea/Textarea.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,sBAAsB,EAAE,MAAM,OAAO,CAAA;AAE/D,OAAO,gBAAgB,CAAA;AACvB,OAAO,6BAA6B,CAAA;AAEpC,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,UAAU,CAAC;IAClG,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;IAC5B,uDAAuD;IACvD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,QAAQ,+GAqFnB,CAAA"}
@@ -0,0 +1,61 @@
1
+ import { forwardRef, useCallback, useLayoutEffect, useRef, useState } from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import "../../styles/scrollbars.css";
4
+ import "./Textarea.css";
5
+ //#region src/components/Textarea/Textarea.tsx
6
+ var Textarea = forwardRef(function Textarea({ className, rows, autoGrow = false, maxHeight = 240, resize = "vertical", mono = false, showCount = false, invalid = false, value, defaultValue, maxLength, onInput, style, ...rest }, ref) {
7
+ const fieldRef = useRef(null);
8
+ const [uncontrolledLength, setUncontrolledLength] = useState(() => String(defaultValue ?? "").length);
9
+ const setRefs = useCallback((node) => {
10
+ fieldRef.current = node;
11
+ if (typeof ref === "function") ref(node);
12
+ else if (ref) ref.current = node;
13
+ }, [ref]);
14
+ const resizeToContent = useCallback(() => {
15
+ const field = fieldRef.current;
16
+ if (!field) return;
17
+ field.style.height = "auto";
18
+ field.style.height = `${Math.min(field.scrollHeight, maxHeight)}px`;
19
+ }, [maxHeight]);
20
+ useLayoutEffect(() => {
21
+ if (autoGrow) resizeToContent();
22
+ });
23
+ const classes = ["vgui-textarea"];
24
+ if (resize === "none") classes.push("vgui-textarea--fixed");
25
+ if (autoGrow) classes.push("vgui-textarea--auto-grow");
26
+ if (mono) classes.push("vgui-textarea--mono");
27
+ if (invalid) classes.push("vgui-textarea--invalid");
28
+ if (className) classes.push(className);
29
+ const length = value !== void 0 ? String(value).length : uncontrolledLength;
30
+ const handleInput = (event) => {
31
+ if (value === void 0) setUncontrolledLength(event.currentTarget.value.length);
32
+ if (autoGrow) resizeToContent();
33
+ onInput?.(event);
34
+ };
35
+ return /* @__PURE__ */ jsxs("span", {
36
+ className: classes.join(" "),
37
+ children: [/* @__PURE__ */ jsx("textarea", {
38
+ ref: setRefs,
39
+ className: "vgui-textarea__field vgui-scroll-surface",
40
+ rows,
41
+ value,
42
+ defaultValue,
43
+ maxLength,
44
+ style: autoGrow ? {
45
+ ...style,
46
+ maxHeight
47
+ } : style,
48
+ onInput: handleInput,
49
+ ...rest
50
+ }), showCount ? /* @__PURE__ */ jsx("span", {
51
+ className: "vgui-textarea__count",
52
+ "aria-hidden": "true",
53
+ children: maxLength != null ? `${length} / ${maxLength}` : length
54
+ }) : null]
55
+ });
56
+ });
57
+ Textarea.displayName = "Textarea";
58
+ //#endregion
59
+ export { Textarea };
60
+
61
+ //# sourceMappingURL=Textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.js","names":[],"sources":["../../../src/components/Textarea/Textarea.tsx"],"sourcesContent":["import { forwardRef, useCallback, useLayoutEffect, useRef, useState } from 'react'\nimport type { InputEvent, TextareaHTMLAttributes } from 'react'\n\nimport './Textarea.css'\nimport '../../styles/scrollbars.css'\n\nexport interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'children'> {\n /** Visible rows. Sets `rows`; the 60px `min-height` still applies. */\n rows?: number\n /** Grow to fit content instead of scrolling, up to `maxHeight`. */\n autoGrow?: boolean\n /** Cap for `autoGrow`, in pixels. Defaults to 240. */\n maxHeight?: number\n /** Prevent the user from resizing the field. Defaults to `vertical`. */\n resize?: 'none' | 'vertical'\n /** Monospaced text, for console and config content. */\n mono?: boolean\n /** Show a live character count, expressed against `maxLength` when given. */\n showCount?: boolean\n /** Render the invalid border. Does not set aria-invalid. */\n invalid?: boolean\n}\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n {\n className,\n rows,\n autoGrow = false,\n maxHeight = 240,\n resize = 'vertical',\n mono = false,\n showCount = false,\n invalid = false,\n value,\n defaultValue,\n maxLength,\n onInput,\n style,\n ...rest\n },\n ref,\n) {\n const fieldRef = useRef<HTMLTextAreaElement>(null)\n const [uncontrolledLength, setUncontrolledLength] = useState(\n () => String(defaultValue ?? '').length,\n )\n\n const setRefs = useCallback(\n (node: HTMLTextAreaElement | null) => {\n fieldRef.current = node\n if (typeof ref === 'function') {\n ref(node)\n } else if (ref) {\n ref.current = node\n }\n },\n [ref],\n )\n\n const resizeToContent = useCallback(() => {\n const field = fieldRef.current\n if (!field) return\n // Mirror `scrollHeight`: it is only meaningful once the box is unconstrained.\n field.style.height = 'auto'\n field.style.height = `${Math.min(field.scrollHeight, maxHeight)}px`\n }, [maxHeight])\n\n // Runs after every render so a controlled value resizes the box too. An\n // uncontrolled field does not re-render, hence the `onInput` hook below.\n useLayoutEffect(() => {\n if (autoGrow) resizeToContent()\n })\n\n const classes = ['vgui-textarea']\n if (resize === 'none') classes.push('vgui-textarea--fixed')\n if (autoGrow) classes.push('vgui-textarea--auto-grow')\n if (mono) classes.push('vgui-textarea--mono')\n if (invalid) classes.push('vgui-textarea--invalid')\n if (className) classes.push(className)\n\n const length = value !== undefined ? String(value).length : uncontrolledLength\n\n const handleInput = (event: InputEvent<HTMLTextAreaElement>) => {\n if (value === undefined) setUncontrolledLength(event.currentTarget.value.length)\n if (autoGrow) resizeToContent()\n onInput?.(event)\n }\n\n return (\n <span className={classes.join(' ')}>\n <textarea\n ref={setRefs}\n className=\"vgui-textarea__field vgui-scroll-surface\"\n rows={rows}\n value={value}\n defaultValue={defaultValue}\n maxLength={maxLength}\n style={autoGrow ? { ...style, maxHeight } : style}\n onInput={handleInput}\n {...rest}\n />\n {showCount ? (\n <span className=\"vgui-textarea__count\" aria-hidden=\"true\">\n {maxLength != null ? `${length} / ${maxLength}` : length}\n </span>\n ) : null}\n </span>\n )\n})\n\nTextarea.displayName = 'Textarea'\n"],"mappings":";;;;;AAuBA,IAAa,WAAW,WAA+C,SAAS,SAC9E,EACE,WACA,MACA,WAAW,OACX,YAAY,KACZ,SAAS,YACT,OAAO,OACP,YAAY,OACZ,UAAU,OACV,OACA,cACA,WACA,SACA,OACA,GAAG,QAEL,KACA;CACA,MAAM,WAAW,OAA4B,IAAI;CACjD,MAAM,CAAC,oBAAoB,yBAAyB,eAC5C,OAAO,gBAAgB,EAAE,CAAC,CAAC,MACnC;CAEA,MAAM,UAAU,aACb,SAAqC;EACpC,SAAS,UAAU;EACnB,IAAI,OAAO,QAAQ,YACjB,IAAI,IAAI;OACH,IAAI,KACT,IAAI,UAAU;CAElB,GACA,CAAC,GAAG,CACN;CAEA,MAAM,kBAAkB,kBAAkB;EACxC,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,OAAO;EAEZ,MAAM,MAAM,SAAS;EACrB,MAAM,MAAM,SAAS,GAAG,KAAK,IAAI,MAAM,cAAc,SAAS,EAAE;CAClE,GAAG,CAAC,SAAS,CAAC;CAId,sBAAsB;EACpB,IAAI,UAAU,gBAAgB;CAChC,CAAC;CAED,MAAM,UAAU,CAAC,eAAe;CAChC,IAAI,WAAW,QAAQ,QAAQ,KAAK,sBAAsB;CAC1D,IAAI,UAAU,QAAQ,KAAK,0BAA0B;CACrD,IAAI,MAAM,QAAQ,KAAK,qBAAqB;CAC5C,IAAI,SAAS,QAAQ,KAAK,wBAAwB;CAClD,IAAI,WAAW,QAAQ,KAAK,SAAS;CAErC,MAAM,SAAS,UAAU,KAAA,IAAY,OAAO,KAAK,CAAC,CAAC,SAAS;CAE5D,MAAM,eAAe,UAA2C;EAC9D,IAAI,UAAU,KAAA,GAAW,sBAAsB,MAAM,cAAc,MAAM,MAAM;EAC/E,IAAI,UAAU,gBAAgB;EAC9B,UAAU,KAAK;CACjB;CAEA,OACE,qBAAC,QAAD;EAAM,WAAW,QAAQ,KAAK,GAAG;EAAjC,UAAA,CACE,oBAAC,YAAD;GACE,KAAK;GACL,WAAU;GACJ;GACC;GACO;GACH;GACX,OAAO,WAAW;IAAE,GAAG;IAAO;GAAU,IAAI;GAC5C,SAAS;GACT,GAAI;EACL,CAAA,GACA,YACC,oBAAC,QAAD;GAAM,WAAU;GAAuB,eAAY;GAChD,UAAA,aAAa,OAAO,GAAG,OAAO,KAAK,cAAc;EAC9C,CAAA,IACJ,IACA;;AAEV,CAAC;AAED,SAAS,cAAc"}
@@ -0,0 +1,3 @@
1
+ export { Textarea } from './Textarea';
2
+ export type { TextareaProps } from './Textarea';
3
+ //# sourceMappingURL=index.d.ts.map