@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,816 @@
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, state, query } from "lit/decorators.js";
9
+ import { ifDefined } from "lit/directives/if-defined.js";
10
+ import { srOnly } from "./sr-only.js";
11
+ import { trackAnchor, placeBelow } from "./floating.js";
12
+ import "./tt-icon.js";
13
+ let uid = 0;
14
+ /**
15
+ * A select you can type into.
16
+ *
17
+ * WHERE IT SITS. tt-select is right up to roughly twenty options: you open
18
+ * it, you look, you pick. Past that, looking stops working and you need to
19
+ * narrow the list by typing. That is the only difference in intent, but it
20
+ * changes the control's shape: the trigger becomes a text input rather
21
+ * than a button, which brings a filtering state, a no-results state, and
22
+ * the problem below. Keeping tt-select simple was worth a second component.
23
+ *
24
+ * THE AWKWARD BIT, which every combobox has to answer. One input has two
25
+ * jobs: it displays the current selection, and it holds what you are
26
+ * typing. Those conflict the moment you type, because the selection is
27
+ * still set but the text no longer shows it.
28
+ *
29
+ * This resolves it by treating the two as different modes rather than one
30
+ * value. Closed, the input shows the selected option's label. Open, it
31
+ * shows the query, which starts empty so the whole list is visible. Close
32
+ * without choosing and the query is discarded, so the field can never be
33
+ * left displaying text that is not the actual value. The selection only
34
+ * ever changes by choosing an option.
35
+ */
36
+ let TTCombobox = class TTCombobox extends LitElement {
37
+ constructor() {
38
+ super(...arguments);
39
+ this.internals = this.attachInternals();
40
+ /* See tt-quantity: a form-associated element submits under its name
41
+ CONTENT ATTRIBUTE, so this has to reflect. */
42
+ this.name = "";
43
+ this.value = "";
44
+ this.options = [];
45
+ this.label = "";
46
+ this.placeholder = "Search or select";
47
+ this.emptyText = "No matches";
48
+ this.error = "";
49
+ this.disabled = false;
50
+ this.required = false;
51
+ // small | medium | large, as on tt-input (Oct 2026), so a row of
52
+ // fields can share one height. Reflected: the sizes are :host rules.
53
+ this.size = "medium";
54
+ // Named for a screen reader, invisible on screen. Same contract as
55
+ // tt-input and tt-checkbox.
56
+ this.labelHidden = false;
57
+ // Offer a clear button once something is chosen.
58
+ this.clearable = false;
59
+ this.open = false;
60
+ // What has been typed this session. Never the selection.
61
+ this.query = "";
62
+ // Where the arrow keys are. Not the selection: you can move the cursor
63
+ // over an option without choosing it.
64
+ this.activeIndex = -1;
65
+ this.instanceId = ++uid;
66
+ this.listId = `tt-combobox-list-${this.instanceId}`;
67
+ this.handleDocumentClick = (event) => {
68
+ if (!event.composedPath().includes(this))
69
+ this.closeList(false);
70
+ };
71
+ this.reposition = () => {
72
+ if (this.open)
73
+ this.position();
74
+ };
75
+ }
76
+ static { this.formAssociated = true; }
77
+ get form() {
78
+ return this.internals.form;
79
+ }
80
+ get validity() {
81
+ return this.internals.validity;
82
+ }
83
+ checkValidity() {
84
+ return this.internals.checkValidity();
85
+ }
86
+ reportValidity() {
87
+ return this.internals.reportValidity();
88
+ }
89
+ connectedCallback() {
90
+ super.connectedCallback();
91
+ this.syncFormState();
92
+ }
93
+ disconnectedCallback() {
94
+ this.removeGlobalListeners();
95
+ super.disconnectedCallback();
96
+ }
97
+ formResetCallback() {
98
+ this.value = "";
99
+ this.query = "";
100
+ }
101
+ formStateRestoreCallback(state) {
102
+ this.value = state ?? "";
103
+ }
104
+ syncFormState() {
105
+ this.internals.setFormValue(this.value);
106
+ if (this.required && !this.value) {
107
+ this.internals.setValidity({ valueMissing: true }, "Please choose an option.", this.input ?? undefined);
108
+ }
109
+ else {
110
+ this.internals.setValidity({});
111
+ }
112
+ }
113
+ /* ---- derived ---- */
114
+ get selected() {
115
+ return this.options.find((o) => o.value === this.value);
116
+ }
117
+ /*
118
+ Named "filtered", not "matches". Element already has a matches()
119
+ method, and shadowing a built-in DOM member breaks the element type
120
+ outright - the same trap as naming a property "title".
121
+
122
+ Substring, case-insensitive, on the label. Deliberately not fuzzy
123
+ matching: fuzzy ranks results in an order the user cannot predict,
124
+ which is fine for a command palette and wrong for a field where they
125
+ already know the name of the thing they want.
126
+ */
127
+ /*
128
+ Matches are RANKED by where they hit, not just whether they hit.
129
+
130
+ A plain `label.includes(q)` is fine for a list of twelve and useless
131
+ for a list of hundreds: in a car catalogue, typing "a" matched 181 of
132
+ 248 options, because almost every label contains an "a" somewhere, and
133
+ they came back in whatever order the consumer happened to supply. The
134
+ first keystroke should narrow the list, not shuffle it.
135
+
136
+ Four tiers, and the order between them is the whole point. An exact
137
+ label beats a label that starts with the query, which beats a label
138
+ where some WORD starts with it ("x5" finding "BMW X5"), which beats a
139
+ match buried mid-word. Ties keep the order the consumer gave, which is
140
+ usually already meaningful - most popular first, say - so the sort has
141
+ to be stable, and Array.prototype.sort is only stable with respect to
142
+ the input order. Mapping to indexed pairs first is what guarantees it.
143
+ */
144
+ score(label, q) {
145
+ const l = label.toLowerCase();
146
+ if (l === q)
147
+ return 4;
148
+ if (l.startsWith(q))
149
+ return 3;
150
+ // \b would not fire after "-" or "/", which is exactly where model
151
+ // names break: "E-Class", "CR-V".
152
+ if (l.split(/[\s\-/(),.]+/).some((word) => word.startsWith(q)))
153
+ return 2;
154
+ if (l.includes(q))
155
+ return 1;
156
+ return 0;
157
+ }
158
+ get filtered() {
159
+ const q = this.query.trim().toLowerCase();
160
+ if (q === "")
161
+ return this.options;
162
+ return this.options
163
+ .map((option, index) => ({ option, index, score: this.score(option.label, q) }))
164
+ .filter((entry) => entry.score > 0)
165
+ .sort((a, b) => b.score - a.score || a.index - b.index)
166
+ .map((entry) => entry.option);
167
+ }
168
+ /* ---- open / close ---- */
169
+ openList() {
170
+ if (this.disabled || this.open)
171
+ return;
172
+ this.open = true;
173
+ // Empty, so opening shows everything. Pre-filling with the current
174
+ // label would filter the list down to the thing already chosen, which
175
+ // is the least useful list possible.
176
+ this.query = "";
177
+ this.activeIndex = this.filtered.findIndex((o) => o.value === this.value);
178
+ document.addEventListener("click", this.handleDocumentClick);
179
+ this.untrack = trackAnchor(this, this.reposition);
180
+ }
181
+ closeList(refocus = true) {
182
+ if (!this.open)
183
+ return;
184
+ this.open = false;
185
+ this.activeIndex = -1;
186
+ // Discard the query. The input goes back to showing the selection, so
187
+ // it can never be left displaying something that is not the value.
188
+ this.query = "";
189
+ this.removeGlobalListeners();
190
+ if (refocus)
191
+ this.input?.focus();
192
+ }
193
+ removeGlobalListeners() {
194
+ document.removeEventListener("click", this.handleDocumentClick);
195
+ this.untrack?.();
196
+ this.untrack = undefined;
197
+ }
198
+ /**
199
+ * Clicking the field opens the list. FOCUS DOES NOT.
200
+ *
201
+ * This looks like a downgrade and is the opposite. Opening on focus
202
+ * creates a loop that is invisible until somebody uses a real mouse:
203
+ * choosing an option calls closeList, closeList returns focus to the
204
+ * input so a keyboard user does not lose their place, that focus fires
205
+ * the focus handler, and the list reopens the instant it closes. The
206
+ * chosen value is set correctly, so it looks purely like a broken menu.
207
+ *
208
+ * It survived a headless test because a synthetic .click() never moves
209
+ * focus off the input, so the focus() inside closeList is a no-op and
210
+ * dispatches nothing. Only a real pointer, which blurs the input on
211
+ * mousedown, makes it fire.
212
+ *
213
+ * Every way a person actually asks for the list is still covered: click
214
+ * the field here, type (handleInput opens), or press ArrowDown/ArrowUp.
215
+ * Only tabbing THROUGH the field no longer explodes a listbox open,
216
+ * which matches the ARIA combobox pattern anyway.
217
+ */
218
+ handleFieldClick() {
219
+ if (this.disabled)
220
+ return;
221
+ this.input?.focus();
222
+ // The list is a sibling of the field, not a child, so an option click
223
+ // never bubbles back through here and cannot re-open what it closed.
224
+ this.openList();
225
+ }
226
+ /* ---- selection ---- */
227
+ choose(option) {
228
+ if (option.disabled)
229
+ return;
230
+ this.value = option.value;
231
+ this.closeList();
232
+ this.dispatchEvent(new CustomEvent("tt-change", {
233
+ detail: { value: this.value },
234
+ bubbles: true,
235
+ composed: true,
236
+ }));
237
+ }
238
+ clear(event) {
239
+ event.stopPropagation();
240
+ this.value = "";
241
+ this.query = "";
242
+ this.dispatchEvent(new CustomEvent("tt-change", {
243
+ detail: { value: "" },
244
+ bubbles: true,
245
+ composed: true,
246
+ }));
247
+ this.input?.focus();
248
+ }
249
+ /* ---- input ---- */
250
+ handleInput(event) {
251
+ if (!this.open)
252
+ this.openList();
253
+ this.query = event.target.value;
254
+ // Typing invalidates wherever the cursor was, so put it on the best
255
+ // remaining candidate rather than leaving it pointing at nothing.
256
+ this.activeIndex = this.filtered.length > 0 ? 0 : -1;
257
+ }
258
+ move(delta) {
259
+ const list = this.filtered;
260
+ if (list.length === 0)
261
+ return;
262
+ let next = this.activeIndex;
263
+ for (let i = 0; i < list.length; i++) {
264
+ next = (next + delta + list.length) % list.length;
265
+ if (!list[next].disabled)
266
+ break;
267
+ }
268
+ this.activeIndex = next;
269
+ this.scrollActiveIntoView();
270
+ }
271
+ scrollActiveIntoView() {
272
+ this.updateComplete.then(() => {
273
+ const items = this.list?.querySelectorAll("li");
274
+ items?.[this.activeIndex]?.scrollIntoView({ block: "nearest" });
275
+ });
276
+ }
277
+ handleKeydown(event) {
278
+ if (this.disabled)
279
+ return;
280
+ switch (event.key) {
281
+ case "ArrowDown":
282
+ event.preventDefault();
283
+ if (this.open)
284
+ this.move(1);
285
+ else
286
+ this.openList();
287
+ break;
288
+ case "ArrowUp":
289
+ event.preventDefault();
290
+ if (!this.open)
291
+ this.openList();
292
+ this.move(-1);
293
+ break;
294
+ case "Home":
295
+ if (this.open) {
296
+ event.preventDefault();
297
+ this.activeIndex = -1;
298
+ this.move(1);
299
+ }
300
+ break;
301
+ case "End":
302
+ if (this.open) {
303
+ event.preventDefault();
304
+ this.activeIndex = 0;
305
+ this.move(-1);
306
+ }
307
+ break;
308
+ case "Enter": {
309
+ // Only swallow Enter while a choice is actually pending, so the
310
+ // key still submits the surrounding form the rest of the time.
311
+ const option = this.filtered[this.activeIndex];
312
+ if (this.open && option) {
313
+ event.preventDefault();
314
+ this.choose(option);
315
+ }
316
+ break;
317
+ }
318
+ case "Escape":
319
+ if (this.open) {
320
+ event.preventDefault();
321
+ this.closeList();
322
+ }
323
+ break;
324
+ case "Tab":
325
+ this.closeList(false);
326
+ break;
327
+ }
328
+ }
329
+ /* ---- positioning ---- */
330
+ updated(changed) {
331
+ if (changed.has("value") || changed.has("required")) {
332
+ this.syncFormState();
333
+ }
334
+ if (changed.has("open") || (this.open && changed.has("query"))) {
335
+ this.syncPopover();
336
+ }
337
+ }
338
+ syncPopover() {
339
+ const list = this.list;
340
+ if (!list)
341
+ return;
342
+ if (this.open) {
343
+ if (!list.matches(":popover-open"))
344
+ list.showPopover();
345
+ this.position();
346
+ }
347
+ else if (list.matches(":popover-open")) {
348
+ list.hidePopover();
349
+ }
350
+ }
351
+ position() {
352
+ if (!this.field || !this.list)
353
+ return;
354
+ // A field's dropdown should be exactly as wide as the field, which is
355
+ // the one thing placeBelow does not decide for you. Set BEFORE placing:
356
+ // the width decides how options wrap, so the height placeBelow
357
+ // measures to choose above or below was the previous width's.
358
+ this.list.style.width = `${this.field.getBoundingClientRect().width}px`;
359
+ placeBelow(this.field, this.list, { align: "start" });
360
+ }
361
+ focus(options) {
362
+ this.input?.focus(options);
363
+ }
364
+ static { this.styles = [srOnly, css `
365
+ /* The browser's own [hidden] rule loses to any :host display, so a
366
+ hidden element would still show. Important, so it always wins. */
367
+ :host([hidden]) {
368
+ display: none !important;
369
+ }
370
+
371
+ :host {
372
+ /* A grid or flex item defaults to min-width: auto, which floors it at
373
+ its MIN-CONTENT width. See tt-input for what that broke. */
374
+ min-width: 0;
375
+
376
+ display: block;
377
+ width: 100%;
378
+ font-family: var(--tt-font-sans);
379
+ }
380
+
381
+ .wrap {
382
+ display: flex;
383
+ flex-direction: column;
384
+ gap: var(--tt-space-2);
385
+ }
386
+
387
+ .label {
388
+ font-size: var(--tt-text-sm);
389
+ font-weight: var(--tt-weight-medium);
390
+ color: var(--tt-foreground);
391
+ }
392
+
393
+ .req {
394
+ margin-left: 2px;
395
+ color: var(--tt-destructive);
396
+ }
397
+
398
+ /* Matches tt-input's control box, because this IS a field. The border
399
+ lives here so the icons sit inside it. */
400
+ .field {
401
+ display: flex;
402
+ align-items: center;
403
+ gap: var(--tt-space-2);
404
+
405
+ min-height: var(--tt-control-md);
406
+ padding: 0 13px;
407
+ box-sizing: border-box;
408
+
409
+ border: 1px solid var(--tt-input);
410
+ border-radius: var(--tt-group-radius, var(--tt-radius));
411
+
412
+ background: var(--tt-field);
413
+ color: var(--tt-foreground);
414
+
415
+ cursor: text;
416
+
417
+ transition: border-color var(--tt-duration-normal) var(--tt-ease);
418
+ }
419
+
420
+ /* The same three steps as tt-input. */
421
+ :host([size="small"]) .field {
422
+ min-height: var(--tt-control-sm);
423
+ padding: 0 11px;
424
+ }
425
+
426
+ :host([size="large"]) .field {
427
+ min-height: var(--tt-control-lg);
428
+ padding: 0 16px;
429
+ }
430
+
431
+ :host([size="large"]) input {
432
+ font-size: var(--tt-text-md);
433
+ }
434
+
435
+ /* iOS zooms the viewport when a focused field is under 16px. tt-input
436
+ and tt-textarea guarded against it; this field did not. */
437
+ @media (max-width: 480px) {
438
+ input,
439
+ :host([size="large"]) input {
440
+ font-size: 16px;
441
+ }
442
+ }
443
+
444
+ .field:hover:not(.disabled):not(.error) {
445
+ border-color: var(--tt-border-strong);
446
+ }
447
+
448
+ .field:focus-within {
449
+ border-color: var(--tt-ring);
450
+ outline: var(--tt-ring-width) solid var(--tt-ring);
451
+ outline-offset: calc(var(--tt-ring-width) * -1);
452
+ }
453
+
454
+ .field.error {
455
+ border-color: var(--tt-destructive);
456
+ }
457
+
458
+ .field.error:focus-within {
459
+ outline-color: var(--tt-destructive);
460
+ }
461
+
462
+ /*
463
+ A disabled FIELD does not fade. It takes the muted surface and muted
464
+ text, the same as tt-input and tt-textarea, so a disabled row of
465
+ fields reads as one state. It used to fade the whole host as well,
466
+ which made a disabled select look different from a disabled input
467
+ beside it.
468
+ */
469
+ .field.disabled {
470
+ background: var(--tt-muted);
471
+ color: var(--tt-muted-foreground);
472
+ cursor: not-allowed;
473
+ }
474
+
475
+ input {
476
+ flex: 1;
477
+ min-width: 0;
478
+
479
+ padding: 0;
480
+ border: none;
481
+ background: transparent;
482
+ color: inherit;
483
+
484
+ font: inherit;
485
+ font-size: var(--tt-text-sm);
486
+ /* font: inherit also brings the PAGE's line-height in. Inside a
487
+ paragraph at line-height 2 the input was 28px tall, and a compact
488
+ small combobox grew to 30px beside 28px controls. normal is what
489
+ tt-input's input keeps. */
490
+ line-height: normal;
491
+
492
+ cursor: inherit;
493
+ }
494
+
495
+ input:focus {
496
+ outline: none;
497
+ }
498
+
499
+ input::placeholder {
500
+ color: var(--tt-muted-foreground);
501
+ }
502
+
503
+ .chevron {
504
+ color: var(--tt-muted-foreground);
505
+ transition: transform var(--tt-duration-fast) var(--tt-ease);
506
+ }
507
+
508
+ /* Keyed off a class, not :host([open]). The open flag is @state, so it
509
+ never reaches the DOM and :host([open]) can never match. */
510
+ .field.open .chevron {
511
+ transform: rotate(180deg);
512
+ }
513
+
514
+ .clear {
515
+ display: inline-flex;
516
+ align-items: center;
517
+ justify-content: center;
518
+
519
+ /* Same size as tt-search's clear button: two fields, one clear
520
+ control. It was 20px here and 24px there. */
521
+ width: calc(var(--tt-control-sm) - 8px);
522
+ height: calc(var(--tt-control-sm) - 8px);
523
+
524
+ padding: 0;
525
+ border: none;
526
+ border-radius: var(--tt-radius-full);
527
+
528
+ background: transparent;
529
+ color: var(--tt-muted-foreground);
530
+
531
+ cursor: pointer;
532
+
533
+ -webkit-user-select: none;
534
+ user-select: none;
535
+ }
536
+
537
+ .clear:hover {
538
+ background: var(--tt-accent);
539
+ color: var(--tt-foreground);
540
+ }
541
+
542
+ .clear:focus-visible {
543
+ outline: var(--tt-ring-width) solid var(--tt-ring);
544
+ outline-offset: var(--tt-ring-offset);
545
+ }
546
+
547
+ /* Top layer, so no ancestor's overflow can clip it. Position and
548
+ width both come from script. */
549
+ ul {
550
+ position: fixed;
551
+ margin: 0;
552
+ padding: var(--tt-space-1);
553
+
554
+ max-height: 260px;
555
+ overflow-y: auto;
556
+ box-sizing: border-box;
557
+
558
+ list-style: none;
559
+
560
+ background: var(--tt-popover);
561
+ color: var(--tt-popover-foreground);
562
+
563
+ border: 1px solid var(--tt-border);
564
+ border-radius: var(--tt-radius);
565
+ box-shadow: var(--tt-elevation-2);
566
+ }
567
+
568
+ /* In and out of the top layer, as on tt-dropdown-menu: see the note
569
+ there for why display and overlay ride along, and why translate. */
570
+ ul {
571
+ transition:
572
+ opacity var(--tt-duration-fast) var(--tt-ease-in),
573
+ translate var(--tt-duration-fast) var(--tt-ease-in),
574
+ overlay var(--tt-duration-fast) allow-discrete,
575
+ display var(--tt-duration-fast) allow-discrete;
576
+ }
577
+
578
+ ul:popover-open {
579
+ transition-duration: var(--tt-duration-slow);
580
+ transition-timing-function: var(--tt-ease-out);
581
+ }
582
+
583
+ @starting-style {
584
+ ul:popover-open {
585
+ opacity: 0;
586
+ translate: 0 -4px;
587
+ }
588
+ }
589
+
590
+ /* Closed, and closing: clicks during the fade reach the page. */
591
+ ul:not(:popover-open) {
592
+ display: none;
593
+ opacity: 0;
594
+ translate: 0 -4px;
595
+ pointer-events: none;
596
+ }
597
+
598
+ li {
599
+ padding: var(--tt-space-2) var(--tt-space-3);
600
+ border-radius: var(--tt-radius-sm);
601
+
602
+ font-size: var(--tt-text-sm);
603
+ cursor: pointer;
604
+
605
+ -webkit-user-select: none;
606
+ user-select: none;
607
+ }
608
+
609
+ li[aria-selected="true"] {
610
+ font-weight: var(--tt-weight-semibold);
611
+ }
612
+
613
+ li.active {
614
+ background: var(--tt-accent);
615
+ color: var(--tt-accent-foreground);
616
+ }
617
+
618
+ li[aria-disabled="true"] {
619
+ opacity: var(--tt-opacity-disabled);
620
+ cursor: not-allowed;
621
+ }
622
+
623
+ .empty {
624
+ padding: var(--tt-space-3);
625
+ font-size: var(--tt-text-sm);
626
+ color: var(--tt-muted-foreground);
627
+ text-align: center;
628
+ cursor: default;
629
+ }
630
+
631
+ .error-text {
632
+ color: var(--tt-destructive);
633
+ font-size: var(--tt-text-xs);
634
+ font-weight: var(--tt-weight-medium);
635
+ }
636
+
637
+ `]; }
638
+ render() {
639
+ const filtered = this.filtered;
640
+ const errorId = this.error ? `tt-combobox-error-${this.instanceId}` : undefined;
641
+ const labelId = `tt-combobox-label-${this.instanceId}`;
642
+ // Open means "showing the query", closed means "showing the value".
643
+ const shown = this.open ? this.query : (this.selected?.label ?? "");
644
+ return html `
645
+ <div class="wrap">
646
+ ${this.label
647
+ ? html `
648
+ <span
649
+ class="label ${this.labelHidden ? "sr-only" : ""}"
650
+ part="label"
651
+ id=${labelId}
652
+ >
653
+ ${this.label}
654
+ ${this.required
655
+ ? html `<span class="req" aria-hidden="true">*</span>`
656
+ : ""}
657
+ </span>
658
+ `
659
+ : ""}
660
+
661
+ <div
662
+ class="field ${this.open ? "open" : ""} ${this.error
663
+ ? "error"
664
+ : ""} ${this.disabled ? "disabled" : ""}"
665
+ part="field"
666
+ @click=${this.handleFieldClick}
667
+ >
668
+ <input
669
+ part="input"
670
+ type="text"
671
+ role="combobox"
672
+ aria-labelledby=${ifDefined(this.label ? labelId : undefined)}
673
+ autocomplete="off"
674
+ spellcheck="false"
675
+ .value=${shown}
676
+ placeholder=${this.selected && !this.open
677
+ ? this.selected.label
678
+ : this.placeholder}
679
+ aria-expanded=${this.open ? "true" : "false"}
680
+ aria-controls=${this.listId}
681
+ aria-autocomplete="list"
682
+ aria-activedescendant=${this.open && this.activeIndex >= 0
683
+ ? `${this.listId}-${this.activeIndex}`
684
+ : ""}
685
+ aria-required=${this.required ? "true" : "false"}
686
+ aria-invalid=${this.error ? "true" : "false"}
687
+ aria-describedby=${errorId ?? ""}
688
+ ?disabled=${this.disabled}
689
+ @input=${this.handleInput}
690
+ @keydown=${this.handleKeydown}
691
+ />
692
+
693
+ ${this.clearable && this.value && !this.disabled
694
+ ? html `
695
+ <button
696
+ class="clear"
697
+ type="button"
698
+ aria-label="Clear selection"
699
+ @click=${this.clear}
700
+ >
701
+ <tt-icon name="x" size="14px"></tt-icon>
702
+ </button>
703
+ `
704
+ : ""}
705
+
706
+ <tt-icon
707
+ class="chevron"
708
+ name="chevron-down"
709
+ size="16px"
710
+ ></tt-icon>
711
+ </div>
712
+
713
+ <ul part="list" id=${this.listId} popover="manual" role="listbox">
714
+ ${filtered.length === 0
715
+ ? html `<li class="empty" role="presentation">${this.emptyText}</li>`
716
+ : filtered.map((option, index) => html `
717
+ <li
718
+ id=${`${this.listId}-${index}`}
719
+ role="option"
720
+ class=${index === this.activeIndex ? "active" : ""}
721
+ aria-selected=${option.value === this.value
722
+ ? "true"
723
+ : "false"}
724
+ aria-disabled=${option.disabled ? "true" : "false"}
725
+ @click=${() => this.choose(option)}
726
+ @mousemove=${() => (this.activeIndex = index)}
727
+ >
728
+ ${option.label}
729
+ </li>
730
+ `)}
731
+ </ul>
732
+
733
+ <!--
734
+ The list changes as you type, and nothing said so. Focus stays in
735
+ the input, so a screen-reader user typed into silence, and an
736
+ empty result ("No matches") was never spoken at all. Polite, and
737
+ only while there is a query, so opening the list stays quiet.
738
+ -->
739
+ <span class="sr-only" role="status">
740
+ ${this.open && this.query.trim()
741
+ ? filtered.length === 0
742
+ ? this.emptyText
743
+ : `${filtered.length} ${filtered.length === 1 ? "result" : "results"}`
744
+ : ""}
745
+ </span>
746
+
747
+ ${this.error
748
+ ? html `
749
+ <span id=${ifDefined(errorId)} class="error-text" role="alert">
750
+ ${this.error}
751
+ </span>
752
+ `
753
+ : ""}
754
+ </div>
755
+ `;
756
+ }
757
+ };
758
+ __decorate([
759
+ property({ type: String, reflect: true })
760
+ ], TTCombobox.prototype, "name", void 0);
761
+ __decorate([
762
+ property({ type: String })
763
+ ], TTCombobox.prototype, "value", void 0);
764
+ __decorate([
765
+ property({ type: Array })
766
+ ], TTCombobox.prototype, "options", void 0);
767
+ __decorate([
768
+ property({ type: String })
769
+ ], TTCombobox.prototype, "label", void 0);
770
+ __decorate([
771
+ property({ type: String })
772
+ ], TTCombobox.prototype, "placeholder", void 0);
773
+ __decorate([
774
+ property({ type: String, attribute: "empty-text" })
775
+ ], TTCombobox.prototype, "emptyText", void 0);
776
+ __decorate([
777
+ property({ type: String })
778
+ ], TTCombobox.prototype, "error", void 0);
779
+ __decorate([
780
+ property({ type: Boolean, reflect: true })
781
+ ], TTCombobox.prototype, "disabled", void 0);
782
+ __decorate([
783
+ property({ type: Boolean })
784
+ ], TTCombobox.prototype, "required", void 0);
785
+ __decorate([
786
+ property({ type: String, reflect: true })
787
+ ], TTCombobox.prototype, "size", void 0);
788
+ __decorate([
789
+ property({ type: Boolean, attribute: "label-hidden", reflect: true })
790
+ ], TTCombobox.prototype, "labelHidden", void 0);
791
+ __decorate([
792
+ property({ type: Boolean })
793
+ ], TTCombobox.prototype, "clearable", void 0);
794
+ __decorate([
795
+ state()
796
+ ], TTCombobox.prototype, "open", void 0);
797
+ __decorate([
798
+ state()
799
+ ], TTCombobox.prototype, "query", void 0);
800
+ __decorate([
801
+ state()
802
+ ], TTCombobox.prototype, "activeIndex", void 0);
803
+ __decorate([
804
+ query("input")
805
+ ], TTCombobox.prototype, "input", void 0);
806
+ __decorate([
807
+ query(".field")
808
+ ], TTCombobox.prototype, "field", void 0);
809
+ __decorate([
810
+ query("ul")
811
+ ], TTCombobox.prototype, "list", void 0);
812
+ TTCombobox = __decorate([
813
+ customElement("tt-combobox")
814
+ ], TTCombobox);
815
+ export { TTCombobox };
816
+ //# sourceMappingURL=tt-combobox.js.map