@furystack/shades-common-components 11.0.0 → 12.0.1

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 (768) hide show
  1. package/CHANGELOG.md +443 -0
  2. package/esm/components/accordion/accordion-item.d.ts +31 -0
  3. package/esm/components/accordion/accordion-item.d.ts.map +1 -0
  4. package/esm/components/accordion/accordion-item.js +147 -0
  5. package/esm/components/accordion/accordion-item.js.map +1 -0
  6. package/esm/components/accordion/accordion.d.ts +27 -0
  7. package/esm/components/accordion/accordion.d.ts.map +1 -0
  8. package/esm/components/accordion/accordion.js +39 -0
  9. package/esm/components/accordion/accordion.js.map +1 -0
  10. package/esm/components/accordion/accordion.spec.d.ts +2 -0
  11. package/esm/components/accordion/accordion.spec.d.ts.map +1 -0
  12. package/esm/components/accordion/accordion.spec.js +284 -0
  13. package/esm/components/accordion/accordion.spec.js.map +1 -0
  14. package/esm/components/accordion/index.d.ts +3 -0
  15. package/esm/components/accordion/index.d.ts.map +1 -0
  16. package/esm/components/accordion/index.js +3 -0
  17. package/esm/components/accordion/index.js.map +1 -0
  18. package/esm/components/alert.d.ts +21 -0
  19. package/esm/components/alert.d.ts.map +1 -0
  20. package/esm/components/alert.js +131 -0
  21. package/esm/components/alert.js.map +1 -0
  22. package/esm/components/alert.spec.d.ts +2 -0
  23. package/esm/components/alert.spec.d.ts.map +1 -0
  24. package/esm/components/alert.spec.js +177 -0
  25. package/esm/components/alert.spec.js.map +1 -0
  26. package/esm/components/app-bar-link.d.ts +22 -2
  27. package/esm/components/app-bar-link.d.ts.map +1 -1
  28. package/esm/components/app-bar-link.js +20 -7
  29. package/esm/components/app-bar-link.js.map +1 -1
  30. package/esm/components/app-bar-link.spec.js +22 -19
  31. package/esm/components/app-bar-link.spec.js.map +1 -1
  32. package/esm/components/app-bar.d.ts +2 -0
  33. package/esm/components/app-bar.d.ts.map +1 -1
  34. package/esm/components/app-bar.js +16 -11
  35. package/esm/components/app-bar.js.map +1 -1
  36. package/esm/components/app-bar.spec.js +67 -52
  37. package/esm/components/app-bar.spec.js.map +1 -1
  38. package/esm/components/avatar.d.ts +2 -0
  39. package/esm/components/avatar.d.ts.map +1 -1
  40. package/esm/components/avatar.js +40 -37
  41. package/esm/components/avatar.js.map +1 -1
  42. package/esm/components/badge.d.ts +35 -0
  43. package/esm/components/badge.d.ts.map +1 -0
  44. package/esm/components/badge.js +68 -0
  45. package/esm/components/badge.js.map +1 -0
  46. package/esm/components/badge.spec.d.ts +2 -0
  47. package/esm/components/badge.spec.d.ts.map +1 -0
  48. package/esm/components/badge.spec.js +157 -0
  49. package/esm/components/badge.spec.js.map +1 -0
  50. package/esm/components/breadcrumb.d.ts +103 -0
  51. package/esm/components/breadcrumb.d.ts.map +1 -0
  52. package/esm/components/breadcrumb.js +121 -0
  53. package/esm/components/breadcrumb.js.map +1 -0
  54. package/esm/components/breadcrumb.spec.d.ts +2 -0
  55. package/esm/components/breadcrumb.spec.d.ts.map +1 -0
  56. package/esm/components/breadcrumb.spec.js +251 -0
  57. package/esm/components/breadcrumb.spec.js.map +1 -0
  58. package/esm/components/button-group.d.ts +85 -0
  59. package/esm/components/button-group.d.ts.map +1 -0
  60. package/esm/components/button-group.js +290 -0
  61. package/esm/components/button-group.js.map +1 -0
  62. package/esm/components/button-group.spec.d.ts +2 -0
  63. package/esm/components/button-group.spec.d.ts.map +1 -0
  64. package/esm/components/button-group.spec.js +502 -0
  65. package/esm/components/button-group.spec.js.map +1 -0
  66. package/esm/components/button.d.ts +44 -2
  67. package/esm/components/button.d.ts.map +1 -1
  68. package/esm/components/button.js +82 -73
  69. package/esm/components/button.js.map +1 -1
  70. package/esm/components/button.spec.js +205 -50
  71. package/esm/components/button.spec.js.map +1 -1
  72. package/esm/components/card.d.ts +117 -0
  73. package/esm/components/card.d.ts.map +1 -0
  74. package/esm/components/card.js +181 -0
  75. package/esm/components/card.js.map +1 -0
  76. package/esm/components/card.spec.d.ts +2 -0
  77. package/esm/components/card.spec.d.ts.map +1 -0
  78. package/esm/components/card.spec.js +278 -0
  79. package/esm/components/card.spec.js.map +1 -0
  80. package/esm/components/carousel.d.ts +50 -0
  81. package/esm/components/carousel.d.ts.map +1 -0
  82. package/esm/components/carousel.js +263 -0
  83. package/esm/components/carousel.js.map +1 -0
  84. package/esm/components/carousel.spec.d.ts +2 -0
  85. package/esm/components/carousel.spec.d.ts.map +1 -0
  86. package/esm/components/carousel.spec.js +677 -0
  87. package/esm/components/carousel.spec.js.map +1 -0
  88. package/esm/components/chip.d.ts +23 -0
  89. package/esm/components/chip.d.ts.map +1 -0
  90. package/esm/components/chip.js +139 -0
  91. package/esm/components/chip.js.map +1 -0
  92. package/esm/components/chip.spec.d.ts +2 -0
  93. package/esm/components/chip.spec.d.ts.map +1 -0
  94. package/esm/components/chip.spec.js +142 -0
  95. package/esm/components/chip.spec.js.map +1 -0
  96. package/esm/components/circular-progress.d.ts +37 -0
  97. package/esm/components/circular-progress.d.ts.map +1 -0
  98. package/esm/components/circular-progress.js +84 -0
  99. package/esm/components/circular-progress.js.map +1 -0
  100. package/esm/components/circular-progress.spec.d.ts +2 -0
  101. package/esm/components/circular-progress.spec.d.ts.map +1 -0
  102. package/esm/components/circular-progress.spec.js +228 -0
  103. package/esm/components/circular-progress.spec.js.map +1 -0
  104. package/esm/components/command-palette/command-palette-input.d.ts +3 -0
  105. package/esm/components/command-palette/command-palette-input.d.ts.map +1 -1
  106. package/esm/components/command-palette/command-palette-input.js +17 -9
  107. package/esm/components/command-palette/command-palette-input.js.map +1 -1
  108. package/esm/components/command-palette/command-palette-input.spec.js +172 -161
  109. package/esm/components/command-palette/command-palette-input.spec.js.map +1 -1
  110. package/esm/components/command-palette/command-palette-manager.spec.js +130 -114
  111. package/esm/components/command-palette/command-palette-manager.spec.js.map +1 -1
  112. package/esm/components/command-palette/command-palette-suggestion-list.d.ts +2 -0
  113. package/esm/components/command-palette/command-palette-suggestion-list.d.ts.map +1 -1
  114. package/esm/components/command-palette/command-palette-suggestion-list.js +20 -20
  115. package/esm/components/command-palette/command-palette-suggestion-list.js.map +1 -1
  116. package/esm/components/command-palette/command-palette-suggestion-list.spec.js +296 -278
  117. package/esm/components/command-palette/command-palette-suggestion-list.spec.js.map +1 -1
  118. package/esm/components/command-palette/index.d.ts +2 -0
  119. package/esm/components/command-palette/index.d.ts.map +1 -1
  120. package/esm/components/command-palette/index.js +25 -94
  121. package/esm/components/command-palette/index.js.map +1 -1
  122. package/esm/components/command-palette/index.spec.js +12 -12
  123. package/esm/components/command-palette/index.spec.js.map +1 -1
  124. package/esm/components/context-menu/context-menu-item.d.ts +9 -0
  125. package/esm/components/context-menu/context-menu-item.d.ts.map +1 -0
  126. package/esm/components/context-menu/context-menu-item.js +56 -0
  127. package/esm/components/context-menu/context-menu-item.js.map +1 -0
  128. package/esm/components/context-menu/context-menu-manager.d.ts +52 -0
  129. package/esm/components/context-menu/context-menu-manager.d.ts.map +1 -0
  130. package/esm/components/context-menu/context-menu-manager.js +128 -0
  131. package/esm/components/context-menu/context-menu-manager.js.map +1 -0
  132. package/esm/components/context-menu/context-menu-manager.spec.d.ts +2 -0
  133. package/esm/components/context-menu/context-menu-manager.spec.d.ts.map +1 -0
  134. package/esm/components/context-menu/context-menu-manager.spec.js +326 -0
  135. package/esm/components/context-menu/context-menu-manager.spec.js.map +1 -0
  136. package/esm/components/context-menu/context-menu.d.ts +8 -0
  137. package/esm/components/context-menu/context-menu.d.ts.map +1 -0
  138. package/esm/components/context-menu/context-menu.js +79 -0
  139. package/esm/components/context-menu/context-menu.js.map +1 -0
  140. package/esm/components/context-menu/context-menu.spec.d.ts +2 -0
  141. package/esm/components/context-menu/context-menu.spec.d.ts.map +1 -0
  142. package/esm/components/context-menu/context-menu.spec.js +282 -0
  143. package/esm/components/context-menu/context-menu.spec.js.map +1 -0
  144. package/esm/components/context-menu/index.d.ts +4 -0
  145. package/esm/components/context-menu/index.d.ts.map +1 -0
  146. package/esm/components/context-menu/index.js +4 -0
  147. package/esm/components/context-menu/index.js.map +1 -0
  148. package/esm/components/data-grid/body.spec.js +194 -184
  149. package/esm/components/data-grid/body.spec.js.map +1 -1
  150. package/esm/components/data-grid/data-grid-row.d.ts.map +1 -1
  151. package/esm/components/data-grid/data-grid-row.js +66 -54
  152. package/esm/components/data-grid/data-grid-row.js.map +1 -1
  153. package/esm/components/data-grid/data-grid-row.spec.js +127 -95
  154. package/esm/components/data-grid/data-grid-row.spec.js.map +1 -1
  155. package/esm/components/data-grid/data-grid.d.ts.map +1 -1
  156. package/esm/components/data-grid/data-grid.js +17 -16
  157. package/esm/components/data-grid/data-grid.js.map +1 -1
  158. package/esm/components/data-grid/data-grid.spec.js +364 -430
  159. package/esm/components/data-grid/data-grid.spec.js.map +1 -1
  160. package/esm/components/data-grid/footer.spec.js +215 -203
  161. package/esm/components/data-grid/footer.spec.js.map +1 -1
  162. package/esm/components/data-grid/header.d.ts +3 -1
  163. package/esm/components/data-grid/header.d.ts.map +1 -1
  164. package/esm/components/data-grid/header.js +42 -30
  165. package/esm/components/data-grid/header.js.map +1 -1
  166. package/esm/components/data-grid/header.spec.js +330 -307
  167. package/esm/components/data-grid/header.spec.js.map +1 -1
  168. package/esm/components/data-grid/selection-cell.d.ts +2 -0
  169. package/esm/components/data-grid/selection-cell.d.ts.map +1 -1
  170. package/esm/components/data-grid/selection-cell.js +2 -7
  171. package/esm/components/data-grid/selection-cell.js.map +1 -1
  172. package/esm/components/data-grid/selection-cell.spec.js +45 -36
  173. package/esm/components/data-grid/selection-cell.spec.js.map +1 -1
  174. package/esm/components/dialog.d.ts +46 -0
  175. package/esm/components/dialog.d.ts.map +1 -0
  176. package/esm/components/dialog.js +178 -0
  177. package/esm/components/dialog.js.map +1 -0
  178. package/esm/components/dialog.spec.d.ts +2 -0
  179. package/esm/components/dialog.spec.d.ts.map +1 -0
  180. package/esm/components/dialog.spec.js +113 -0
  181. package/esm/components/dialog.spec.js.map +1 -0
  182. package/esm/components/divider.d.ts +22 -0
  183. package/esm/components/divider.d.ts.map +1 -0
  184. package/esm/components/divider.js +113 -0
  185. package/esm/components/divider.js.map +1 -0
  186. package/esm/components/divider.spec.d.ts +2 -0
  187. package/esm/components/divider.spec.d.ts.map +1 -0
  188. package/esm/components/divider.spec.js +136 -0
  189. package/esm/components/divider.spec.js.map +1 -0
  190. package/esm/components/drawer/drawer-toggle-button.d.ts +36 -0
  191. package/esm/components/drawer/drawer-toggle-button.d.ts.map +1 -0
  192. package/esm/components/drawer/drawer-toggle-button.js +94 -0
  193. package/esm/components/drawer/drawer-toggle-button.js.map +1 -0
  194. package/esm/components/drawer/drawer-toggle-button.spec.d.ts +2 -0
  195. package/esm/components/drawer/drawer-toggle-button.spec.d.ts.map +1 -0
  196. package/esm/components/drawer/drawer-toggle-button.spec.js +306 -0
  197. package/esm/components/drawer/drawer-toggle-button.spec.js.map +1 -0
  198. package/esm/components/drawer/index.d.ts +56 -0
  199. package/esm/components/drawer/index.d.ts.map +1 -0
  200. package/esm/components/drawer/index.js +172 -0
  201. package/esm/components/drawer/index.js.map +1 -0
  202. package/esm/components/drawer/index.spec.d.ts +2 -0
  203. package/esm/components/drawer/index.spec.d.ts.map +1 -0
  204. package/esm/components/drawer/index.spec.js +538 -0
  205. package/esm/components/drawer/index.spec.js.map +1 -0
  206. package/esm/components/dropdown.d.ts +15 -0
  207. package/esm/components/dropdown.d.ts.map +1 -0
  208. package/esm/components/dropdown.js +262 -0
  209. package/esm/components/dropdown.js.map +1 -0
  210. package/esm/components/dropdown.spec.d.ts +2 -0
  211. package/esm/components/dropdown.spec.d.ts.map +1 -0
  212. package/esm/components/dropdown.spec.js +372 -0
  213. package/esm/components/dropdown.spec.js.map +1 -0
  214. package/esm/components/fab.d.ts +10 -1
  215. package/esm/components/fab.d.ts.map +1 -1
  216. package/esm/components/fab.js +24 -8
  217. package/esm/components/fab.js.map +1 -1
  218. package/esm/components/fab.spec.js +50 -39
  219. package/esm/components/fab.spec.js.map +1 -1
  220. package/esm/components/form.d.ts.map +1 -1
  221. package/esm/components/form.js +9 -7
  222. package/esm/components/form.js.map +1 -1
  223. package/esm/components/form.spec.js +209 -199
  224. package/esm/components/form.spec.js.map +1 -1
  225. package/esm/components/grid.js +10 -10
  226. package/esm/components/grid.js.map +1 -1
  227. package/esm/components/grid.spec.js +109 -85
  228. package/esm/components/grid.spec.js.map +1 -1
  229. package/esm/components/icons/icon-definitions.d.ts +140 -0
  230. package/esm/components/icons/icon-definitions.d.ts.map +1 -0
  231. package/esm/components/icons/icon-definitions.js +432 -0
  232. package/esm/components/icons/icon-definitions.js.map +1 -0
  233. package/esm/components/icons/icon-definitions.spec.d.ts +2 -0
  234. package/esm/components/icons/icon-definitions.spec.d.ts.map +1 -0
  235. package/esm/components/icons/icon-definitions.spec.js +59 -0
  236. package/esm/components/icons/icon-definitions.spec.js.map +1 -0
  237. package/esm/components/icons/icon-types.d.ts +48 -0
  238. package/esm/components/icons/icon-types.d.ts.map +1 -0
  239. package/esm/components/icons/icon-types.js +2 -0
  240. package/esm/components/icons/icon-types.js.map +1 -0
  241. package/esm/components/icons/icon.d.ts +56 -0
  242. package/esm/components/icons/icon.d.ts.map +1 -0
  243. package/esm/components/icons/icon.js +61 -0
  244. package/esm/components/icons/icon.js.map +1 -0
  245. package/esm/components/icons/icon.spec.d.ts +2 -0
  246. package/esm/components/icons/icon.spec.d.ts.map +1 -0
  247. package/esm/components/icons/icon.spec.js +224 -0
  248. package/esm/components/icons/icon.spec.js.map +1 -0
  249. package/esm/components/icons/index.d.ts +5 -0
  250. package/esm/components/icons/index.d.ts.map +1 -0
  251. package/esm/components/icons/index.js +3 -0
  252. package/esm/components/icons/index.js.map +1 -0
  253. package/esm/components/image.d.ts +62 -0
  254. package/esm/components/image.d.ts.map +1 -0
  255. package/esm/components/image.js +348 -0
  256. package/esm/components/image.js.map +1 -0
  257. package/esm/components/image.spec.d.ts +2 -0
  258. package/esm/components/image.spec.d.ts.map +1 -0
  259. package/esm/components/image.spec.js +542 -0
  260. package/esm/components/image.spec.js.map +1 -0
  261. package/esm/components/index.d.ts +32 -4
  262. package/esm/components/index.d.ts.map +1 -1
  263. package/esm/components/index.js +32 -4
  264. package/esm/components/index.js.map +1 -1
  265. package/esm/components/inputs/autocomplete.d.ts +2 -0
  266. package/esm/components/inputs/autocomplete.d.ts.map +1 -1
  267. package/esm/components/inputs/autocomplete.js +10 -6
  268. package/esm/components/inputs/autocomplete.js.map +1 -1
  269. package/esm/components/inputs/autocomplete.spec.js +10 -1
  270. package/esm/components/inputs/autocomplete.spec.js.map +1 -1
  271. package/esm/components/inputs/checkbox.d.ts +50 -0
  272. package/esm/components/inputs/checkbox.d.ts.map +1 -0
  273. package/esm/components/inputs/checkbox.js +126 -0
  274. package/esm/components/inputs/checkbox.js.map +1 -0
  275. package/esm/components/inputs/checkbox.spec.d.ts +2 -0
  276. package/esm/components/inputs/checkbox.spec.d.ts.map +1 -0
  277. package/esm/components/inputs/checkbox.spec.js +287 -0
  278. package/esm/components/inputs/checkbox.spec.js.map +1 -0
  279. package/esm/components/inputs/index.d.ts +7 -0
  280. package/esm/components/inputs/index.d.ts.map +1 -1
  281. package/esm/components/inputs/index.js +7 -0
  282. package/esm/components/inputs/index.js.map +1 -1
  283. package/esm/components/inputs/input-number.d.ts +79 -0
  284. package/esm/components/inputs/input-number.d.ts.map +1 -0
  285. package/esm/components/inputs/input-number.js +232 -0
  286. package/esm/components/inputs/input-number.js.map +1 -0
  287. package/esm/components/inputs/input-number.spec.d.ts +2 -0
  288. package/esm/components/inputs/input-number.spec.d.ts.map +1 -0
  289. package/esm/components/inputs/input-number.spec.js +516 -0
  290. package/esm/components/inputs/input-number.spec.js.map +1 -0
  291. package/esm/components/inputs/input.d.ts +2 -1
  292. package/esm/components/inputs/input.d.ts.map +1 -1
  293. package/esm/components/inputs/input.js +86 -116
  294. package/esm/components/inputs/input.js.map +1 -1
  295. package/esm/components/inputs/input.spec.js +461 -427
  296. package/esm/components/inputs/input.spec.js.map +1 -1
  297. package/esm/components/inputs/radio-group.d.ts +38 -0
  298. package/esm/components/inputs/radio-group.d.ts.map +1 -0
  299. package/esm/components/inputs/radio-group.js +58 -0
  300. package/esm/components/inputs/radio-group.js.map +1 -0
  301. package/esm/components/inputs/radio-group.spec.d.ts +2 -0
  302. package/esm/components/inputs/radio-group.spec.d.ts.map +1 -0
  303. package/esm/components/inputs/radio-group.spec.js +201 -0
  304. package/esm/components/inputs/radio-group.spec.js.map +1 -0
  305. package/esm/components/inputs/radio.d.ts +42 -0
  306. package/esm/components/inputs/radio.d.ts.map +1 -0
  307. package/esm/components/inputs/radio.js +134 -0
  308. package/esm/components/inputs/radio.js.map +1 -0
  309. package/esm/components/inputs/radio.spec.d.ts +2 -0
  310. package/esm/components/inputs/radio.spec.d.ts.map +1 -0
  311. package/esm/components/inputs/radio.spec.js +211 -0
  312. package/esm/components/inputs/radio.spec.js.map +1 -0
  313. package/esm/components/inputs/select.d.ts +67 -0
  314. package/esm/components/inputs/select.d.ts.map +1 -0
  315. package/esm/components/inputs/select.js +581 -0
  316. package/esm/components/inputs/select.js.map +1 -0
  317. package/esm/components/inputs/select.spec.d.ts +2 -0
  318. package/esm/components/inputs/select.spec.d.ts.map +1 -0
  319. package/esm/components/inputs/select.spec.js +1009 -0
  320. package/esm/components/inputs/select.spec.js.map +1 -0
  321. package/esm/components/inputs/slider.d.ts +66 -0
  322. package/esm/components/inputs/slider.d.ts.map +1 -0
  323. package/esm/components/inputs/slider.js +526 -0
  324. package/esm/components/inputs/slider.js.map +1 -0
  325. package/esm/components/inputs/slider.spec.d.ts +2 -0
  326. package/esm/components/inputs/slider.spec.d.ts.map +1 -0
  327. package/esm/components/inputs/slider.spec.js +812 -0
  328. package/esm/components/inputs/slider.spec.js.map +1 -0
  329. package/esm/components/inputs/switch.d.ts +50 -0
  330. package/esm/components/inputs/switch.d.ts.map +1 -0
  331. package/esm/components/inputs/switch.js +138 -0
  332. package/esm/components/inputs/switch.js.map +1 -0
  333. package/esm/components/inputs/switch.spec.d.ts +2 -0
  334. package/esm/components/inputs/switch.spec.d.ts.map +1 -0
  335. package/esm/components/inputs/switch.spec.js +313 -0
  336. package/esm/components/inputs/switch.spec.js.map +1 -0
  337. package/esm/components/inputs/text-area.d.ts +2 -0
  338. package/esm/components/inputs/text-area.d.ts.map +1 -1
  339. package/esm/components/inputs/text-area.js +13 -21
  340. package/esm/components/inputs/text-area.js.map +1 -1
  341. package/esm/components/inputs/text-area.spec.js +171 -156
  342. package/esm/components/inputs/text-area.spec.js.map +1 -1
  343. package/esm/components/linear-progress.d.ts +32 -0
  344. package/esm/components/linear-progress.d.ts.map +1 -0
  345. package/esm/components/linear-progress.js +79 -0
  346. package/esm/components/linear-progress.js.map +1 -0
  347. package/esm/components/linear-progress.spec.d.ts +2 -0
  348. package/esm/components/linear-progress.spec.d.ts.map +1 -0
  349. package/esm/components/linear-progress.spec.js +251 -0
  350. package/esm/components/linear-progress.spec.js.map +1 -0
  351. package/esm/components/list/index.d.ts +3 -0
  352. package/esm/components/list/index.d.ts.map +1 -0
  353. package/esm/components/list/index.js +3 -0
  354. package/esm/components/list/index.js.map +1 -0
  355. package/esm/components/list/list-item.d.ts +13 -0
  356. package/esm/components/list/list-item.d.ts.map +1 -0
  357. package/esm/components/list/list-item.js +81 -0
  358. package/esm/components/list/list-item.js.map +1 -0
  359. package/esm/components/list/list.d.ts +18 -0
  360. package/esm/components/list/list.d.ts.map +1 -0
  361. package/esm/components/list/list.js +42 -0
  362. package/esm/components/list/list.js.map +1 -0
  363. package/esm/components/list/list.spec.d.ts +2 -0
  364. package/esm/components/list/list.spec.d.ts.map +1 -0
  365. package/esm/components/list/list.spec.js +540 -0
  366. package/esm/components/list/list.spec.js.map +1 -0
  367. package/esm/components/loader.d.ts +2 -0
  368. package/esm/components/loader.d.ts.map +1 -1
  369. package/esm/components/loader.js +18 -10
  370. package/esm/components/loader.js.map +1 -1
  371. package/esm/components/loader.spec.js +191 -175
  372. package/esm/components/loader.spec.js.map +1 -1
  373. package/esm/components/menu/index.d.ts +3 -0
  374. package/esm/components/menu/index.d.ts.map +1 -0
  375. package/esm/components/menu/index.js +3 -0
  376. package/esm/components/menu/index.js.map +1 -0
  377. package/esm/components/menu/menu-types.d.ts +27 -0
  378. package/esm/components/menu/menu-types.d.ts.map +1 -0
  379. package/esm/components/menu/menu-types.js +22 -0
  380. package/esm/components/menu/menu-types.js.map +1 -0
  381. package/esm/components/menu/menu-types.spec.d.ts +2 -0
  382. package/esm/components/menu/menu-types.spec.d.ts.map +1 -0
  383. package/esm/components/menu/menu-types.spec.js +103 -0
  384. package/esm/components/menu/menu-types.spec.js.map +1 -0
  385. package/esm/components/menu/menu.d.ts +17 -0
  386. package/esm/components/menu/menu.d.ts.map +1 -0
  387. package/esm/components/menu/menu.js +240 -0
  388. package/esm/components/menu/menu.js.map +1 -0
  389. package/esm/components/menu/menu.spec.d.ts +2 -0
  390. package/esm/components/menu/menu.spec.d.ts.map +1 -0
  391. package/esm/components/menu/menu.spec.js +427 -0
  392. package/esm/components/menu/menu.spec.js.map +1 -0
  393. package/esm/components/modal.d.ts +3 -2
  394. package/esm/components/modal.d.ts.map +1 -1
  395. package/esm/components/modal.js +8 -5
  396. package/esm/components/modal.js.map +1 -1
  397. package/esm/components/modal.spec.js +50 -43
  398. package/esm/components/modal.spec.js.map +1 -1
  399. package/esm/components/noty-list.d.ts +4 -0
  400. package/esm/components/noty-list.d.ts.map +1 -1
  401. package/esm/components/noty-list.js +65 -53
  402. package/esm/components/noty-list.js.map +1 -1
  403. package/esm/components/noty-list.spec.js +71 -68
  404. package/esm/components/noty-list.spec.js.map +1 -1
  405. package/esm/components/page-container/index.d.ts +54 -0
  406. package/esm/components/page-container/index.d.ts.map +1 -0
  407. package/esm/components/page-container/index.js +63 -0
  408. package/esm/components/page-container/index.js.map +1 -0
  409. package/esm/components/page-container/index.spec.d.ts +2 -0
  410. package/esm/components/page-container/index.spec.d.ts.map +1 -0
  411. package/esm/components/page-container/index.spec.js +217 -0
  412. package/esm/components/page-container/index.spec.js.map +1 -0
  413. package/esm/components/page-container/page-header.d.ts +57 -0
  414. package/esm/components/page-container/page-header.d.ts.map +1 -0
  415. package/esm/components/page-container/page-header.js +93 -0
  416. package/esm/components/page-container/page-header.js.map +1 -0
  417. package/esm/components/page-container/page-header.spec.d.ts +2 -0
  418. package/esm/components/page-container/page-header.spec.d.ts.map +1 -0
  419. package/esm/components/page-container/page-header.spec.js +230 -0
  420. package/esm/components/page-container/page-header.spec.js.map +1 -0
  421. package/esm/components/page-layout/index.d.ts +83 -0
  422. package/esm/components/page-layout/index.d.ts.map +1 -0
  423. package/esm/components/page-layout/index.js +288 -0
  424. package/esm/components/page-layout/index.js.map +1 -0
  425. package/esm/components/page-layout/index.spec.d.ts +2 -0
  426. package/esm/components/page-layout/index.spec.d.ts.map +1 -0
  427. package/esm/components/page-layout/index.spec.js +637 -0
  428. package/esm/components/page-layout/index.spec.js.map +1 -0
  429. package/esm/components/pagination.d.ts +43 -0
  430. package/esm/components/pagination.d.ts.map +1 -0
  431. package/esm/components/pagination.js +165 -0
  432. package/esm/components/pagination.js.map +1 -0
  433. package/esm/components/pagination.spec.d.ts +2 -0
  434. package/esm/components/pagination.spec.d.ts.map +1 -0
  435. package/esm/components/pagination.spec.js +195 -0
  436. package/esm/components/pagination.spec.js.map +1 -0
  437. package/esm/components/paper.d.ts +3 -1
  438. package/esm/components/paper.d.ts.map +1 -1
  439. package/esm/components/paper.js +11 -9
  440. package/esm/components/paper.js.map +1 -1
  441. package/esm/components/paper.spec.js +26 -18
  442. package/esm/components/paper.spec.js.map +1 -1
  443. package/esm/components/rating.d.ts +62 -0
  444. package/esm/components/rating.d.ts.map +1 -0
  445. package/esm/components/rating.js +201 -0
  446. package/esm/components/rating.js.map +1 -0
  447. package/esm/components/rating.spec.d.ts +2 -0
  448. package/esm/components/rating.spec.d.ts.map +1 -0
  449. package/esm/components/rating.spec.js +663 -0
  450. package/esm/components/rating.spec.js.map +1 -0
  451. package/esm/components/result.d.ts +37 -0
  452. package/esm/components/result.d.ts.map +1 -0
  453. package/esm/components/result.js +109 -0
  454. package/esm/components/result.js.map +1 -0
  455. package/esm/components/result.spec.d.ts +2 -0
  456. package/esm/components/result.spec.d.ts.map +1 -0
  457. package/esm/components/result.spec.js +159 -0
  458. package/esm/components/result.spec.js.map +1 -0
  459. package/esm/components/searchable-input-styles.d.ts +8 -0
  460. package/esm/components/searchable-input-styles.d.ts.map +1 -0
  461. package/esm/components/searchable-input-styles.js +71 -0
  462. package/esm/components/searchable-input-styles.js.map +1 -0
  463. package/esm/components/skeleton.d.ts +2 -0
  464. package/esm/components/skeleton.d.ts.map +1 -1
  465. package/esm/components/skeleton.js +19 -6
  466. package/esm/components/skeleton.js.map +1 -1
  467. package/esm/components/skeleton.spec.js +103 -95
  468. package/esm/components/skeleton.spec.js.map +1 -1
  469. package/esm/components/styles.d.ts.map +1 -1
  470. package/esm/components/styles.js +14 -13
  471. package/esm/components/styles.js.map +1 -1
  472. package/esm/components/styles.spec.js +27 -26
  473. package/esm/components/styles.spec.js.map +1 -1
  474. package/esm/components/suggest/index.d.ts.map +1 -1
  475. package/esm/components/suggest/index.js +24 -85
  476. package/esm/components/suggest/index.js.map +1 -1
  477. package/esm/components/suggest/index.spec.js +402 -378
  478. package/esm/components/suggest/index.spec.js.map +1 -1
  479. package/esm/components/suggest/suggest-input.d.ts +2 -0
  480. package/esm/components/suggest/suggest-input.d.ts.map +1 -1
  481. package/esm/components/suggest/suggest-input.js +10 -8
  482. package/esm/components/suggest/suggest-input.js.map +1 -1
  483. package/esm/components/suggest/suggest-input.spec.js +83 -71
  484. package/esm/components/suggest/suggest-input.spec.js.map +1 -1
  485. package/esm/components/suggest/suggest-manager.spec.js +102 -92
  486. package/esm/components/suggest/suggest-manager.spec.js.map +1 -1
  487. package/esm/components/suggest/suggestion-list.d.ts.map +1 -1
  488. package/esm/components/suggest/suggestion-list.js +21 -22
  489. package/esm/components/suggest/suggestion-list.js.map +1 -1
  490. package/esm/components/suggest/suggestion-list.spec.js +165 -146
  491. package/esm/components/suggest/suggestion-list.spec.js.map +1 -1
  492. package/esm/components/tabs.d.ts +18 -2
  493. package/esm/components/tabs.d.ts.map +1 -1
  494. package/esm/components/tabs.js +154 -14
  495. package/esm/components/tabs.js.map +1 -1
  496. package/esm/components/tabs.spec.js +295 -7
  497. package/esm/components/tabs.spec.js.map +1 -1
  498. package/esm/components/timeline.d.ts +53 -0
  499. package/esm/components/timeline.d.ts.map +1 -0
  500. package/esm/components/timeline.js +162 -0
  501. package/esm/components/timeline.js.map +1 -0
  502. package/esm/components/timeline.spec.d.ts +2 -0
  503. package/esm/components/timeline.spec.d.ts.map +1 -0
  504. package/esm/components/timeline.spec.js +209 -0
  505. package/esm/components/timeline.spec.js.map +1 -0
  506. package/esm/components/tooltip.d.ts +25 -0
  507. package/esm/components/tooltip.d.ts.map +1 -0
  508. package/esm/components/tooltip.js +113 -0
  509. package/esm/components/tooltip.js.map +1 -0
  510. package/esm/components/tooltip.spec.d.ts +2 -0
  511. package/esm/components/tooltip.spec.d.ts.map +1 -0
  512. package/esm/components/tooltip.spec.js +152 -0
  513. package/esm/components/tooltip.spec.js.map +1 -0
  514. package/esm/components/tree/index.d.ts +3 -0
  515. package/esm/components/tree/index.d.ts.map +1 -0
  516. package/esm/components/tree/index.js +3 -0
  517. package/esm/components/tree/index.js.map +1 -0
  518. package/esm/components/tree/tree-item.d.ts +14 -0
  519. package/esm/components/tree/tree-item.d.ts.map +1 -0
  520. package/esm/components/tree/tree-item.js +118 -0
  521. package/esm/components/tree/tree-item.js.map +1 -0
  522. package/esm/components/tree/tree.d.ts +20 -0
  523. package/esm/components/tree/tree.d.ts.map +1 -0
  524. package/esm/components/tree/tree.js +66 -0
  525. package/esm/components/tree/tree.js.map +1 -0
  526. package/esm/components/tree/tree.spec.d.ts +2 -0
  527. package/esm/components/tree/tree.spec.d.ts.map +1 -0
  528. package/esm/components/tree/tree.spec.js +427 -0
  529. package/esm/components/tree/tree.spec.js.map +1 -0
  530. package/esm/components/typography.d.ts +48 -0
  531. package/esm/components/typography.d.ts.map +1 -0
  532. package/esm/components/typography.js +223 -0
  533. package/esm/components/typography.js.map +1 -0
  534. package/esm/components/typography.spec.d.ts +2 -0
  535. package/esm/components/typography.spec.d.ts.map +1 -0
  536. package/esm/components/typography.spec.js +199 -0
  537. package/esm/components/typography.spec.js.map +1 -0
  538. package/esm/components/wizard/index.d.ts +2 -0
  539. package/esm/components/wizard/index.d.ts.map +1 -1
  540. package/esm/components/wizard/index.spec.js +70 -56
  541. package/esm/components/wizard/index.spec.js.map +1 -1
  542. package/esm/services/click-away-service.d.ts +5 -2
  543. package/esm/services/click-away-service.d.ts.map +1 -1
  544. package/esm/services/click-away-service.js +7 -1
  545. package/esm/services/click-away-service.js.map +1 -1
  546. package/esm/services/click-away-service.spec.js +14 -12
  547. package/esm/services/click-away-service.spec.js.map +1 -1
  548. package/esm/services/css-variable-theme.d.ts +167 -1
  549. package/esm/services/css-variable-theme.d.ts.map +1 -1
  550. package/esm/services/css-variable-theme.js +102 -0
  551. package/esm/services/css-variable-theme.js.map +1 -1
  552. package/esm/services/css-variable-theme.spec.js +131 -1
  553. package/esm/services/css-variable-theme.spec.js.map +1 -1
  554. package/esm/services/default-dark-theme.d.ts +107 -2
  555. package/esm/services/default-dark-theme.d.ts.map +1 -1
  556. package/esm/services/default-dark-theme.js +87 -1
  557. package/esm/services/default-dark-theme.js.map +1 -1
  558. package/esm/services/default-light-theme.d.ts +107 -2
  559. package/esm/services/default-light-theme.d.ts.map +1 -1
  560. package/esm/services/default-light-theme.js +86 -0
  561. package/esm/services/default-light-theme.js.map +1 -1
  562. package/esm/services/index.d.ts +6 -2
  563. package/esm/services/index.d.ts.map +1 -1
  564. package/esm/services/index.js +6 -2
  565. package/esm/services/index.js.map +1 -1
  566. package/esm/services/layout-service.d.ts +217 -0
  567. package/esm/services/layout-service.d.ts.map +1 -0
  568. package/esm/services/layout-service.js +331 -0
  569. package/esm/services/layout-service.js.map +1 -0
  570. package/esm/services/layout-service.spec.d.ts +2 -0
  571. package/esm/services/layout-service.spec.d.ts.map +1 -0
  572. package/esm/services/layout-service.spec.js +425 -0
  573. package/esm/services/layout-service.spec.js.map +1 -0
  574. package/esm/services/list-service.d.ts +31 -0
  575. package/esm/services/list-service.d.ts.map +1 -0
  576. package/esm/services/list-service.js +149 -0
  577. package/esm/services/list-service.js.map +1 -0
  578. package/esm/services/list-service.spec.d.ts +2 -0
  579. package/esm/services/list-service.spec.d.ts.map +1 -0
  580. package/esm/services/list-service.spec.js +283 -0
  581. package/esm/services/list-service.spec.js.map +1 -0
  582. package/esm/services/palette-css-vars.d.ts +12 -0
  583. package/esm/services/palette-css-vars.d.ts.map +1 -0
  584. package/esm/services/palette-css-vars.js +44 -0
  585. package/esm/services/palette-css-vars.js.map +1 -0
  586. package/esm/services/theme-provider-service.d.ts +387 -2
  587. package/esm/services/theme-provider-service.d.ts.map +1 -1
  588. package/esm/services/theme-provider-service.js.map +1 -1
  589. package/esm/services/tree-service.d.ts +61 -0
  590. package/esm/services/tree-service.d.ts.map +1 -0
  591. package/esm/services/tree-service.js +149 -0
  592. package/esm/services/tree-service.js.map +1 -0
  593. package/esm/services/tree-service.spec.d.ts +2 -0
  594. package/esm/services/tree-service.spec.d.ts.map +1 -0
  595. package/esm/services/tree-service.spec.js +338 -0
  596. package/esm/services/tree-service.spec.js.map +1 -0
  597. package/esm/utils/promisify-animation.d.ts.map +1 -1
  598. package/esm/utils/promisify-animation.js +6 -1
  599. package/esm/utils/promisify-animation.js.map +1 -1
  600. package/package.json +7 -8
  601. package/src/components/accordion/accordion-item.tsx +197 -0
  602. package/src/components/accordion/accordion.spec.tsx +418 -0
  603. package/src/components/accordion/accordion.tsx +50 -0
  604. package/src/components/accordion/index.ts +2 -0
  605. package/src/components/alert.spec.tsx +256 -0
  606. package/src/components/alert.tsx +186 -0
  607. package/src/components/app-bar-link.spec.tsx +22 -19
  608. package/src/components/app-bar-link.tsx +29 -10
  609. package/src/components/app-bar.spec.tsx +73 -58
  610. package/src/components/app-bar.tsx +19 -12
  611. package/src/components/avatar.tsx +46 -47
  612. package/src/components/badge.spec.tsx +228 -0
  613. package/src/components/badge.tsx +104 -0
  614. package/src/components/breadcrumb.spec.tsx +396 -0
  615. package/src/components/breadcrumb.tsx +188 -0
  616. package/src/components/button-group.spec.tsx +611 -0
  617. package/src/components/button-group.tsx +423 -0
  618. package/src/components/button.spec.tsx +257 -67
  619. package/src/components/button.tsx +130 -80
  620. package/src/components/card.spec.tsx +389 -0
  621. package/src/components/card.tsx +261 -0
  622. package/src/components/carousel.spec.tsx +894 -0
  623. package/src/components/carousel.tsx +376 -0
  624. package/src/components/chip.spec.tsx +200 -0
  625. package/src/components/chip.tsx +188 -0
  626. package/src/components/circular-progress.spec.tsx +289 -0
  627. package/src/components/circular-progress.tsx +145 -0
  628. package/src/components/command-palette/command-palette-input.spec.tsx +219 -219
  629. package/src/components/command-palette/command-palette-input.tsx +25 -9
  630. package/src/components/command-palette/command-palette-manager.spec.ts +132 -117
  631. package/src/components/command-palette/command-palette-suggestion-list.spec.tsx +358 -358
  632. package/src/components/command-palette/command-palette-suggestion-list.tsx +22 -20
  633. package/src/components/command-palette/index.spec.tsx +12 -12
  634. package/src/components/command-palette/index.tsx +25 -102
  635. package/src/components/context-menu/context-menu-item.tsx +85 -0
  636. package/src/components/context-menu/context-menu-manager.spec.ts +433 -0
  637. package/src/components/context-menu/context-menu-manager.ts +148 -0
  638. package/src/components/context-menu/context-menu.spec.tsx +352 -0
  639. package/src/components/context-menu/context-menu.tsx +116 -0
  640. package/src/components/context-menu/index.ts +3 -0
  641. package/src/components/data-grid/body.spec.tsx +287 -283
  642. package/src/components/data-grid/data-grid-row.spec.tsx +165 -140
  643. package/src/components/data-grid/data-grid-row.tsx +72 -55
  644. package/src/components/data-grid/data-grid.spec.tsx +659 -729
  645. package/src/components/data-grid/data-grid.tsx +19 -15
  646. package/src/components/data-grid/footer.spec.tsx +249 -237
  647. package/src/components/data-grid/header.spec.tsx +374 -351
  648. package/src/components/data-grid/header.tsx +58 -39
  649. package/src/components/data-grid/selection-cell.spec.tsx +46 -45
  650. package/src/components/data-grid/selection-cell.tsx +2 -6
  651. package/src/components/dialog.spec.tsx +135 -0
  652. package/src/components/dialog.tsx +277 -0
  653. package/src/components/divider.spec.tsx +197 -0
  654. package/src/components/divider.tsx +147 -0
  655. package/src/components/drawer/drawer-toggle-button.spec.tsx +374 -0
  656. package/src/components/drawer/drawer-toggle-button.tsx +124 -0
  657. package/src/components/drawer/index.spec.tsx +748 -0
  658. package/src/components/drawer/index.tsx +227 -0
  659. package/src/components/dropdown.spec.tsx +445 -0
  660. package/src/components/dropdown.tsx +343 -0
  661. package/src/components/fab.spec.tsx +51 -40
  662. package/src/components/fab.tsx +32 -9
  663. package/src/components/form.spec.tsx +303 -293
  664. package/src/components/form.tsx +10 -7
  665. package/src/components/grid.spec.tsx +276 -183
  666. package/src/components/grid.tsx +10 -10
  667. package/src/components/icons/icon-definitions.spec.ts +68 -0
  668. package/src/components/icons/icon-definitions.ts +509 -0
  669. package/src/components/icons/icon-types.ts +48 -0
  670. package/src/components/icons/icon.spec.tsx +314 -0
  671. package/src/components/icons/icon.tsx +111 -0
  672. package/src/components/icons/index.ts +4 -0
  673. package/src/components/image.spec.tsx +748 -0
  674. package/src/components/image.tsx +520 -0
  675. package/src/components/index.ts +32 -4
  676. package/src/components/inputs/autocomplete.spec.tsx +10 -1
  677. package/src/components/inputs/autocomplete.tsx +13 -7
  678. package/src/components/inputs/checkbox.spec.tsx +377 -0
  679. package/src/components/inputs/checkbox.tsx +198 -0
  680. package/src/components/inputs/index.ts +7 -0
  681. package/src/components/inputs/input-number.spec.tsx +686 -0
  682. package/src/components/inputs/input-number.tsx +387 -0
  683. package/src/components/inputs/input.spec.tsx +544 -508
  684. package/src/components/inputs/input.tsx +91 -132
  685. package/src/components/inputs/radio-group.spec.tsx +281 -0
  686. package/src/components/inputs/radio-group.tsx +108 -0
  687. package/src/components/inputs/radio.spec.tsx +273 -0
  688. package/src/components/inputs/radio.tsx +199 -0
  689. package/src/components/inputs/select.spec.tsx +1237 -0
  690. package/src/components/inputs/select.tsx +775 -0
  691. package/src/components/inputs/slider.spec.tsx +1020 -0
  692. package/src/components/inputs/slider.tsx +696 -0
  693. package/src/components/inputs/switch.spec.tsx +410 -0
  694. package/src/components/inputs/switch.tsx +218 -0
  695. package/src/components/inputs/text-area.spec.tsx +186 -171
  696. package/src/components/inputs/text-area.tsx +13 -19
  697. package/src/components/linear-progress.spec.tsx +320 -0
  698. package/src/components/linear-progress.tsx +127 -0
  699. package/src/components/list/index.ts +2 -0
  700. package/src/components/list/list-item.tsx +106 -0
  701. package/src/components/list/list.spec.tsx +817 -0
  702. package/src/components/list/list.tsx +92 -0
  703. package/src/components/loader.spec.tsx +220 -204
  704. package/src/components/loader.tsx +17 -9
  705. package/src/components/menu/index.ts +2 -0
  706. package/src/components/menu/menu-types.spec.ts +122 -0
  707. package/src/components/menu/menu-types.ts +43 -0
  708. package/src/components/menu/menu.spec.tsx +483 -0
  709. package/src/components/menu/menu.tsx +326 -0
  710. package/src/components/modal.spec.tsx +65 -55
  711. package/src/components/modal.tsx +9 -6
  712. package/src/components/noty-list.spec.tsx +78 -75
  713. package/src/components/noty-list.tsx +76 -68
  714. package/src/components/page-container/index.spec.tsx +274 -0
  715. package/src/components/page-container/index.tsx +82 -0
  716. package/src/components/page-container/page-header.spec.tsx +308 -0
  717. package/src/components/page-container/page-header.tsx +127 -0
  718. package/src/components/page-layout/index.spec.tsx +882 -0
  719. package/src/components/page-layout/index.tsx +392 -0
  720. package/src/components/pagination.spec.tsx +275 -0
  721. package/src/components/pagination.tsx +249 -0
  722. package/src/components/paper.spec.tsx +26 -18
  723. package/src/components/paper.tsx +12 -10
  724. package/src/components/rating.spec.tsx +866 -0
  725. package/src/components/rating.tsx +286 -0
  726. package/src/components/result.spec.tsx +221 -0
  727. package/src/components/result.tsx +155 -0
  728. package/src/components/searchable-input-styles.ts +81 -0
  729. package/src/components/skeleton.spec.tsx +126 -118
  730. package/src/components/skeleton.tsx +23 -6
  731. package/src/components/styles.spec.ts +27 -28
  732. package/src/components/styles.tsx +15 -13
  733. package/src/components/suggest/index.spec.tsx +611 -587
  734. package/src/components/suggest/index.tsx +28 -95
  735. package/src/components/suggest/suggest-input.spec.tsx +95 -81
  736. package/src/components/suggest/suggest-input.tsx +9 -7
  737. package/src/components/suggest/suggest-manager.spec.ts +103 -93
  738. package/src/components/suggest/suggestion-list.spec.tsx +194 -173
  739. package/src/components/suggest/suggestion-list.tsx +23 -22
  740. package/src/components/tabs.spec.tsx +369 -7
  741. package/src/components/tabs.tsx +221 -18
  742. package/src/components/timeline.spec.tsx +294 -0
  743. package/src/components/timeline.tsx +221 -0
  744. package/src/components/tooltip.spec.tsx +223 -0
  745. package/src/components/tooltip.tsx +155 -0
  746. package/src/components/tree/index.ts +2 -0
  747. package/src/components/tree/tree-item.tsx +161 -0
  748. package/src/components/tree/tree.spec.tsx +677 -0
  749. package/src/components/tree/tree.tsx +111 -0
  750. package/src/components/typography.spec.tsx +235 -0
  751. package/src/components/typography.tsx +292 -0
  752. package/src/components/wizard/index.spec.tsx +77 -68
  753. package/src/services/click-away-service.spec.ts +14 -16
  754. package/src/services/click-away-service.ts +9 -3
  755. package/src/services/css-variable-theme.spec.ts +169 -1
  756. package/src/services/css-variable-theme.ts +107 -2
  757. package/src/services/default-dark-theme.ts +89 -3
  758. package/src/services/default-light-theme.ts +88 -2
  759. package/src/services/index.ts +6 -2
  760. package/src/services/layout-service.spec.ts +535 -0
  761. package/src/services/layout-service.ts +391 -0
  762. package/src/services/list-service.spec.ts +362 -0
  763. package/src/services/list-service.ts +169 -0
  764. package/src/services/palette-css-vars.ts +46 -0
  765. package/src/services/theme-provider-service.ts +246 -1
  766. package/src/services/tree-service.spec.ts +412 -0
  767. package/src/services/tree-service.ts +179 -0
  768. package/src/utils/promisify-animation.ts +7 -1
@@ -1,6 +1,7 @@
1
+ import type { FindOptions } from '@furystack/core'
1
2
  import { Injector } from '@furystack/inject'
2
3
  import { createComponent, initializeShadeRoot } from '@furystack/shades'
3
- import { ObservableValue, sleepAsync } from '@furystack/utils'
4
+ import { ObservableValue, sleepAsync, usingAsync } from '@furystack/utils'
4
5
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
5
6
  import { CollectionService } from '../../services/collection-service.js'
6
7
  import { DataGrid } from './data-grid.js'
@@ -29,227 +30,189 @@ describe('DataGrid', () => {
29
30
  return service
30
31
  }
31
32
 
33
+ const withTestGrid = async (
34
+ fn: (ctx: {
35
+ injector: Injector
36
+ service: CollectionService<TestEntry>
37
+ findOptions: ObservableValue<FindOptions<TestEntry, Array<keyof TestEntry>>>
38
+ }) => Promise<void>,
39
+ opts?: { createService?: () => CollectionService<TestEntry> },
40
+ ) => {
41
+ await usingAsync(new Injector(), async (injector) => {
42
+ await usingAsync(opts?.createService?.() ?? createTestService(), async (service) => {
43
+ await usingAsync(
44
+ new ObservableValue<FindOptions<TestEntry, Array<keyof TestEntry>>>({}),
45
+ async (findOptions) => {
46
+ await fn({ injector, service, findOptions })
47
+ },
48
+ )
49
+ })
50
+ })
51
+ }
52
+
32
53
  describe('rendering', () => {
33
54
  it('should render with columns', async () => {
34
- const injector = new Injector()
35
- const rootElement = document.getElementById('root') as HTMLDivElement
36
- const service = createTestService()
37
- const findOptions = new ObservableValue<any>({})
38
-
39
- initializeShadeRoot({
40
- injector,
41
- rootElement,
42
- jsxElement: (
43
- <DataGrid<TestEntry, 'id' | 'name'>
44
- columns={['id', 'name']}
45
- collectionService={service}
46
- findOptions={findOptions}
47
- styles={{}}
48
- headerComponents={{}}
49
- rowComponents={{}}
50
- />
51
- ),
52
- })
55
+ await withTestGrid(async ({ injector, service, findOptions }) => {
56
+ const rootElement = document.getElementById('root') as HTMLDivElement
53
57
 
54
- await sleepAsync(50)
58
+ initializeShadeRoot({
59
+ injector,
60
+ rootElement,
61
+ jsxElement: (
62
+ <DataGrid<TestEntry, 'id' | 'name'>
63
+ columns={['id', 'name']}
64
+ collectionService={service}
65
+ findOptions={findOptions}
66
+ styles={{}}
67
+ headerComponents={{}}
68
+ rowComponents={{}}
69
+ />
70
+ ),
71
+ })
55
72
 
56
- const grid = document.querySelector('shade-data-grid')
57
- expect(grid).not.toBeNull()
73
+ await sleepAsync(50)
58
74
 
59
- const headers = grid?.querySelectorAll('th')
60
- expect(headers?.length).toBe(2)
75
+ const grid = document.querySelector('shade-data-grid')
76
+ expect(grid).not.toBeNull()
61
77
 
62
- service[Symbol.dispose]()
63
- findOptions[Symbol.dispose]()
78
+ const headers = grid?.querySelectorAll('th')
79
+ expect(headers?.length).toBe(2)
80
+ })
64
81
  })
65
82
 
66
83
  it('should render table structure', async () => {
67
- const injector = new Injector()
68
- const rootElement = document.getElementById('root') as HTMLDivElement
69
- const service = createTestService()
70
- const findOptions = new ObservableValue<any>({})
71
-
72
- initializeShadeRoot({
73
- injector,
74
- rootElement,
75
- jsxElement: (
76
- <DataGrid<TestEntry, 'id' | 'name'>
77
- columns={['id', 'name']}
78
- collectionService={service}
79
- findOptions={findOptions}
80
- styles={{}}
81
- headerComponents={{}}
82
- rowComponents={{}}
83
- />
84
- ),
85
- })
84
+ await withTestGrid(async ({ injector, service, findOptions }) => {
85
+ const rootElement = document.getElementById('root') as HTMLDivElement
86
86
 
87
- await sleepAsync(50)
87
+ initializeShadeRoot({
88
+ injector,
89
+ rootElement,
90
+ jsxElement: (
91
+ <DataGrid<TestEntry, 'id' | 'name'>
92
+ columns={['id', 'name']}
93
+ collectionService={service}
94
+ findOptions={findOptions}
95
+ styles={{}}
96
+ headerComponents={{}}
97
+ rowComponents={{}}
98
+ />
99
+ ),
100
+ })
88
101
 
89
- const grid = document.querySelector('shade-data-grid')
90
- const table = grid?.querySelector('table')
91
- const thead = grid?.querySelector('thead')
92
- const tbody = grid?.querySelector('tbody')
102
+ await sleepAsync(50)
93
103
 
94
- expect(table).not.toBeNull()
95
- expect(thead).not.toBeNull()
96
- expect(tbody).not.toBeNull()
104
+ const grid = document.querySelector('shade-data-grid')
105
+ const table = grid?.querySelector('table')
106
+ const thead = grid?.querySelector('thead')
107
+ const tbody = grid?.querySelector('tbody')
97
108
 
98
- service[Symbol.dispose]()
99
- findOptions[Symbol.dispose]()
109
+ expect(table).not.toBeNull()
110
+ expect(thead).not.toBeNull()
111
+ expect(tbody).not.toBeNull()
112
+ })
100
113
  })
101
114
 
102
115
  it('should render custom header components when provided', async () => {
103
- const injector = new Injector()
104
- const rootElement = document.getElementById('root') as HTMLDivElement
105
- const service = createTestService()
106
- const findOptions = new ObservableValue<any>({})
107
-
108
- initializeShadeRoot({
109
- injector,
110
- rootElement,
111
- jsxElement: (
112
- <DataGrid<TestEntry, 'id' | 'name'>
113
- columns={['id', 'name']}
114
- collectionService={service}
115
- findOptions={findOptions}
116
- styles={{}}
117
- headerComponents={{
118
- id: () => <span data-testid="custom-header-id">Custom ID Header</span>,
119
- }}
120
- rowComponents={{}}
121
- />
122
- ),
123
- })
116
+ await withTestGrid(async ({ injector, service, findOptions }) => {
117
+ const rootElement = document.getElementById('root') as HTMLDivElement
124
118
 
125
- await sleepAsync(50)
119
+ initializeShadeRoot({
120
+ injector,
121
+ rootElement,
122
+ jsxElement: (
123
+ <DataGrid<TestEntry, 'id' | 'name'>
124
+ columns={['id', 'name']}
125
+ collectionService={service}
126
+ findOptions={findOptions}
127
+ styles={{}}
128
+ headerComponents={{
129
+ id: () => <span data-testid="custom-header-id">Custom ID Header</span>,
130
+ }}
131
+ rowComponents={{}}
132
+ />
133
+ ),
134
+ })
126
135
 
127
- const grid = document.querySelector('shade-data-grid')
128
- const customHeader = grid?.querySelector('[data-testid="custom-header-id"]')
129
- expect(customHeader).not.toBeNull()
130
- expect(customHeader?.textContent).toBe('Custom ID Header')
136
+ await sleepAsync(50)
131
137
 
132
- service[Symbol.dispose]()
133
- findOptions[Symbol.dispose]()
138
+ const grid = document.querySelector('shade-data-grid')
139
+ const customHeader = grid?.querySelector('[data-testid="custom-header-id"]')
140
+ expect(customHeader).not.toBeNull()
141
+ expect(customHeader?.textContent).toBe('Custom ID Header')
142
+ })
134
143
  })
135
144
 
136
145
  it('should render default header components from headerComponents.default', async () => {
137
- const injector = new Injector()
138
- const rootElement = document.getElementById('root') as HTMLDivElement
139
- const service = createTestService()
140
- const findOptions = new ObservableValue<any>({})
141
-
142
- initializeShadeRoot({
143
- injector,
144
- rootElement,
145
- jsxElement: (
146
- <DataGrid<TestEntry, 'id' | 'name'>
147
- columns={['id', 'name']}
148
- collectionService={service}
149
- findOptions={findOptions}
150
- styles={{}}
151
- headerComponents={{
152
- default: (name) => <span data-testid={`default-header-${name}`}>Default: {name}</span>,
153
- }}
154
- rowComponents={{}}
155
- />
156
- ),
157
- })
146
+ await withTestGrid(async ({ injector, service, findOptions }) => {
147
+ const rootElement = document.getElementById('root') as HTMLDivElement
158
148
 
159
- await sleepAsync(50)
149
+ initializeShadeRoot({
150
+ injector,
151
+ rootElement,
152
+ jsxElement: (
153
+ <DataGrid<TestEntry, 'id' | 'name'>
154
+ columns={['id', 'name']}
155
+ collectionService={service}
156
+ findOptions={findOptions}
157
+ styles={{}}
158
+ headerComponents={{
159
+ default: (name) => <span data-testid={`default-header-${name}`}>Default: {name}</span>,
160
+ }}
161
+ rowComponents={{}}
162
+ />
163
+ ),
164
+ })
160
165
 
161
- const grid = document.querySelector('shade-data-grid')
162
- const defaultHeaderId = grid?.querySelector('[data-testid="default-header-id"]')
163
- const defaultHeaderName = grid?.querySelector('[data-testid="default-header-name"]')
166
+ await sleepAsync(50)
164
167
 
165
- expect(defaultHeaderId?.textContent).toBe('Default: id')
166
- expect(defaultHeaderName?.textContent).toBe('Default: name')
168
+ const grid = document.querySelector('shade-data-grid')
169
+ const defaultHeaderId = grid?.querySelector('[data-testid="default-header-id"]')
170
+ const defaultHeaderName = grid?.querySelector('[data-testid="default-header-name"]')
167
171
 
168
- service[Symbol.dispose]()
169
- findOptions[Symbol.dispose]()
172
+ expect(defaultHeaderId?.textContent).toBe('Default: id')
173
+ expect(defaultHeaderName?.textContent).toBe('Default: name')
174
+ })
170
175
  })
171
176
 
172
177
  it('should render DataGridHeader when no custom header is provided', async () => {
173
- const injector = new Injector()
174
- const rootElement = document.getElementById('root') as HTMLDivElement
175
- const service = createTestService()
176
- const findOptions = new ObservableValue<any>({})
177
-
178
- initializeShadeRoot({
179
- injector,
180
- rootElement,
181
- jsxElement: (
182
- <DataGrid<TestEntry, 'id' | 'name'>
183
- columns={['id', 'name']}
184
- collectionService={service}
185
- findOptions={findOptions}
186
- styles={{}}
187
- headerComponents={{}}
188
- rowComponents={{}}
189
- />
190
- ),
191
- })
178
+ await withTestGrid(async ({ injector, service, findOptions }) => {
179
+ const rootElement = document.getElementById('root') as HTMLDivElement
192
180
 
193
- await sleepAsync(50)
181
+ initializeShadeRoot({
182
+ injector,
183
+ rootElement,
184
+ jsxElement: (
185
+ <DataGrid<TestEntry, 'id' | 'name'>
186
+ columns={['id', 'name']}
187
+ collectionService={service}
188
+ findOptions={findOptions}
189
+ styles={{}}
190
+ headerComponents={{}}
191
+ rowComponents={{}}
192
+ />
193
+ ),
194
+ })
194
195
 
195
- const grid = document.querySelector('shade-data-grid')
196
- const defaultHeaders = grid?.querySelectorAll('data-grid-header')
197
- expect(defaultHeaders?.length).toBe(2)
196
+ await sleepAsync(50)
198
197
 
199
- service[Symbol.dispose]()
200
- findOptions[Symbol.dispose]()
198
+ const grid = document.querySelector('shade-data-grid')
199
+ const defaultHeaders = grid?.querySelectorAll('data-grid-header')
200
+ expect(defaultHeaders?.length).toBe(2)
201
+ })
201
202
  })
202
203
  })
203
204
 
204
205
  describe('focus management', () => {
205
206
  it('should set focus on click', async () => {
206
- const injector = new Injector()
207
- const rootElement = document.getElementById('root') as HTMLDivElement
208
- const service = createTestService()
209
- const findOptions = new ObservableValue<any>({})
210
-
211
- expect(service.hasFocus.getValue()).toBe(false)
212
-
213
- initializeShadeRoot({
214
- injector,
215
- rootElement,
216
- jsxElement: (
217
- <DataGrid<TestEntry, 'id' | 'name'>
218
- columns={['id', 'name']}
219
- collectionService={service}
220
- findOptions={findOptions}
221
- styles={{}}
222
- headerComponents={{}}
223
- rowComponents={{}}
224
- />
225
- ),
226
- })
227
-
228
- await sleepAsync(50)
229
-
230
- const grid = document.querySelector('shade-data-grid')
231
- const wrapper = grid?.querySelector('.shade-grid-wrapper') as HTMLElement
207
+ await withTestGrid(async ({ injector, service, findOptions }) => {
208
+ const rootElement = document.getElementById('root') as HTMLDivElement
232
209
 
233
- wrapper?.click()
210
+ expect(service.hasFocus.getValue()).toBe(false)
234
211
 
235
- expect(service.hasFocus.getValue()).toBe(true)
236
-
237
- service[Symbol.dispose]()
238
- findOptions[Symbol.dispose]()
239
- })
240
-
241
- it('should lose focus on click outside', async () => {
242
- const injector = new Injector()
243
- const rootElement = document.getElementById('root') as HTMLDivElement
244
- const service = createTestService()
245
- const findOptions = new ObservableValue<any>({})
246
-
247
- initializeShadeRoot({
248
- injector,
249
- rootElement,
250
- jsxElement: (
251
- <>
252
- <div data-testid="outside">Outside</div>
212
+ initializeShadeRoot({
213
+ injector,
214
+ rootElement,
215
+ jsxElement: (
253
216
  <DataGrid<TestEntry, 'id' | 'name'>
254
217
  columns={['id', 'name']}
255
218
  collectionService={service}
@@ -258,682 +221,649 @@ describe('DataGrid', () => {
258
221
  headerComponents={{}}
259
222
  rowComponents={{}}
260
223
  />
261
- </>
262
- ),
263
- })
264
-
265
- await sleepAsync(50)
224
+ ),
225
+ })
266
226
 
267
- const grid = document.querySelector('shade-data-grid')
268
- const wrapper = grid?.querySelector('.shade-grid-wrapper') as HTMLElement
269
- wrapper?.click()
227
+ await sleepAsync(50)
270
228
 
271
- expect(service.hasFocus.getValue()).toBe(true)
229
+ const grid = document.querySelector('shade-data-grid')
230
+ const wrapper = grid?.querySelector('.shade-grid-wrapper') as HTMLElement
272
231
 
273
- const outside = document.querySelector('[data-testid="outside"]') as HTMLElement
274
- outside?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
232
+ wrapper?.click()
275
233
 
276
- expect(service.hasFocus.getValue()).toBe(false)
234
+ expect(service.hasFocus.getValue()).toBe(true)
235
+ })
236
+ })
277
237
 
278
- service[Symbol.dispose]()
279
- findOptions[Symbol.dispose]()
238
+ it('should lose focus on click outside', async () => {
239
+ await withTestGrid(async ({ injector, service, findOptions }) => {
240
+ const rootElement = document.getElementById('root') as HTMLDivElement
241
+
242
+ initializeShadeRoot({
243
+ injector,
244
+ rootElement,
245
+ jsxElement: (
246
+ <>
247
+ <div data-testid="outside">Outside</div>
248
+ <DataGrid<TestEntry, 'id' | 'name'>
249
+ columns={['id', 'name']}
250
+ collectionService={service}
251
+ findOptions={findOptions}
252
+ styles={{}}
253
+ headerComponents={{}}
254
+ rowComponents={{}}
255
+ />
256
+ </>
257
+ ),
258
+ })
259
+
260
+ await sleepAsync(50)
261
+
262
+ const grid = document.querySelector('shade-data-grid')
263
+ const wrapper = grid?.querySelector('.shade-grid-wrapper') as HTMLElement
264
+ wrapper?.click()
265
+
266
+ expect(service.hasFocus.getValue()).toBe(true)
267
+
268
+ const outside = document.querySelector('[data-testid="outside"]') as HTMLElement
269
+ outside?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
270
+
271
+ expect(service.hasFocus.getValue()).toBe(false)
272
+ })
280
273
  })
281
274
  })
282
275
 
283
276
  describe('keyboard navigation', () => {
284
277
  it('should handle ArrowDown to move focus to next entry', async () => {
285
- const injector = new Injector()
286
- const rootElement = document.getElementById('root') as HTMLDivElement
287
- const service = createTestService()
288
- const findOptions = new ObservableValue<any>({})
289
-
290
- service.hasFocus.setValue(true)
291
- service.focusedEntry.setValue(service.data.getValue().entries[0])
292
-
293
- initializeShadeRoot({
294
- injector,
295
- rootElement,
296
- jsxElement: (
297
- <DataGrid<TestEntry, 'id' | 'name'>
298
- columns={['id', 'name']}
299
- collectionService={service}
300
- findOptions={findOptions}
301
- styles={{}}
302
- headerComponents={{}}
303
- rowComponents={{}}
304
- />
305
- ),
306
- })
278
+ await withTestGrid(async ({ injector, service, findOptions }) => {
279
+ const rootElement = document.getElementById('root') as HTMLDivElement
307
280
 
308
- await sleepAsync(50)
281
+ service.hasFocus.setValue(true)
282
+ service.focusedEntry.setValue(service.data.getValue().entries[0])
283
+
284
+ initializeShadeRoot({
285
+ injector,
286
+ rootElement,
287
+ jsxElement: (
288
+ <DataGrid<TestEntry, 'id' | 'name'>
289
+ columns={['id', 'name']}
290
+ collectionService={service}
291
+ findOptions={findOptions}
292
+ styles={{}}
293
+ headerComponents={{}}
294
+ rowComponents={{}}
295
+ />
296
+ ),
297
+ })
309
298
 
310
- const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
311
- window.dispatchEvent(keydownEvent)
299
+ await sleepAsync(50)
312
300
 
313
- expect(service.focusedEntry.getValue()).toEqual({ id: 2, name: 'Second' })
301
+ const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
302
+ window.dispatchEvent(keydownEvent)
314
303
 
315
- service[Symbol.dispose]()
316
- findOptions[Symbol.dispose]()
304
+ expect(service.focusedEntry.getValue()).toEqual({ id: 2, name: 'Second' })
305
+ })
317
306
  })
318
307
 
319
308
  it('should handle ArrowUp to move focus to previous entry', async () => {
320
- const injector = new Injector()
321
- const rootElement = document.getElementById('root') as HTMLDivElement
322
- const service = createTestService()
323
- const findOptions = new ObservableValue<any>({})
324
-
325
- service.hasFocus.setValue(true)
326
- service.focusedEntry.setValue(service.data.getValue().entries[1])
327
-
328
- initializeShadeRoot({
329
- injector,
330
- rootElement,
331
- jsxElement: (
332
- <DataGrid<TestEntry, 'id' | 'name'>
333
- columns={['id', 'name']}
334
- collectionService={service}
335
- findOptions={findOptions}
336
- styles={{}}
337
- headerComponents={{}}
338
- rowComponents={{}}
339
- />
340
- ),
341
- })
309
+ await withTestGrid(async ({ injector, service, findOptions }) => {
310
+ const rootElement = document.getElementById('root') as HTMLDivElement
342
311
 
343
- await sleepAsync(50)
312
+ service.hasFocus.setValue(true)
313
+ service.focusedEntry.setValue(service.data.getValue().entries[1])
344
314
 
345
- const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true })
346
- window.dispatchEvent(keydownEvent)
315
+ initializeShadeRoot({
316
+ injector,
317
+ rootElement,
318
+ jsxElement: (
319
+ <DataGrid<TestEntry, 'id' | 'name'>
320
+ columns={['id', 'name']}
321
+ collectionService={service}
322
+ findOptions={findOptions}
323
+ styles={{}}
324
+ headerComponents={{}}
325
+ rowComponents={{}}
326
+ />
327
+ ),
328
+ })
329
+
330
+ await sleepAsync(50)
347
331
 
348
- expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
332
+ const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true })
333
+ window.dispatchEvent(keydownEvent)
349
334
 
350
- service[Symbol.dispose]()
351
- findOptions[Symbol.dispose]()
335
+ expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
336
+ })
352
337
  })
353
338
 
354
339
  it('should handle Home to move focus to first entry', async () => {
355
- const injector = new Injector()
356
- const rootElement = document.getElementById('root') as HTMLDivElement
357
- const service = createTestService()
358
- const findOptions = new ObservableValue<any>({})
359
-
360
- service.hasFocus.setValue(true)
361
- service.focusedEntry.setValue(service.data.getValue().entries[2])
362
-
363
- initializeShadeRoot({
364
- injector,
365
- rootElement,
366
- jsxElement: (
367
- <DataGrid<TestEntry, 'id' | 'name'>
368
- columns={['id', 'name']}
369
- collectionService={service}
370
- findOptions={findOptions}
371
- styles={{}}
372
- headerComponents={{}}
373
- rowComponents={{}}
374
- />
375
- ),
376
- })
340
+ await withTestGrid(async ({ injector, service, findOptions }) => {
341
+ const rootElement = document.getElementById('root') as HTMLDivElement
377
342
 
378
- await sleepAsync(50)
343
+ service.hasFocus.setValue(true)
344
+ service.focusedEntry.setValue(service.data.getValue().entries[2])
379
345
 
380
- const keydownEvent = new KeyboardEvent('keydown', { key: 'Home', bubbles: true })
381
- window.dispatchEvent(keydownEvent)
346
+ initializeShadeRoot({
347
+ injector,
348
+ rootElement,
349
+ jsxElement: (
350
+ <DataGrid<TestEntry, 'id' | 'name'>
351
+ columns={['id', 'name']}
352
+ collectionService={service}
353
+ findOptions={findOptions}
354
+ styles={{}}
355
+ headerComponents={{}}
356
+ rowComponents={{}}
357
+ />
358
+ ),
359
+ })
360
+
361
+ await sleepAsync(50)
382
362
 
383
- expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
363
+ const keydownEvent = new KeyboardEvent('keydown', { key: 'Home', bubbles: true })
364
+ window.dispatchEvent(keydownEvent)
384
365
 
385
- service[Symbol.dispose]()
386
- findOptions[Symbol.dispose]()
366
+ expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
367
+ })
387
368
  })
388
369
 
389
370
  it('should handle End to move focus to last entry', async () => {
390
- const injector = new Injector()
391
- const rootElement = document.getElementById('root') as HTMLDivElement
392
- const service = createTestService()
393
- const findOptions = new ObservableValue<any>({})
394
-
395
- service.hasFocus.setValue(true)
396
- service.focusedEntry.setValue(service.data.getValue().entries[0])
397
-
398
- initializeShadeRoot({
399
- injector,
400
- rootElement,
401
- jsxElement: (
402
- <DataGrid<TestEntry, 'id' | 'name'>
403
- columns={['id', 'name']}
404
- collectionService={service}
405
- findOptions={findOptions}
406
- styles={{}}
407
- headerComponents={{}}
408
- rowComponents={{}}
409
- />
410
- ),
411
- })
371
+ await withTestGrid(async ({ injector, service, findOptions }) => {
372
+ const rootElement = document.getElementById('root') as HTMLDivElement
412
373
 
413
- await sleepAsync(50)
374
+ service.hasFocus.setValue(true)
375
+ service.focusedEntry.setValue(service.data.getValue().entries[0])
376
+
377
+ initializeShadeRoot({
378
+ injector,
379
+ rootElement,
380
+ jsxElement: (
381
+ <DataGrid<TestEntry, 'id' | 'name'>
382
+ columns={['id', 'name']}
383
+ collectionService={service}
384
+ findOptions={findOptions}
385
+ styles={{}}
386
+ headerComponents={{}}
387
+ rowComponents={{}}
388
+ />
389
+ ),
390
+ })
414
391
 
415
- const keydownEvent = new KeyboardEvent('keydown', { key: 'End', bubbles: true })
416
- window.dispatchEvent(keydownEvent)
392
+ await sleepAsync(50)
417
393
 
418
- expect(service.focusedEntry.getValue()).toEqual({ id: 3, name: 'Third' })
394
+ const keydownEvent = new KeyboardEvent('keydown', { key: 'End', bubbles: true })
395
+ window.dispatchEvent(keydownEvent)
419
396
 
420
- service[Symbol.dispose]()
421
- findOptions[Symbol.dispose]()
397
+ expect(service.focusedEntry.getValue()).toEqual({ id: 3, name: 'Third' })
398
+ })
422
399
  })
423
400
 
424
401
  it('should handle Tab to toggle focus', async () => {
425
- const injector = new Injector()
426
- const rootElement = document.getElementById('root') as HTMLDivElement
427
- const service = createTestService()
428
- const findOptions = new ObservableValue<any>({})
429
-
430
- service.hasFocus.setValue(true)
431
-
432
- initializeShadeRoot({
433
- injector,
434
- rootElement,
435
- jsxElement: (
436
- <DataGrid<TestEntry, 'id' | 'name'>
437
- columns={['id', 'name']}
438
- collectionService={service}
439
- findOptions={findOptions}
440
- styles={{}}
441
- headerComponents={{}}
442
- rowComponents={{}}
443
- />
444
- ),
445
- })
402
+ await withTestGrid(async ({ injector, service, findOptions }) => {
403
+ const rootElement = document.getElementById('root') as HTMLDivElement
446
404
 
447
- await sleepAsync(50)
405
+ service.hasFocus.setValue(true)
448
406
 
449
- const keydownEvent = new KeyboardEvent('keydown', { key: 'Tab', bubbles: true })
450
- window.dispatchEvent(keydownEvent)
407
+ initializeShadeRoot({
408
+ injector,
409
+ rootElement,
410
+ jsxElement: (
411
+ <DataGrid<TestEntry, 'id' | 'name'>
412
+ columns={['id', 'name']}
413
+ collectionService={service}
414
+ findOptions={findOptions}
415
+ styles={{}}
416
+ headerComponents={{}}
417
+ rowComponents={{}}
418
+ />
419
+ ),
420
+ })
451
421
 
452
- expect(service.hasFocus.getValue()).toBe(false)
422
+ await sleepAsync(50)
453
423
 
454
- service[Symbol.dispose]()
455
- findOptions[Symbol.dispose]()
456
- })
424
+ const keydownEvent = new KeyboardEvent('keydown', { key: 'Tab', bubbles: true })
425
+ window.dispatchEvent(keydownEvent)
457
426
 
458
- it('should handle Escape to clear selection and search', async () => {
459
- const injector = new Injector()
460
- const rootElement = document.getElementById('root') as HTMLDivElement
461
- const service = createTestService()
462
- const findOptions = new ObservableValue<any>({})
463
-
464
- const { entries } = service.data.getValue()
465
- service.hasFocus.setValue(true)
466
- service.selection.setValue([entries[0], entries[1]])
467
- service.searchTerm.setValue('test')
468
-
469
- initializeShadeRoot({
470
- injector,
471
- rootElement,
472
- jsxElement: (
473
- <DataGrid<TestEntry, 'id' | 'name'>
474
- columns={['id', 'name']}
475
- collectionService={service}
476
- findOptions={findOptions}
477
- styles={{}}
478
- headerComponents={{}}
479
- rowComponents={{}}
480
- />
481
- ),
427
+ expect(service.hasFocus.getValue()).toBe(false)
482
428
  })
429
+ })
483
430
 
484
- await sleepAsync(50)
431
+ it('should handle Escape to clear selection and search', async () => {
432
+ await withTestGrid(async ({ injector, service, findOptions }) => {
433
+ const rootElement = document.getElementById('root') as HTMLDivElement
434
+
435
+ const { entries } = service.data.getValue()
436
+ service.hasFocus.setValue(true)
437
+ service.selection.setValue([entries[0], entries[1]])
438
+ service.searchTerm.setValue('test')
439
+
440
+ initializeShadeRoot({
441
+ injector,
442
+ rootElement,
443
+ jsxElement: (
444
+ <DataGrid<TestEntry, 'id' | 'name'>
445
+ columns={['id', 'name']}
446
+ collectionService={service}
447
+ findOptions={findOptions}
448
+ styles={{}}
449
+ headerComponents={{}}
450
+ rowComponents={{}}
451
+ />
452
+ ),
453
+ })
485
454
 
486
- const keydownEvent = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })
487
- window.dispatchEvent(keydownEvent)
455
+ await sleepAsync(50)
488
456
 
489
- expect(service.selection.getValue()).toEqual([])
490
- expect(service.searchTerm.getValue()).toBe('')
457
+ const keydownEvent = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })
458
+ window.dispatchEvent(keydownEvent)
491
459
 
492
- service[Symbol.dispose]()
493
- findOptions[Symbol.dispose]()
460
+ expect(service.selection.getValue()).toEqual([])
461
+ expect(service.searchTerm.getValue()).toBe('')
462
+ })
494
463
  })
495
464
 
496
465
  it('should handle Space to toggle selection of focused entry', async () => {
497
- const injector = new Injector()
498
- const rootElement = document.getElementById('root') as HTMLDivElement
499
- const service = createTestService()
500
- const findOptions = new ObservableValue<any>({})
501
-
502
- const { entries } = service.data.getValue()
503
- service.hasFocus.setValue(true)
504
- service.focusedEntry.setValue(entries[0])
505
-
506
- initializeShadeRoot({
507
- injector,
508
- rootElement,
509
- jsxElement: (
510
- <DataGrid<TestEntry, 'id' | 'name'>
511
- columns={['id', 'name']}
512
- collectionService={service}
513
- findOptions={findOptions}
514
- styles={{}}
515
- headerComponents={{}}
516
- rowComponents={{}}
517
- />
518
- ),
519
- })
466
+ await withTestGrid(async ({ injector, service, findOptions }) => {
467
+ const rootElement = document.getElementById('root') as HTMLDivElement
520
468
 
521
- await sleepAsync(50)
469
+ const { entries } = service.data.getValue()
470
+ service.hasFocus.setValue(true)
471
+ service.focusedEntry.setValue(entries[0])
522
472
 
523
- const keydownEvent = new KeyboardEvent('keydown', { key: ' ', bubbles: true })
524
- window.dispatchEvent(keydownEvent)
473
+ initializeShadeRoot({
474
+ injector,
475
+ rootElement,
476
+ jsxElement: (
477
+ <DataGrid<TestEntry, 'id' | 'name'>
478
+ columns={['id', 'name']}
479
+ collectionService={service}
480
+ findOptions={findOptions}
481
+ styles={{}}
482
+ headerComponents={{}}
483
+ rowComponents={{}}
484
+ />
485
+ ),
486
+ })
487
+
488
+ await sleepAsync(50)
525
489
 
526
- expect(service.selection.getValue()).toContain(entries[0])
490
+ const keydownEvent = new KeyboardEvent('keydown', { key: ' ', bubbles: true })
491
+ window.dispatchEvent(keydownEvent)
527
492
 
528
- window.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true }))
529
- expect(service.selection.getValue()).not.toContain(entries[0])
493
+ expect(service.selection.getValue()).toContain(entries[0])
530
494
 
531
- service[Symbol.dispose]()
532
- findOptions[Symbol.dispose]()
495
+ window.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true }))
496
+ expect(service.selection.getValue()).not.toContain(entries[0])
497
+ })
533
498
  })
534
499
 
535
500
  it('should handle + to select all entries', async () => {
536
- const injector = new Injector()
537
- const rootElement = document.getElementById('root') as HTMLDivElement
538
- const service = createTestService()
539
- const findOptions = new ObservableValue<any>({})
540
-
541
- service.hasFocus.setValue(true)
542
-
543
- initializeShadeRoot({
544
- injector,
545
- rootElement,
546
- jsxElement: (
547
- <DataGrid<TestEntry, 'id' | 'name'>
548
- columns={['id', 'name']}
549
- collectionService={service}
550
- findOptions={findOptions}
551
- styles={{}}
552
- headerComponents={{}}
553
- rowComponents={{}}
554
- />
555
- ),
556
- })
501
+ await withTestGrid(async ({ injector, service, findOptions }) => {
502
+ const rootElement = document.getElementById('root') as HTMLDivElement
557
503
 
558
- await sleepAsync(50)
504
+ service.hasFocus.setValue(true)
559
505
 
560
- const keydownEvent = new KeyboardEvent('keydown', { key: '+', bubbles: true })
561
- window.dispatchEvent(keydownEvent)
506
+ initializeShadeRoot({
507
+ injector,
508
+ rootElement,
509
+ jsxElement: (
510
+ <DataGrid<TestEntry, 'id' | 'name'>
511
+ columns={['id', 'name']}
512
+ collectionService={service}
513
+ findOptions={findOptions}
514
+ styles={{}}
515
+ headerComponents={{}}
516
+ rowComponents={{}}
517
+ />
518
+ ),
519
+ })
562
520
 
563
- expect(service.selection.getValue().length).toBe(3)
521
+ await sleepAsync(50)
564
522
 
565
- service[Symbol.dispose]()
566
- findOptions[Symbol.dispose]()
523
+ const keydownEvent = new KeyboardEvent('keydown', { key: '+', bubbles: true })
524
+ window.dispatchEvent(keydownEvent)
525
+
526
+ expect(service.selection.getValue().length).toBe(3)
527
+ })
567
528
  })
568
529
 
569
530
  it('should handle - to deselect all entries', async () => {
570
- const injector = new Injector()
571
- const rootElement = document.getElementById('root') as HTMLDivElement
572
- const service = createTestService()
573
- const findOptions = new ObservableValue<any>({})
574
-
575
- const { entries } = service.data.getValue()
576
- service.hasFocus.setValue(true)
577
- service.selection.setValue([...entries])
578
-
579
- initializeShadeRoot({
580
- injector,
581
- rootElement,
582
- jsxElement: (
583
- <DataGrid<TestEntry, 'id' | 'name'>
584
- columns={['id', 'name']}
585
- collectionService={service}
586
- findOptions={findOptions}
587
- styles={{}}
588
- headerComponents={{}}
589
- rowComponents={{}}
590
- />
591
- ),
592
- })
531
+ await withTestGrid(async ({ injector, service, findOptions }) => {
532
+ const rootElement = document.getElementById('root') as HTMLDivElement
593
533
 
594
- await sleepAsync(50)
534
+ const { entries } = service.data.getValue()
535
+ service.hasFocus.setValue(true)
536
+ service.selection.setValue([...entries])
595
537
 
596
- const keydownEvent = new KeyboardEvent('keydown', { key: '-', bubbles: true })
597
- window.dispatchEvent(keydownEvent)
538
+ initializeShadeRoot({
539
+ injector,
540
+ rootElement,
541
+ jsxElement: (
542
+ <DataGrid<TestEntry, 'id' | 'name'>
543
+ columns={['id', 'name']}
544
+ collectionService={service}
545
+ findOptions={findOptions}
546
+ styles={{}}
547
+ headerComponents={{}}
548
+ rowComponents={{}}
549
+ />
550
+ ),
551
+ })
598
552
 
599
- expect(service.selection.getValue().length).toBe(0)
553
+ await sleepAsync(50)
600
554
 
601
- service[Symbol.dispose]()
602
- findOptions[Symbol.dispose]()
555
+ const keydownEvent = new KeyboardEvent('keydown', { key: '-', bubbles: true })
556
+ window.dispatchEvent(keydownEvent)
557
+
558
+ expect(service.selection.getValue().length).toBe(0)
559
+ })
603
560
  })
604
561
 
605
562
  it('should handle * to invert selection', async () => {
606
- const injector = new Injector()
607
- const rootElement = document.getElementById('root') as HTMLDivElement
608
- const service = createTestService()
609
- const findOptions = new ObservableValue<any>({})
610
-
611
- const { entries } = service.data.getValue()
612
- service.hasFocus.setValue(true)
613
- service.selection.setValue([entries[0]])
614
-
615
- initializeShadeRoot({
616
- injector,
617
- rootElement,
618
- jsxElement: (
619
- <DataGrid<TestEntry, 'id' | 'name'>
620
- columns={['id', 'name']}
621
- collectionService={service}
622
- findOptions={findOptions}
623
- styles={{}}
624
- headerComponents={{}}
625
- rowComponents={{}}
626
- />
627
- ),
628
- })
563
+ await withTestGrid(async ({ injector, service, findOptions }) => {
564
+ const rootElement = document.getElementById('root') as HTMLDivElement
629
565
 
630
- await sleepAsync(50)
566
+ const { entries } = service.data.getValue()
567
+ service.hasFocus.setValue(true)
568
+ service.selection.setValue([entries[0]])
631
569
 
632
- const keydownEvent = new KeyboardEvent('keydown', { key: '*', bubbles: true })
633
- window.dispatchEvent(keydownEvent)
570
+ initializeShadeRoot({
571
+ injector,
572
+ rootElement,
573
+ jsxElement: (
574
+ <DataGrid<TestEntry, 'id' | 'name'>
575
+ columns={['id', 'name']}
576
+ collectionService={service}
577
+ findOptions={findOptions}
578
+ styles={{}}
579
+ headerComponents={{}}
580
+ rowComponents={{}}
581
+ />
582
+ ),
583
+ })
584
+
585
+ await sleepAsync(50)
634
586
 
635
- const selection = service.selection.getValue()
636
- expect(selection).not.toContain(entries[0])
637
- expect(selection).toContain(entries[1])
638
- expect(selection).toContain(entries[2])
587
+ const keydownEvent = new KeyboardEvent('keydown', { key: '*', bubbles: true })
588
+ window.dispatchEvent(keydownEvent)
639
589
 
640
- service[Symbol.dispose]()
641
- findOptions[Symbol.dispose]()
590
+ const selection = service.selection.getValue()
591
+ expect(selection).not.toContain(entries[0])
592
+ expect(selection).toContain(entries[1])
593
+ expect(selection).toContain(entries[2])
594
+ })
642
595
  })
643
596
 
644
597
  it('should not handle keyboard when not focused', async () => {
645
- const injector = new Injector()
646
- const rootElement = document.getElementById('root') as HTMLDivElement
647
- const service = createTestService()
648
- const findOptions = new ObservableValue<any>({})
649
-
650
- service.hasFocus.setValue(false)
651
- service.focusedEntry.setValue(service.data.getValue().entries[0])
652
-
653
- initializeShadeRoot({
654
- injector,
655
- rootElement,
656
- jsxElement: (
657
- <DataGrid<TestEntry, 'id' | 'name'>
658
- columns={['id', 'name']}
659
- collectionService={service}
660
- findOptions={findOptions}
661
- styles={{}}
662
- headerComponents={{}}
663
- rowComponents={{}}
664
- />
665
- ),
666
- })
598
+ await withTestGrid(async ({ injector, service, findOptions }) => {
599
+ const rootElement = document.getElementById('root') as HTMLDivElement
667
600
 
668
- await sleepAsync(50)
601
+ service.hasFocus.setValue(false)
602
+ service.focusedEntry.setValue(service.data.getValue().entries[0])
603
+
604
+ initializeShadeRoot({
605
+ injector,
606
+ rootElement,
607
+ jsxElement: (
608
+ <DataGrid<TestEntry, 'id' | 'name'>
609
+ columns={['id', 'name']}
610
+ collectionService={service}
611
+ findOptions={findOptions}
612
+ styles={{}}
613
+ headerComponents={{}}
614
+ rowComponents={{}}
615
+ />
616
+ ),
617
+ })
669
618
 
670
- const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
671
- window.dispatchEvent(keydownEvent)
619
+ await sleepAsync(50)
672
620
 
673
- expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
621
+ const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
622
+ window.dispatchEvent(keydownEvent)
674
623
 
675
- service[Symbol.dispose]()
676
- findOptions[Symbol.dispose]()
624
+ expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
625
+ })
677
626
  })
678
627
 
679
628
  it('should handle Insert to toggle selection and move to next', async () => {
680
- const injector = new Injector()
681
- const rootElement = document.getElementById('root') as HTMLDivElement
682
- const service = createTestService()
683
- const findOptions = new ObservableValue<any>({})
684
-
685
- const { entries } = service.data.getValue()
686
- service.hasFocus.setValue(true)
687
- service.focusedEntry.setValue(entries[0])
688
-
689
- initializeShadeRoot({
690
- injector,
691
- rootElement,
692
- jsxElement: (
693
- <DataGrid<TestEntry, 'id' | 'name'>
694
- columns={['id', 'name']}
695
- collectionService={service}
696
- findOptions={findOptions}
697
- styles={{}}
698
- headerComponents={{}}
699
- rowComponents={{}}
700
- />
701
- ),
702
- })
629
+ await withTestGrid(async ({ injector, service, findOptions }) => {
630
+ const rootElement = document.getElementById('root') as HTMLDivElement
703
631
 
704
- await sleepAsync(50)
632
+ const { entries } = service.data.getValue()
633
+ service.hasFocus.setValue(true)
634
+ service.focusedEntry.setValue(entries[0])
635
+
636
+ initializeShadeRoot({
637
+ injector,
638
+ rootElement,
639
+ jsxElement: (
640
+ <DataGrid<TestEntry, 'id' | 'name'>
641
+ columns={['id', 'name']}
642
+ collectionService={service}
643
+ findOptions={findOptions}
644
+ styles={{}}
645
+ headerComponents={{}}
646
+ rowComponents={{}}
647
+ />
648
+ ),
649
+ })
705
650
 
706
- const keydownEvent = new KeyboardEvent('keydown', { key: 'Insert', bubbles: true })
707
- window.dispatchEvent(keydownEvent)
651
+ await sleepAsync(50)
708
652
 
709
- expect(service.selection.getValue()).toContain(entries[0])
710
- expect(service.focusedEntry.getValue()).toEqual(entries[1])
653
+ const keydownEvent = new KeyboardEvent('keydown', { key: 'Insert', bubbles: true })
654
+ window.dispatchEvent(keydownEvent)
711
655
 
712
- service[Symbol.dispose]()
713
- findOptions[Symbol.dispose]()
656
+ expect(service.selection.getValue()).toContain(entries[0])
657
+ expect(service.focusedEntry.getValue()).toEqual(entries[1])
658
+ })
714
659
  })
715
660
  })
716
661
 
717
662
  describe('styles', () => {
718
663
  it('should apply wrapper styles when provided', async () => {
719
- const injector = new Injector()
720
- const rootElement = document.getElementById('root') as HTMLDivElement
721
- const service = createTestService()
722
- const findOptions = new ObservableValue<any>({})
723
-
724
- initializeShadeRoot({
725
- injector,
726
- rootElement,
727
- jsxElement: (
728
- <DataGrid<TestEntry, 'id' | 'name'>
729
- columns={['id', 'name']}
730
- collectionService={service}
731
- findOptions={findOptions}
732
- styles={{
733
- wrapper: { backgroundColor: 'red' },
734
- }}
735
- headerComponents={{}}
736
- rowComponents={{}}
737
- />
738
- ),
739
- })
664
+ await withTestGrid(async ({ injector, service, findOptions }) => {
665
+ const rootElement = document.getElementById('root') as HTMLDivElement
740
666
 
741
- await sleepAsync(50)
667
+ initializeShadeRoot({
668
+ injector,
669
+ rootElement,
670
+ jsxElement: (
671
+ <DataGrid<TestEntry, 'id' | 'name'>
672
+ columns={['id', 'name']}
673
+ collectionService={service}
674
+ findOptions={findOptions}
675
+ styles={{
676
+ wrapper: { backgroundColor: 'red' },
677
+ }}
678
+ headerComponents={{}}
679
+ rowComponents={{}}
680
+ />
681
+ ),
682
+ })
742
683
 
743
- const grid = document.querySelector('shade-data-grid') as HTMLElement
744
- expect(grid?.style.backgroundColor).toBe('red')
684
+ await sleepAsync(50)
745
685
 
746
- service[Symbol.dispose]()
747
- findOptions[Symbol.dispose]()
686
+ const grid = document.querySelector('shade-data-grid') as HTMLElement
687
+ expect(grid?.style.backgroundColor).toBe('red')
688
+ })
748
689
  })
749
690
 
750
691
  it('should apply header styles when provided', async () => {
751
- const injector = new Injector()
752
- const rootElement = document.getElementById('root') as HTMLDivElement
753
- const service = createTestService()
754
- const findOptions = new ObservableValue<any>({})
755
-
756
- initializeShadeRoot({
757
- injector,
758
- rootElement,
759
- jsxElement: (
760
- <DataGrid<TestEntry, 'id' | 'name'>
761
- columns={['id', 'name']}
762
- collectionService={service}
763
- findOptions={findOptions}
764
- styles={{
765
- header: { color: 'blue' },
766
- }}
767
- headerComponents={{}}
768
- rowComponents={{}}
769
- />
770
- ),
771
- })
692
+ await withTestGrid(async ({ injector, service, findOptions }) => {
693
+ const rootElement = document.getElementById('root') as HTMLDivElement
772
694
 
773
- await sleepAsync(50)
695
+ initializeShadeRoot({
696
+ injector,
697
+ rootElement,
698
+ jsxElement: (
699
+ <DataGrid<TestEntry, 'id' | 'name'>
700
+ columns={['id', 'name']}
701
+ collectionService={service}
702
+ findOptions={findOptions}
703
+ styles={{
704
+ header: { color: 'blue' },
705
+ }}
706
+ headerComponents={{}}
707
+ rowComponents={{}}
708
+ />
709
+ ),
710
+ })
774
711
 
775
- const grid = document.querySelector('shade-data-grid')
776
- const headers = grid?.querySelectorAll('th') as NodeListOf<HTMLElement>
777
- expect(headers?.[0]?.style.color).toBe('blue')
712
+ await sleepAsync(50)
778
713
 
779
- service[Symbol.dispose]()
780
- findOptions[Symbol.dispose]()
714
+ const grid = document.querySelector('shade-data-grid')
715
+ const headers = grid?.querySelectorAll('th') as NodeListOf<HTMLElement>
716
+ expect(headers?.[0]?.style.color).toBe('blue')
717
+ })
781
718
  })
782
719
  })
783
720
 
784
721
  describe('empty and loading states', () => {
785
722
  it('should show empty component when no data', async () => {
786
- const injector = new Injector()
787
- const rootElement = document.getElementById('root') as HTMLDivElement
788
- const service = new CollectionService<TestEntry>()
789
- const findOptions = new ObservableValue<any>({})
790
-
791
- initializeShadeRoot({
792
- injector,
793
- rootElement,
794
- jsxElement: (
795
- <DataGrid<TestEntry, 'id' | 'name'>
796
- columns={['id', 'name']}
797
- collectionService={service}
798
- findOptions={findOptions}
799
- styles={{}}
800
- headerComponents={{}}
801
- rowComponents={{}}
802
- emptyComponent={<div data-testid="empty-state">No data available</div>}
803
- />
804
- ),
805
- })
806
-
807
- await sleepAsync(50)
808
-
809
- const grid = document.querySelector('shade-data-grid')
810
- const emptyState = grid?.querySelector('[data-testid="empty-state"]')
811
- expect(emptyState).not.toBeNull()
812
- expect(emptyState?.textContent).toBe('No data available')
813
-
814
- service[Symbol.dispose]()
815
- findOptions[Symbol.dispose]()
723
+ await withTestGrid(
724
+ async ({ injector, service, findOptions }) => {
725
+ const rootElement = document.getElementById('root') as HTMLDivElement
726
+
727
+ initializeShadeRoot({
728
+ injector,
729
+ rootElement,
730
+ jsxElement: (
731
+ <DataGrid<TestEntry, 'id' | 'name'>
732
+ columns={['id', 'name']}
733
+ collectionService={service}
734
+ findOptions={findOptions}
735
+ styles={{}}
736
+ headerComponents={{}}
737
+ rowComponents={{}}
738
+ emptyComponent={<div data-testid="empty-state">No data available</div>}
739
+ />
740
+ ),
741
+ })
742
+
743
+ await sleepAsync(50)
744
+
745
+ const grid = document.querySelector('shade-data-grid')
746
+ const emptyState = grid?.querySelector('[data-testid="empty-state"]')
747
+ expect(emptyState).not.toBeNull()
748
+ expect(emptyState?.textContent).toBe('No data available')
749
+ },
750
+ { createService: () => new CollectionService<TestEntry>() },
751
+ )
816
752
  })
817
753
  })
818
754
 
819
755
  describe('row interactions', () => {
820
756
  it('should pass row click to collectionService', async () => {
821
- const injector = new Injector()
822
- const rootElement = document.getElementById('root') as HTMLDivElement
823
757
  const onRowClick = vi.fn()
824
- const service = new CollectionService<TestEntry>({ onRowClick })
825
- const findOptions = new ObservableValue<any>({})
826
-
827
- service.data.setValue({
828
- count: 1,
829
- entries: [{ id: 1, name: 'Test' }],
830
- })
831
-
832
- initializeShadeRoot({
833
- injector,
834
- rootElement,
835
- jsxElement: (
836
- <DataGrid<TestEntry, 'id' | 'name'>
837
- columns={['id', 'name']}
838
- collectionService={service}
839
- findOptions={findOptions}
840
- styles={{}}
841
- headerComponents={{}}
842
- rowComponents={{}}
843
- />
844
- ),
845
- })
846
-
847
- await sleepAsync(50)
848
-
849
- const grid = document.querySelector('shade-data-grid')
850
- const cell = grid?.querySelector('td') as HTMLTableCellElement
851
- cell?.click()
852
-
853
- expect(onRowClick).toHaveBeenCalledWith({ id: 1, name: 'Test' })
854
-
855
- service[Symbol.dispose]()
856
- findOptions[Symbol.dispose]()
758
+ await withTestGrid(
759
+ async ({ injector, service, findOptions }) => {
760
+ const rootElement = document.getElementById('root') as HTMLDivElement
761
+
762
+ service.data.setValue({
763
+ count: 1,
764
+ entries: [{ id: 1, name: 'Test' }],
765
+ })
766
+
767
+ initializeShadeRoot({
768
+ injector,
769
+ rootElement,
770
+ jsxElement: (
771
+ <DataGrid<TestEntry, 'id' | 'name'>
772
+ columns={['id', 'name']}
773
+ collectionService={service}
774
+ findOptions={findOptions}
775
+ styles={{}}
776
+ headerComponents={{}}
777
+ rowComponents={{}}
778
+ />
779
+ ),
780
+ })
781
+
782
+ await sleepAsync(50)
783
+
784
+ const grid = document.querySelector('shade-data-grid')
785
+ const cell = grid?.querySelector('td') as HTMLTableCellElement
786
+ cell?.click()
787
+
788
+ expect(onRowClick).toHaveBeenCalledWith({ id: 1, name: 'Test' })
789
+ },
790
+ { createService: () => new CollectionService<TestEntry>({ onRowClick }) },
791
+ )
857
792
  })
858
793
 
859
794
  it('should pass row double click to collectionService', async () => {
860
- const injector = new Injector()
861
- const rootElement = document.getElementById('root') as HTMLDivElement
862
795
  const onRowDoubleClick = vi.fn()
863
- const service = new CollectionService<TestEntry>({ onRowDoubleClick })
864
- const findOptions = new ObservableValue<any>({})
865
-
866
- service.data.setValue({
867
- count: 1,
868
- entries: [{ id: 1, name: 'Test' }],
869
- })
870
-
871
- initializeShadeRoot({
872
- injector,
873
- rootElement,
874
- jsxElement: (
875
- <DataGrid<TestEntry, 'id' | 'name'>
876
- columns={['id', 'name']}
877
- collectionService={service}
878
- findOptions={findOptions}
879
- styles={{}}
880
- headerComponents={{}}
881
- rowComponents={{}}
882
- />
883
- ),
884
- })
885
-
886
- await sleepAsync(50)
887
-
888
- const grid = document.querySelector('shade-data-grid')
889
- const cell = grid?.querySelector('td') as HTMLTableCellElement
890
- const dblClickEvent = new MouseEvent('dblclick', { bubbles: true })
891
- cell?.dispatchEvent(dblClickEvent)
892
-
893
- expect(onRowDoubleClick).toHaveBeenCalledWith({ id: 1, name: 'Test' })
894
-
895
- service[Symbol.dispose]()
896
- findOptions[Symbol.dispose]()
796
+ await withTestGrid(
797
+ async ({ injector, service, findOptions }) => {
798
+ const rootElement = document.getElementById('root') as HTMLDivElement
799
+
800
+ service.data.setValue({
801
+ count: 1,
802
+ entries: [{ id: 1, name: 'Test' }],
803
+ })
804
+
805
+ initializeShadeRoot({
806
+ injector,
807
+ rootElement,
808
+ jsxElement: (
809
+ <DataGrid<TestEntry, 'id' | 'name'>
810
+ columns={['id', 'name']}
811
+ collectionService={service}
812
+ findOptions={findOptions}
813
+ styles={{}}
814
+ headerComponents={{}}
815
+ rowComponents={{}}
816
+ />
817
+ ),
818
+ })
819
+
820
+ await sleepAsync(50)
821
+
822
+ const grid = document.querySelector('shade-data-grid')
823
+ const cell = grid?.querySelector('td') as HTMLTableCellElement
824
+ const dblClickEvent = new MouseEvent('dblclick', { bubbles: true })
825
+ cell?.dispatchEvent(dblClickEvent)
826
+
827
+ expect(onRowDoubleClick).toHaveBeenCalledWith({ id: 1, name: 'Test' })
828
+ },
829
+ { createService: () => new CollectionService<TestEntry>({ onRowDoubleClick }) },
830
+ )
897
831
  })
898
832
  })
899
833
 
900
834
  describe('keyboard listener cleanup', () => {
901
835
  it('should remove keyboard listener when component is disconnected', async () => {
902
- const injector = new Injector()
903
- const rootElement = document.getElementById('root') as HTMLDivElement
904
- const service = createTestService()
905
- const findOptions = new ObservableValue<any>({})
906
-
907
- service.hasFocus.setValue(true)
908
- service.focusedEntry.setValue(service.data.getValue().entries[0])
909
-
910
- initializeShadeRoot({
911
- injector,
912
- rootElement,
913
- jsxElement: (
914
- <DataGrid<TestEntry, 'id' | 'name'>
915
- columns={['id', 'name']}
916
- collectionService={service}
917
- findOptions={findOptions}
918
- styles={{}}
919
- headerComponents={{}}
920
- rowComponents={{}}
921
- />
922
- ),
923
- })
836
+ await withTestGrid(async ({ injector, service, findOptions }) => {
837
+ const rootElement = document.getElementById('root') as HTMLDivElement
924
838
 
925
- await sleepAsync(50)
839
+ service.hasFocus.setValue(true)
840
+ service.focusedEntry.setValue(service.data.getValue().entries[0])
926
841
 
927
- const grid = document.querySelector('shade-data-grid') as HTMLElement
928
- grid.remove()
842
+ initializeShadeRoot({
843
+ injector,
844
+ rootElement,
845
+ jsxElement: (
846
+ <DataGrid<TestEntry, 'id' | 'name'>
847
+ columns={['id', 'name']}
848
+ collectionService={service}
849
+ findOptions={findOptions}
850
+ styles={{}}
851
+ headerComponents={{}}
852
+ rowComponents={{}}
853
+ />
854
+ ),
855
+ })
856
+
857
+ await sleepAsync(50)
929
858
 
930
- await sleepAsync(10)
859
+ const grid = document.querySelector('shade-data-grid') as HTMLElement
860
+ grid.remove()
931
861
 
932
- window.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
933
- expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
862
+ await sleepAsync(10)
934
863
 
935
- service[Symbol.dispose]()
936
- findOptions[Symbol.dispose]()
864
+ window.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
865
+ expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
866
+ })
937
867
  })
938
868
  })
939
869
  })