@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,429 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import "../../styles/scrollbars.css";
4
+ import "./Table.css";
5
+ //#region src/components/Table/Table.tsx
6
+ /** No column widths exist in the corpus, so an unresized flex column still
7
+ * needs a number: `aria-valuenow` has to report something. */
8
+ var FALLBACK_COLUMN_WIDTH = 120;
9
+ /** WCAG 2.5.8 again — a column narrower than this cannot be grabbed. */
10
+ var MIN_COLUMN_WIDTH = 24;
11
+ /** One arrow keypress on the dragger; a round number inside the 2/4/8 scale. */
12
+ var RESIZE_STEP = 8;
13
+ /** How long a run of typed characters keeps building a typeahead query. */
14
+ var TYPEAHEAD_RESET_MS = 600;
15
+ function toIdArray(value) {
16
+ if (value === void 0) return [];
17
+ return Array.isArray(value) ? value.slice() : [value];
18
+ }
19
+ function clamp(value, min, max) {
20
+ return Math.min(Math.max(value, min), max);
21
+ }
22
+ function toSortKey(value) {
23
+ return typeof value === "string" || typeof value === "number" ? value : "";
24
+ }
25
+ function compare(a, b) {
26
+ if (typeof a === "number" && typeof b === "number") {
27
+ if (Number.isNaN(a) || Number.isNaN(b)) return 0;
28
+ return a - b;
29
+ }
30
+ return String(a).localeCompare(String(b));
31
+ }
32
+ function Table(props) {
33
+ const { className, columns, rows, rowId, selected, defaultSelected, multi = false, onSelectedChange, sort, onSortChange, resizable = false, onColumnResize, headerUppercase = false, stickyHeader = false, emptyMessage = "No rows.", busy = false, style, "aria-label": ariaLabel, ...rest } = props;
34
+ const [uncontrolledSelected, setUncontrolledSelected] = useState(() => toIdArray(defaultSelected));
35
+ const [uncontrolledSort, setUncontrolledSort] = useState(null);
36
+ const [widths, setWidths] = useState({});
37
+ const [activeId, setActiveId] = useState(null);
38
+ const [headerIndex, setHeaderIndex] = useState(0);
39
+ const rowRefs = useRef(/* @__PURE__ */ new Map());
40
+ const headerRefs = useRef(/* @__PURE__ */ new Map());
41
+ const typeaheadRef = useRef({
42
+ query: "",
43
+ timer: null
44
+ });
45
+ /**
46
+ * Shift+click anchors on the row that was active when the range started. It
47
+ * lives in a ref because a pointer press moves DOM focus before the click
48
+ * lands, which would otherwise overwrite the anchor with the clicked row.
49
+ */
50
+ const anchorRef = useRef(null);
51
+ const activeSort = sort === void 0 ? uncontrolledSort : sort;
52
+ const selectedIds = selected === void 0 ? uncontrolledSelected : toIdArray(selected);
53
+ const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds]);
54
+ const orderedRows = useMemo(() => {
55
+ const column = activeSort ? columns.find((entry) => entry.id === activeSort.columnId) : void 0;
56
+ if (!activeSort || !column) return rows;
57
+ const valueOf = column.sortValue ?? ((row) => toSortKey(column.cell(row)));
58
+ const direction = activeSort.direction === "asc" ? 1 : -1;
59
+ return rows.slice().sort((a, b) => compare(valueOf(a), valueOf(b)) * direction);
60
+ }, [
61
+ activeSort,
62
+ columns,
63
+ rows
64
+ ]);
65
+ const ids = useMemo(() => orderedRows.map((row) => rowId(row)), [orderedRows, rowId]);
66
+ const isEmpty = ids.length === 0;
67
+ const sortableColumns = useMemo(() => columns.filter((column) => column.sortable), [columns]);
68
+ const activeHeader = sortableColumns.length === 0 ? -1 : clamp(headerIndex, 0, sortableColumns.length - 1);
69
+ const fallbackActiveId = ids.find((id) => selectedSet.has(id)) ?? ids[0] ?? null;
70
+ const activeRowId = activeId !== null && ids.includes(activeId) ? activeId : fallbackActiveId;
71
+ useEffect(() => {
72
+ const typeahead = typeaheadRef.current;
73
+ return () => {
74
+ if (typeahead.timer !== null) clearTimeout(typeahead.timer);
75
+ };
76
+ }, []);
77
+ const setRowRef = useCallback((id, node) => {
78
+ if (node) rowRefs.current.set(id, node);
79
+ else rowRefs.current.delete(id);
80
+ }, []);
81
+ const textOf = useCallback((id) => (rowRefs.current.get(id)?.textContent ?? "").trim(), []);
82
+ const commit = useCallback((next) => {
83
+ if (selected === void 0) setUncontrolledSelected(next);
84
+ onSelectedChange?.(multi ? next : next[0] ?? "");
85
+ }, [
86
+ multi,
87
+ onSelectedChange,
88
+ selected
89
+ ]);
90
+ const focusRow = useCallback((id) => {
91
+ setActiveId(id);
92
+ anchorRef.current = id;
93
+ const node = rowRefs.current.get(id);
94
+ if (!node) return;
95
+ /**
96
+ * jsdom has no layout engine, so `scrollIntoView` may be a stub or missing
97
+ * entirely; the active row is still the active row without it.
98
+ */
99
+ if (typeof node.scrollIntoView === "function") node.scrollIntoView({ block: "nearest" });
100
+ node.focus();
101
+ }, []);
102
+ const moveActive = useCallback((step) => {
103
+ if (ids.length === 0) return;
104
+ const current = activeRowId === null ? -1 : ids.indexOf(activeRowId);
105
+ const next = step === "first" ? 0 : step === "last" ? ids.length - 1 : clamp((current < 0 ? 0 : current) + step, 0, ids.length - 1);
106
+ focusRow(ids[next]);
107
+ }, [
108
+ activeRowId,
109
+ focusRow,
110
+ ids
111
+ ]);
112
+ const selectRow = useCallback((id, mode) => {
113
+ const anchor = anchorRef.current ?? activeRowId;
114
+ let next;
115
+ if (mode === "range" && anchor !== null && anchor !== id) {
116
+ const from = ids.indexOf(anchor);
117
+ const to = ids.indexOf(id);
118
+ next = ids.slice(Math.min(from, to), Math.max(from, to) + 1);
119
+ } else if (mode === "range" || mode === "replace") next = [id];
120
+ else next = selectedSet.has(id) ? selectedIds.filter((entry) => entry !== id) : [...selectedIds, id];
121
+ if (mode !== "range") anchorRef.current = id;
122
+ commit(next);
123
+ }, [
124
+ activeRowId,
125
+ commit,
126
+ ids,
127
+ selectedIds,
128
+ selectedSet
129
+ ]);
130
+ const activate = useCallback((id) => {
131
+ selectRow(id, multi ? "toggle" : "replace");
132
+ }, [multi, selectRow]);
133
+ const typeahead = useCallback((character) => {
134
+ const state = typeaheadRef.current;
135
+ const buffer = (state.query + character).toLowerCase();
136
+ state.query = buffer;
137
+ if (state.timer !== null) clearTimeout(state.timer);
138
+ state.timer = setTimeout(() => {
139
+ state.query = "";
140
+ }, TYPEAHEAD_RESET_MS);
141
+ if (ids.length === 0) return;
142
+ const start = activeRowId === null ? -1 : ids.indexOf(activeRowId);
143
+ for (let offset = 1; offset <= ids.length; offset += 1) {
144
+ const id = ids[(start + offset + ids.length) % ids.length];
145
+ if (textOf(id).toLowerCase().startsWith(buffer)) {
146
+ focusRow(id);
147
+ return;
148
+ }
149
+ }
150
+ }, [
151
+ activeRowId,
152
+ focusRow,
153
+ ids,
154
+ textOf
155
+ ]);
156
+ const handleRowKeyDown = useCallback((event) => {
157
+ const { key } = event;
158
+ if (key === "ArrowDown") {
159
+ event.preventDefault();
160
+ moveActive(1);
161
+ return;
162
+ }
163
+ if (key === "ArrowUp") {
164
+ event.preventDefault();
165
+ if (activeRowId === ids[0] && sortableColumns.length > 0) {
166
+ const header = sortableColumns[activeHeader];
167
+ if (header) headerRefs.current.get(header.id)?.focus();
168
+ return;
169
+ }
170
+ moveActive(-1);
171
+ return;
172
+ }
173
+ if (key === "Home" || key === "End") {
174
+ event.preventDefault();
175
+ moveActive(key === "Home" ? "first" : "last");
176
+ return;
177
+ }
178
+ if (key === "Enter" || key === " ") {
179
+ event.preventDefault();
180
+ if (activeRowId !== null) activate(activeRowId);
181
+ return;
182
+ }
183
+ if (key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) typeahead(key);
184
+ }, [
185
+ activate,
186
+ activeHeader,
187
+ activeRowId,
188
+ ids,
189
+ moveActive,
190
+ sortableColumns,
191
+ typeahead
192
+ ]);
193
+ const handleRowClick = useCallback((event, id) => {
194
+ setActiveId(id);
195
+ if (!multi) {
196
+ selectRow(id, "replace");
197
+ return;
198
+ }
199
+ if (event.shiftKey) {
200
+ selectRow(id, "range");
201
+ return;
202
+ }
203
+ selectRow(id, event.ctrlKey || event.metaKey ? "toggle" : "replace");
204
+ }, [multi, selectRow]);
205
+ const cycleSort = useCallback((columnId) => {
206
+ const next = {
207
+ columnId,
208
+ direction: activeSort?.columnId === columnId && activeSort.direction === "asc" ? "desc" : "asc"
209
+ };
210
+ if (sort === void 0) setUncontrolledSort(next);
211
+ onSortChange?.(next);
212
+ }, [
213
+ activeSort,
214
+ onSortChange,
215
+ sort
216
+ ]);
217
+ const focusHeader = useCallback((index) => {
218
+ if (sortableColumns.length === 0) return;
219
+ const next = clamp(index, 0, sortableColumns.length - 1);
220
+ setHeaderIndex(next);
221
+ headerRefs.current.get(sortableColumns[next].id)?.focus();
222
+ }, [sortableColumns]);
223
+ const handleHeaderKeyDown = useCallback((event, index) => {
224
+ const { key } = event;
225
+ if (key === "ArrowRight") {
226
+ event.preventDefault();
227
+ focusHeader(index + 1);
228
+ return;
229
+ }
230
+ if (key === "ArrowLeft") {
231
+ event.preventDefault();
232
+ focusHeader(index - 1);
233
+ return;
234
+ }
235
+ if (key === "Home" || key === "End") {
236
+ event.preventDefault();
237
+ focusHeader(key === "Home" ? 0 : sortableColumns.length - 1);
238
+ return;
239
+ }
240
+ if (key === "ArrowDown") {
241
+ event.preventDefault();
242
+ if (ids[0] !== void 0) focusRow(ids[0]);
243
+ }
244
+ }, [
245
+ focusHeader,
246
+ focusRow,
247
+ ids,
248
+ sortableColumns.length
249
+ ]);
250
+ const widthOf = useCallback((column) => widths[column.id] ?? column.defaultWidth ?? column.width, [widths]);
251
+ const applyWidth = useCallback((columnId, width) => {
252
+ const next = Number.isFinite(width) ? Math.max(MIN_COLUMN_WIDTH, Math.round(width)) : MIN_COLUMN_WIDTH;
253
+ setWidths((previous) => ({
254
+ ...previous,
255
+ [columnId]: next
256
+ }));
257
+ return next;
258
+ }, []);
259
+ const handleDraggerKeyDown = useCallback((event, column) => {
260
+ if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
261
+ event.preventDefault();
262
+ const current = widthOf(column) ?? FALLBACK_COLUMN_WIDTH;
263
+ const step = event.key === "ArrowLeft" ? -8 : RESIZE_STEP;
264
+ const next = applyWidth(column.id, current + step);
265
+ onColumnResize?.(column.id, next);
266
+ }, [
267
+ applyWidth,
268
+ onColumnResize,
269
+ widthOf
270
+ ]);
271
+ const [dragging, setDragging] = useState(false);
272
+ const dragRef = useRef(null);
273
+ const handleDraggerPointerDown = useCallback((event, column) => {
274
+ const startWidth = widthOf(column) ?? FALLBACK_COLUMN_WIDTH;
275
+ dragRef.current = {
276
+ columnId: column.id,
277
+ startX: event.clientX,
278
+ startWidth,
279
+ width: startWidth
280
+ };
281
+ setDragging(true);
282
+ }, [widthOf]);
283
+ useEffect(() => {
284
+ if (!dragging) return;
285
+ const handleMove = (event) => {
286
+ const drag = dragRef.current;
287
+ if (!drag || !Number.isFinite(event.clientX) || !Number.isFinite(event.clientY)) return;
288
+ drag.width = applyWidth(drag.columnId, drag.startWidth + (event.clientX - drag.startX));
289
+ };
290
+ const handleUp = () => {
291
+ const drag = dragRef.current;
292
+ dragRef.current = null;
293
+ setDragging(false);
294
+ if (drag) onColumnResize?.(drag.columnId, drag.width);
295
+ };
296
+ window.addEventListener("pointermove", handleMove);
297
+ window.addEventListener("pointerup", handleUp);
298
+ window.addEventListener("pointercancel", handleUp);
299
+ return () => {
300
+ window.removeEventListener("pointermove", handleMove);
301
+ window.removeEventListener("pointerup", handleUp);
302
+ window.removeEventListener("pointercancel", handleUp);
303
+ };
304
+ }, [
305
+ applyWidth,
306
+ dragging,
307
+ onColumnResize
308
+ ]);
309
+ const columnStyle = useCallback((column) => {
310
+ const width = widthOf(column);
311
+ return width === void 0 ? {
312
+ flex: "1 1 auto",
313
+ minWidth: 0
314
+ } : {
315
+ flex: `0 0 ${width}px`,
316
+ width
317
+ };
318
+ }, [widthOf]);
319
+ const gridClassName = [
320
+ "vgui-table",
321
+ headerUppercase ? "vgui-table--header-uppercase" : null,
322
+ resizable ? "vgui-table--resizable" : null,
323
+ stickyHeader ? "vgui-table--sticky" : null,
324
+ dragging ? "vgui-table--dragging" : null,
325
+ className ?? null
326
+ ].filter(Boolean).join(" ");
327
+ return /* @__PURE__ */ jsxs("div", {
328
+ ...rest,
329
+ className: gridClassName,
330
+ style,
331
+ role: "grid",
332
+ "aria-label": ariaLabel,
333
+ "aria-colcount": columns.length,
334
+ "aria-rowcount": ids.length,
335
+ "aria-multiselectable": multi ? true : void 0,
336
+ "aria-busy": busy || void 0,
337
+ children: [/* @__PURE__ */ jsx("div", {
338
+ className: "vgui-table__head",
339
+ role: "row",
340
+ children: columns.map((column, index) => {
341
+ const sorted = activeSort?.columnId === column.id;
342
+ const sortableIndex = sortableColumns.indexOf(column);
343
+ const label = /* @__PURE__ */ jsxs("span", {
344
+ className: "vgui-table__th-label",
345
+ children: [column.headerIcon ? /* @__PURE__ */ jsx("span", {
346
+ className: "vgui-table__th-icon",
347
+ "aria-hidden": "true",
348
+ children: column.headerIcon
349
+ }) : null, column.header]
350
+ });
351
+ return /* @__PURE__ */ jsxs("div", {
352
+ className: "vgui-table__th",
353
+ role: "columnheader",
354
+ "aria-colindex": index + 1,
355
+ "aria-sort": sorted ? activeSort?.direction === "asc" ? "ascending" : "descending" : void 0,
356
+ "data-align": column.align ?? "start",
357
+ style: columnStyle(column),
358
+ children: [column.sortable ? /* @__PURE__ */ jsxs("button", {
359
+ type: "button",
360
+ className: "vgui-table__sort",
361
+ ref: (node) => {
362
+ if (node) headerRefs.current.set(column.id, node);
363
+ else headerRefs.current.delete(column.id);
364
+ },
365
+ tabIndex: sortableIndex === activeHeader ? 0 : -1,
366
+ onClick: () => cycleSort(column.id),
367
+ onKeyDown: (event) => handleHeaderKeyDown(event, sortableIndex),
368
+ children: [label, /* @__PURE__ */ jsx("span", {
369
+ className: "vgui-table__sort-indicator",
370
+ "data-direction": sorted ? activeSort?.direction : "none",
371
+ "aria-hidden": "true"
372
+ })]
373
+ }) : label, resizable ? /* @__PURE__ */ jsx("div", {
374
+ className: "vgui-table__dragger",
375
+ role: "separator",
376
+ "aria-orientation": "vertical",
377
+ "aria-label": `Resize ${column.header} column`,
378
+ "aria-valuemin": MIN_COLUMN_WIDTH,
379
+ "aria-valuenow": widthOf(column) ?? FALLBACK_COLUMN_WIDTH,
380
+ tabIndex: 0,
381
+ onPointerDown: (event) => handleDraggerPointerDown(event, column),
382
+ onKeyDown: (event) => handleDraggerKeyDown(event, column)
383
+ }) : null]
384
+ }, column.id);
385
+ })
386
+ }), /* @__PURE__ */ jsx("div", {
387
+ className: "vgui-table__body vgui-scroll-surface",
388
+ role: "rowgroup",
389
+ children: isEmpty ? /* @__PURE__ */ jsx("div", {
390
+ className: "vgui-table__row vgui-table__row--empty",
391
+ role: "row",
392
+ children: /* @__PURE__ */ jsx("div", {
393
+ className: "vgui-table__cell vgui-table__empty",
394
+ role: "gridcell",
395
+ "aria-colindex": 1,
396
+ "aria-colspan": columns.length,
397
+ "aria-live": "polite",
398
+ children: emptyMessage
399
+ })
400
+ }) : orderedRows.map((row, index) => {
401
+ const id = rowId(row);
402
+ const isSelected = selectedSet.has(id);
403
+ return /* @__PURE__ */ jsx("div", {
404
+ ref: (node) => setRowRef(id, node),
405
+ className: ["vgui-table__row", isSelected ? "vgui-table__row--selected" : null].filter(Boolean).join(" "),
406
+ role: "row",
407
+ "aria-rowindex": index + 1,
408
+ "aria-selected": isSelected,
409
+ tabIndex: id === activeRowId ? 0 : -1,
410
+ onClick: (event) => handleRowClick(event, id),
411
+ onFocus: () => setActiveId(id),
412
+ onKeyDown: handleRowKeyDown,
413
+ children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx("div", {
414
+ className: "vgui-table__cell",
415
+ role: "gridcell",
416
+ "aria-colindex": columnIndex + 1,
417
+ "data-align": column.align ?? "start",
418
+ style: columnStyle(column),
419
+ children: column.cell(row)
420
+ }, column.id))
421
+ }, id);
422
+ })
423
+ })]
424
+ });
425
+ }
426
+ //#endregion
427
+ export { Table };
428
+
429
+ //# sourceMappingURL=Table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Table.js","names":[],"sources":["../../../src/components/Table/Table.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type {\n CSSProperties,\n HTMLAttributes,\n KeyboardEvent as ReactKeyboardEvent,\n MouseEvent as ReactMouseEvent,\n PointerEvent as ReactPointerEvent,\n ReactNode,\n} from 'react'\n\nimport './Table.css'\nimport '../../styles/scrollbars.css'\n\nexport interface TableSort {\n /** Column the rows are ordered by. */\n columnId: string\n /** Ordering direction. */\n direction: 'asc' | 'desc'\n}\n\nexport interface TableColumn<Row> {\n /** Stable identity; also the aria-colindex key. */\n id: string\n /** Header label. */\n header: string\n /** Cell renderer for a row. */\n cell: (row: Row) => ReactNode\n /** Fixed width in pixels; omit to flex. */\n width?: number\n /** Initial width when resizable and uncontrolled. */\n defaultWidth?: number\n /**\n * Value the rows are ordered by. Falls back to the rendered text when the\n * cell produces a string or a number, and to nothing otherwise — a cell\n * holding markup has no order the component could guess.\n */\n sortValue?: (row: Row) => string | number\n /** Makes the header a sort button for this column. */\n sortable?: boolean\n /** Header alignment; VGUI headers are left-aligned. */\n align?: 'start' | 'center' | 'end'\n /** Optional header glyph, e.g. the VAC shield. */\n headerIcon?: ReactNode\n}\n\nexport interface TableProps<Row> extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Column definitions, in display order. */\n columns: TableColumn<Row>[]\n /** Row data. */\n rows: Row[]\n /** Returns the stable id used for selection and React keys. */\n rowId: (row: Row) => string\n /** Controlled selection. Use `string[]` when `multi` is set. */\n selected?: string | string[]\n /** Initial selection when uncontrolled. */\n defaultSelected?: string | string[]\n /** Allows Ctrl/Shift multi-selection. */\n multi?: boolean\n /** Called with the new selection. */\n onSelectedChange?: (ids: string | string[]) => void\n /** Controlled sort. */\n sort?: TableSort\n /** Called when a sortable header is activated. */\n onSortChange?: (sort: TableSort) => void\n /** Allows column resizing with a visible dragger. */\n resizable?: boolean\n /** Called with the new width after a resize gesture ends. */\n onColumnResize?: (columnId: string, width: number) => void\n /** Renders headers in uppercase, as the main client window does. */\n headerUppercase?: boolean\n /** Sticky header. No corpus precedent; see Open questions. */\n stickyHeader?: boolean\n /** Message shown in the grid's single row when there are no rows. */\n emptyMessage?: string\n /** Sets `aria-busy` on the grid while a refresh is in flight. */\n busy?: boolean\n}\n\n/** No column widths exist in the corpus, so an unresized flex column still\n * needs a number: `aria-valuenow` has to report something. */\nconst FALLBACK_COLUMN_WIDTH = 120\n\n/** WCAG 2.5.8 again — a column narrower than this cannot be grabbed. */\nconst MIN_COLUMN_WIDTH = 24\n\n/** One arrow keypress on the dragger; a round number inside the 2/4/8 scale. */\nconst RESIZE_STEP = 8\n\n/** How long a run of typed characters keeps building a typeahead query. */\nconst TYPEAHEAD_RESET_MS = 600\n\nfunction toIdArray(value: string | string[] | undefined): string[] {\n if (value === undefined) return []\n return Array.isArray(value) ? value.slice() : [value]\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max)\n}\n\nfunction toSortKey(value: ReactNode): string | number {\n return typeof value === 'string' || typeof value === 'number' ? value : ''\n}\n\nfunction compare(a: string | number, b: string | number): number {\n if (typeof a === 'number' && typeof b === 'number') {\n // A NaN from either side would make the comparator non-transitive.\n if (Number.isNaN(a) || Number.isNaN(b)) return 0\n return a - b\n }\n return String(a).localeCompare(String(b))\n}\n\nexport function Table<Row>(props: TableProps<Row>) {\n const {\n className,\n columns,\n rows,\n rowId,\n selected,\n defaultSelected,\n multi = false,\n onSelectedChange,\n sort,\n onSortChange,\n resizable = false,\n onColumnResize,\n headerUppercase = false,\n stickyHeader = false,\n emptyMessage = 'No rows.',\n busy = false,\n style,\n 'aria-label': ariaLabel,\n ...rest\n } = props\n\n const [uncontrolledSelected, setUncontrolledSelected] = useState<string[]>(() =>\n toIdArray(defaultSelected),\n )\n const [uncontrolledSort, setUncontrolledSort] = useState<TableSort | null>(null)\n const [widths, setWidths] = useState<Record<string, number>>({})\n const [activeId, setActiveId] = useState<string | null>(null)\n const [headerIndex, setHeaderIndex] = useState(0)\n\n const rowRefs = useRef(new Map<string, HTMLDivElement>())\n const headerRefs = useRef(new Map<string, HTMLButtonElement>())\n const typeaheadRef = useRef<{ query: string; timer: ReturnType<typeof setTimeout> | null }>({\n query: '',\n timer: null,\n })\n /**\n * Shift+click anchors on the row that was active when the range started. It\n * lives in a ref because a pointer press moves DOM focus before the click\n * lands, which would otherwise overwrite the anchor with the clicked row.\n */\n const anchorRef = useRef<string | null>(null)\n\n const activeSort = sort === undefined ? uncontrolledSort : sort\n const selectedIds = selected === undefined ? uncontrolledSelected : toIdArray(selected)\n const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds])\n\n // Sorting is applied here rather than by the caller so a controlled `sort`\n // still reorders the rows; `sortValue` is the only way to order markup cells.\n const orderedRows = useMemo(() => {\n const column = activeSort ? columns.find((entry) => entry.id === activeSort.columnId) : undefined\n if (!activeSort || !column) return rows\n\n const valueOf = column.sortValue ?? ((row: Row) => toSortKey(column.cell(row)))\n const direction = activeSort.direction === 'asc' ? 1 : -1\n // `Array.prototype.sort` is stable, so rows that compare equal keep their\n // original order instead of shuffling on every render.\n return rows.slice().sort((a, b) => compare(valueOf(a), valueOf(b)) * direction)\n }, [activeSort, columns, rows])\n\n const ids = useMemo(() => orderedRows.map((row) => rowId(row)), [orderedRows, rowId])\n const isEmpty = ids.length === 0\n\n const sortableColumns = useMemo(() => columns.filter((column) => column.sortable), [columns])\n const activeHeader = sortableColumns.length === 0 ? -1 : clamp(headerIndex, 0, sortableColumns.length - 1)\n\n const fallbackActiveId = ids.find((id) => selectedSet.has(id)) ?? ids[0] ?? null\n const activeRowId = activeId !== null && ids.includes(activeId) ? activeId : fallbackActiveId\n\n useEffect(() => {\n const typeahead = typeaheadRef.current\n return () => {\n if (typeahead.timer !== null) clearTimeout(typeahead.timer)\n }\n }, [])\n\n const setRowRef = useCallback((id: string, node: HTMLDivElement | null) => {\n if (node) rowRefs.current.set(id, node)\n else rowRefs.current.delete(id)\n }, [])\n\n const textOf = useCallback((id: string) => (rowRefs.current.get(id)?.textContent ?? '').trim(), [])\n\n const commit = useCallback(\n (next: string[]) => {\n if (selected === undefined) setUncontrolledSelected(next)\n onSelectedChange?.(multi ? next : (next[0] ?? ''))\n },\n [multi, onSelectedChange, selected],\n )\n\n const focusRow = useCallback((id: string) => {\n setActiveId(id)\n anchorRef.current = id\n const node = rowRefs.current.get(id)\n if (!node) return\n /**\n * jsdom has no layout engine, so `scrollIntoView` may be a stub or missing\n * entirely; the active row is still the active row without it.\n */\n if (typeof node.scrollIntoView === 'function') node.scrollIntoView({ block: 'nearest' })\n node.focus()\n }, [])\n\n const moveActive = useCallback(\n (step: number | 'first' | 'last') => {\n if (ids.length === 0) return\n const current = activeRowId === null ? -1 : ids.indexOf(activeRowId)\n const base = current < 0 ? 0 : current\n const next =\n step === 'first' ? 0 : step === 'last' ? ids.length - 1 : clamp(base + step, 0, ids.length - 1)\n focusRow(ids[next])\n },\n [activeRowId, focusRow, ids],\n )\n\n const selectRow = useCallback(\n (id: string, mode: 'replace' | 'toggle' | 'range') => {\n const anchor = anchorRef.current ?? activeRowId\n let next: string[]\n\n if (mode === 'range' && anchor !== null && anchor !== id) {\n const from = ids.indexOf(anchor)\n const to = ids.indexOf(id)\n next = ids.slice(Math.min(from, to), Math.max(from, to) + 1)\n } else if (mode === 'range' || mode === 'replace') {\n next = [id]\n } else {\n next = selectedSet.has(id)\n ? selectedIds.filter((entry) => entry !== id)\n : [...selectedIds, id]\n }\n\n // A range keeps its original anchor; every other gesture moves it.\n if (mode !== 'range') anchorRef.current = id\n commit(next)\n },\n [activeRowId, commit, ids, selectedIds, selectedSet],\n )\n\n const activate = useCallback(\n (id: string) => {\n selectRow(id, multi ? 'toggle' : 'replace')\n },\n [multi, selectRow],\n )\n\n const typeahead = useCallback(\n (character: string) => {\n const state = typeaheadRef.current\n const buffer = (state.query + character).toLowerCase()\n state.query = buffer\n if (state.timer !== null) clearTimeout(state.timer)\n state.timer = setTimeout(() => {\n state.query = ''\n }, TYPEAHEAD_RESET_MS)\n\n if (ids.length === 0) return\n const start = activeRowId === null ? -1 : ids.indexOf(activeRowId)\n for (let offset = 1; offset <= ids.length; offset += 1) {\n const id = ids[(start + offset + ids.length) % ids.length]\n if (textOf(id).toLowerCase().startsWith(buffer)) {\n focusRow(id)\n return\n }\n }\n },\n [activeRowId, focusRow, ids, textOf],\n )\n\n const handleRowKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLDivElement>) => {\n const { key } = event\n\n if (key === 'ArrowDown') {\n event.preventDefault()\n moveActive(1)\n return\n }\n\n if (key === 'ArrowUp') {\n event.preventDefault()\n // The first row hands focus back to the sortable header strip, which is\n // the grid's single tab stop, so the grid is not a keyboard dead end.\n if (activeRowId === ids[0] && sortableColumns.length > 0) {\n const header = sortableColumns[activeHeader]\n if (header) headerRefs.current.get(header.id)?.focus()\n return\n }\n moveActive(-1)\n return\n }\n\n if (key === 'Home' || key === 'End') {\n event.preventDefault()\n moveActive(key === 'Home' ? 'first' : 'last')\n return\n }\n\n if (key === 'Enter' || key === ' ') {\n event.preventDefault()\n if (activeRowId !== null) activate(activeRowId)\n return\n }\n\n if (key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {\n typeahead(key)\n }\n },\n [activate, activeHeader, activeRowId, ids, moveActive, sortableColumns, typeahead],\n )\n\n const handleRowClick = useCallback(\n (event: ReactMouseEvent<HTMLDivElement>, id: string) => {\n setActiveId(id)\n\n if (!multi) {\n selectRow(id, 'replace')\n return\n }\n if (event.shiftKey) {\n selectRow(id, 'range')\n return\n }\n selectRow(id, event.ctrlKey || event.metaKey ? 'toggle' : 'replace')\n },\n [multi, selectRow],\n )\n\n const cycleSort = useCallback(\n (columnId: string) => {\n // `TableSort` carries no third value, so the cycle is asc → desc → asc.\n // A caller that wants the sorted state cleared passes `sort={undefined}`.\n const direction = activeSort?.columnId === columnId && activeSort.direction === 'asc' ? 'desc' : 'asc'\n const next: TableSort = { columnId, direction }\n if (sort === undefined) setUncontrolledSort(next)\n onSortChange?.(next)\n },\n [activeSort, onSortChange, sort],\n )\n\n const focusHeader = useCallback(\n (index: number) => {\n if (sortableColumns.length === 0) return\n const next = clamp(index, 0, sortableColumns.length - 1)\n setHeaderIndex(next)\n headerRefs.current.get(sortableColumns[next].id)?.focus()\n },\n [sortableColumns],\n )\n\n const handleHeaderKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLButtonElement>, index: number) => {\n const { key } = event\n\n if (key === 'ArrowRight') {\n event.preventDefault()\n focusHeader(index + 1)\n return\n }\n if (key === 'ArrowLeft') {\n event.preventDefault()\n focusHeader(index - 1)\n return\n }\n if (key === 'Home' || key === 'End') {\n event.preventDefault()\n focusHeader(key === 'Home' ? 0 : sortableColumns.length - 1)\n return\n }\n // The single tab stop lands on the header strip, so the rows sit one\n // ArrowDown away and the grid is reachable in both directions.\n if (key === 'ArrowDown') {\n event.preventDefault()\n if (ids[0] !== undefined) focusRow(ids[0])\n }\n },\n [focusHeader, focusRow, ids, sortableColumns.length],\n )\n\n const widthOf = useCallback(\n (column: TableColumn<Row>) => widths[column.id] ?? column.defaultWidth ?? column.width,\n [widths],\n )\n\n const applyWidth = useCallback((columnId: string, width: number) => {\n const next = Number.isFinite(width) ? Math.max(MIN_COLUMN_WIDTH, Math.round(width)) : MIN_COLUMN_WIDTH\n setWidths((previous) => ({ ...previous, [columnId]: next }))\n return next\n }, [])\n\n const handleDraggerKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLDivElement>, column: TableColumn<Row>) => {\n if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return\n event.preventDefault()\n const current = widthOf(column) ?? FALLBACK_COLUMN_WIDTH\n const step = event.key === 'ArrowLeft' ? -RESIZE_STEP : RESIZE_STEP\n const next = applyWidth(column.id, current + step)\n onColumnResize?.(column.id, next)\n },\n [applyWidth, onColumnResize, widthOf],\n )\n\n const [dragging, setDragging] = useState(false)\n const dragRef = useRef<{ columnId: string; startX: number; startWidth: number; width: number } | null>(\n null,\n )\n\n const handleDraggerPointerDown = useCallback(\n (event: ReactPointerEvent<HTMLDivElement>, column: TableColumn<Row>) => {\n const startWidth = widthOf(column) ?? FALLBACK_COLUMN_WIDTH\n dragRef.current = { columnId: column.id, startX: event.clientX, startWidth, width: startWidth }\n setDragging(true)\n },\n [widthOf],\n )\n\n useEffect(() => {\n if (!dragging) return\n\n const handleMove = (event: PointerEvent) => {\n const drag = dragRef.current\n // jsdom reports no coordinates at all, so a synthetic drag is a no-op\n // rather than a resize to NaN.\n if (!drag || !Number.isFinite(event.clientX) || !Number.isFinite(event.clientY)) return\n drag.width = applyWidth(drag.columnId, drag.startWidth + (event.clientX - drag.startX))\n }\n\n const handleUp = () => {\n const drag = dragRef.current\n dragRef.current = null\n setDragging(false)\n if (drag) onColumnResize?.(drag.columnId, drag.width)\n }\n\n window.addEventListener('pointermove', handleMove)\n window.addEventListener('pointerup', handleUp)\n window.addEventListener('pointercancel', handleUp)\n return () => {\n window.removeEventListener('pointermove', handleMove)\n window.removeEventListener('pointerup', handleUp)\n window.removeEventListener('pointercancel', handleUp)\n }\n }, [applyWidth, dragging, onColumnResize])\n\n const columnStyle = useCallback(\n (column: TableColumn<Row>): CSSProperties => {\n const width = widthOf(column)\n return width === undefined\n ? { flex: '1 1 auto', minWidth: 0 }\n : { flex: `0 0 ${width}px`, width }\n },\n [widthOf],\n )\n\n const gridClassName = [\n 'vgui-table',\n headerUppercase ? 'vgui-table--header-uppercase' : null,\n resizable ? 'vgui-table--resizable' : null,\n stickyHeader ? 'vgui-table--sticky' : null,\n dragging ? 'vgui-table--dragging' : null,\n className ?? null,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div\n {...rest}\n className={gridClassName}\n style={style}\n role=\"grid\"\n aria-label={ariaLabel}\n aria-colcount={columns.length}\n aria-rowcount={ids.length}\n aria-multiselectable={multi ? true : undefined}\n aria-busy={busy || undefined}\n >\n <div className=\"vgui-table__head\" role=\"row\">\n {columns.map((column, index) => {\n const sorted = activeSort?.columnId === column.id\n const sortableIndex = sortableColumns.indexOf(column)\n const label = (\n <span className=\"vgui-table__th-label\">\n {column.headerIcon ? (\n <span className=\"vgui-table__th-icon\" aria-hidden=\"true\">\n {column.headerIcon}\n </span>\n ) : null}\n {column.header}\n </span>\n )\n\n return (\n <div\n key={column.id}\n className=\"vgui-table__th\"\n role=\"columnheader\"\n aria-colindex={index + 1}\n // `none` is never emitted: an unsorted header carries no state at\n // all, so `aria-sort` is absent rather than falsely neutral.\n aria-sort={sorted ? (activeSort?.direction === 'asc' ? 'ascending' : 'descending') : undefined}\n data-align={column.align ?? 'start'}\n style={columnStyle(column)}\n >\n {column.sortable ? (\n <button\n type=\"button\"\n className=\"vgui-table__sort\"\n ref={(node) => {\n if (node) headerRefs.current.set(column.id, node)\n else headerRefs.current.delete(column.id)\n }}\n tabIndex={sortableIndex === activeHeader ? 0 : -1}\n onClick={() => cycleSort(column.id)}\n onKeyDown={(event) => handleHeaderKeyDown(event, sortableIndex)}\n >\n {label}\n <span\n className=\"vgui-table__sort-indicator\"\n data-direction={sorted ? activeSort?.direction : 'none'}\n aria-hidden=\"true\"\n />\n </button>\n ) : (\n label\n )}\n {resizable ? (\n <div\n className=\"vgui-table__dragger\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={`Resize ${column.header} column`}\n aria-valuemin={MIN_COLUMN_WIDTH}\n aria-valuenow={widthOf(column) ?? FALLBACK_COLUMN_WIDTH}\n tabIndex={0}\n onPointerDown={(event) => handleDraggerPointerDown(event, column)}\n onKeyDown={(event) => handleDraggerKeyDown(event, column)}\n />\n ) : null}\n </div>\n )\n })}\n </div>\n\n <div className=\"vgui-table__body vgui-scroll-surface\" role=\"rowgroup\">\n {isEmpty ? (\n <div className=\"vgui-table__row vgui-table__row--empty\" role=\"row\">\n {/*\n * An empty `rowgroup` is an `aria-required-children` violation, so\n * the empty state keeps the grid and its headers — a refresh should\n * not take the column strip away — and puts the message in one cell\n * that spans the grid. No `aria-rowindex` here: the grid's\n * `aria-rowcount` is 0, and a message is not a row of data. The\n * message is a live region without changing the cell's role.\n */}\n <div\n className=\"vgui-table__cell vgui-table__empty\"\n role=\"gridcell\"\n aria-colindex={1}\n aria-colspan={columns.length}\n aria-live=\"polite\"\n >\n {emptyMessage}\n </div>\n </div>\n ) : (\n orderedRows.map((row, index) => {\n const id = rowId(row)\n const isSelected = selectedSet.has(id)\n\n return (\n <div\n key={id}\n ref={(node) => setRowRef(id, node)}\n className={['vgui-table__row', isSelected ? 'vgui-table__row--selected' : null]\n .filter(Boolean)\n .join(' ')}\n role=\"row\"\n aria-rowindex={index + 1}\n aria-selected={isSelected}\n tabIndex={id === activeRowId ? 0 : -1}\n onClick={(event) => handleRowClick(event, id)}\n onFocus={() => setActiveId(id)}\n onKeyDown={handleRowKeyDown}\n >\n {columns.map((column, columnIndex) => (\n <div\n key={column.id}\n className=\"vgui-table__cell\"\n role=\"gridcell\"\n aria-colindex={columnIndex + 1}\n data-align={column.align ?? 'start'}\n style={columnStyle(column)}\n >\n {column.cell(row)}\n </div>\n ))}\n </div>\n )\n })\n )}\n </div>\n </div>\n )\n}\n"],"mappings":";;;;;;;AAgFA,IAAM,wBAAwB;;AAG9B,IAAM,mBAAmB;;AAGzB,IAAM,cAAc;;AAGpB,IAAM,qBAAqB;AAE3B,SAAS,UAAU,OAAgD;CACjE,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC;CACjC,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,MAAM,IAAI,CAAC,KAAK;AACtD;AAEA,SAAS,MAAM,OAAe,KAAa,KAAqB;CAC9D,OAAO,KAAK,IAAI,KAAK,IAAI,OAAO,GAAG,GAAG,GAAG;AAC3C;AAEA,SAAS,UAAU,OAAmC;CACpD,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,QAAQ;AAC1E;AAEA,SAAS,QAAQ,GAAoB,GAA4B;CAC/D,IAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;EAElD,IAAI,OAAO,MAAM,CAAC,KAAK,OAAO,MAAM,CAAC,GAAG,OAAO;EAC/C,OAAO,IAAI;CACb;CACA,OAAO,OAAO,CAAC,CAAC,CAAC,cAAc,OAAO,CAAC,CAAC;AAC1C;AAEA,SAAgB,MAAW,OAAwB;CACjD,MAAM,EACJ,WACA,SACA,MACA,OACA,UACA,iBACA,QAAQ,OACR,kBACA,MACA,cACA,YAAY,OACZ,gBACA,kBAAkB,OAClB,eAAe,OACf,eAAe,YACf,OAAO,OACP,OACA,cAAc,WACd,GAAG,SACD;CAEJ,MAAM,CAAC,sBAAsB,2BAA2B,eACtD,UAAU,eAAe,CAC3B;CACA,MAAM,CAAC,kBAAkB,uBAAuB,SAA2B,IAAI;CAC/E,MAAM,CAAC,QAAQ,aAAa,SAAiC,CAAC,CAAC;CAC/D,MAAM,CAAC,UAAU,eAAe,SAAwB,IAAI;CAC5D,MAAM,CAAC,aAAa,kBAAkB,SAAS,CAAC;CAEhD,MAAM,UAAU,uBAAO,IAAI,IAA4B,CAAC;CACxD,MAAM,aAAa,uBAAO,IAAI,IAA+B,CAAC;CAC9D,MAAM,eAAe,OAAuE;EAC1F,OAAO;EACP,OAAO;CACT,CAAC;;;;;;CAMD,MAAM,YAAY,OAAsB,IAAI;CAE5C,MAAM,aAAa,SAAS,KAAA,IAAY,mBAAmB;CAC3D,MAAM,cAAc,aAAa,KAAA,IAAY,uBAAuB,UAAU,QAAQ;CACtF,MAAM,cAAc,cAAc,IAAI,IAAI,WAAW,GAAG,CAAC,WAAW,CAAC;CAIrE,MAAM,cAAc,cAAc;EAChC,MAAM,SAAS,aAAa,QAAQ,MAAM,UAAU,MAAM,OAAO,WAAW,QAAQ,IAAI,KAAA;EACxF,IAAI,CAAC,cAAc,CAAC,QAAQ,OAAO;EAEnC,MAAM,UAAU,OAAO,eAAe,QAAa,UAAU,OAAO,KAAK,GAAG,CAAC;EAC7E,MAAM,YAAY,WAAW,cAAc,QAAQ,IAAI;EAGvD,OAAO,KAAK,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,QAAQ,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,SAAS;CAChF,GAAG;EAAC;EAAY;EAAS;CAAI,CAAC;CAE9B,MAAM,MAAM,cAAc,YAAY,KAAK,QAAQ,MAAM,GAAG,CAAC,GAAG,CAAC,aAAa,KAAK,CAAC;CACpF,MAAM,UAAU,IAAI,WAAW;CAE/B,MAAM,kBAAkB,cAAc,QAAQ,QAAQ,WAAW,OAAO,QAAQ,GAAG,CAAC,OAAO,CAAC;CAC5F,MAAM,eAAe,gBAAgB,WAAW,IAAI,KAAK,MAAM,aAAa,GAAG,gBAAgB,SAAS,CAAC;CAEzG,MAAM,mBAAmB,IAAI,MAAM,OAAO,YAAY,IAAI,EAAE,CAAC,KAAK,IAAI,MAAM;CAC5E,MAAM,cAAc,aAAa,QAAQ,IAAI,SAAS,QAAQ,IAAI,WAAW;CAE7E,gBAAgB;EACd,MAAM,YAAY,aAAa;EAC/B,aAAa;GACX,IAAI,UAAU,UAAU,MAAM,aAAa,UAAU,KAAK;EAC5D;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,YAAY,aAAa,IAAY,SAAgC;EACzE,IAAI,MAAM,QAAQ,QAAQ,IAAI,IAAI,IAAI;OACjC,QAAQ,QAAQ,OAAO,EAAE;CAChC,GAAG,CAAC,CAAC;CAEL,MAAM,SAAS,aAAa,QAAgB,QAAQ,QAAQ,IAAI,EAAE,CAAC,EAAE,eAAe,GAAA,CAAI,KAAK,GAAG,CAAC,CAAC;CAElG,MAAM,SAAS,aACZ,SAAmB;EAClB,IAAI,aAAa,KAAA,GAAW,wBAAwB,IAAI;EACxD,mBAAmB,QAAQ,OAAQ,KAAK,MAAM,EAAG;CACnD,GACA;EAAC;EAAO;EAAkB;CAAQ,CACpC;CAEA,MAAM,WAAW,aAAa,OAAe;EAC3C,YAAY,EAAE;EACd,UAAU,UAAU;EACpB,MAAM,OAAO,QAAQ,QAAQ,IAAI,EAAE;EACnC,IAAI,CAAC,MAAM;;;;;EAKX,IAAI,OAAO,KAAK,mBAAmB,YAAY,KAAK,eAAe,EAAE,OAAO,UAAU,CAAC;EACvF,KAAK,MAAM;CACb,GAAG,CAAC,CAAC;CAEL,MAAM,aAAa,aAChB,SAAoC;EACnC,IAAI,IAAI,WAAW,GAAG;EACtB,MAAM,UAAU,gBAAgB,OAAO,KAAK,IAAI,QAAQ,WAAW;EAEnE,MAAM,OACJ,SAAS,UAAU,IAAI,SAAS,SAAS,IAAI,SAAS,IAAI,OAF/C,UAAU,IAAI,IAAI,WAE0C,MAAM,GAAG,IAAI,SAAS,CAAC;EAChG,SAAS,IAAI,KAAK;CACpB,GACA;EAAC;EAAa;EAAU;CAAG,CAC7B;CAEA,MAAM,YAAY,aACf,IAAY,SAAyC;EACpD,MAAM,SAAS,UAAU,WAAW;EACpC,IAAI;EAEJ,IAAI,SAAS,WAAW,WAAW,QAAQ,WAAW,IAAI;GACxD,MAAM,OAAO,IAAI,QAAQ,MAAM;GAC/B,MAAM,KAAK,IAAI,QAAQ,EAAE;GACzB,OAAO,IAAI,MAAM,KAAK,IAAI,MAAM,EAAE,GAAG,KAAK,IAAI,MAAM,EAAE,IAAI,CAAC;EAC7D,OAAO,IAAI,SAAS,WAAW,SAAS,WACtC,OAAO,CAAC,EAAE;OAEV,OAAO,YAAY,IAAI,EAAE,IACrB,YAAY,QAAQ,UAAU,UAAU,EAAE,IAC1C,CAAC,GAAG,aAAa,EAAE;EAIzB,IAAI,SAAS,SAAS,UAAU,UAAU;EAC1C,OAAO,IAAI;CACb,GACA;EAAC;EAAa;EAAQ;EAAK;EAAa;CAAW,CACrD;CAEA,MAAM,WAAW,aACd,OAAe;EACd,UAAU,IAAI,QAAQ,WAAW,SAAS;CAC5C,GACA,CAAC,OAAO,SAAS,CACnB;CAEA,MAAM,YAAY,aACf,cAAsB;EACrB,MAAM,QAAQ,aAAa;EAC3B,MAAM,UAAU,MAAM,QAAQ,UAAA,CAAW,YAAY;EACrD,MAAM,QAAQ;EACd,IAAI,MAAM,UAAU,MAAM,aAAa,MAAM,KAAK;EAClD,MAAM,QAAQ,iBAAiB;GAC7B,MAAM,QAAQ;EAChB,GAAG,kBAAkB;EAErB,IAAI,IAAI,WAAW,GAAG;EACtB,MAAM,QAAQ,gBAAgB,OAAO,KAAK,IAAI,QAAQ,WAAW;EACjE,KAAK,IAAI,SAAS,GAAG,UAAU,IAAI,QAAQ,UAAU,GAAG;GACtD,MAAM,KAAK,KAAK,QAAQ,SAAS,IAAI,UAAU,IAAI;GACnD,IAAI,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,MAAM,GAAG;IAC/C,SAAS,EAAE;IACX;GACF;EACF;CACF,GACA;EAAC;EAAa;EAAU;EAAK;CAAM,CACrC;CAEA,MAAM,mBAAmB,aACtB,UAA8C;EAC7C,MAAM,EAAE,QAAQ;EAEhB,IAAI,QAAQ,aAAa;GACvB,MAAM,eAAe;GACrB,WAAW,CAAC;GACZ;EACF;EAEA,IAAI,QAAQ,WAAW;GACrB,MAAM,eAAe;GAGrB,IAAI,gBAAgB,IAAI,MAAM,gBAAgB,SAAS,GAAG;IACxD,MAAM,SAAS,gBAAgB;IAC/B,IAAI,QAAQ,WAAW,QAAQ,IAAI,OAAO,EAAE,CAAC,EAAE,MAAM;IACrD;GACF;GACA,WAAW,EAAE;GACb;EACF;EAEA,IAAI,QAAQ,UAAU,QAAQ,OAAO;GACnC,MAAM,eAAe;GACrB,WAAW,QAAQ,SAAS,UAAU,MAAM;GAC5C;EACF;EAEA,IAAI,QAAQ,WAAW,QAAQ,KAAK;GAClC,MAAM,eAAe;GACrB,IAAI,gBAAgB,MAAM,SAAS,WAAW;GAC9C;EACF;EAEA,IAAI,IAAI,WAAW,KAAK,CAAC,MAAM,WAAW,CAAC,MAAM,WAAW,CAAC,MAAM,QACjE,UAAU,GAAG;CAEjB,GACA;EAAC;EAAU;EAAc;EAAa;EAAK;EAAY;EAAiB;CAAS,CACnF;CAEA,MAAM,iBAAiB,aACpB,OAAwC,OAAe;EACtD,YAAY,EAAE;EAEd,IAAI,CAAC,OAAO;GACV,UAAU,IAAI,SAAS;GACvB;EACF;EACA,IAAI,MAAM,UAAU;GAClB,UAAU,IAAI,OAAO;GACrB;EACF;EACA,UAAU,IAAI,MAAM,WAAW,MAAM,UAAU,WAAW,SAAS;CACrE,GACA,CAAC,OAAO,SAAS,CACnB;CAEA,MAAM,YAAY,aACf,aAAqB;EAIpB,MAAM,OAAkB;GAAE;GAAU,WADlB,YAAY,aAAa,YAAY,WAAW,cAAc,QAAQ,SAAS;EACnD;EAC9C,IAAI,SAAS,KAAA,GAAW,oBAAoB,IAAI;EAChD,eAAe,IAAI;CACrB,GACA;EAAC;EAAY;EAAc;CAAI,CACjC;CAEA,MAAM,cAAc,aACjB,UAAkB;EACjB,IAAI,gBAAgB,WAAW,GAAG;EAClC,MAAM,OAAO,MAAM,OAAO,GAAG,gBAAgB,SAAS,CAAC;EACvD,eAAe,IAAI;EACnB,WAAW,QAAQ,IAAI,gBAAgB,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM;CAC1D,GACA,CAAC,eAAe,CAClB;CAEA,MAAM,sBAAsB,aACzB,OAA8C,UAAkB;EAC/D,MAAM,EAAE,QAAQ;EAEhB,IAAI,QAAQ,cAAc;GACxB,MAAM,eAAe;GACrB,YAAY,QAAQ,CAAC;GACrB;EACF;EACA,IAAI,QAAQ,aAAa;GACvB,MAAM,eAAe;GACrB,YAAY,QAAQ,CAAC;GACrB;EACF;EACA,IAAI,QAAQ,UAAU,QAAQ,OAAO;GACnC,MAAM,eAAe;GACrB,YAAY,QAAQ,SAAS,IAAI,gBAAgB,SAAS,CAAC;GAC3D;EACF;EAGA,IAAI,QAAQ,aAAa;GACvB,MAAM,eAAe;GACrB,IAAI,IAAI,OAAO,KAAA,GAAW,SAAS,IAAI,EAAE;EAC3C;CACF,GACA;EAAC;EAAa;EAAU;EAAK,gBAAgB;CAAM,CACrD;CAEA,MAAM,UAAU,aACb,WAA6B,OAAO,OAAO,OAAO,OAAO,gBAAgB,OAAO,OACjF,CAAC,MAAM,CACT;CAEA,MAAM,aAAa,aAAa,UAAkB,UAAkB;EAClE,MAAM,OAAO,OAAO,SAAS,KAAK,IAAI,KAAK,IAAI,kBAAkB,KAAK,MAAM,KAAK,CAAC,IAAI;EACtF,WAAW,cAAc;GAAE,GAAG;IAAW,WAAW;EAAK,EAAE;EAC3D,OAAO;CACT,GAAG,CAAC,CAAC;CAEL,MAAM,uBAAuB,aAC1B,OAA2C,WAA6B;EACvE,IAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,cAAc;EAC7D,MAAM,eAAe;EACrB,MAAM,UAAU,QAAQ,MAAM,KAAK;EACnC,MAAM,OAAO,MAAM,QAAQ,cAAc,KAAe;EACxD,MAAM,OAAO,WAAW,OAAO,IAAI,UAAU,IAAI;EACjD,iBAAiB,OAAO,IAAI,IAAI;CAClC,GACA;EAAC;EAAY;EAAgB;CAAO,CACtC;CAEA,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAC9C,MAAM,UAAU,OACd,IACF;CAEA,MAAM,2BAA2B,aAC9B,OAA0C,WAA6B;EACtE,MAAM,aAAa,QAAQ,MAAM,KAAK;EACtC,QAAQ,UAAU;GAAE,UAAU,OAAO;GAAI,QAAQ,MAAM;GAAS;GAAY,OAAO;EAAW;EAC9F,YAAY,IAAI;CAClB,GACA,CAAC,OAAO,CACV;CAEA,gBAAgB;EACd,IAAI,CAAC,UAAU;EAEf,MAAM,cAAc,UAAwB;GAC1C,MAAM,OAAO,QAAQ;GAGrB,IAAI,CAAC,QAAQ,CAAC,OAAO,SAAS,MAAM,OAAO,KAAK,CAAC,OAAO,SAAS,MAAM,OAAO,GAAG;GACjF,KAAK,QAAQ,WAAW,KAAK,UAAU,KAAK,cAAc,MAAM,UAAU,KAAK,OAAO;EACxF;EAEA,MAAM,iBAAiB;GACrB,MAAM,OAAO,QAAQ;GACrB,QAAQ,UAAU;GAClB,YAAY,KAAK;GACjB,IAAI,MAAM,iBAAiB,KAAK,UAAU,KAAK,KAAK;EACtD;EAEA,OAAO,iBAAiB,eAAe,UAAU;EACjD,OAAO,iBAAiB,aAAa,QAAQ;EAC7C,OAAO,iBAAiB,iBAAiB,QAAQ;EACjD,aAAa;GACX,OAAO,oBAAoB,eAAe,UAAU;GACpD,OAAO,oBAAoB,aAAa,QAAQ;GAChD,OAAO,oBAAoB,iBAAiB,QAAQ;EACtD;CACF,GAAG;EAAC;EAAY;EAAU;CAAc,CAAC;CAEzC,MAAM,cAAc,aACjB,WAA4C;EAC3C,MAAM,QAAQ,QAAQ,MAAM;EAC5B,OAAO,UAAU,KAAA,IACb;GAAE,MAAM;GAAY,UAAU;EAAE,IAChC;GAAE,MAAM,OAAO,MAAM;GAAK;EAAM;CACtC,GACA,CAAC,OAAO,CACV;CAEA,MAAM,gBAAgB;EACpB;EACA,kBAAkB,iCAAiC;EACnD,YAAY,0BAA0B;EACtC,eAAe,uBAAuB;EACtC,WAAW,yBAAyB;EACpC,aAAa;CACf,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;CAEX,OACE,qBAAC,OAAD;EACE,GAAI;EACJ,WAAW;EACJ;EACP,MAAK;EACL,cAAY;EACZ,iBAAe,QAAQ;EACvB,iBAAe,IAAI;EACnB,wBAAsB,QAAQ,OAAO,KAAA;EACrC,aAAW,QAAQ,KAAA;EATrB,UAAA,CAWE,oBAAC,OAAD;GAAK,WAAU;GAAmB,MAAK;GACpC,UAAA,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,SAAS,YAAY,aAAa,OAAO;IAC/C,MAAM,gBAAgB,gBAAgB,QAAQ,MAAM;IACpD,MAAM,QACJ,qBAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CACG,OAAO,aACN,oBAAC,QAAD;MAAM,WAAU;MAAsB,eAAY;MAC/C,UAAA,OAAO;KACJ,CAAA,IACJ,MACH,OAAO,MACJ;;IAGR,OACE,qBAAC,OAAD;KAEE,WAAU;KACV,MAAK;KACL,iBAAe,QAAQ;KAGvB,aAAW,SAAU,YAAY,cAAc,QAAQ,cAAc,eAAgB,KAAA;KACrF,cAAY,OAAO,SAAS;KAC5B,OAAO,YAAY,MAAM;KAT3B,UAAA,CAWG,OAAO,WACN,qBAAC,UAAD;MACE,MAAK;MACL,WAAU;MACV,MAAM,SAAS;OACb,IAAI,MAAM,WAAW,QAAQ,IAAI,OAAO,IAAI,IAAI;YAC3C,WAAW,QAAQ,OAAO,OAAO,EAAE;MAC1C;MACA,UAAU,kBAAkB,eAAe,IAAI;MAC/C,eAAe,UAAU,OAAO,EAAE;MAClC,YAAY,UAAU,oBAAoB,OAAO,aAAa;MAThE,UAAA,CAWG,OACD,oBAAC,QAAD;OACE,WAAU;OACV,kBAAgB,SAAS,YAAY,YAAY;OACjD,eAAY;MACb,CAAA,CACK;KAER,CAAA,IAAA,OAED,YACC,oBAAC,OAAD;MACE,WAAU;MACV,MAAK;MACL,oBAAiB;MACjB,cAAY,UAAU,OAAO,OAAO;MACpC,iBAAe;MACf,iBAAe,QAAQ,MAAM,KAAK;MAClC,UAAU;MACV,gBAAgB,UAAU,yBAAyB,OAAO,MAAM;MAChE,YAAY,UAAU,qBAAqB,OAAO,MAAM;KACzD,CAAA,IACC,IACD;IA7CE,GAAA,OAAO,EA6CT;GAET,CAAC;EACE,CAAA,GAEL,oBAAC,OAAD;GAAK,WAAU;GAAuC,MAAK;GACxD,UAAA,UACC,oBAAC,OAAD;IAAK,WAAU;IAAyC,MAAK;IAS3D,UAAA,oBAAC,OAAD;KACE,WAAU;KACV,MAAK;KACL,iBAAe;KACf,gBAAc,QAAQ;KACtB,aAAU;KAET,UAAA;IACE,CAAA;GACF,CAAA,IAEL,YAAY,KAAK,KAAK,UAAU;IAC9B,MAAM,KAAK,MAAM,GAAG;IACpB,MAAM,aAAa,YAAY,IAAI,EAAE;IAErC,OACE,oBAAC,OAAD;KAEE,MAAM,SAAS,UAAU,IAAI,IAAI;KACjC,WAAW,CAAC,mBAAmB,aAAa,8BAA8B,IAAI,CAAC,CAC5E,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;KACX,MAAK;KACL,iBAAe,QAAQ;KACvB,iBAAe;KACf,UAAU,OAAO,cAAc,IAAI;KACnC,UAAU,UAAU,eAAe,OAAO,EAAE;KAC5C,eAAe,YAAY,EAAE;KAC7B,WAAW;KAEV,UAAA,QAAQ,KAAK,QAAQ,gBACpB,oBAAC,OAAD;MAEE,WAAU;MACV,MAAK;MACL,iBAAe,cAAc;MAC7B,cAAY,OAAO,SAAS;MAC5B,OAAO,YAAY,MAAM;MAExB,UAAA,OAAO,KAAK,GAAG;KACb,GARE,OAAO,EAQT,CACN;IACE,GAzBE,EAyBF;GAET,CAAC;EAEA,CAAA,CACF;;AAET"}
@@ -0,0 +1,3 @@
1
+ export { Table } from './Table';
2
+ export type { TableColumn, TableProps, TableSort } from './Table';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1,138 @@
1
+ /*
2
+ * Green Steam property sheet — `PropertySheet` / `PageTab` (steam.styles:1793).
3
+ *
4
+ * Both tab states paint `--vgui-surface`; nothing about the selected tab is
5
+ * brighter. Selection is carried by the label colour plus the seam erasure —
6
+ * the selected tab paints 1px *past* its own bottom edge, over the strip's
7
+ * rail, exactly as `fill( x0 + 1, y1 - 1, x1 - 1, y1 + 2, GreenBG )` does.
8
+ */
9
+
10
+ .vgui-tabs {
11
+ display: flex;
12
+ flex-direction: column;
13
+ color: var(--vgui-text-strong);
14
+ font-family: var(--vgui-font);
15
+ font-size: var(--vgui-font-size);
16
+ line-height: var(--vgui-line-height);
17
+ }
18
+
19
+ .vgui-tabs__strip {
20
+ display: flex;
21
+ align-items: flex-end;
22
+ /* PropertySheet.TabGap = 3 (steam.styles:337) */
23
+ gap: var(--vgui-tabs-gap, 3px);
24
+ margin: 0;
25
+ padding: 0;
26
+ /* The rail the selected tab has to erase. */
27
+ border-bottom: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
28
+ }
29
+
30
+ .vgui-tabs__tab {
31
+ display: inline-flex;
32
+ align-items: center;
33
+ gap: 4px;
34
+ min-height: var(--vgui-min-target-size);
35
+ margin: 0;
36
+ padding: 2px 10px;
37
+ border: 0;
38
+ border-radius: 0;
39
+ background-color: var(--vgui-surface);
40
+ color: var(--vgui-text-strong);
41
+ font: inherit;
42
+ text-align: left;
43
+ cursor: default;
44
+ /* Raised bevel: bright top/left, dark right, no bottom — the tab's own fill
45
+ runs to its lower edge so it appears to merge downward. */
46
+ box-shadow:
47
+ inset var(--vgui-bevel-width) var(--vgui-bevel-width) 0 var(--vgui-bevel-light),
48
+ inset calc(-1 * var(--vgui-bevel-width)) 0 0 var(--vgui-bevel-dark);
49
+ }
50
+
51
+ /* Invented: `PageTab` declares no hover block (Tabs.md, Open questions). */
52
+ .vgui-tabs__tab:not(.vgui-tabs__tab--selected):hover {
53
+ background-color: var(--vgui-surface-light);
54
+ }
55
+
56
+ .vgui-tabs__tab--selected {
57
+ /* `--vgui-heading` maize is 3.62:1 on this fill; `--vgui-text-hover` is
58
+ 5.52:1 — Tabs.md, Accessibility, fix 1. */
59
+ color: var(--vgui-text-hover);
60
+ /* The seam erasure. Never `border-bottom: 0`: that would shorten the layout
61
+ box and make the strip jitter. */
62
+ margin-bottom: calc(-1 * var(--vgui-tabs-overlap, 1px));
63
+ padding-bottom: 3px;
64
+ }
65
+
66
+ .vgui-tabs__tab:disabled,
67
+ .vgui-tabs__tab--disabled {
68
+ color: var(--vgui-text-disabled);
69
+ text-shadow: var(--vgui-bevel-width) var(--vgui-bevel-width) 0 var(--vgui-text-disabled-shadow);
70
+ cursor: not-allowed;
71
+ }
72
+
73
+ .vgui-tabs__tab:disabled:hover,
74
+ .vgui-tabs__tab--disabled:hover {
75
+ background-color: var(--vgui-surface);
76
+ }
77
+
78
+ .vgui-tabs__tab:focus-visible {
79
+ outline: var(--vgui-focus-ring);
80
+ outline-offset: var(--vgui-focus-ring-offset);
81
+ }
82
+
83
+ .vgui-crisp .vgui-tabs__tab:focus-visible {
84
+ outline: var(--vgui-focus-ring-valve);
85
+ outline-offset: var(--vgui-focus-ring-valve-offset);
86
+ }
87
+
88
+ .vgui-tabs__label {
89
+ white-space: nowrap;
90
+ }
91
+
92
+ /* TabCloseButton { padding-right = 16 } (steam.styles:3130). Not focusable —
93
+ see the note in Tabs.tsx; the keyboard path is Delete on the tab. */
94
+ .vgui-tabs__close {
95
+ display: inline-flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ width: var(--vgui-tabs-close-slot, 16px);
99
+ height: var(--vgui-tabs-close-slot, 16px);
100
+ margin-left: auto;
101
+ padding: 0;
102
+ color: inherit;
103
+ line-height: 1;
104
+ cursor: pointer;
105
+ }
106
+
107
+ .vgui-tabs__close:hover {
108
+ color: var(--vgui-text-strong);
109
+ }
110
+
111
+ .vgui-tabs__panel {
112
+ padding: 8px;
113
+ }
114
+
115
+ .vgui-tabs--clay .vgui-tabs__panel {
116
+ /* LightClayBG — "property sheet interior, active tab" (steamscheme.res:38).
117
+ The page border is PropertySheetBG `#4a4846`, which has no token; the
118
+ nearest declared clay chrome is `--vgui-clay-surface` `#464646`. */
119
+ background-color: var(--vgui-clay-light);
120
+ border: var(--vgui-bevel-width) solid var(--vgui-clay-surface);
121
+ color: var(--vgui-text-strong);
122
+ }
123
+
124
+ .vgui-tabs--green .vgui-tabs__panel {
125
+ background-color: var(--vgui-surface);
126
+ border: var(--vgui-bevel-width) solid var(--vgui-bevel-dark);
127
+ color: var(--vgui-text-strong);
128
+ }
129
+
130
+ .vgui-tabs__panel:focus-visible {
131
+ outline: var(--vgui-focus-ring);
132
+ outline-offset: var(--vgui-focus-ring-offset);
133
+ }
134
+
135
+ .vgui-crisp .vgui-tabs__panel:focus-visible {
136
+ outline: var(--vgui-focus-ring-valve);
137
+ outline-offset: var(--vgui-focus-ring-valve-offset);
138
+ }
@@ -0,0 +1 @@
1
+ export {}