@tartaguti/ui-components 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +21 -0
  3. package/README.md +192 -2
  4. package/THIRD-PARTY-NOTICES.md +29 -0
  5. package/custom-elements.json +16899 -0
  6. package/dist/accordion/tt-accordion-item.d.ts +32 -0
  7. package/dist/accordion/tt-accordion-item.d.ts.map +1 -0
  8. package/dist/accordion/tt-accordion-item.js +247 -0
  9. package/dist/accordion/tt-accordion-item.js.map +1 -0
  10. package/dist/accordion/tt-accordion.d.ts +28 -0
  11. package/dist/accordion/tt-accordion.d.ts.map +1 -0
  12. package/dist/accordion/tt-accordion.js +148 -0
  13. package/dist/accordion/tt-accordion.js.map +1 -0
  14. package/dist/bento/tt-bento-item.d.ts +35 -0
  15. package/dist/bento/tt-bento-item.d.ts.map +1 -0
  16. package/dist/bento/tt-bento-item.js +201 -0
  17. package/dist/bento/tt-bento-item.js.map +1 -0
  18. package/dist/bento/tt-bento.d.ts +25 -0
  19. package/dist/bento/tt-bento.d.ts.map +1 -0
  20. package/dist/bento/tt-bento.js +314 -0
  21. package/dist/bento/tt-bento.js.map +1 -0
  22. package/dist/floating.d.ts +61 -0
  23. package/dist/floating.d.ts.map +1 -0
  24. package/dist/floating.js +120 -0
  25. package/dist/floating.js.map +1 -0
  26. package/dist/index.d.ts +92 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +96 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/interaction/tt-draggable.d.ts +29 -0
  31. package/dist/interaction/tt-draggable.d.ts.map +1 -0
  32. package/dist/interaction/tt-draggable.js +66 -0
  33. package/dist/interaction/tt-draggable.js.map +1 -0
  34. package/dist/interaction/tt-droppable.d.ts +37 -0
  35. package/dist/interaction/tt-droppable.d.ts.map +1 -0
  36. package/dist/interaction/tt-droppable.js +108 -0
  37. package/dist/interaction/tt-droppable.js.map +1 -0
  38. package/dist/interaction/tt-resizable.d.ts +45 -0
  39. package/dist/interaction/tt-resizable.d.ts.map +1 -0
  40. package/dist/interaction/tt-resizable.js +210 -0
  41. package/dist/interaction/tt-resizable.js.map +1 -0
  42. package/dist/interaction/tt-reveal.d.ts +54 -0
  43. package/dist/interaction/tt-reveal.d.ts.map +1 -0
  44. package/dist/interaction/tt-reveal.js +302 -0
  45. package/dist/interaction/tt-reveal.js.map +1 -0
  46. package/dist/motion.d.ts +8 -0
  47. package/dist/motion.d.ts.map +1 -0
  48. package/dist/motion.js +49 -0
  49. package/dist/motion.js.map +1 -0
  50. package/dist/overlay.d.ts +7 -0
  51. package/dist/overlay.d.ts.map +1 -0
  52. package/dist/overlay.js +121 -0
  53. package/dist/overlay.js.map +1 -0
  54. package/dist/safe-url.d.ts +14 -0
  55. package/dist/safe-url.d.ts.map +1 -0
  56. package/dist/safe-url.js +46 -0
  57. package/dist/safe-url.js.map +1 -0
  58. package/dist/scroll-lock.d.ts +22 -0
  59. package/dist/scroll-lock.d.ts.map +1 -0
  60. package/dist/scroll-lock.js +56 -0
  61. package/dist/scroll-lock.js.map +1 -0
  62. package/dist/sidebar/tt-menu-group.d.ts +69 -0
  63. package/dist/sidebar/tt-menu-group.d.ts.map +1 -0
  64. package/dist/sidebar/tt-menu-group.js +358 -0
  65. package/dist/sidebar/tt-menu-group.js.map +1 -0
  66. package/dist/sidebar/tt-menu-item.d.ts +70 -0
  67. package/dist/sidebar/tt-menu-item.d.ts.map +1 -0
  68. package/dist/sidebar/tt-menu-item.js +502 -0
  69. package/dist/sidebar/tt-menu-item.js.map +1 -0
  70. package/dist/sidebar/tt-sidebar-footer.d.ts +39 -0
  71. package/dist/sidebar/tt-sidebar-footer.d.ts.map +1 -0
  72. package/dist/sidebar/tt-sidebar-footer.js +205 -0
  73. package/dist/sidebar/tt-sidebar-footer.js.map +1 -0
  74. package/dist/sidebar/tt-sidebar-header.d.ts +31 -0
  75. package/dist/sidebar/tt-sidebar-header.d.ts.map +1 -0
  76. package/dist/sidebar/tt-sidebar-header.js +150 -0
  77. package/dist/sidebar/tt-sidebar-header.js.map +1 -0
  78. package/dist/sidebar/tt-sidebar.d.ts +72 -0
  79. package/dist/sidebar/tt-sidebar.d.ts.map +1 -0
  80. package/dist/sidebar/tt-sidebar.js +539 -0
  81. package/dist/sidebar/tt-sidebar.js.map +1 -0
  82. package/dist/sr-only.d.ts +15 -0
  83. package/dist/sr-only.d.ts.map +1 -0
  84. package/dist/sr-only.js +27 -0
  85. package/dist/sr-only.js.map +1 -0
  86. package/dist/tokens.css +1124 -0
  87. package/dist/tt-alert.d.ts +26 -0
  88. package/dist/tt-alert.d.ts.map +1 -0
  89. package/dist/tt-alert.js +165 -0
  90. package/dist/tt-alert.js.map +1 -0
  91. package/dist/tt-aspect-ratio.d.ts +40 -0
  92. package/dist/tt-aspect-ratio.d.ts.map +1 -0
  93. package/dist/tt-aspect-ratio.js +98 -0
  94. package/dist/tt-aspect-ratio.js.map +1 -0
  95. package/dist/tt-auth.d.ts +75 -0
  96. package/dist/tt-auth.d.ts.map +1 -0
  97. package/dist/tt-auth.js +520 -0
  98. package/dist/tt-auth.js.map +1 -0
  99. package/dist/tt-avatar.d.ts +26 -0
  100. package/dist/tt-avatar.d.ts.map +1 -0
  101. package/dist/tt-avatar.js +169 -0
  102. package/dist/tt-avatar.js.map +1 -0
  103. package/dist/tt-badge.d.ts +36 -0
  104. package/dist/tt-badge.d.ts.map +1 -0
  105. package/dist/tt-badge.js +135 -0
  106. package/dist/tt-badge.js.map +1 -0
  107. package/dist/tt-breadcrumbs.d.ts +22 -0
  108. package/dist/tt-breadcrumbs.d.ts.map +1 -0
  109. package/dist/tt-breadcrumbs.js +144 -0
  110. package/dist/tt-breadcrumbs.js.map +1 -0
  111. package/dist/tt-button-group.d.ts +32 -0
  112. package/dist/tt-button-group.d.ts.map +1 -0
  113. package/dist/tt-button-group.js +132 -0
  114. package/dist/tt-button-group.js.map +1 -0
  115. package/dist/tt-button.d.ts +31 -0
  116. package/dist/tt-button.d.ts.map +1 -0
  117. package/dist/tt-button.js +483 -0
  118. package/dist/tt-button.js.map +1 -0
  119. package/dist/tt-card.d.ts +26 -0
  120. package/dist/tt-card.d.ts.map +1 -0
  121. package/dist/tt-card.js +429 -0
  122. package/dist/tt-card.js.map +1 -0
  123. package/dist/tt-chart.d.ts +36 -0
  124. package/dist/tt-chart.d.ts.map +1 -0
  125. package/dist/tt-chart.js +332 -0
  126. package/dist/tt-chart.js.map +1 -0
  127. package/dist/tt-checkbox-group.d.ts +38 -0
  128. package/dist/tt-checkbox-group.d.ts.map +1 -0
  129. package/dist/tt-checkbox-group.js +243 -0
  130. package/dist/tt-checkbox-group.js.map +1 -0
  131. package/dist/tt-checkbox.d.ts +35 -0
  132. package/dist/tt-checkbox.d.ts.map +1 -0
  133. package/dist/tt-checkbox.js +354 -0
  134. package/dist/tt-checkbox.js.map +1 -0
  135. package/dist/tt-code-block.d.ts +37 -0
  136. package/dist/tt-code-block.d.ts.map +1 -0
  137. package/dist/tt-code-block.js +409 -0
  138. package/dist/tt-code-block.js.map +1 -0
  139. package/dist/tt-collapsible.d.ts +71 -0
  140. package/dist/tt-collapsible.d.ts.map +1 -0
  141. package/dist/tt-collapsible.js +206 -0
  142. package/dist/tt-collapsible.js.map +1 -0
  143. package/dist/tt-combobox.d.ts +107 -0
  144. package/dist/tt-combobox.d.ts.map +1 -0
  145. package/dist/tt-combobox.js +816 -0
  146. package/dist/tt-combobox.js.map +1 -0
  147. package/dist/tt-company-card.d.ts +30 -0
  148. package/dist/tt-company-card.d.ts.map +1 -0
  149. package/dist/tt-company-card.js +382 -0
  150. package/dist/tt-company-card.js.map +1 -0
  151. package/dist/tt-comparison-table.d.ts +59 -0
  152. package/dist/tt-comparison-table.d.ts.map +1 -0
  153. package/dist/tt-comparison-table.js +441 -0
  154. package/dist/tt-comparison-table.js.map +1 -0
  155. package/dist/tt-component-doc.d.ts +63 -0
  156. package/dist/tt-component-doc.d.ts.map +1 -0
  157. package/dist/tt-component-doc.js +585 -0
  158. package/dist/tt-component-doc.js.map +1 -0
  159. package/dist/tt-confirm.d.ts +45 -0
  160. package/dist/tt-confirm.d.ts.map +1 -0
  161. package/dist/tt-confirm.js +151 -0
  162. package/dist/tt-confirm.js.map +1 -0
  163. package/dist/tt-contact-list.d.ts +18 -0
  164. package/dist/tt-contact-list.d.ts.map +1 -0
  165. package/dist/tt-contact-list.js +101 -0
  166. package/dist/tt-contact-list.js.map +1 -0
  167. package/dist/tt-copy-button.d.ts +25 -0
  168. package/dist/tt-copy-button.d.ts.map +1 -0
  169. package/dist/tt-copy-button.js +194 -0
  170. package/dist/tt-copy-button.js.map +1 -0
  171. package/dist/tt-data-table.d.ts +96 -0
  172. package/dist/tt-data-table.d.ts.map +1 -0
  173. package/dist/tt-data-table.js +812 -0
  174. package/dist/tt-data-table.js.map +1 -0
  175. package/dist/tt-divider.d.ts +19 -0
  176. package/dist/tt-divider.d.ts.map +1 -0
  177. package/dist/tt-divider.js +104 -0
  178. package/dist/tt-divider.js.map +1 -0
  179. package/dist/tt-drawer.d.ts +38 -0
  180. package/dist/tt-drawer.d.ts.map +1 -0
  181. package/dist/tt-drawer.js +433 -0
  182. package/dist/tt-drawer.js.map +1 -0
  183. package/dist/tt-dropdown-menu.d.ts +57 -0
  184. package/dist/tt-dropdown-menu.d.ts.map +1 -0
  185. package/dist/tt-dropdown-menu.js +631 -0
  186. package/dist/tt-dropdown-menu.js.map +1 -0
  187. package/dist/tt-empty-state.d.ts +13 -0
  188. package/dist/tt-empty-state.d.ts.map +1 -0
  189. package/dist/tt-empty-state.js +94 -0
  190. package/dist/tt-empty-state.js.map +1 -0
  191. package/dist/tt-example.d.ts +33 -0
  192. package/dist/tt-example.d.ts.map +1 -0
  193. package/dist/tt-example.js +250 -0
  194. package/dist/tt-example.js.map +1 -0
  195. package/dist/tt-file-upload.d.ts +85 -0
  196. package/dist/tt-file-upload.d.ts.map +1 -0
  197. package/dist/tt-file-upload.js +662 -0
  198. package/dist/tt-file-upload.js.map +1 -0
  199. package/dist/tt-filter.d.ts +62 -0
  200. package/dist/tt-filter.d.ts.map +1 -0
  201. package/dist/tt-filter.js +393 -0
  202. package/dist/tt-filter.js.map +1 -0
  203. package/dist/tt-form.d.ts +33 -0
  204. package/dist/tt-form.d.ts.map +1 -0
  205. package/dist/tt-form.js +202 -0
  206. package/dist/tt-form.js.map +1 -0
  207. package/dist/tt-grid.d.ts +22 -0
  208. package/dist/tt-grid.d.ts.map +1 -0
  209. package/dist/tt-grid.js +106 -0
  210. package/dist/tt-grid.js.map +1 -0
  211. package/dist/tt-icon.d.ts +20 -0
  212. package/dist/tt-icon.d.ts.map +1 -0
  213. package/dist/tt-icon.js +510 -0
  214. package/dist/tt-icon.js.map +1 -0
  215. package/dist/tt-image.d.ts +59 -0
  216. package/dist/tt-image.d.ts.map +1 -0
  217. package/dist/tt-image.js +314 -0
  218. package/dist/tt-image.js.map +1 -0
  219. package/dist/tt-inbox.d.ts +45 -0
  220. package/dist/tt-inbox.d.ts.map +1 -0
  221. package/dist/tt-inbox.js +275 -0
  222. package/dist/tt-inbox.js.map +1 -0
  223. package/dist/tt-input.d.ts +43 -0
  224. package/dist/tt-input.d.ts.map +1 -0
  225. package/dist/tt-input.js +476 -0
  226. package/dist/tt-input.js.map +1 -0
  227. package/dist/tt-kbd.d.ts +39 -0
  228. package/dist/tt-kbd.d.ts.map +1 -0
  229. package/dist/tt-kbd.js +145 -0
  230. package/dist/tt-kbd.js.map +1 -0
  231. package/dist/tt-key-values.d.ts +17 -0
  232. package/dist/tt-key-values.d.ts.map +1 -0
  233. package/dist/tt-key-values.js +126 -0
  234. package/dist/tt-key-values.js.map +1 -0
  235. package/dist/tt-knowledge-doc.d.ts +24 -0
  236. package/dist/tt-knowledge-doc.d.ts.map +1 -0
  237. package/dist/tt-knowledge-doc.js +120 -0
  238. package/dist/tt-knowledge-doc.js.map +1 -0
  239. package/dist/tt-layout.d.ts +36 -0
  240. package/dist/tt-layout.d.ts.map +1 -0
  241. package/dist/tt-layout.js +318 -0
  242. package/dist/tt-layout.js.map +1 -0
  243. package/dist/tt-modal.d.ts +32 -0
  244. package/dist/tt-modal.d.ts.map +1 -0
  245. package/dist/tt-modal.js +553 -0
  246. package/dist/tt-modal.js.map +1 -0
  247. package/dist/tt-navbar.d.ts +33 -0
  248. package/dist/tt-navbar.d.ts.map +1 -0
  249. package/dist/tt-navbar.js +390 -0
  250. package/dist/tt-navbar.js.map +1 -0
  251. package/dist/tt-page-header.d.ts +28 -0
  252. package/dist/tt-page-header.d.ts.map +1 -0
  253. package/dist/tt-page-header.js +166 -0
  254. package/dist/tt-page-header.js.map +1 -0
  255. package/dist/tt-page.d.ts +14 -0
  256. package/dist/tt-page.d.ts.map +1 -0
  257. package/dist/tt-page.js +163 -0
  258. package/dist/tt-page.js.map +1 -0
  259. package/dist/tt-pagination.d.ts +27 -0
  260. package/dist/tt-pagination.d.ts.map +1 -0
  261. package/dist/tt-pagination.js +194 -0
  262. package/dist/tt-pagination.js.map +1 -0
  263. package/dist/tt-preview.d.ts +11 -0
  264. package/dist/tt-preview.d.ts.map +1 -0
  265. package/dist/tt-preview.js +68 -0
  266. package/dist/tt-preview.js.map +1 -0
  267. package/dist/tt-product.d.ts +40 -0
  268. package/dist/tt-product.d.ts.map +1 -0
  269. package/dist/tt-product.js +590 -0
  270. package/dist/tt-product.js.map +1 -0
  271. package/dist/tt-profile-card.d.ts +23 -0
  272. package/dist/tt-profile-card.d.ts.map +1 -0
  273. package/dist/tt-profile-card.js +199 -0
  274. package/dist/tt-profile-card.js.map +1 -0
  275. package/dist/tt-progress.d.ts +26 -0
  276. package/dist/tt-progress.d.ts.map +1 -0
  277. package/dist/tt-progress.js +156 -0
  278. package/dist/tt-progress.js.map +1 -0
  279. package/dist/tt-quantity.d.ts +36 -0
  280. package/dist/tt-quantity.d.ts.map +1 -0
  281. package/dist/tt-quantity.js +396 -0
  282. package/dist/tt-quantity.js.map +1 -0
  283. package/dist/tt-radio-group.d.ts +50 -0
  284. package/dist/tt-radio-group.d.ts.map +1 -0
  285. package/dist/tt-radio-group.js +372 -0
  286. package/dist/tt-radio-group.js.map +1 -0
  287. package/dist/tt-rating.d.ts +54 -0
  288. package/dist/tt-rating.d.ts.map +1 -0
  289. package/dist/tt-rating.js +312 -0
  290. package/dist/tt-rating.js.map +1 -0
  291. package/dist/tt-search.d.ts +47 -0
  292. package/dist/tt-search.d.ts.map +1 -0
  293. package/dist/tt-search.js +360 -0
  294. package/dist/tt-search.js.map +1 -0
  295. package/dist/tt-section.d.ts +13 -0
  296. package/dist/tt-section.d.ts.map +1 -0
  297. package/dist/tt-section.js +98 -0
  298. package/dist/tt-section.js.map +1 -0
  299. package/dist/tt-select.d.ts +62 -0
  300. package/dist/tt-select.d.ts.map +1 -0
  301. package/dist/tt-select.js +662 -0
  302. package/dist/tt-select.js.map +1 -0
  303. package/dist/tt-skeleton.d.ts +20 -0
  304. package/dist/tt-skeleton.d.ts.map +1 -0
  305. package/dist/tt-skeleton.js +143 -0
  306. package/dist/tt-skeleton.js.map +1 -0
  307. package/dist/tt-slider.d.ts +74 -0
  308. package/dist/tt-slider.d.ts.map +1 -0
  309. package/dist/tt-slider.js +426 -0
  310. package/dist/tt-slider.js.map +1 -0
  311. package/dist/tt-social-links.d.ts +34 -0
  312. package/dist/tt-social-links.d.ts.map +1 -0
  313. package/dist/tt-social-links.js +242 -0
  314. package/dist/tt-social-links.js.map +1 -0
  315. package/dist/tt-sparkline.d.ts +19 -0
  316. package/dist/tt-sparkline.d.ts.map +1 -0
  317. package/dist/tt-sparkline.js +191 -0
  318. package/dist/tt-sparkline.js.map +1 -0
  319. package/dist/tt-spinner.d.ts +19 -0
  320. package/dist/tt-spinner.d.ts.map +1 -0
  321. package/dist/tt-spinner.js +93 -0
  322. package/dist/tt-spinner.js.map +1 -0
  323. package/dist/tt-stack.d.ts +42 -0
  324. package/dist/tt-stack.d.ts.map +1 -0
  325. package/dist/tt-stack.js +158 -0
  326. package/dist/tt-stack.js.map +1 -0
  327. package/dist/tt-stat.d.ts +17 -0
  328. package/dist/tt-stat.d.ts.map +1 -0
  329. package/dist/tt-stat.js +134 -0
  330. package/dist/tt-stat.js.map +1 -0
  331. package/dist/tt-switch.d.ts +39 -0
  332. package/dist/tt-switch.d.ts.map +1 -0
  333. package/dist/tt-switch.js +254 -0
  334. package/dist/tt-switch.js.map +1 -0
  335. package/dist/tt-switcher.d.ts +23 -0
  336. package/dist/tt-switcher.d.ts.map +1 -0
  337. package/dist/tt-switcher.js +203 -0
  338. package/dist/tt-switcher.js.map +1 -0
  339. package/dist/tt-table-cell.d.ts +26 -0
  340. package/dist/tt-table-cell.d.ts.map +1 -0
  341. package/dist/tt-table-cell.js +121 -0
  342. package/dist/tt-table-cell.js.map +1 -0
  343. package/dist/tt-table-row.d.ts +31 -0
  344. package/dist/tt-table-row.d.ts.map +1 -0
  345. package/dist/tt-table-row.js +72 -0
  346. package/dist/tt-table-row.js.map +1 -0
  347. package/dist/tt-table.d.ts +44 -0
  348. package/dist/tt-table.d.ts.map +1 -0
  349. package/dist/tt-table.js +270 -0
  350. package/dist/tt-table.js.map +1 -0
  351. package/dist/tt-tabs.d.ts +31 -0
  352. package/dist/tt-tabs.d.ts.map +1 -0
  353. package/dist/tt-tabs.js +223 -0
  354. package/dist/tt-tabs.js.map +1 -0
  355. package/dist/tt-tag-list.d.ts +19 -0
  356. package/dist/tt-tag-list.d.ts.map +1 -0
  357. package/dist/tt-tag-list.js +136 -0
  358. package/dist/tt-tag-list.js.map +1 -0
  359. package/dist/tt-text.d.ts +52 -0
  360. package/dist/tt-text.d.ts.map +1 -0
  361. package/dist/tt-text.js +337 -0
  362. package/dist/tt-text.js.map +1 -0
  363. package/dist/tt-textarea.d.ts +43 -0
  364. package/dist/tt-textarea.d.ts.map +1 -0
  365. package/dist/tt-textarea.js +356 -0
  366. package/dist/tt-textarea.js.map +1 -0
  367. package/dist/tt-thread.d.ts +62 -0
  368. package/dist/tt-thread.d.ts.map +1 -0
  369. package/dist/tt-thread.js +374 -0
  370. package/dist/tt-thread.js.map +1 -0
  371. package/dist/tt-toast.d.ts +49 -0
  372. package/dist/tt-toast.d.ts.map +1 -0
  373. package/dist/tt-toast.js +440 -0
  374. package/dist/tt-toast.js.map +1 -0
  375. package/dist/tt-toggle-group.d.ts +73 -0
  376. package/dist/tt-toggle-group.d.ts.map +1 -0
  377. package/dist/tt-toggle-group.js +273 -0
  378. package/dist/tt-toggle-group.js.map +1 -0
  379. package/dist/tt-toggle.d.ts +54 -0
  380. package/dist/tt-toggle.d.ts.map +1 -0
  381. package/dist/tt-toggle.js +232 -0
  382. package/dist/tt-toggle.js.map +1 -0
  383. package/dist/tt-toolbar.d.ts +26 -0
  384. package/dist/tt-toolbar.d.ts.map +1 -0
  385. package/dist/tt-toolbar.js +164 -0
  386. package/dist/tt-toolbar.js.map +1 -0
  387. package/dist/tt-tooltip.d.ts +42 -0
  388. package/dist/tt-tooltip.d.ts.map +1 -0
  389. package/dist/tt-tooltip.js +299 -0
  390. package/dist/tt-tooltip.js.map +1 -0
  391. package/package.json +84 -4
  392. package/vscode.html-custom-data.json +2911 -0
@@ -0,0 +1,812 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, html, css } from "lit";
8
+ import { customElement, property, query, state } from "lit/decorators.js";
9
+ import { ifDefined } from "lit/directives/if-defined.js";
10
+ import { repeat } from "lit/directives/repeat.js";
11
+ import "./tt-checkbox.js";
12
+ import "./tt-skeleton.js";
13
+ import "./tt-empty-state.js";
14
+ import "./tt-dropdown-menu.js";
15
+ import "./tt-icon.js";
16
+ import { srOnly } from "./sr-only.js";
17
+ /*
18
+ Rows kept in the page above and below the visible ones while
19
+ virtualized, so a fast scroll or a Tab to the next row lands on a row
20
+ that already exists instead of a blank.
21
+ */
22
+ const OVERSCAN = 5;
23
+ /** A row's height before the first one is measured: the default density. */
24
+ const ROW_ESTIMATE = 49;
25
+ /**
26
+ * Working table: sorting, selection, row actions, sticky header, and
27
+ * loading and empty states. With visible-rows it is virtualized: a box
28
+ * that many rows tall, holding only the rows in view, so ten thousand
29
+ * rows scroll as smoothly as ten.
30
+ *
31
+ * It owns nothing. Sort state and selection come in as properties and
32
+ * changes go out as events, so the page stays the single source of truth
33
+ * and can put either in a URL. Sorting itself is the page's job too: it
34
+ * knows whether the data is an in-memory array or a server query.
35
+ */
36
+ let TTDataTable = class TTDataTable extends LitElement {
37
+ constructor() {
38
+ super(...arguments);
39
+ this.columns = [];
40
+ this.rows = [];
41
+ /*
42
+ The table's name for screen readers, announced on entering it
43
+ ("Team members, table"). Same word and job as tt-table's label. A
44
+ heading above the table names it for sighted readers only.
45
+ */
46
+ this.label = "";
47
+ this.selectable = false;
48
+ this.selected = [];
49
+ // Same menu on every row. Leave empty for no actions column.
50
+ this.rowActions = [];
51
+ this.loading = false;
52
+ this.loadingRows = 5;
53
+ this.emptyHeading = "Nothing here yet";
54
+ this.emptyDescription = "";
55
+ // Rows respond to clicks. Only set this when there is somewhere to go.
56
+ this.clickableRows = false;
57
+ /*
58
+ How many rows tall the table is, as a box that scrolls. Only the rows
59
+ in view (plus a few spare) exist in the page, so the cost of a scroll
60
+ stays the same at 10,000 rows as at 10. 0, the default, shows every
61
+ row as a plain table.
62
+
63
+ Virtualized rows need one height each, so their cells stay on one
64
+ line and long values end in an ellipsis.
65
+ */
66
+ this.visibleRows = 0;
67
+ // The row at the top of the scroll box, from its scroll position.
68
+ this.firstInView = 0;
69
+ // Measured from the rendered page, so density, touch and themes all count.
70
+ this.rowHeight = 0;
71
+ this.headerHeight = 0;
72
+ /*
73
+ Column widths, measured once and then fixed. A table sizes columns
74
+ from the rows it holds, and a virtualized one holds different rows at
75
+ every scroll, so unfixed columns would jump sideways while scrolling.
76
+
77
+ A table that fits its box keeps them as shares (%), so it still fits
78
+ when the box narrows. One wider than its box keeps pixels and scrolls
79
+ sideways, as the plain table does, rather than squeezing every column
80
+ into an ellipsis on a phone.
81
+ */
82
+ this.columnWidths = [];
83
+ this.widthUnit = "%";
84
+ this.frame = 0;
85
+ this.wrapWidth = 0;
86
+ this.lastRange = "";
87
+ this.handleScroll = () => {
88
+ if (!this.virtual || this.frame)
89
+ return;
90
+ this.frame = requestAnimationFrame(() => {
91
+ this.frame = 0;
92
+ this.syncToScroll();
93
+ this.announceRange();
94
+ });
95
+ };
96
+ }
97
+ /*
98
+ What a row's selection checkbox is called.
99
+
100
+ "Select row" repeated twenty times tells a screen-reader user which
101
+ control they are on but nothing about what it does. The first column
102
+ is the closest thing to a row's name that a generic table can know,
103
+ so "Select Adriatik" comes out of the data rather than a guess.
104
+ */
105
+ rowLabel(row) {
106
+ const name = this.rowName(row);
107
+ return name ? `Select ${name}` : "Select row";
108
+ }
109
+ /*
110
+ Only plain text names a row. A rich first cell (a template with an
111
+ avatar and two lines) stringified to "[object Object]", which a screen
112
+ reader then read out on every row.
113
+ */
114
+ rowName(row) {
115
+ const first = this.columns[0];
116
+ const value = first ? row[first.key] : undefined;
117
+ return typeof value === "string" || typeof value === "number" ? String(value) : "";
118
+ }
119
+ get virtual() {
120
+ return this.visibleRows > 0 && !this.loading && this.rows.length > 0;
121
+ }
122
+ /** The slice of rows in the page: the ones in view plus OVERSCAN each side. */
123
+ get inPage() {
124
+ const count = this.rows.length;
125
+ if (!this.virtual)
126
+ return { start: 0, end: count };
127
+ // Clamped, because rows can shrink while the box is scrolled far down.
128
+ const first = Math.max(0, Math.min(this.firstInView, count - this.visibleRows));
129
+ return {
130
+ start: Math.max(0, first - OVERSCAN),
131
+ end: Math.min(count, first + this.visibleRows + OVERSCAN),
132
+ };
133
+ }
134
+ connectedCallback() {
135
+ super.connectedCallback();
136
+ // Measured again after the first render (firstUpdated) or a reconnect.
137
+ if (this.hasUpdated)
138
+ this.observeWidth();
139
+ }
140
+ disconnectedCallback() {
141
+ super.disconnectedCallback();
142
+ cancelAnimationFrame(this.frame);
143
+ this.frame = 0;
144
+ this.resizeObserver?.disconnect();
145
+ }
146
+ firstUpdated() {
147
+ this.observeWidth();
148
+ }
149
+ updated() {
150
+ if (this.virtual)
151
+ this.measureSoon();
152
+ else if (this.columnWidths.length > 0)
153
+ this.columnWidths = [];
154
+ }
155
+ /* A new width makes the fixed column widths wrong: measure them again. */
156
+ observeWidth() {
157
+ if (typeof ResizeObserver === "undefined" || !this.wrap)
158
+ return;
159
+ this.resizeObserver?.disconnect();
160
+ this.resizeObserver = new ResizeObserver(([entry]) => {
161
+ const width = Math.round(entry.contentRect.width);
162
+ if (width === this.wrapWidth)
163
+ return;
164
+ this.wrapWidth = width;
165
+ if (this.columnWidths.length > 0)
166
+ this.columnWidths = [];
167
+ });
168
+ this.resizeObserver.observe(this.wrap);
169
+ }
170
+ /*
171
+ Measuring happens a frame after rendering, never inside updated():
172
+ each measurement can change state, and a change during an update
173
+ would schedule another update straight away.
174
+ */
175
+ measureSoon() {
176
+ if (this.frame)
177
+ return;
178
+ this.frame = requestAnimationFrame(() => {
179
+ this.frame = 0;
180
+ this.measure();
181
+ });
182
+ }
183
+ measure() {
184
+ if (!this.virtual)
185
+ return;
186
+ const changed = (a, b) => Math.abs(a - b) > 0.5;
187
+ const row = this.renderRoot.querySelector("tbody tr.row");
188
+ const rowHeight = row?.getBoundingClientRect().height ?? 0;
189
+ if (rowHeight > 0 && changed(rowHeight, this.rowHeight))
190
+ this.rowHeight = rowHeight;
191
+ const header = this.renderRoot.querySelector("thead tr");
192
+ const headerHeight = header?.getBoundingClientRect().height ?? 0;
193
+ if (headerHeight > 0 && changed(headerHeight, this.headerHeight))
194
+ this.headerHeight = headerHeight;
195
+ if (this.columnWidths.length === 0) {
196
+ const widths = [...this.renderRoot.querySelectorAll("thead th")].map((cell) => cell.getBoundingClientRect().width);
197
+ const total = widths.reduce((sum, width) => sum + width, 0);
198
+ if (widths.length > 0 && widths.every((width) => width > 0)) {
199
+ const fits = total <= (this.wrap?.clientWidth ?? 0) + 1;
200
+ this.widthUnit = fits ? "%" : "px";
201
+ this.columnWidths = fits ? widths.map((width) => (width / total) * 100) : widths;
202
+ }
203
+ }
204
+ // The scroll position can move without a scroll the table hears
205
+ // about: rows shrinking under it clamp it.
206
+ this.syncToScroll();
207
+ this.announceRange();
208
+ }
209
+ syncToScroll() {
210
+ if (!this.wrap)
211
+ return;
212
+ // Half a pixel of slack: scrollTop is rounded, rows are not, and 300
213
+ // rows down must not read as 299.
214
+ const first = Math.floor((this.wrap.scrollTop + 0.5) / (this.rowHeight || ROW_ESTIMATE));
215
+ if (first !== this.firstInView)
216
+ this.firstInView = first;
217
+ }
218
+ /*
219
+ Which rows are in view, as indexes into rows (end excluded), each time
220
+ that changes. Enough to fetch the next page from a server before the
221
+ person scrolls into it.
222
+ */
223
+ announceRange() {
224
+ const count = this.rows.length;
225
+ const start = Math.max(0, Math.min(this.firstInView, count - this.visibleRows));
226
+ const end = Math.min(count, start + this.visibleRows);
227
+ const key = `${start}:${end}:${count}`;
228
+ if (key === this.lastRange)
229
+ return;
230
+ this.lastRange = key;
231
+ this.dispatchEvent(new CustomEvent("tt-range-change", {
232
+ detail: { start, end, total: count },
233
+ bubbles: true,
234
+ composed: true,
235
+ }));
236
+ }
237
+ get hasActions() {
238
+ return this.rowActions.length > 0;
239
+ }
240
+ get columnCount() {
241
+ return (this.columns.length + (this.selectable ? 1 : 0) + (this.hasActions ? 1 : 0));
242
+ }
243
+ /*
244
+ Both answer for the rows ON SCREEN, compared by id, never by count.
245
+
246
+ `selected` can hold ids that are not in `rows`: picked before a filter
247
+ hid them, or on another page. Comparing lengths then lies. Pick three
248
+ rows, filter to three different ones, and the header claimed "all
249
+ selected" while nothing visible was ticked.
250
+ */
251
+ get allSelected() {
252
+ return (this.rows.length > 0 &&
253
+ this.rows.every((row) => this.selected.includes(row.id)));
254
+ }
255
+ get someSelected() {
256
+ return (!this.allSelected &&
257
+ this.rows.some((row) => this.selected.includes(row.id)));
258
+ }
259
+ emitSelection(next) {
260
+ this.dispatchEvent(new CustomEvent("tt-selection-change", {
261
+ detail: { selected: next },
262
+ bubbles: true,
263
+ composed: true,
264
+ }));
265
+ }
266
+ toggleAll(event) {
267
+ // tt-checkbox emits its own composed tt-change. Without this it would
268
+ // reach the page too, arriving after ours with no `selected` in it.
269
+ event.stopPropagation();
270
+ /*
271
+ Select-all applies to what is currently on screen, which is what a
272
+ user means by "all" when a filter is active. It adds or removes ONLY
273
+ those rows: a selection made before the filter, now hidden, is not
274
+ the header checkbox's to throw away.
275
+ */
276
+ const visible = this.rows.map((r) => r.id);
277
+ this.emitSelection(this.allSelected
278
+ ? this.selected.filter((id) => !visible.includes(id))
279
+ : [...this.selected, ...visible.filter((id) => !this.selected.includes(id))]);
280
+ }
281
+ toggleRow(id, event) {
282
+ event.stopPropagation();
283
+ this.emitSelection(this.selected.includes(id)
284
+ ? this.selected.filter((s) => s !== id)
285
+ : [...this.selected, id]);
286
+ }
287
+ /*
288
+ Cycles ascending, descending, then off. The third state matters: once
289
+ sorted there is otherwise no way back to the original order, which is
290
+ usually meaningful (newest first, or whatever the server chose).
291
+ */
292
+ toggleSort(column) {
293
+ if (!column.sortable)
294
+ return;
295
+ let next;
296
+ if (this.sort?.key !== column.key) {
297
+ next = { key: column.key, direction: "asc" };
298
+ }
299
+ else if (this.sort.direction === "asc") {
300
+ next = { key: column.key, direction: "desc" };
301
+ }
302
+ else {
303
+ next = undefined;
304
+ }
305
+ this.dispatchEvent(new CustomEvent("tt-sort", {
306
+ detail: { sort: next },
307
+ bubbles: true,
308
+ composed: true,
309
+ }));
310
+ }
311
+ clickRow(row) {
312
+ if (!this.clickableRows)
313
+ return;
314
+ this.dispatchEvent(new CustomEvent("tt-row-click", {
315
+ detail: { row },
316
+ bubbles: true,
317
+ composed: true,
318
+ }));
319
+ }
320
+ chooseAction(row, event) {
321
+ // The menu's tt-menu-select is generic. Re-emit it as something the page
322
+ // can act on: which action, on which row.
323
+ event.stopPropagation();
324
+ const { value } = event.detail;
325
+ this.dispatchEvent(new CustomEvent("tt-row-action", {
326
+ detail: { action: value, row },
327
+ bubbles: true,
328
+ composed: true,
329
+ }));
330
+ }
331
+ static { this.styles = [
332
+ srOnly,
333
+ css `
334
+ /* The browser's own [hidden] rule loses to any :host display, so a
335
+ hidden element would still show. Important, so it always wins. */
336
+ :host([hidden]) {
337
+ display: none !important;
338
+ }
339
+
340
+ :host {
341
+ display: block;
342
+ font-family: var(--tt-font-sans);
343
+ }
344
+
345
+ .wrap {
346
+ width: 100%;
347
+ overflow-x: auto;
348
+ box-sizing: border-box;
349
+
350
+ background: var(--tt-card);
351
+ border: 1px solid var(--tt-border);
352
+ border-radius: var(--tt-radius-lg);
353
+
354
+ -webkit-overflow-scrolling: touch;
355
+ }
356
+
357
+ table {
358
+ width: 100%;
359
+ border-collapse: collapse;
360
+ font-size: var(--tt-text-sm);
361
+ }
362
+
363
+ /*
364
+ Sticky header: the column labels stay put while the body scrolls,
365
+ so you never lose track of what a column means in a long list.
366
+
367
+ It sticks to .wrap, not to the page. overflow-x: auto turns .wrap
368
+ into a scroll container on BOTH axes, and sticky always pins to the
369
+ nearest one. So it only works once the consumer gives the wrap a
370
+ height (::part(wrap) { max-height }). There is no way to scroll
371
+ sideways inside a box AND stick to the page's scroll; that is CSS,
372
+ not a choice made here.
373
+ */
374
+ thead th {
375
+ position: sticky;
376
+ top: 0;
377
+ z-index: 1;
378
+
379
+ /* The same pair as tt-table, so a colour theme tints every table header. */
380
+ background: var(--tt-table-header);
381
+ color: var(--tt-table-header-foreground);
382
+
383
+ padding: var(--tt-space-3) var(--tt-space-4);
384
+
385
+ font-size: var(--tt-text-xs);
386
+ font-weight: var(--tt-weight-semibold);
387
+ text-align: left;
388
+ text-transform: uppercase;
389
+ letter-spacing: 0.05em;
390
+ white-space: nowrap;
391
+ }
392
+
393
+ th.end,
394
+ td.end {
395
+ text-align: right;
396
+ }
397
+
398
+ td {
399
+ padding: var(--tt-space-3) var(--tt-space-4);
400
+ border-top: 1px solid var(--tt-border);
401
+ color: var(--tt-foreground);
402
+ line-height: var(--tt-leading-snug);
403
+ vertical-align: middle;
404
+ }
405
+
406
+ tbody tr {
407
+ transition: background var(--tt-duration-fast) var(--tt-ease);
408
+ }
409
+
410
+ tbody tr:hover {
411
+ background: var(--tt-accent);
412
+ }
413
+
414
+ tbody tr.clickable {
415
+ cursor: pointer;
416
+ }
417
+
418
+ /* Selected sits after hover so it wins, and gets its own darker
419
+ hover so a selected row still reacts to the pointer. */
420
+ tbody tr.selected {
421
+ background: color-mix(in srgb, var(--tt-primary) 8%, transparent);
422
+ }
423
+
424
+ tbody tr.selected:hover {
425
+ background: color-mix(in srgb, var(--tt-primary) 14%, transparent);
426
+ }
427
+
428
+ tbody tr:focus-visible {
429
+ outline: var(--tt-ring-width) solid var(--tt-ring);
430
+ outline-offset: var(--tt-ring-offset);
431
+ }
432
+
433
+ /* Sort controls are real buttons so the header is keyboard reachable.
434
+ A th with a click handler is not. */
435
+ .sort {
436
+ display: inline-flex;
437
+ align-items: center;
438
+ gap: var(--tt-space-1);
439
+
440
+ padding: 0;
441
+ border: none;
442
+ background: transparent;
443
+ color: inherit;
444
+
445
+ font: inherit;
446
+ font-size: inherit;
447
+ font-weight: inherit;
448
+ letter-spacing: inherit;
449
+ text-transform: inherit;
450
+
451
+ cursor: pointer;
452
+ }
453
+
454
+ .sort:hover {
455
+ color: var(--tt-foreground);
456
+ }
457
+
458
+ .sort:focus-visible {
459
+ outline: var(--tt-ring-width) solid var(--tt-ring);
460
+ outline-offset: var(--tt-ring-offset);
461
+ border-radius: var(--tt-radius-sm);
462
+ }
463
+
464
+ /* Reserve the arrow's space always, so a header does not shift
465
+ sideways the moment you sort by it. The icon is always rendered and
466
+ only faded, so it holds its own width. */
467
+ .arrow {
468
+ display: inline-flex;
469
+ opacity: 0;
470
+ }
471
+
472
+ .sorted {
473
+ color: var(--tt-foreground);
474
+ }
475
+
476
+ .sorted .arrow {
477
+ opacity: 1;
478
+ }
479
+
480
+ /* width:1% on a table cell means "as narrow as the content allows".
481
+ The other columns absorb the leftover space. */
482
+ .select-cell,
483
+ .actions-cell {
484
+ width: 1%;
485
+ white-space: nowrap;
486
+ }
487
+
488
+ .select-cell {
489
+ padding-right: 0;
490
+ }
491
+
492
+ .actions-cell {
493
+ text-align: right;
494
+ }
495
+
496
+ .state {
497
+ padding: var(--tt-space-6);
498
+ }
499
+
500
+ /* Virtualized: a box that scrolls on its own, and does not hand the
501
+ scroll on to the page when it reaches an end. */
502
+ .wrap.virtual {
503
+ overflow-y: auto;
504
+ overscroll-behavior: contain;
505
+ }
506
+
507
+ table.fixed {
508
+ table-layout: fixed;
509
+ }
510
+
511
+ /* One line per cell, so every row is the one height the window math
512
+ assumes. Data cells only: the checkbox and menu keep their focus
513
+ rings. */
514
+ .virtual td.cell {
515
+ overflow: hidden;
516
+ text-overflow: ellipsis;
517
+ white-space: nowrap;
518
+ }
519
+
520
+ tr.spacer td {
521
+ padding: 0;
522
+ border: 0;
523
+ }
524
+
525
+ /* Tighter sides on phones: a third column fits instead of scrolling. */
526
+ @media (max-width: 480px) {
527
+ thead th,
528
+ td {
529
+ padding-inline: var(--tt-space-3);
530
+ }
531
+
532
+ tr.spacer td {
533
+ padding: 0;
534
+ }
535
+ }
536
+
537
+ tbody tr.spacer:hover {
538
+ background: transparent;
539
+ }
540
+
541
+ `,
542
+ ]; }
543
+ renderHeader() {
544
+ return html `
545
+ <thead>
546
+ <tr aria-rowindex=${ifDefined(this.virtual ? 1 : undefined)}>
547
+ ${this.selectable
548
+ ? html `
549
+ <th class="select-cell">
550
+ <!--
551
+ The checkbox names ITSELF, but its label lives in a
552
+ nested shadow root, and a table header cell is judged
553
+ on its own text. Same pattern as the actions column
554
+ above: the column gets a name, the control gets a name,
555
+ and they are not the same sentence.
556
+ -->
557
+ <span class="sr-only">Select</span>
558
+ <tt-checkbox
559
+ label="Select all rows"
560
+ label-hidden
561
+ .checked=${this.allSelected}
562
+ .indeterminate=${this.someSelected}
563
+ @tt-change=${this.toggleAll}
564
+ ></tt-checkbox>
565
+ </th>
566
+ `
567
+ : ""}
568
+ ${this.columns.map((column) => {
569
+ const isSorted = this.sort?.key === column.key;
570
+ const direction = this.sort?.direction;
571
+ return html `
572
+ <th
573
+ class=${column.align === "end" ? "end" : ""}
574
+ style=${ifDefined(column.width ? `width:${column.width}` : undefined)}
575
+ aria-sort=${ifDefined(!column.sortable
576
+ ? undefined
577
+ : !isSorted
578
+ ? "none"
579
+ : direction === "asc"
580
+ ? "ascending"
581
+ : "descending")}
582
+ >
583
+ ${column.sortable
584
+ ? html `
585
+ <button
586
+ class="sort ${isSorted ? "sorted" : ""}"
587
+ type="button"
588
+ @click=${() => this.toggleSort(column)}
589
+ >
590
+ ${column.label}
591
+ <span class="arrow" aria-hidden="true">
592
+ <tt-icon
593
+ name=${direction === "desc" ? "arrow-down" : "arrow-up"}
594
+ size="12px"
595
+ ></tt-icon>
596
+ </span>
597
+ </button>
598
+ `
599
+ : column.label}
600
+ </th>
601
+ `;
602
+ })}
603
+ ${this.hasActions
604
+ ? html `<th class="actions-cell">
605
+ <span class="sr-only">Actions</span>
606
+ </th>`
607
+ : ""}
608
+ </tr>
609
+ </thead>
610
+ `;
611
+ }
612
+ renderLoading() {
613
+ return html `
614
+ <tbody aria-busy="true">
615
+ ${Array.from({ length: this.loadingRows }, () => html `
616
+ <tr>
617
+ <td colspan=${this.columnCount}>
618
+ <tt-skeleton variant="text"></tt-skeleton>
619
+ </td>
620
+ </tr>
621
+ `)}
622
+ </tbody>
623
+ `;
624
+ }
625
+ renderRow(row, index) {
626
+ const isSelected = this.selected.includes(row.id);
627
+ return html `
628
+ <tr
629
+ class="row ${this.clickableRows ? "clickable" : ""} ${isSelected
630
+ ? "selected"
631
+ : ""}"
632
+ aria-rowindex=${ifDefined(this.virtual ? index + 2 : undefined)}
633
+ tabindex=${ifDefined(this.clickableRows ? 0 : undefined)}
634
+ @click=${() => this.clickRow(row)}
635
+ @keydown=${(e) => {
636
+ /*
637
+ Only a key pressed on the row ITSELF. Keys bubble, so Enter on
638
+ the row's checkbox or its actions menu reaches this handler
639
+ too, and opening the menu would also navigate away. target is
640
+ where the key was pressed; currentTarget is this <tr>.
641
+ */
642
+ if (e.target !== e.currentTarget)
643
+ return;
644
+ if (this.clickableRows && e.key === "Enter")
645
+ this.clickRow(row);
646
+ }}
647
+ >
648
+ ${this.selectable
649
+ ? html `
650
+ <td class="select-cell" @click=${(e) => e.stopPropagation()}>
651
+ <tt-checkbox
652
+ .label=${this.rowLabel(row)}
653
+ label-hidden
654
+ .checked=${isSelected}
655
+ @tt-change=${(e) => this.toggleRow(row.id, e)}
656
+ ></tt-checkbox>
657
+ </td>
658
+ `
659
+ : ""}
660
+ ${this.columns.map((column) => html `
661
+ <td class="cell ${column.align === "end" ? "end" : ""}">
662
+ ${row[column.key] ?? ""}
663
+ </td>
664
+ `)}
665
+ ${this.hasActions
666
+ ? html `
667
+ <td
668
+ class="actions-cell"
669
+ @click=${(e) => e.stopPropagation()}
670
+ >
671
+ <tt-dropdown-menu
672
+ .items=${this.rowActions}
673
+ label=${this.rowName(row) ? `Actions for ${this.rowName(row)}` : "Actions"}
674
+ @tt-menu-select=${(e) => this.chooseAction(row, e)}
675
+ ></tt-dropdown-menu>
676
+ </td>
677
+ `
678
+ : ""}
679
+ </tr>
680
+ `;
681
+ }
682
+ /*
683
+ The rows in view, with a spacer row above and below standing in for
684
+ the rest, so the scrollbar is as long as the whole table. Keyed by id,
685
+ so a row keeps its element (and its focus, its open menu) while the
686
+ window slides over it.
687
+ */
688
+ renderRows() {
689
+ const { start, end } = this.inPage;
690
+ const height = this.rowHeight || ROW_ESTIMATE;
691
+ const spacer = (rows) => rows > 0
692
+ ? html `<tr class="spacer" aria-hidden="true" style="height: ${rows * height}px">
693
+ <td colspan=${this.columnCount}></td>
694
+ </tr>`
695
+ : "";
696
+ return html `
697
+ ${spacer(start)}
698
+ ${repeat(this.rows.slice(start, end), (row) => row.id, (row, offset) => this.renderRow(row, start + offset))}
699
+ ${spacer(this.rows.length - end)}
700
+ `;
701
+ }
702
+ render() {
703
+ const virtual = this.virtual;
704
+ const fixed = virtual && this.columnWidths.length > 0;
705
+ // The header, the rows in view and the two borders of .wrap.
706
+ const boxHeight = (this.headerHeight || ROW_ESTIMATE) + this.visibleRows * (this.rowHeight || ROW_ESTIMATE) + 2;
707
+ return html `
708
+ <div
709
+ class="wrap ${virtual ? "virtual" : ""}"
710
+ part="wrap"
711
+ style=${ifDefined(virtual ? `max-height: ${boxHeight}px` : undefined)}
712
+ @scroll=${this.handleScroll}
713
+ >
714
+ <table
715
+ part="table"
716
+ class=${fixed ? "fixed" : ""}
717
+ aria-label=${ifDefined(this.label || undefined)}
718
+ aria-rowcount=${ifDefined(virtual ? this.rows.length + 1 : undefined)}
719
+ >
720
+ ${fixed
721
+ ? html `<colgroup>
722
+ ${this.columnWidths.map((width) => html `<col style="width: ${width}${this.widthUnit}" />`)}
723
+ </colgroup>`
724
+ : ""}
725
+ ${this.renderHeader()}
726
+ ${this.loading
727
+ ? this.renderLoading()
728
+ : html `
729
+ <tbody>
730
+ ${this.rows.length === 0
731
+ ? html `
732
+ <tr>
733
+ <td class="state" colspan=${this.columnCount}>
734
+ <tt-empty-state
735
+ heading=${this.emptyHeading}
736
+ description=${this.emptyDescription}
737
+ >
738
+ <slot name="empty-actions" slot="actions"></slot>
739
+ </tt-empty-state>
740
+ </td>
741
+ </tr>
742
+ `
743
+ : this.renderRows()}
744
+ </tbody>
745
+ `}
746
+ </table>
747
+ </div>
748
+ `;
749
+ }
750
+ };
751
+ __decorate([
752
+ property({ type: Array })
753
+ ], TTDataTable.prototype, "columns", void 0);
754
+ __decorate([
755
+ property({ type: Array })
756
+ ], TTDataTable.prototype, "rows", void 0);
757
+ __decorate([
758
+ property({ type: String })
759
+ ], TTDataTable.prototype, "label", void 0);
760
+ __decorate([
761
+ property({ type: Object })
762
+ ], TTDataTable.prototype, "sort", void 0);
763
+ __decorate([
764
+ property({ type: Boolean })
765
+ ], TTDataTable.prototype, "selectable", void 0);
766
+ __decorate([
767
+ property({ type: Array })
768
+ ], TTDataTable.prototype, "selected", void 0);
769
+ __decorate([
770
+ property({ type: Array, attribute: "row-actions" })
771
+ ], TTDataTable.prototype, "rowActions", void 0);
772
+ __decorate([
773
+ property({ type: Boolean })
774
+ ], TTDataTable.prototype, "loading", void 0);
775
+ __decorate([
776
+ property({ type: Number, attribute: "loading-rows" })
777
+ ], TTDataTable.prototype, "loadingRows", void 0);
778
+ __decorate([
779
+ property({ type: String, attribute: "empty-heading" })
780
+ ], TTDataTable.prototype, "emptyHeading", void 0);
781
+ __decorate([
782
+ property({ type: String, attribute: "empty-description" })
783
+ ], TTDataTable.prototype, "emptyDescription", void 0);
784
+ __decorate([
785
+ property({ type: Boolean, attribute: "clickable-rows" })
786
+ ], TTDataTable.prototype, "clickableRows", void 0);
787
+ __decorate([
788
+ property({ type: Number, attribute: "visible-rows" })
789
+ ], TTDataTable.prototype, "visibleRows", void 0);
790
+ __decorate([
791
+ state()
792
+ ], TTDataTable.prototype, "firstInView", void 0);
793
+ __decorate([
794
+ state()
795
+ ], TTDataTable.prototype, "rowHeight", void 0);
796
+ __decorate([
797
+ state()
798
+ ], TTDataTable.prototype, "headerHeight", void 0);
799
+ __decorate([
800
+ state()
801
+ ], TTDataTable.prototype, "columnWidths", void 0);
802
+ __decorate([
803
+ state()
804
+ ], TTDataTable.prototype, "widthUnit", void 0);
805
+ __decorate([
806
+ query(".wrap")
807
+ ], TTDataTable.prototype, "wrap", void 0);
808
+ TTDataTable = __decorate([
809
+ customElement("tt-data-table")
810
+ ], TTDataTable);
811
+ export { TTDataTable };
812
+ //# sourceMappingURL=tt-data-table.js.map