@tartaguti/ui-components 0.0.0-stage → 0.1.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 +7 -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 +16731 -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 +69 -0
  172. package/dist/tt-data-table.d.ts.map +1 -0
  173. package/dist/tt-data-table.js +542 -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 +2907 -0
@@ -0,0 +1,2907 @@
1
+ {
2
+ "version": 1.1,
3
+ "tags": [
4
+ {
5
+ "name": "tt-accordion",
6
+ "description": "Groups `tt-accordion-item` children and owns which of them are open:\n\n <tt-accordion>\n <tt-accordion-item heading=\"Shipping\">...</tt-accordion-item>\n <tt-accordion-item heading=\"Returns\">...</tt-accordion-item>\n </tt-accordion>\n\nBy default one item is open at a time. Set `multiple` to let them stack.\nClicking an open header always closes it.\n\n**Events:** tt-accordion-change",
7
+ "attributes": [
8
+ {
9
+ "name": "multiple",
10
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-accordion>`"
11
+ }
12
+ ]
13
+ },
14
+ {
15
+ "name": "tt-accordion-item",
16
+ "description": "One row of a `tt-accordion`.\n\nIt deliberately does not own `open`. Clicking the header fires\n`tt-accordion-toggle` and the parent decides what happens, which is what\nmakes single-open mode possible: only the parent can know that opening\nthis item has to close another one.\n\nUsed on its own it will not open, because nothing is listening.\n\n**Events:** tt-accordion-toggle",
17
+ "attributes": [
18
+ {
19
+ "name": "open",
20
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-accordion-item>`"
21
+ },
22
+ {
23
+ "name": "disabled",
24
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-accordion-item>`"
25
+ },
26
+ {
27
+ "name": "heading",
28
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-accordion-item>`"
29
+ },
30
+ {
31
+ "name": "value",
32
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-accordion-item>`"
33
+ },
34
+ {
35
+ "name": "heading-level",
36
+ "description": "Type: `number`\n\nDefault: `3`\n\nOn `<tt-accordion-item>`"
37
+ }
38
+ ]
39
+ },
40
+ {
41
+ "name": "tt-alert",
42
+ "description": "A message that stays on the page, in context.\n\nNot the same thing as tt-toast. A toast is transient and global: \"saved\".\nAn alert is persistent and local: it sits next to the thing it is about\nand stays until the situation changes. Use an alert for \"this listing is\nunverified\" or \"your trial ends in 3 days\".\n\n**Events:** tt-close",
43
+ "attributes": [
44
+ {
45
+ "name": "variant",
46
+ "description": "Type: `AlertVariant`\n\nDefault: `\"neutral\"`\n\nOn `<tt-alert>`",
47
+ "values": [
48
+ {
49
+ "name": "neutral"
50
+ },
51
+ {
52
+ "name": "info"
53
+ },
54
+ {
55
+ "name": "success"
56
+ },
57
+ {
58
+ "name": "warning"
59
+ },
60
+ {
61
+ "name": "danger"
62
+ }
63
+ ]
64
+ },
65
+ {
66
+ "name": "heading",
67
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-alert>`"
68
+ },
69
+ {
70
+ "name": "closable",
71
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-alert>`"
72
+ }
73
+ ]
74
+ },
75
+ {
76
+ "name": "tt-aspect-ratio",
77
+ "description": "Holds a box at a fixed width-to-height ratio.\n\nFor anything whose height must be known before its content arrives: a\nvideo embed, a map, an image placeholder, a chart. Without it the page\nreflows the moment the content loads, which is the single largest\ncause of layout shift on a media-heavy page.\n\n---------------------------------------------------------------------\nWHY THIS IS NOT JUST `aspect-ratio` IN YOUR OWN CSS.\n\nIt nearly is, and if you control the CSS you should write it yourself.\nThis exists for the case where you do not: slotted content, a block\nsomeone copied, a cell inside a grid. It also solves the part people\nget wrong, which is that `aspect-ratio` alone does nothing unless the\nCHILD is told to fill the box. That is the `::slotted` rule below and\nit is the whole reason this is a component.\n\n---------------------------------------------------------------------\nON THE `ratio` FORMAT.\n\nTakes \"16/9\" or \"1.777\". Both land in the same CSS property, which\naccepts either. The string form is kept because \"16/9\" is what the\nratio is CALLED, and a reader recognising it at a glance is worth more\nthan saving a division.",
78
+ "attributes": [
79
+ {
80
+ "name": "ratio",
81
+ "description": "Type: `string`\n\nDefault: `\"16/9\"`\n\nOn `<tt-aspect-ratio>`"
82
+ }
83
+ ]
84
+ },
85
+ {
86
+ "name": "tt-auth",
87
+ "description": "The four screens every application needs, as one component.\n\nOne element with a `mode` rather than four elements, the same choice\ntt-product and tt-profile-card make with `orientation`. All four share\na card, a heading, an error region and a footer; only the fields and\nthe event differ. Four components would repeat that shell four times\nand let it drift.\n\nIT NEVER TALKS TO A SERVER AND NEVER DECIDES ANYTHING. It reports what\nwas typed and what was asked for. Whether the credentials are valid,\nwhether the account exists, and what happens next all belong to\nwhoever is using it. That is what keeps it usable against any backend.\n\nThe events, for the custom-elements manifest. Its analyzer reads event\nnames from string literals at the dispatch site, and these are chosen at\nrun time, so without the tags the manifest listed a bogus event instead.\n\n**Events:** tt-sign-in, tt-sign-up, tt-forgot, tt-reset, tt-mode",
88
+ "attributes": [
89
+ {
90
+ "name": "mode",
91
+ "description": "Type: `AuthMode`\n\nDefault: `\"signIn\"`\n\nOn `<tt-auth>`",
92
+ "values": [
93
+ {
94
+ "name": "signIn"
95
+ },
96
+ {
97
+ "name": "signUp"
98
+ },
99
+ {
100
+ "name": "forgotPsw"
101
+ },
102
+ {
103
+ "name": "resetPsw"
104
+ }
105
+ ]
106
+ },
107
+ {
108
+ "name": "heading",
109
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-auth>`"
110
+ },
111
+ {
112
+ "name": "description",
113
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-auth>`"
114
+ },
115
+ {
116
+ "name": "submit-label",
117
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-auth>`"
118
+ },
119
+ {
120
+ "name": "email-label",
121
+ "description": "Type: `string`\n\nDefault: `\"Email\"`\n\nOn `<tt-auth>`"
122
+ },
123
+ {
124
+ "name": "password-label",
125
+ "description": "Type: `string`\n\nDefault: `\"Password\"`\n\nOn `<tt-auth>`"
126
+ },
127
+ {
128
+ "name": "name-label",
129
+ "description": "Type: `string`\n\nDefault: `\"Full name\"`\n\nOn `<tt-auth>`"
130
+ },
131
+ {
132
+ "name": "email",
133
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-auth>`"
134
+ },
135
+ {
136
+ "name": "name",
137
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-auth>`"
138
+ },
139
+ {
140
+ "name": "remember-me",
141
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-auth>`"
142
+ },
143
+ {
144
+ "name": "loading",
145
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-auth>`"
146
+ },
147
+ {
148
+ "name": "sent",
149
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-auth>`"
150
+ },
151
+ {
152
+ "name": "error",
153
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-auth>`"
154
+ }
155
+ ]
156
+ },
157
+ {
158
+ "name": "tt-avatar",
159
+ "description": "Image with an initials fallback. The fallback is the entire point:\nlogos and profile photos fail to load constantly, and a broken image\nicon is the difference between a product that looks maintained and one\nthat does not.",
160
+ "attributes": [
161
+ {
162
+ "name": "src",
163
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-avatar>`"
164
+ },
165
+ {
166
+ "name": "name",
167
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-avatar>`"
168
+ },
169
+ {
170
+ "name": "size",
171
+ "description": "Type: `AvatarSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-avatar>`",
172
+ "values": [
173
+ {
174
+ "name": "small"
175
+ },
176
+ {
177
+ "name": "medium"
178
+ },
179
+ {
180
+ "name": "large"
181
+ }
182
+ ]
183
+ },
184
+ {
185
+ "name": "square",
186
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-avatar>`"
187
+ }
188
+ ]
189
+ },
190
+ {
191
+ "name": "tt-badge",
192
+ "description": "A small status label. Presentational only: it displays state, it never\nowns it.\n\nTHREE THINGS THAT WERE WRONG AND ARE WORTH KNOWING.\n\nline-height was 1.5. On a pill that is not a paragraph, an inherited\nbody line-height adds invisible space above and below the text, so the\nbadge came out taller than it looked and sat off-centre next to a name.\nA pill sets line-height: 1 and gets its height from padding, which is\nthe only way the height is predictable.\n\nneutral was --tt-muted-foreground mixed 14% into transparent, which is\na grey wash of a grey. Neutral is the most common variant and it looked\nlike a rendering mistake. It now uses the real muted surface.\n\nwhite-space: nowrap with no escape meant a long label pushed its way\nout of whatever contained it. It still refuses to wrap, because a badge\nthat wraps stops being a badge, but it now truncates instead of\noverflowing.",
193
+ "attributes": [
194
+ {
195
+ "name": "variant",
196
+ "description": "Type: `BadgeVariant`\n\nDefault: `\"neutral\"`\n\nOn `<tt-badge>`",
197
+ "values": [
198
+ {
199
+ "name": "neutral"
200
+ },
201
+ {
202
+ "name": "success"
203
+ },
204
+ {
205
+ "name": "warning"
206
+ },
207
+ {
208
+ "name": "danger"
209
+ }
210
+ ]
211
+ },
212
+ {
213
+ "name": "size",
214
+ "description": "Type: `BadgeSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-badge>`",
215
+ "values": [
216
+ {
217
+ "name": "small"
218
+ },
219
+ {
220
+ "name": "medium"
221
+ }
222
+ ]
223
+ }
224
+ ]
225
+ },
226
+ {
227
+ "name": "tt-bento",
228
+ "description": "The grid net. Tiles span whole cells of it, so a composition reads as a\ndeliberate arrangement rather than a row of equal boxes:\n\n <tt-bento>\n <tt-stat bento-span=\"6\" bento-rows=\"4\"></tt-stat>\n <tt-bento-item bento-span=\"2\" bento-rows=\"2\">module</tt-bento-item>\n </tt-bento>\n\nIt measures ITSELF, not the viewport, so a bento in a sidebar and a bento\non a full page get the right column count with neither knowing where it\nis. Cells are square, so a span and a row count describe a shape.",
229
+ "attributes": [
230
+ {
231
+ "name": "columns",
232
+ "description": "Type: `12 | 24`\n\nDefault: `12`\n\nOn `<tt-bento>`"
233
+ }
234
+ ]
235
+ },
236
+ {
237
+ "name": "tt-bento-item",
238
+ "description": "A tile surface for a `tt-bento`.\n\nIt owns no placement. `bento-span` and `bento-rows` are read by the grid\noff any direct child, so this component exists purely to give bare\ncontent a surface: background, border, the 2xl corner, padding, and the\nconcentric radius its own children read.\n\nAnything that already brings its own surface - a tt-card, a tt-stat, a\ntt-chart - goes straight into the grid and needs none of this:\n\n <tt-bento>\n <tt-stat bento-span=\"2\"></tt-stat>\n <tt-bento-item bento-span=\"2\">bare content</tt-bento-item>\n </tt-bento>",
239
+ "attributes": [
240
+ {
241
+ "name": "plain",
242
+ "description": "Drop the tile surface and render as a bare grid cell.\n\nType: `boolean`\n\nDefault: `false`\n\nOn `<tt-bento-item>`"
243
+ },
244
+ {
245
+ "name": "clickable",
246
+ "description": "The whole tile leads somewhere. Adds hover, focus and keyboard\nactivation. Named clickable, as on tt-card and tt-sidebar-footer.\n\nType: `boolean`\n\nDefault: `false`\n\nOn `<tt-bento-item>`"
247
+ }
248
+ ]
249
+ },
250
+ {
251
+ "name": "tt-breadcrumbs",
252
+ "description": "Trail showing where the current page sits. Emits a navigation event\nrather than following links itself, so it works with a client router,\na server one, or neither.\n\n**Events:** tt-navigate",
253
+ "attributes": [
254
+ {
255
+ "name": "items",
256
+ "description": "Type: `Crumb[]`\n\nDefault: `[]`\n\nOn `<tt-breadcrumbs>`"
257
+ }
258
+ ]
259
+ },
260
+ {
261
+ "name": "tt-button",
262
+ "description": "**Events:** tt-button-click",
263
+ "attributes": [
264
+ {
265
+ "name": "variant",
266
+ "description": "Type: `ButtonVariant`\n\nDefault: `\"primary\"`\n\nOn `<tt-button>`",
267
+ "values": [
268
+ {
269
+ "name": "primary"
270
+ },
271
+ {
272
+ "name": "secondary"
273
+ },
274
+ {
275
+ "name": "danger"
276
+ },
277
+ {
278
+ "name": "ghost"
279
+ }
280
+ ]
281
+ },
282
+ {
283
+ "name": "size",
284
+ "description": "Type: `ButtonSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-button>`",
285
+ "values": [
286
+ {
287
+ "name": "small"
288
+ },
289
+ {
290
+ "name": "medium"
291
+ },
292
+ {
293
+ "name": "large"
294
+ }
295
+ ]
296
+ },
297
+ {
298
+ "name": "disabled",
299
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-button>`"
300
+ },
301
+ {
302
+ "name": "loading",
303
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-button>`"
304
+ },
305
+ {
306
+ "name": "full-width",
307
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-button>`"
308
+ },
309
+ {
310
+ "name": "pill",
311
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-button>`"
312
+ },
313
+ {
314
+ "name": "type",
315
+ "description": "Type: `ButtonType`\n\nDefault: `\"button\"`\n\nOn `<tt-button>`",
316
+ "values": [
317
+ {
318
+ "name": "button"
319
+ },
320
+ {
321
+ "name": "submit"
322
+ },
323
+ {
324
+ "name": "reset"
325
+ }
326
+ ]
327
+ },
328
+ {
329
+ "name": "label",
330
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-button>`"
331
+ },
332
+ {
333
+ "name": "current",
334
+ "description": "Type: `ButtonCurrent | \"\"`\n\nDefault: `\"\"`\n\nOn `<tt-button>`"
335
+ },
336
+ {
337
+ "name": "expanded",
338
+ "description": "Type: `\"true\" | \"false\" | \"\"`\n\nDefault: `\"\"`\n\nOn `<tt-button>`",
339
+ "values": [
340
+ {
341
+ "name": "true"
342
+ },
343
+ {
344
+ "name": "false"
345
+ },
346
+ {
347
+ "name": ""
348
+ }
349
+ ]
350
+ }
351
+ ]
352
+ },
353
+ {
354
+ "name": "tt-button-group",
355
+ "description": "Attaches controls into one unit: the corners where they meet flatten,\nand their borders collapse onto a single shared edge.\n\nUse it when the buttons are alternatives to each other, or steps in one\ndecision. Do NOT use it as a way to save space between unrelated\nactions: joining \"Reload\" to \"Checkout\" tells the reader they belong\ntogether, and they do not. A plain flex row with a gap is right for\nthose, which is what tt-toolbar already does.\n\nHOW IT REACHES INSIDE ITS CHILDREN. Each control's radius lives on an\nelement in its own shadow root, and ::slotted() only ever matches the\nhost, never anything within it. So a group cannot restyle a button's\ncorners directly. What it can do is set a CUSTOM PROPERTY on the host,\nbecause custom properties inherit through the shadow boundary, and each\ngroupable control reads `--tt-group-radius` for its own radius. The\ngroup sets that per position, and the child applies it.\n\nWorks with tt-button, tt-dropdown-menu, tt-select and tt-input.",
356
+ "attributes": [
357
+ {
358
+ "name": "orientation",
359
+ "description": "Type: `\"horizontal\" | \"vertical\"`\n\nDefault: `\"horizontal\"`\n\nOn `<tt-button-group>`",
360
+ "values": [
361
+ {
362
+ "name": "horizontal"
363
+ },
364
+ {
365
+ "name": "vertical"
366
+ }
367
+ ]
368
+ }
369
+ ]
370
+ },
371
+ {
372
+ "name": "tt-card",
373
+ "description": "",
374
+ "attributes": [
375
+ {
376
+ "name": "variant",
377
+ "description": "Type: `CardVariant`\n\nDefault: `\"default\"`\n\nOn `<tt-card>`",
378
+ "values": [
379
+ {
380
+ "name": "default"
381
+ },
382
+ {
383
+ "name": "outlined"
384
+ },
385
+ {
386
+ "name": "elevated"
387
+ }
388
+ ]
389
+ },
390
+ {
391
+ "name": "padding",
392
+ "description": "Type: `CardPadding`\n\nDefault: `\"medium\"`\n\nOn `<tt-card>`",
393
+ "values": [
394
+ {
395
+ "name": "none"
396
+ },
397
+ {
398
+ "name": "small"
399
+ },
400
+ {
401
+ "name": "medium"
402
+ },
403
+ {
404
+ "name": "large"
405
+ }
406
+ ]
407
+ },
408
+ {
409
+ "name": "radius",
410
+ "description": "Type: `CardRadius`\n\nDefault: `\"medium\"`\n\nOn `<tt-card>`",
411
+ "values": [
412
+ {
413
+ "name": "none"
414
+ },
415
+ {
416
+ "name": "small"
417
+ },
418
+ {
419
+ "name": "medium"
420
+ },
421
+ {
422
+ "name": "large"
423
+ },
424
+ {
425
+ "name": "xlarge"
426
+ }
427
+ ]
428
+ },
429
+ {
430
+ "name": "clickable",
431
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-card>`"
432
+ },
433
+ {
434
+ "name": "inline",
435
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-card>`"
436
+ },
437
+ {
438
+ "name": "heading",
439
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-card>`"
440
+ },
441
+ {
442
+ "name": "description",
443
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-card>`"
444
+ },
445
+ {
446
+ "name": "heading-level",
447
+ "description": "Type: `number`\n\nDefault: `3`\n\nOn `<tt-card>`"
448
+ }
449
+ ]
450
+ },
451
+ {
452
+ "name": "tt-chart",
453
+ "description": "",
454
+ "attributes": [
455
+ {
456
+ "name": "type",
457
+ "description": "Type: `ChartType`\n\nDefault: `\"bar\"`\n\nOn `<tt-chart>`"
458
+ },
459
+ {
460
+ "name": "labels",
461
+ "description": "Type: `string[]`\n\nDefault: `[]`\n\nOn `<tt-chart>`"
462
+ },
463
+ {
464
+ "name": "series",
465
+ "description": "Type: `ChartSeries[]`\n\nDefault: `[]`\n\nOn `<tt-chart>`"
466
+ },
467
+ {
468
+ "name": "legend",
469
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-chart>`"
470
+ },
471
+ {
472
+ "name": "stacked",
473
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-chart>`"
474
+ },
475
+ {
476
+ "name": "label",
477
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-chart>`"
478
+ }
479
+ ]
480
+ },
481
+ {
482
+ "name": "tt-checkbox",
483
+ "description": "**Events:** tt-change",
484
+ "attributes": [
485
+ {
486
+ "name": "name",
487
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-checkbox>`"
488
+ },
489
+ {
490
+ "name": "value",
491
+ "description": "Type: `string`\n\nDefault: `\"on\"`\n\nOn `<tt-checkbox>`"
492
+ },
493
+ {
494
+ "name": "checked",
495
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-checkbox>`"
496
+ },
497
+ {
498
+ "name": "indeterminate",
499
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-checkbox>`"
500
+ },
501
+ {
502
+ "name": "disabled",
503
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-checkbox>`"
504
+ },
505
+ {
506
+ "name": "required",
507
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-checkbox>`"
508
+ },
509
+ {
510
+ "name": "label",
511
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-checkbox>`"
512
+ },
513
+ {
514
+ "name": "label-hidden",
515
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-checkbox>`"
516
+ },
517
+ {
518
+ "name": "error",
519
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-checkbox>`"
520
+ }
521
+ ]
522
+ },
523
+ {
524
+ "name": "tt-checkbox-group",
525
+ "description": "**Events:** tt-change",
526
+ "attributes": [
527
+ {
528
+ "name": "name",
529
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-checkbox-group>`"
530
+ },
531
+ {
532
+ "name": "label",
533
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-checkbox-group>`"
534
+ },
535
+ {
536
+ "name": "label-hidden",
537
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-checkbox-group>`"
538
+ },
539
+ {
540
+ "name": "options",
541
+ "description": "Type: `CheckboxGroupOption[]`\n\nDefault: `[]`\n\nOn `<tt-checkbox-group>`"
542
+ },
543
+ {
544
+ "name": "values",
545
+ "description": "Type: `string[]`\n\nDefault: `[]`\n\nOn `<tt-checkbox-group>`"
546
+ },
547
+ {
548
+ "name": "disabled",
549
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-checkbox-group>`"
550
+ },
551
+ {
552
+ "name": "error",
553
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-checkbox-group>`"
554
+ },
555
+ {
556
+ "name": "orientation",
557
+ "description": "Type: `\"horizontal\" | \"vertical\"`\n\nDefault: `\"vertical\"`\n\nOn `<tt-checkbox-group>`",
558
+ "values": [
559
+ {
560
+ "name": "horizontal"
561
+ },
562
+ {
563
+ "name": "vertical"
564
+ }
565
+ ]
566
+ }
567
+ ]
568
+ },
569
+ {
570
+ "name": "tt-code-block",
571
+ "description": "",
572
+ "attributes": [
573
+ {
574
+ "name": "code",
575
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-code-block>`"
576
+ },
577
+ {
578
+ "name": "language",
579
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-code-block>`"
580
+ },
581
+ {
582
+ "name": "filename",
583
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-code-block>`"
584
+ },
585
+ {
586
+ "name": "show-line-numbers",
587
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-code-block>`"
588
+ },
589
+ {
590
+ "name": "tabs",
591
+ "description": "Type: `CodeTab[]`\n\nDefault: `[]`\n\nOn `<tt-code-block>`"
592
+ }
593
+ ]
594
+ },
595
+ {
596
+ "name": "tt-collapsible",
597
+ "description": "One section that opens and closes. The plainest member of a family of\nthree, and the differences matter:\n\n tt-collapsible ONE section, no heading of its own, no styling.\n You supply the trigger. Use it to hide detail\n inside something else: \"show 3 more\", an advanced\n block in a form, a nested panel.\n tt-accordion-item a section WITH a styled heading button, meant to\n sit in a tt-accordion that coordinates siblings.\n tt-menu-group the sidebar's version, with its own uppercase\n heading and rail behaviour.\n\nReach for this one when you already have something to click and only\nneed the opening part.\n\n---------------------------------------------------------------------\nIT OWNS ITS OWN `open`, and that is deliberate.\n\nThe house rule is that a component reports intent and the owner\ndecides, which is why tt-accordion-item refuses to open itself: an\naccordion may need to close a sibling first, so the decision is not\nthe item's to make.\n\nNothing coordinates a collapsible. There is no sibling to close and no\nparent to ask, so a component that would not open itself would need a\nlistener on every single use to do the one thing it is for. It flips\nand then announces, the same shape as tt-switch and tt-menu-group.\n\nSet `open` from outside whenever you do want to own it; the property\nis the source of truth either way.\n\n---------------------------------------------------------------------\nTHE HEIGHT ANIMATION.\n\nA grid track from 0fr to 1fr, because nothing here knows how tall the\ncontent is and every max-height guess is either too small, which\nclips, or too large, which makes the close look slow and the open look\nlate.\n\nThe `overflow: hidden` on the inner element is NOT decoration. An fr\ntrack keeps an automatic minimum equal to its content unless the item\ninside opts out of it, so without that line the panel never collapses\nat all. That exact bug shipped in tt-menu-group and hid behind an\nopacity fade for a week.\n\nThe events, for the custom-elements manifest. Its analyzer reads event\nnames from string literals at the dispatch site, and these are chosen at\nrun time, so without the tags the manifest listed a bogus event instead.\n\n**Events:** tt-toggle, tt-open, tt-close",
598
+ "attributes": [
599
+ {
600
+ "name": "open",
601
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-collapsible>`"
602
+ },
603
+ {
604
+ "name": "disabled",
605
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-collapsible>`"
606
+ }
607
+ ]
608
+ },
609
+ {
610
+ "name": "tt-combobox",
611
+ "description": "A select you can type into.\n\nWHERE IT SITS. tt-select is right up to roughly twenty options: you open\nit, you look, you pick. Past that, looking stops working and you need to\nnarrow the list by typing. That is the only difference in intent, but it\nchanges the control's shape: the trigger becomes a text input rather\nthan a button, which brings a filtering state, a no-results state, and\nthe problem below. Keeping tt-select simple was worth a second component.\n\nTHE AWKWARD BIT, which every combobox has to answer. One input has two\njobs: it displays the current selection, and it holds what you are\ntyping. Those conflict the moment you type, because the selection is\nstill set but the text no longer shows it.\n\nThis resolves it by treating the two as different modes rather than one\nvalue. Closed, the input shows the selected option's label. Open, it\nshows the query, which starts empty so the whole list is visible. Close\nwithout choosing and the query is discarded, so the field can never be\nleft displaying text that is not the actual value. The selection only\never changes by choosing an option.\n\n**Events:** tt-change",
612
+ "attributes": [
613
+ {
614
+ "name": "name",
615
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-combobox>`"
616
+ },
617
+ {
618
+ "name": "value",
619
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-combobox>`"
620
+ },
621
+ {
622
+ "name": "options",
623
+ "description": "Type: `SelectOption[]`\n\nDefault: `[]`\n\nOn `<tt-combobox>`"
624
+ },
625
+ {
626
+ "name": "label",
627
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-combobox>`"
628
+ },
629
+ {
630
+ "name": "placeholder",
631
+ "description": "Type: `string`\n\nDefault: `\"Search or select\"`\n\nOn `<tt-combobox>`"
632
+ },
633
+ {
634
+ "name": "empty-text",
635
+ "description": "Type: `string`\n\nDefault: `\"No matches\"`\n\nOn `<tt-combobox>`"
636
+ },
637
+ {
638
+ "name": "error",
639
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-combobox>`"
640
+ },
641
+ {
642
+ "name": "disabled",
643
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-combobox>`"
644
+ },
645
+ {
646
+ "name": "required",
647
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-combobox>`"
648
+ },
649
+ {
650
+ "name": "size",
651
+ "description": "Type: `\"small\" | \"medium\" | \"large\"`\n\nDefault: `\"medium\"`\n\nOn `<tt-combobox>`",
652
+ "values": [
653
+ {
654
+ "name": "small"
655
+ },
656
+ {
657
+ "name": "medium"
658
+ },
659
+ {
660
+ "name": "large"
661
+ }
662
+ ]
663
+ },
664
+ {
665
+ "name": "label-hidden",
666
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-combobox>`"
667
+ },
668
+ {
669
+ "name": "clearable",
670
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-combobox>`"
671
+ }
672
+ ]
673
+ },
674
+ {
675
+ "name": "tt-company-card",
676
+ "description": "**Events:** tt-company-select, tt-company-action",
677
+ "attributes": [
678
+ {
679
+ "name": "value",
680
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-company-card>`"
681
+ },
682
+ {
683
+ "name": "name",
684
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-company-card>`"
685
+ },
686
+ {
687
+ "name": "logo",
688
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-company-card>`"
689
+ },
690
+ {
691
+ "name": "verified",
692
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-company-card>`"
693
+ },
694
+ {
695
+ "name": "city",
696
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-company-card>`"
697
+ },
698
+ {
699
+ "name": "country",
700
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-company-card>`"
701
+ },
702
+ {
703
+ "name": "description",
704
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-company-card>`"
705
+ },
706
+ {
707
+ "name": "industry",
708
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-company-card>`"
709
+ },
710
+ {
711
+ "name": "tags",
712
+ "description": "Type: `string[]`\n\nDefault: `[]`\n\nOn `<tt-company-card>`"
713
+ },
714
+ {
715
+ "name": "description-lines",
716
+ "description": "Type: `number`\n\nDefault: `2`\n\nOn `<tt-company-card>`"
717
+ },
718
+ {
719
+ "name": "actions",
720
+ "description": "Type: `MenuAction[]`\n\nDefault: `[]`\n\nOn `<tt-company-card>`"
721
+ }
722
+ ]
723
+ },
724
+ {
725
+ "name": "tt-comparison-table",
726
+ "description": "Puts several things side by side against the same set of attributes.\n\nMost directories make you open two tabs and look back and forth. This\nis the component that removes that, which the notes call out as a\ngenuine differentiator, and it generalises well beyond suppliers:\npricing tiers, product specs, plan features.\n\nTWO THINGS MAKE IT ACTUALLY USEFUL rather than just a table turned on\nits side.\n\nFirst, the ROW LABELS ARE THE FIRST COLUMN and they stick while you\nscroll sideways. Comparing is a horizontal act, and a comparison where\nyou lose track of which attribute you are reading is worse than two\ntabs.\n\nSecond, `differencesOnly` hides every row where all items agree. On a\nprofile with thirty attributes, the four that differ are the entire\nquestion, and they are invisible among the twenty-six that do not.\n\nBooleans render as a tick or a dash rather than the words true and\nfalse, because a column of ticks is scannable and a column of \"true\" is\nnot.\n\n**Events:** tt-remove",
727
+ "attributes": [
728
+ {
729
+ "name": "rows",
730
+ "description": "Type: `CompareRow[]`\n\nDefault: `[]`\n\nOn `<tt-comparison-table>`"
731
+ },
732
+ {
733
+ "name": "items",
734
+ "description": "Type: `CompareItem[]`\n\nDefault: `[]`\n\nOn `<tt-comparison-table>`"
735
+ },
736
+ {
737
+ "name": "differences-only",
738
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-comparison-table>`"
739
+ },
740
+ {
741
+ "name": "removable",
742
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-comparison-table>`"
743
+ },
744
+ {
745
+ "name": "empty-text",
746
+ "description": "Type: `string`\n\nDefault: `\"Nothing to compare yet\"`\n\nOn `<tt-comparison-table>`"
747
+ }
748
+ ]
749
+ },
750
+ {
751
+ "name": "tt-component-doc",
752
+ "description": "**Events:** tt-doc-link",
753
+ "attributes": [
754
+ {
755
+ "name": "heading",
756
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-component-doc>`"
757
+ },
758
+ {
759
+ "name": "description",
760
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-component-doc>`"
761
+ },
762
+ {
763
+ "name": "code",
764
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-component-doc>`"
765
+ },
766
+ {
767
+ "name": "props",
768
+ "description": "Type: `TableRow[]`\n\nDefault: `[]`\n\nOn `<tt-component-doc>`"
769
+ },
770
+ {
771
+ "name": "events",
772
+ "description": "Type: `TableRow[]`\n\nDefault: `[]`\n\nOn `<tt-component-doc>`"
773
+ },
774
+ {
775
+ "name": "methods",
776
+ "description": "Type: `TableRow[]`\n\nDefault: `[]`\n\nOn `<tt-component-doc>`"
777
+ },
778
+ {
779
+ "name": "slots",
780
+ "description": "Type: `TableRow[]`\n\nDefault: `[]`\n\nOn `<tt-component-doc>`"
781
+ },
782
+ {
783
+ "name": "parts",
784
+ "description": "Type: `TableRow[]`\n\nDefault: `[]`\n\nOn `<tt-component-doc>`"
785
+ },
786
+ {
787
+ "name": "css-properties",
788
+ "description": "Type: `TableRow[]`\n\nDefault: `[]`\n\nOn `<tt-component-doc>`"
789
+ },
790
+ {
791
+ "name": "import-path",
792
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-component-doc>`"
793
+ },
794
+ {
795
+ "name": "anatomy",
796
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-component-doc>`"
797
+ },
798
+ {
799
+ "name": "examples",
800
+ "description": "Type: `DocExample[]`\n\nDefault: `[]`\n\nOn `<tt-component-doc>`"
801
+ },
802
+ {
803
+ "name": "guidelines",
804
+ "description": "Type: `DocGuidelines | null`\n\nDefault: `null`\n\nOn `<tt-component-doc>`"
805
+ },
806
+ {
807
+ "name": "accessibility",
808
+ "description": "Type: `DocAccessibility | null`\n\nDefault: `null`\n\nOn `<tt-component-doc>`"
809
+ },
810
+ {
811
+ "name": "related",
812
+ "description": "Type: `DocRelated[]`\n\nDefault: `[]`\n\nOn `<tt-component-doc>`"
813
+ }
814
+ ]
815
+ },
816
+ {
817
+ "name": "tt-confirm",
818
+ "description": "Confirmation dialog with a promise-based API. Mount one near the app\nroot, then anywhere else:\n\n if (await confirm({ heading: \"Delete request?\", danger: true })) {\n ...\n }\n\nThe promise is the point. The alternative is a dialog component plus\nopen state plus two event handlers plus a variable remembering what you\nwere about to do, spread across every caller. Here the decision reads\nas one line, in the order it happens.",
819
+ "attributes": []
820
+ },
821
+ {
822
+ "name": "tt-contact-list",
823
+ "description": "",
824
+ "attributes": [
825
+ {
826
+ "name": "contacts",
827
+ "description": "Type: `Contact[]`\n\nDefault: `[]`\n\nOn `<tt-contact-list>`"
828
+ }
829
+ ]
830
+ },
831
+ {
832
+ "name": "tt-copy-button",
833
+ "description": "Copies a string to the clipboard and confirms it in place.\n\nThe confirmation matters more than the copying: without it nobody knows\nwhether the click worked, and they click again.\n\n**Events:** tt-copy",
834
+ "attributes": [
835
+ {
836
+ "name": "value",
837
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-copy-button>`"
838
+ },
839
+ {
840
+ "name": "label",
841
+ "description": "Type: `string`\n\nDefault: `\"Copy\"`\n\nOn `<tt-copy-button>`"
842
+ },
843
+ {
844
+ "name": "copied-label",
845
+ "description": "Type: `string`\n\nDefault: `\"Copied\"`\n\nOn `<tt-copy-button>`"
846
+ },
847
+ {
848
+ "name": "icon-only",
849
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-copy-button>`"
850
+ }
851
+ ]
852
+ },
853
+ {
854
+ "name": "tt-data-table",
855
+ "description": "Working table: sorting, selection, row actions, sticky header, and\nloading and empty states.\n\nIt owns nothing. Sort state and selection come in as properties and\nchanges go out as events, so the page stays the single source of truth\nand can put either in a URL. Sorting itself is the page's job too: it\nknows whether the data is an in-memory array or a server query.\n\n**Events:** tt-selection-change, tt-sort, tt-row-click, tt-row-action",
856
+ "attributes": [
857
+ {
858
+ "name": "columns",
859
+ "description": "Type: `DataColumn[]`\n\nDefault: `[]`\n\nOn `<tt-data-table>`"
860
+ },
861
+ {
862
+ "name": "rows",
863
+ "description": "Type: `DataRow[]`\n\nDefault: `[]`\n\nOn `<tt-data-table>`"
864
+ },
865
+ {
866
+ "name": "label",
867
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-data-table>`"
868
+ },
869
+ {
870
+ "name": "sort",
871
+ "description": "Type: `SortState | undefined`\n\nOn `<tt-data-table>`"
872
+ },
873
+ {
874
+ "name": "selectable",
875
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-data-table>`"
876
+ },
877
+ {
878
+ "name": "selected",
879
+ "description": "Type: `string[]`\n\nDefault: `[]`\n\nOn `<tt-data-table>`"
880
+ },
881
+ {
882
+ "name": "row-actions",
883
+ "description": "Type: `MenuAction[]`\n\nDefault: `[]`\n\nOn `<tt-data-table>`"
884
+ },
885
+ {
886
+ "name": "loading",
887
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-data-table>`"
888
+ },
889
+ {
890
+ "name": "loading-rows",
891
+ "description": "Type: `number`\n\nDefault: `5`\n\nOn `<tt-data-table>`"
892
+ },
893
+ {
894
+ "name": "empty-heading",
895
+ "description": "Type: `string`\n\nDefault: `\"Nothing here yet\"`\n\nOn `<tt-data-table>`"
896
+ },
897
+ {
898
+ "name": "empty-description",
899
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-data-table>`"
900
+ },
901
+ {
902
+ "name": "clickable-rows",
903
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-data-table>`"
904
+ }
905
+ ]
906
+ },
907
+ {
908
+ "name": "tt-divider",
909
+ "description": "A separating line, optionally with a label in the middle.\n\nTrivial, and worth having: without it every page writes its own\nborder-top with slightly different spacing, and the product drifts.",
910
+ "attributes": [
911
+ {
912
+ "name": "label",
913
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-divider>`"
914
+ },
915
+ {
916
+ "name": "vertical",
917
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-divider>`"
918
+ }
919
+ ]
920
+ },
921
+ {
922
+ "name": "tt-drawer",
923
+ "description": "A panel that slides in over the page.\n\nUse it instead of a modal when the thing behind still matters: editing\na row without losing your place in the list, or a filter panel you\nadjust while watching results change. A modal says \"deal with this\nfirst\"; a drawer says \"here is more, the list is still there\".\n\n**Events:** tt-close",
924
+ "attributes": [
925
+ {
926
+ "name": "open",
927
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-drawer>`"
928
+ },
929
+ {
930
+ "name": "side",
931
+ "description": "Type: `DrawerSide`\n\nDefault: `\"right\"`\n\nOn `<tt-drawer>`",
932
+ "values": [
933
+ {
934
+ "name": "right"
935
+ },
936
+ {
937
+ "name": "left"
938
+ },
939
+ {
940
+ "name": "bottom"
941
+ }
942
+ ]
943
+ },
944
+ {
945
+ "name": "heading",
946
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-drawer>`"
947
+ },
948
+ {
949
+ "name": "size",
950
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-drawer>`"
951
+ },
952
+ {
953
+ "name": "persistent",
954
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-drawer>`"
955
+ }
956
+ ]
957
+ },
958
+ {
959
+ "name": "tt-dropdown-menu",
960
+ "description": "Actions attached to a thing: the row menu behind a table's dots button,\nor a settings menu in a header.\n\nDistinct from tt-select. A select edits a value and shows what is\ncurrently chosen; a menu performs an action and remembers nothing.\n\n**Events:** tt-menu-select",
961
+ "attributes": [
962
+ {
963
+ "name": "items",
964
+ "description": "Type: `MenuAction[]`\n\nDefault: `[]`\n\nOn `<tt-dropdown-menu>`"
965
+ },
966
+ {
967
+ "name": "label",
968
+ "description": "Type: `string`\n\nDefault: `\"Actions\"`\n\nOn `<tt-dropdown-menu>`"
969
+ },
970
+ {
971
+ "name": "align",
972
+ "description": "Type: `\"start\" | \"end\"`\n\nDefault: `\"end\"`\n\nOn `<tt-dropdown-menu>`",
973
+ "values": [
974
+ {
975
+ "name": "start"
976
+ },
977
+ {
978
+ "name": "end"
979
+ }
980
+ ]
981
+ },
982
+ {
983
+ "name": "disabled",
984
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-dropdown-menu>`"
985
+ },
986
+ {
987
+ "name": "size",
988
+ "description": "Type: `\"small\" | \"medium\" | \"large\"`\n\nDefault: `\"small\"`\n\nOn `<tt-dropdown-menu>`",
989
+ "values": [
990
+ {
991
+ "name": "small"
992
+ },
993
+ {
994
+ "name": "medium"
995
+ },
996
+ {
997
+ "name": "large"
998
+ }
999
+ ]
1000
+ }
1001
+ ]
1002
+ },
1003
+ {
1004
+ "name": "tt-empty-state",
1005
+ "description": "",
1006
+ "attributes": [
1007
+ {
1008
+ "name": "heading",
1009
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-empty-state>`"
1010
+ },
1011
+ {
1012
+ "name": "description",
1013
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-empty-state>`"
1014
+ }
1015
+ ]
1016
+ },
1017
+ {
1018
+ "name": "tt-example",
1019
+ "description": "One worked example: a live rendering and the markup that produced it,\nbehind a Preview / Code switch.\n\n <tt-example heading=\"Multiple open\" code=${snippet}>\n <tt-accordion multiple>...</tt-accordion>\n </tt-example>\n\nThe point is that the two halves cannot drift apart on the page the way a\nseparate preview box and a separate code block do. Both panels stay in the\nDOM and are toggled with `hidden`, so switching does not tear down and\nrebuild a live component you were in the middle of poking at.",
1020
+ "attributes": [
1021
+ {
1022
+ "name": "heading",
1023
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-example>`"
1024
+ },
1025
+ {
1026
+ "name": "description",
1027
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-example>`"
1028
+ },
1029
+ {
1030
+ "name": "code",
1031
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-example>`"
1032
+ },
1033
+ {
1034
+ "name": "language",
1035
+ "description": "Type: `string`\n\nDefault: `\"html\"`\n\nOn `<tt-example>`"
1036
+ },
1037
+ {
1038
+ "name": "align",
1039
+ "description": "Type: `\"center\" | \"start\" | \"stretch\"`\n\nDefault: `\"center\"`\n\nOn `<tt-example>`",
1040
+ "values": [
1041
+ {
1042
+ "name": "center"
1043
+ },
1044
+ {
1045
+ "name": "start"
1046
+ },
1047
+ {
1048
+ "name": "stretch"
1049
+ }
1050
+ ]
1051
+ }
1052
+ ]
1053
+ },
1054
+ {
1055
+ "name": "tt-file-upload",
1056
+ "description": "Chooses files, by tapping a button or dropping them on the box. Checks\ntype, size and count before keeping a file, previews images, and\nsubmits the files with its form under `name`.\n\n**Events:** tt-change, tt-reject",
1057
+ "attributes": [
1058
+ {
1059
+ "name": "name",
1060
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-file-upload>`"
1061
+ },
1062
+ {
1063
+ "name": "label",
1064
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-file-upload>`"
1065
+ },
1066
+ {
1067
+ "name": "label-hidden",
1068
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-file-upload>`"
1069
+ },
1070
+ {
1071
+ "name": "description",
1072
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-file-upload>`"
1073
+ },
1074
+ {
1075
+ "name": "accept",
1076
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-file-upload>`"
1077
+ },
1078
+ {
1079
+ "name": "multiple",
1080
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-file-upload>`"
1081
+ },
1082
+ {
1083
+ "name": "max-size",
1084
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-file-upload>`"
1085
+ },
1086
+ {
1087
+ "name": "max-files",
1088
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-file-upload>`"
1089
+ },
1090
+ {
1091
+ "name": "required",
1092
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-file-upload>`"
1093
+ },
1094
+ {
1095
+ "name": "disabled",
1096
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-file-upload>`"
1097
+ },
1098
+ {
1099
+ "name": "error",
1100
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-file-upload>`"
1101
+ }
1102
+ ]
1103
+ },
1104
+ {
1105
+ "name": "tt-filter",
1106
+ "description": "One facet of a filter set: a pill that says what it filters, how many\nare picked, and opens a list of checkboxes.\n\nWHY THIS IS NOT A VARIANT OF SOMETHING ELSE. The library already has\ntwo things that open a list, and this is neither of them:\n\n tt-dropdown-menu performs an action and REMEMBERS NOTHING. It closes\n on choose because the choice is the whole event.\n tt-select edits ONE value and displays the chosen one.\n tt-filter holds a SET, stays open while you build it, and\n reports the whole set.\n\nBending either of the first two into this would have cost them the\nproperty that makes them easy to reason about.\n\nIt composes tt-checkbox-group rather than reimplementing checkboxes, and\nkeeps that component's contract: values come in, tt-change goes out\ncarrying the COMPLETE new array, and this component owns nothing.\n\nLaid out as a pill with a count because a filter has to be readable when\nit is closed. A row of loose checkboxes says what the options are; a\npill says what is actually filtering, which is the thing you need to\nknow when you are looking at a result set and wondering why.\n\n**Events:** tt-change",
1107
+ "attributes": [
1108
+ {
1109
+ "name": "label",
1110
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-filter>`"
1111
+ },
1112
+ {
1113
+ "name": "options",
1114
+ "description": "Type: `CheckboxGroupOption[]`\n\nDefault: `[]`\n\nOn `<tt-filter>`"
1115
+ },
1116
+ {
1117
+ "name": "values",
1118
+ "description": "Type: `string[]`\n\nDefault: `[]`\n\nOn `<tt-filter>`"
1119
+ },
1120
+ {
1121
+ "name": "disabled",
1122
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-filter>`"
1123
+ },
1124
+ {
1125
+ "name": "align",
1126
+ "description": "Type: `\"start\" | \"end\"`\n\nDefault: `\"start\"`\n\nOn `<tt-filter>`",
1127
+ "values": [
1128
+ {
1129
+ "name": "start"
1130
+ },
1131
+ {
1132
+ "name": "end"
1133
+ }
1134
+ ]
1135
+ }
1136
+ ]
1137
+ },
1138
+ {
1139
+ "name": "tt-form",
1140
+ "description": "**Events:** tt-form-submit, tt-form-reset",
1141
+ "attributes": [
1142
+ {
1143
+ "name": "name",
1144
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-form>`"
1145
+ },
1146
+ {
1147
+ "name": "layout",
1148
+ "description": "Type: `FormLayout`\n\nDefault: `\"vertical\"`\n\nOn `<tt-form>`",
1149
+ "values": [
1150
+ {
1151
+ "name": "vertical"
1152
+ },
1153
+ {
1154
+ "name": "horizontal"
1155
+ }
1156
+ ]
1157
+ },
1158
+ {
1159
+ "name": "disabled",
1160
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-form>`"
1161
+ },
1162
+ {
1163
+ "name": "loading",
1164
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-form>`"
1165
+ },
1166
+ {
1167
+ "name": "novalidate",
1168
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-form>`"
1169
+ }
1170
+ ]
1171
+ },
1172
+ {
1173
+ "name": "tt-grid",
1174
+ "description": "Responsive grid. By default it auto-fills as many columns as will fit\nat `minWidth`, so it reflows without media queries. Set `columns` for a\nfixed count instead.",
1175
+ "attributes": [
1176
+ {
1177
+ "name": "min-width",
1178
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-grid>`"
1179
+ },
1180
+ {
1181
+ "name": "gap",
1182
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-grid>`"
1183
+ },
1184
+ {
1185
+ "name": "columns",
1186
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-grid>`"
1187
+ }
1188
+ ]
1189
+ },
1190
+ {
1191
+ "name": "tt-icon",
1192
+ "description": "",
1193
+ "attributes": [
1194
+ {
1195
+ "name": "name",
1196
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-icon>`"
1197
+ },
1198
+ {
1199
+ "name": "size",
1200
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-icon>`"
1201
+ }
1202
+ ]
1203
+ },
1204
+ {
1205
+ "name": "tt-image",
1206
+ "description": "An image in a box the PARENT sizes.\n\nSix properties, and each one answers a question you actually have when\nyou place an image: how big is the box (ratio), what happens to a photo\nthat is not that shape (fit), what are the corners (radius), and is\nthis the one image worth loading early (priority).\n\nThere is deliberately no size scale. The host is a block that fills its\ncontainer, so a card wanting a 34px logo says 34px in its own CSS and\nwins, because rules from the tree that owns an element beat that\nelement's :host. A fixed scale here (icon, profile, small, medium,\nlarge) was five pixel values from one app baked into a library meant\nfor apps that do not exist yet, and three consumers ended up reaching\nthrough ::part just to undo it.\n\nThe other half of the job is that real images fail, arrive late, or\narrive already cached, so the load is treated as state: a skeleton\nwhile it downloads, a fallback if it never arrives.\n\n**Events:** tt-load, tt-error",
1207
+ "attributes": [
1208
+ {
1209
+ "name": "src",
1210
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-image>`"
1211
+ },
1212
+ {
1213
+ "name": "alt",
1214
+ "description": "Describe the picture, or pass \"\" when it is decorative.\n\nType: `string`\n\nDefault: `\"\"`\n\nOn `<tt-image>`"
1215
+ },
1216
+ {
1217
+ "name": "ratio",
1218
+ "description": "Any CSS aspect-ratio: \"16 / 9\", \"4 / 5\", \"1\". Empty means intrinsic.\n\nType: `string`\n\nDefault: `\"\"`\n\nOn `<tt-image>`"
1219
+ },
1220
+ {
1221
+ "name": "fit",
1222
+ "description": "Type: `ImageFit`\n\nDefault: `\"cover\"`\n\nOn `<tt-image>`",
1223
+ "values": [
1224
+ {
1225
+ "name": "cover"
1226
+ },
1227
+ {
1228
+ "name": "contain"
1229
+ }
1230
+ ]
1231
+ },
1232
+ {
1233
+ "name": "radius",
1234
+ "description": "Type: `ImageRadius`\n\nDefault: `\"medium\"`\n\nOn `<tt-image>`"
1235
+ },
1236
+ {
1237
+ "name": "priority",
1238
+ "description": "Above the fold. Loads eagerly and asks the browser to prioritise the\nfetch, which a hero image needs and a thumbnail never does.\n\nType: `boolean`\n\nDefault: `false`\n\nOn `<tt-image>`"
1239
+ }
1240
+ ]
1241
+ },
1242
+ {
1243
+ "name": "tt-inbox",
1244
+ "description": "The list side of a messaging surface: who wrote, about what, when, and\nwhether it has been read.\n\nPairs with tt-thread, which is the reading side. Split in two because\nthey live in different places on screen - side by side on a desktop,\ntwo separate routes on a phone - and a single component would have to\nown that layout decision on the app's behalf.\n\nIt owns nothing. `selected` comes in, `tt-conversation-select` goes out.\nThat matters more here than usual: which conversation is open is the\nkind of state that belongs in the URL, so a thread can be linked to.\n\nUNREAD IS THE ONLY THING IT EMPHASISES. An inbox is read by scanning\nfor what is new, so unread rows carry weight and a dot, and everything\nelse stays quiet. Styling the sender, the subject and the time all\nstrongly would leave nothing for the eye to catch.\n\n**Events:** tt-conversation-select",
1245
+ "attributes": [
1246
+ {
1247
+ "name": "conversations",
1248
+ "description": "Type: `Conversation[]`\n\nDefault: `[]`\n\nOn `<tt-inbox>`"
1249
+ },
1250
+ {
1251
+ "name": "selected",
1252
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-inbox>`"
1253
+ },
1254
+ {
1255
+ "name": "empty-heading",
1256
+ "description": "Type: `string`\n\nDefault: `\"No messages\"`\n\nOn `<tt-inbox>`"
1257
+ },
1258
+ {
1259
+ "name": "empty-description",
1260
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-inbox>`"
1261
+ }
1262
+ ]
1263
+ },
1264
+ {
1265
+ "name": "tt-input",
1266
+ "description": "**Events:** tt-input, tt-change",
1267
+ "attributes": [
1268
+ {
1269
+ "name": "label",
1270
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-input>`"
1271
+ },
1272
+ {
1273
+ "name": "placeholder",
1274
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-input>`"
1275
+ },
1276
+ {
1277
+ "name": "value",
1278
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-input>`"
1279
+ },
1280
+ {
1281
+ "name": "name",
1282
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-input>`"
1283
+ },
1284
+ {
1285
+ "name": "type",
1286
+ "description": "Type: `InputType`\n\nDefault: `\"text\"`\n\nOn `<tt-input>`"
1287
+ },
1288
+ {
1289
+ "name": "autocomplete",
1290
+ "description": "Type: `AutoCompleteToken | undefined`\n\nOn `<tt-input>`"
1291
+ },
1292
+ {
1293
+ "name": "size",
1294
+ "description": "Type: `InputSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-input>`",
1295
+ "values": [
1296
+ {
1297
+ "name": "small"
1298
+ },
1299
+ {
1300
+ "name": "medium"
1301
+ },
1302
+ {
1303
+ "name": "large"
1304
+ }
1305
+ ]
1306
+ },
1307
+ {
1308
+ "name": "disabled",
1309
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-input>`"
1310
+ },
1311
+ {
1312
+ "name": "required",
1313
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-input>`"
1314
+ },
1315
+ {
1316
+ "name": "full-width",
1317
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-input>`"
1318
+ },
1319
+ {
1320
+ "name": "error",
1321
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-input>`"
1322
+ },
1323
+ {
1324
+ "name": "label-hidden",
1325
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-input>`"
1326
+ }
1327
+ ]
1328
+ },
1329
+ {
1330
+ "name": "tt-kbd",
1331
+ "description": "A keyboard key, as printed in documentation and menus.\n\nRenders a real `<kbd>`, which is the element the HTML spec defines for\n\"user input from a keyboard\". A styled `<span>` looks identical and\ntells a screen reader nothing, so this is one of the rare cases where\npicking the right tag IS the accessibility work.\n\nPresentational only. It displays a key, it never listens for one.\n\n---------------------------------------------------------------------\nON `keys`.\n\nA combination is one idea, so it is one element:\n\n <tt-kbd keys=\"Ctrl+K\"></tt-kbd>\n\nsplits on \"+\" and renders a separator between the parts. Writing three\nelements and two literal plus signs in the markup instead would leave\nthe separator's spacing to whoever typed it, and it would be different\non every page by the end of the month.\n\nThe default slot is the escape hatch for anything that is not a\nplus-separated combination, an arrow glyph say.",
1332
+ "attributes": [
1333
+ {
1334
+ "name": "keys",
1335
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-kbd>`"
1336
+ },
1337
+ {
1338
+ "name": "size",
1339
+ "description": "Type: `KbdSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-kbd>`",
1340
+ "values": [
1341
+ {
1342
+ "name": "small"
1343
+ },
1344
+ {
1345
+ "name": "medium"
1346
+ }
1347
+ ]
1348
+ }
1349
+ ]
1350
+ },
1351
+ {
1352
+ "name": "tt-key-values",
1353
+ "description": "",
1354
+ "attributes": [
1355
+ {
1356
+ "name": "items",
1357
+ "description": "Type: `KeyValue[]`\n\nDefault: `[]`\n\nOn `<tt-key-values>`"
1358
+ }
1359
+ ]
1360
+ },
1361
+ {
1362
+ "name": "tt-knowledge-doc",
1363
+ "description": "",
1364
+ "attributes": [
1365
+ {
1366
+ "name": "heading",
1367
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-knowledge-doc>`"
1368
+ },
1369
+ {
1370
+ "name": "description",
1371
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-knowledge-doc>`"
1372
+ },
1373
+ {
1374
+ "name": "code",
1375
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-knowledge-doc>`"
1376
+ },
1377
+ {
1378
+ "name": "language",
1379
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-knowledge-doc>`"
1380
+ },
1381
+ {
1382
+ "name": "patterns",
1383
+ "description": "Type: `SwitcherItem[]`\n\nDefault: `[]`\n\nOn `<tt-knowledge-doc>`"
1384
+ },
1385
+ {
1386
+ "name": "examples",
1387
+ "description": "Type: `DocExample[]`\n\nDefault: `[]`\n\nOn `<tt-knowledge-doc>`"
1388
+ }
1389
+ ]
1390
+ },
1391
+ {
1392
+ "name": "tt-layout",
1393
+ "description": "",
1394
+ "attributes": []
1395
+ },
1396
+ {
1397
+ "name": "tt-menu-group",
1398
+ "description": "A labelled section of sidebar navigation, optionally collapsible.\n\n---------------------------------------------------------------------\nTWO MODES.\n\n (default) the heading is a plain label and the content\n is always there. This is the right shape when\n a group exists to name a set of links rather\n than to hide them.\n collapsible the heading is a button, the content opens\n and closes, and `open` is the state.\n\nOpt-in, like tt-sidebar's collapsible and every other boolean: a\nboolean attribute can only switch something ON.\n\nThe default is the old behaviour exactly, so nothing that already uses\nthis component changes.\n\n---------------------------------------------------------------------\nWHY THE HEADING ROW IS A ROW.\n\nSame reason as tt-menu-item: an actions slot next to a heading BUTTON\ncannot live inside that button, because a button inside a button is\ninvalid HTML. So the heading row holds two siblings.\n\n---------------------------------------------------------------------\nRAIL MODE.\n\nWhen tt-sidebar is collapsed it hides these headings and forces every\ngroup open. A closed group in a rail would be unreachable: its own\nheading is the only way to open it, and that heading is exactly what a\nrail has no room for. Both facts arrive as inherited custom properties,\nso this component still knows nothing about the sidebar.\n\nThe events, for the custom-elements manifest. Its analyzer reads event\nnames from string literals at the dispatch site, and these are chosen at\nrun time, so without the tags the manifest listed a bogus event instead.\n\n**Events:** tt-toggle, tt-open, tt-close",
1399
+ "attributes": [
1400
+ {
1401
+ "name": "heading",
1402
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-menu-group>`"
1403
+ },
1404
+ {
1405
+ "name": "open",
1406
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-menu-group>`"
1407
+ },
1408
+ {
1409
+ "name": "disabled",
1410
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-menu-group>`"
1411
+ },
1412
+ {
1413
+ "name": "collapsible",
1414
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-menu-group>`"
1415
+ }
1416
+ ]
1417
+ },
1418
+ {
1419
+ "name": "tt-menu-item",
1420
+ "description": "One row of sidebar navigation.\n\n---------------------------------------------------------------------\nWHY THE ROW IS NOT ONE ELEMENT.\n\nA menu item can carry a trailing control: a count, or the three dots\nthat open a per-item menu. A button inside a button is invalid HTML and\nbreaks keyboard and screen-reader behaviour in every browser, so the\ntwo cannot nest.\n\nSo the row is a plain container, and the two controls are SIBLINGS\ninside it:\n\n .row the hover surface, the corner, the active bar\n .main a real <button> or <a>, holds the padding, flex: 1\n .trail the badge and the actions, only when there are any\n\nThe padding lives on .main rather than on .row so that clicking the\nblank space beside the label still activates the item. If the row\ncarried the padding, that space would belong to nothing.\n\n---------------------------------------------------------------------\nWHY IT IS NO LONGER role=\"menuitem\".\n\nmenuitem is for application menus, and it is only valid inside a\nrole=\"menu\" parent. This is site navigation inside a landmark, so the\nhonest markup is a link or a button, which also brings Enter, Space,\nmiddle-click and \"open in new tab\" for free instead of reimplementing\nthem. The custom keydown handler this component used to carry is gone\nwith it.\n\n---------------------------------------------------------------------\nRAIL MODE.\n\nNothing here knows whether the sidebar is collapsed. tt-sidebar sets a\nhandful of custom properties when it is, and every one of them is read\nbelow through var() with the expanded value as the fallback. Custom\nproperties inherit and cross shadow boundaries, so this works at any\ndepth with no props and no coordination, and an item used outside a\nsidebar simply gets the fallbacks.\n\n**Events:** tt-menu-click, tt-menu-more",
1421
+ "attributes": [
1422
+ {
1423
+ "name": "variant",
1424
+ "description": "Type: `MenuItemVariant`\n\nDefault: `\"default\"`\n\nOn `<tt-menu-item>`",
1425
+ "values": [
1426
+ {
1427
+ "name": "default"
1428
+ },
1429
+ {
1430
+ "name": "link"
1431
+ }
1432
+ ]
1433
+ },
1434
+ {
1435
+ "name": "active",
1436
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-menu-item>`"
1437
+ },
1438
+ {
1439
+ "name": "disabled",
1440
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-menu-item>`"
1441
+ },
1442
+ {
1443
+ "name": "href",
1444
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-menu-item>`"
1445
+ },
1446
+ {
1447
+ "name": "target",
1448
+ "description": "Type: `string`\n\nDefault: `\"_blank\"`\n\nOn `<tt-menu-item>`"
1449
+ },
1450
+ {
1451
+ "name": "value",
1452
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-menu-item>`"
1453
+ },
1454
+ {
1455
+ "name": "label",
1456
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-menu-item>`"
1457
+ },
1458
+ {
1459
+ "name": "more",
1460
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-menu-item>`"
1461
+ },
1462
+ {
1463
+ "name": "more-label",
1464
+ "description": "Type: `string`\n\nDefault: `\"More actions\"`\n\nOn `<tt-menu-item>`"
1465
+ }
1466
+ ]
1467
+ },
1468
+ {
1469
+ "name": "tt-modal",
1470
+ "description": "**Events:** tt-close",
1471
+ "attributes": [
1472
+ {
1473
+ "name": "open",
1474
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-modal>`"
1475
+ },
1476
+ {
1477
+ "name": "heading",
1478
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-modal>`"
1479
+ },
1480
+ {
1481
+ "name": "size",
1482
+ "description": "Type: `ModalSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-modal>`",
1483
+ "values": [
1484
+ {
1485
+ "name": "small"
1486
+ },
1487
+ {
1488
+ "name": "medium"
1489
+ },
1490
+ {
1491
+ "name": "large"
1492
+ }
1493
+ ]
1494
+ },
1495
+ {
1496
+ "name": "persistent",
1497
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-modal>`"
1498
+ },
1499
+ {
1500
+ "name": "preview",
1501
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-modal>`"
1502
+ }
1503
+ ]
1504
+ },
1505
+ {
1506
+ "name": "tt-navbar",
1507
+ "description": "**Events:** tt-menu-toggle",
1508
+ "attributes": [
1509
+ {
1510
+ "name": "sticky",
1511
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-navbar>`"
1512
+ },
1513
+ {
1514
+ "name": "bordered",
1515
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-navbar>`"
1516
+ },
1517
+ {
1518
+ "name": "size",
1519
+ "description": "Type: `NavbarSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-navbar>`",
1520
+ "values": [
1521
+ {
1522
+ "name": "small"
1523
+ },
1524
+ {
1525
+ "name": "medium"
1526
+ },
1527
+ {
1528
+ "name": "large"
1529
+ }
1530
+ ]
1531
+ },
1532
+ {
1533
+ "name": "mobile-menu-open",
1534
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-navbar>`"
1535
+ },
1536
+ {
1537
+ "name": "scroll-edge",
1538
+ "description": "A soft blurred boundary below the bar instead of a hard rule, for\nwhere content actually scrolls UNDERNEATH it: a landing page, or any\nlayout where the bar floats over the scroller rather than sitting in\na column above it.\n\nNot decoration, and not a nicer border. It marks where UI meets\ncontent, so it is wrong on a bar with nothing passing under it, and\nit does nothing unless `sticky` is set. Use one per scrolling view.\n\nAttribute is `scroll-edge`, kebab-case like every multi-word\nattribute in the library.\n\nType: `boolean`\n\nDefault: `false`\n\nOn `<tt-navbar>`"
1539
+ }
1540
+ ]
1541
+ },
1542
+ {
1543
+ "name": "tt-page",
1544
+ "description": "",
1545
+ "attributes": [
1546
+ {
1547
+ "name": "heading",
1548
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-page>`"
1549
+ },
1550
+ {
1551
+ "name": "description",
1552
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-page>`"
1553
+ },
1554
+ {
1555
+ "name": "width",
1556
+ "description": "Type: `\"narrow\" | \"default\" | \"wide\" | \"full\"`\n\nDefault: `\"default\"`\n\nOn `<tt-page>`",
1557
+ "values": [
1558
+ {
1559
+ "name": "narrow"
1560
+ },
1561
+ {
1562
+ "name": "default"
1563
+ },
1564
+ {
1565
+ "name": "wide"
1566
+ },
1567
+ {
1568
+ "name": "full"
1569
+ }
1570
+ ]
1571
+ }
1572
+ ]
1573
+ },
1574
+ {
1575
+ "name": "tt-page-header",
1576
+ "description": "Title, optional description, optional breadcrumb, and a row of actions\npinned to the right.\n\nThis is the most repeated block in any application: every list, detail\nand settings screen opens with it. Without a component, each page\ninvents slightly different spacing and the product stops feeling like\none thing.\n\ntt-page owns the page frame and its width. This owns the top of the\ncontent.",
1577
+ "attributes": [
1578
+ {
1579
+ "name": "heading",
1580
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-page-header>`"
1581
+ },
1582
+ {
1583
+ "name": "description",
1584
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-page-header>`"
1585
+ },
1586
+ {
1587
+ "name": "bordered",
1588
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-page-header>`"
1589
+ }
1590
+ ]
1591
+ },
1592
+ {
1593
+ "name": "tt-pagination",
1594
+ "description": "Page navigation. Owns nothing: the current page comes in, and a click\nemits the page you asked for. The parent decides what that means and\npasses the new page back down.\n\n**Events:** tt-page-change",
1595
+ "attributes": [
1596
+ {
1597
+ "name": "page",
1598
+ "description": "Type: `number`\n\nDefault: `1`\n\nOn `<tt-pagination>`"
1599
+ },
1600
+ {
1601
+ "name": "total",
1602
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-pagination>`"
1603
+ },
1604
+ {
1605
+ "name": "page-size",
1606
+ "description": "Type: `number`\n\nDefault: `10`\n\nOn `<tt-pagination>`"
1607
+ },
1608
+ {
1609
+ "name": "siblings",
1610
+ "description": "Type: `number`\n\nDefault: `1`\n\nOn `<tt-pagination>`"
1611
+ }
1612
+ ]
1613
+ },
1614
+ {
1615
+ "name": "tt-preview",
1616
+ "description": "",
1617
+ "attributes": []
1618
+ },
1619
+ {
1620
+ "name": "tt-product",
1621
+ "description": "**Events:** tt-product-action",
1622
+ "attributes": [
1623
+ {
1624
+ "name": "src",
1625
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-product>`"
1626
+ },
1627
+ {
1628
+ "name": "ratio",
1629
+ "description": "Type: `string`\n\nDefault: `\"1\"`\n\nOn `<tt-product>`"
1630
+ },
1631
+ {
1632
+ "name": "orientation",
1633
+ "description": "Type: `ProductOrientation`\n\nDefault: `\"vertical\"`\n\nOn `<tt-product>`",
1634
+ "values": [
1635
+ {
1636
+ "name": "vertical"
1637
+ },
1638
+ {
1639
+ "name": "horizontal"
1640
+ }
1641
+ ]
1642
+ },
1643
+ {
1644
+ "name": "variant",
1645
+ "description": "Type: `ProductVariant`\n\nDefault: `\"default\"`\n\nOn `<tt-product>`",
1646
+ "values": [
1647
+ {
1648
+ "name": "default"
1649
+ },
1650
+ {
1651
+ "name": "minimal"
1652
+ },
1653
+ {
1654
+ "name": "elevated"
1655
+ },
1656
+ {
1657
+ "name": "featured"
1658
+ }
1659
+ ]
1660
+ },
1661
+ {
1662
+ "name": "layout",
1663
+ "description": "Type: `ProductLayout`\n\nDefault: `\"standard\"`\n\nOn `<tt-product>`",
1664
+ "values": [
1665
+ {
1666
+ "name": "standard"
1667
+ },
1668
+ {
1669
+ "name": "overlay"
1670
+ },
1671
+ {
1672
+ "name": "compact"
1673
+ }
1674
+ ]
1675
+ },
1676
+ {
1677
+ "name": "heading",
1678
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-product>`"
1679
+ },
1680
+ {
1681
+ "name": "description",
1682
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-product>`"
1683
+ },
1684
+ {
1685
+ "name": "description-lines",
1686
+ "description": "Type: `number`\n\nDefault: `2`\n\nOn `<tt-product>`"
1687
+ },
1688
+ {
1689
+ "name": "price",
1690
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-product>`"
1691
+ },
1692
+ {
1693
+ "name": "was-price",
1694
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-product>`"
1695
+ },
1696
+ {
1697
+ "name": "rating",
1698
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-product>`"
1699
+ },
1700
+ {
1701
+ "name": "value",
1702
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-product>`"
1703
+ },
1704
+ {
1705
+ "name": "button-link",
1706
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-product>`"
1707
+ },
1708
+ {
1709
+ "name": "button-label",
1710
+ "description": "Type: `string`\n\nDefault: `\"Add to basket\"`\n\nOn `<tt-product>`"
1711
+ },
1712
+ {
1713
+ "name": "disabled",
1714
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-product>`"
1715
+ }
1716
+ ]
1717
+ },
1718
+ {
1719
+ "name": "tt-profile-card",
1720
+ "description": "**Events:** tt-profile-action",
1721
+ "attributes": [
1722
+ {
1723
+ "name": "name",
1724
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-profile-card>`"
1725
+ },
1726
+ {
1727
+ "name": "description",
1728
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-profile-card>`"
1729
+ },
1730
+ {
1731
+ "name": "value",
1732
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-profile-card>`"
1733
+ },
1734
+ {
1735
+ "name": "image",
1736
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-profile-card>`"
1737
+ },
1738
+ {
1739
+ "name": "image-alt",
1740
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-profile-card>`"
1741
+ },
1742
+ {
1743
+ "name": "button-label",
1744
+ "description": "Type: `string`\n\nDefault: `\"View Profile\"`\n\nOn `<tt-profile-card>`"
1745
+ },
1746
+ {
1747
+ "name": "orientation",
1748
+ "description": "Type: `ProfileCardOrientation`\n\nDefault: `\"vertical\"`\n\nOn `<tt-profile-card>`",
1749
+ "values": [
1750
+ {
1751
+ "name": "vertical"
1752
+ },
1753
+ {
1754
+ "name": "horizontal"
1755
+ }
1756
+ ]
1757
+ }
1758
+ ]
1759
+ },
1760
+ {
1761
+ "name": "tt-progress",
1762
+ "description": "A labelled progress bar for a known quantity.\n\nIts highest-value use in a directory or SaaS product is a profile\ncompleteness meter. Listing quality is the product, and a visible\n\"your profile is 60% complete\" is the most effective nudge there is\nto improve it.",
1763
+ "attributes": [
1764
+ {
1765
+ "name": "value",
1766
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-progress>`"
1767
+ },
1768
+ {
1769
+ "name": "max",
1770
+ "description": "Type: `number`\n\nDefault: `100`\n\nOn `<tt-progress>`"
1771
+ },
1772
+ {
1773
+ "name": "label",
1774
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-progress>`"
1775
+ },
1776
+ {
1777
+ "name": "show-value",
1778
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-progress>`"
1779
+ },
1780
+ {
1781
+ "name": "grade",
1782
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-progress>`"
1783
+ }
1784
+ ]
1785
+ },
1786
+ {
1787
+ "name": "tt-quantity",
1788
+ "description": "**Events:** tt-change",
1789
+ "attributes": [
1790
+ {
1791
+ "name": "name",
1792
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-quantity>`"
1793
+ },
1794
+ {
1795
+ "name": "value",
1796
+ "description": "Type: `number`\n\nDefault: `1`\n\nOn `<tt-quantity>`"
1797
+ },
1798
+ {
1799
+ "name": "min",
1800
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-quantity>`"
1801
+ },
1802
+ {
1803
+ "name": "max",
1804
+ "description": "Default: `Infinity`\n\nOn `<tt-quantity>`"
1805
+ },
1806
+ {
1807
+ "name": "step",
1808
+ "description": "Type: `number`\n\nDefault: `1`\n\nOn `<tt-quantity>`"
1809
+ },
1810
+ {
1811
+ "name": "label",
1812
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-quantity>`"
1813
+ },
1814
+ {
1815
+ "name": "label-hidden",
1816
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-quantity>`"
1817
+ },
1818
+ {
1819
+ "name": "disabled",
1820
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-quantity>`"
1821
+ },
1822
+ {
1823
+ "name": "size",
1824
+ "description": "Type: `\"small\" | \"medium\" | \"large\"`\n\nDefault: `\"medium\"`\n\nOn `<tt-quantity>`",
1825
+ "values": [
1826
+ {
1827
+ "name": "small"
1828
+ },
1829
+ {
1830
+ "name": "medium"
1831
+ },
1832
+ {
1833
+ "name": "large"
1834
+ }
1835
+ ]
1836
+ }
1837
+ ]
1838
+ },
1839
+ {
1840
+ "name": "tt-radio-group",
1841
+ "description": "Pick exactly one of a small set.\n\nThe group is the form control, not the individual radios, which is why\nthis is form-associated and there is no tt-radio. A lone radio button\nis meaningless: \"one of these\" is a property of the set.\n\n**Events:** tt-change",
1842
+ "attributes": [
1843
+ {
1844
+ "name": "name",
1845
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-radio-group>`"
1846
+ },
1847
+ {
1848
+ "name": "value",
1849
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-radio-group>`"
1850
+ },
1851
+ {
1852
+ "name": "label",
1853
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-radio-group>`"
1854
+ },
1855
+ {
1856
+ "name": "label-hidden",
1857
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-radio-group>`"
1858
+ },
1859
+ {
1860
+ "name": "error",
1861
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-radio-group>`"
1862
+ },
1863
+ {
1864
+ "name": "options",
1865
+ "description": "Type: `RadioOption[]`\n\nDefault: `[]`\n\nOn `<tt-radio-group>`"
1866
+ },
1867
+ {
1868
+ "name": "required",
1869
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-radio-group>`"
1870
+ },
1871
+ {
1872
+ "name": "disabled",
1873
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-radio-group>`"
1874
+ },
1875
+ {
1876
+ "name": "orientation",
1877
+ "description": "Type: `\"horizontal\" | \"vertical\"`\n\nDefault: `\"vertical\"`\n\nOn `<tt-radio-group>`",
1878
+ "values": [
1879
+ {
1880
+ "name": "horizontal"
1881
+ },
1882
+ {
1883
+ "name": "vertical"
1884
+ }
1885
+ ]
1886
+ }
1887
+ ]
1888
+ },
1889
+ {
1890
+ "name": "tt-rating",
1891
+ "description": "A star rating, readable or settable.\n\nThe library already had tt-product, tt-profile-card and tt-company-card\nand no way to say how good any of them were, which is the one number\nevery listing, review and directory entry eventually needs.\n\nTWO COMPONENTS IN ONE, ON PURPOSE. A rating is displayed far more often\nthan it is set, and the two cases want different semantics rather than\ndifferent elements. Read-only is a single image with a text\nalternative, because a screen reader needs \"4.5 out of 5\", not five\nseparate stars it has to add up. Interactive is a slider, which is the\npattern that already works with arrow keys everywhere else.\n\nFractions are supported for the read-only case only. An average of many\nratings is 4.3; nobody has ever meant to award 4.3 themselves.\n\n**Events:** tt-change",
1892
+ "attributes": [
1893
+ {
1894
+ "name": "value",
1895
+ "description": "Stars filled. Fractional values are drawn as partial stars.\n\nType: `number`\n\nDefault: `0`\n\nOn `<tt-rating>`"
1896
+ },
1897
+ {
1898
+ "name": "max",
1899
+ "description": "Type: `number`\n\nDefault: `5`\n\nOn `<tt-rating>`"
1900
+ },
1901
+ {
1902
+ "name": "label",
1903
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-rating>`"
1904
+ },
1905
+ {
1906
+ "name": "show-value",
1907
+ "description": "Show the number beside the stars. An average is easier to read as digits.\n\nType: `boolean`\n\nDefault: `false`\n\nOn `<tt-rating>`"
1908
+ },
1909
+ {
1910
+ "name": "count",
1911
+ "description": "How many ratings the value averages, shown as \"(128)\".\n\nType: `number | undefined`\n\nOn `<tt-rating>`"
1912
+ },
1913
+ {
1914
+ "name": "interactive",
1915
+ "description": "Let the user set it. Off by default: display is the common case.\n\nType: `boolean`\n\nDefault: `false`\n\nOn `<tt-rating>`"
1916
+ },
1917
+ {
1918
+ "name": "size",
1919
+ "description": "Type: `string`\n\nDefault: `\"18px\"`\n\nOn `<tt-rating>`"
1920
+ },
1921
+ {
1922
+ "name": "grade",
1923
+ "description": "Colour by value rather than always gold. Off by default, because a\nproduct rating is gold everywhere and a red two-star review would\nlook like an error state rather than a low score.\n\nType: `boolean`\n\nDefault: `false`\n\nOn `<tt-rating>`"
1924
+ }
1925
+ ]
1926
+ },
1927
+ {
1928
+ "name": "tt-search",
1929
+ "description": "A search field.\n\nOne field, with the magnifier INSIDE it and a clear button that appears\nonly when there is something to clear. There is no separate submit\nbutton, because search is not a form you submit: results follow typing.\nThe old layout put a filled button beside the input, which read as two\ncontrols and made the field look like it needed permission to run.\nEnter still fires tt-search for anyone who expects it to.\n\n`collapsible` is opt-in, and off by default. Collapsing to an icon on a\nphone is right in a navbar, where the row is fighting for space, and\nwrong in a page toolbar, where the field is the main control on screen.\nOnly the host knows which it is, so the host decides.\n\n**Events:** tt-search-input, tt-search",
1930
+ "attributes": [
1931
+ {
1932
+ "name": "placeholder",
1933
+ "description": "Type: `string`\n\nDefault: `\"Search\"`\n\nOn `<tt-search>`"
1934
+ },
1935
+ {
1936
+ "name": "value",
1937
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-search>`"
1938
+ },
1939
+ {
1940
+ "name": "disabled",
1941
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-search>`"
1942
+ },
1943
+ {
1944
+ "name": "size",
1945
+ "description": "Type: `\"small\" | \"medium\" | \"large\"`\n\nDefault: `\"small\"`\n\nOn `<tt-search>`",
1946
+ "values": [
1947
+ {
1948
+ "name": "small"
1949
+ },
1950
+ {
1951
+ "name": "medium"
1952
+ },
1953
+ {
1954
+ "name": "large"
1955
+ }
1956
+ ]
1957
+ },
1958
+ {
1959
+ "name": "collapsible",
1960
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-search>`"
1961
+ },
1962
+ {
1963
+ "name": "debounce",
1964
+ "description": "Type: `number`\n\nDefault: `250`\n\nOn `<tt-search>`"
1965
+ },
1966
+ {
1967
+ "name": "min-length",
1968
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-search>`"
1969
+ }
1970
+ ]
1971
+ },
1972
+ {
1973
+ "name": "tt-section",
1974
+ "description": "",
1975
+ "attributes": [
1976
+ {
1977
+ "name": "heading",
1978
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-section>`"
1979
+ },
1980
+ {
1981
+ "name": "description",
1982
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-section>`"
1983
+ }
1984
+ ]
1985
+ },
1986
+ {
1987
+ "name": "tt-select",
1988
+ "description": "**Events:** tt-change",
1989
+ "attributes": [
1990
+ {
1991
+ "name": "name",
1992
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-select>`"
1993
+ },
1994
+ {
1995
+ "name": "value",
1996
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-select>`"
1997
+ },
1998
+ {
1999
+ "name": "placeholder",
2000
+ "description": "Type: `string`\n\nDefault: `\"Select an option\"`\n\nOn `<tt-select>`"
2001
+ },
2002
+ {
2003
+ "name": "options",
2004
+ "description": "Type: `SelectOption[]`\n\nDefault: `[]`\n\nOn `<tt-select>`"
2005
+ },
2006
+ {
2007
+ "name": "label",
2008
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-select>`"
2009
+ },
2010
+ {
2011
+ "name": "error",
2012
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-select>`"
2013
+ },
2014
+ {
2015
+ "name": "disabled",
2016
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-select>`"
2017
+ },
2018
+ {
2019
+ "name": "required",
2020
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-select>`"
2021
+ },
2022
+ {
2023
+ "name": "size",
2024
+ "description": "Type: `SelectSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-select>`",
2025
+ "values": [
2026
+ {
2027
+ "name": "small"
2028
+ },
2029
+ {
2030
+ "name": "medium"
2031
+ },
2032
+ {
2033
+ "name": "large"
2034
+ }
2035
+ ]
2036
+ },
2037
+ {
2038
+ "name": "label-hidden",
2039
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-select>`"
2040
+ }
2041
+ ]
2042
+ },
2043
+ {
2044
+ "name": "tt-sidebar",
2045
+ "description": "The navigation column of an app shell.\n\n---------------------------------------------------------------------\nHOW COLLAPSING WORKS, AND WHY IT NEEDS NO PROPS.\n\nWith `collapsible`, the sidebar can shrink to an icon rail. Everything\ninside it has to change at once: labels disappear, rows centre, group\nheadings go, badges go, the indent goes. Passing that down would mean a\n`collapsed` prop on every child, kept in sync by hand, at every depth.\n\nInstead the collapsed state is published as ordinary CSS custom\nproperties on the host, and each child reads the ones it cares about\nthrough var() with the expanded value as the fallback:\n\n --tt-menu-label-cols 1fr -> 0fr label track collapses\n --tt-menu-gap sp-2 -> 0px no gap beside nothing\n --tt-menu-justify start-> center icons centre in the rail\n --tt-menu-trail-display flex -> none badges and dots go\n --tt-menu-heading-display flex -> none group headings go\n --tt-menu-rail-rows unset-> 1fr every group forced open\n --tt-menu-rail-visibility unset-> visible ...and its items reachable\n --tt-menu-indent sp-2 -> 0px no nesting indent\n\nCustom properties inherit and they cross shadow boundaries, so this\nreaches a menu item nested three groups deep with no wiring, and a menu\nitem used outside a sidebar simply gets the fallbacks. Same mechanism\nas --tt-radius-nested in tokens.css.\n\nThey are declared in the stylesheet under :host([collapsed]) rather\nthan written from JavaScript, and that matters: a media query can\noverride a stylesheet rule, and cannot override an inline style. It is\nwhat lets the block at the bottom of this file switch the whole rail\noff on a phone, where the sidebar is a drawer and a rail would be an\nunusable 64px strip sliding over the page.\n\n---------------------------------------------------------------------\nWHO OWNS `collapsed`.\n\nThe component toggles itself and announces it with tt-sidebar-toggle,\nthe same shape tt-menu-group uses for open/close. An app that wants to\nremember the choice listens for the event and writes the property back;\none that does not gets working behaviour for free.\n\n**Events:** tt-sidebar-toggle",
2046
+ "attributes": [
2047
+ {
2048
+ "name": "variant",
2049
+ "description": "Type: `SidebarVariant`\n\nDefault: `\"default\"`\n\nOn `<tt-sidebar>`",
2050
+ "values": [
2051
+ {
2052
+ "name": "default"
2053
+ },
2054
+ {
2055
+ "name": "borderless"
2056
+ },
2057
+ {
2058
+ "name": "floating"
2059
+ }
2060
+ ]
2061
+ },
2062
+ {
2063
+ "name": "width",
2064
+ "description": "Type: `number`\n\nDefault: `240`\n\nOn `<tt-sidebar>`"
2065
+ },
2066
+ {
2067
+ "name": "rail-width",
2068
+ "description": "Type: `number`\n\nDefault: `64`\n\nOn `<tt-sidebar>`"
2069
+ },
2070
+ {
2071
+ "name": "collapsible",
2072
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-sidebar>`"
2073
+ },
2074
+ {
2075
+ "name": "collapsed",
2076
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-sidebar>`"
2077
+ },
2078
+ {
2079
+ "name": "label",
2080
+ "description": "Type: `string`\n\nDefault: `\"Main\"`\n\nOn `<tt-sidebar>`"
2081
+ },
2082
+ {
2083
+ "name": "collapse-label",
2084
+ "description": "Type: `string`\n\nDefault: `\"Collapse sidebar\"`\n\nOn `<tt-sidebar>`"
2085
+ },
2086
+ {
2087
+ "name": "expand-label",
2088
+ "description": "Type: `string`\n\nDefault: `\"Expand sidebar\"`\n\nOn `<tt-sidebar>`"
2089
+ }
2090
+ ]
2091
+ },
2092
+ {
2093
+ "name": "tt-sidebar-footer",
2094
+ "description": "The account row at the bottom of a sidebar.\n\nGoes in tt-sidebar's `footer` slot. Same shape as tt-sidebar-header on\npurpose: leading mark, two lines of text, trailing actions. Two rows\nthat look alike should be built alike, or they drift apart the first\ntime one of them is edited.\n\n <tt-sidebar-footer slot=\"footer\" heading=\"Alex Rana\" description=\"alex@x.com\">\n <tt-avatar slot=\"leading\" name=\"Alex Rana\"></tt-avatar>\n <tt-button slot=\"actions\" variant=\"ghost\" size=\"small\">...</tt-button>\n </tt-sidebar-footer>\n\nWith `clickable` the whole row becomes one button and emits\ntt-sidebar-account, for the common case where clicking the account\nopens a menu. It is off by default because a row that looks clickable\nand is not is worse than a plain row, and most footers are plain.\n\n`clickable` and the `actions` slot work together, because the actions\nsit BESIDE the button rather than inside it. A button inside a button\nis invalid HTML, so the row is a container holding two siblings. Same\narrangement as tt-menu-item, for the same reason.\n\n**Events:** tt-sidebar-account",
2095
+ "attributes": [
2096
+ {
2097
+ "name": "heading",
2098
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-sidebar-footer>`"
2099
+ },
2100
+ {
2101
+ "name": "description",
2102
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-sidebar-footer>`"
2103
+ },
2104
+ {
2105
+ "name": "clickable",
2106
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-sidebar-footer>`"
2107
+ }
2108
+ ]
2109
+ },
2110
+ {
2111
+ "name": "tt-sidebar-header",
2112
+ "description": "The brand row at the top of a sidebar.\n\nGoes in tt-sidebar's `header` slot. It exists because every app puts\nthe same three things there in the same order, and hand-rolling that\nrow per app means three apps with three slightly different paddings.\n\n <tt-sidebar collapsible>\n <tt-sidebar-header slot=\"header\" heading=\"Tartaguti\" description=\"Base\">\n <tt-avatar slot=\"leading\" name=\"T\"></tt-avatar>\n </tt-sidebar-header>\n </tt-sidebar>\n\nThe `leading` slot survives rail mode and the text does not, which is\nthe whole reason the mark is a separate slot rather than part of the\nheading. Same inherited-property channel as tt-menu-item; see the note\nat the top of tt-sidebar.",
2113
+ "attributes": [
2114
+ {
2115
+ "name": "heading",
2116
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-sidebar-header>`"
2117
+ },
2118
+ {
2119
+ "name": "description",
2120
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-sidebar-header>`"
2121
+ }
2122
+ ]
2123
+ },
2124
+ {
2125
+ "name": "tt-skeleton",
2126
+ "description": "Placeholder shape shown while data loads. Use it in the same layout as\nthe real content so nothing jumps when the data arrives: a skeleton\nthat is a different size than what replaces it is worse than a spinner.",
2127
+ "attributes": [
2128
+ {
2129
+ "name": "variant",
2130
+ "description": "Type: `\"text\" | \"title\" | \"circle\" | \"rect\"`\n\nDefault: `\"text\"`\n\nOn `<tt-skeleton>`",
2131
+ "values": [
2132
+ {
2133
+ "name": "text"
2134
+ },
2135
+ {
2136
+ "name": "title"
2137
+ },
2138
+ {
2139
+ "name": "circle"
2140
+ },
2141
+ {
2142
+ "name": "rect"
2143
+ }
2144
+ ]
2145
+ },
2146
+ {
2147
+ "name": "width",
2148
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-skeleton>`"
2149
+ },
2150
+ {
2151
+ "name": "height",
2152
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-skeleton>`"
2153
+ },
2154
+ {
2155
+ "name": "lines",
2156
+ "description": "Type: `number`\n\nDefault: `1`\n\nOn `<tt-skeleton>`"
2157
+ }
2158
+ ]
2159
+ },
2160
+ {
2161
+ "name": "tt-slider",
2162
+ "description": "A value picked from a range.\n\n---------------------------------------------------------------------\nIT WRAPS A REAL `<input type=\"range\">`, AND THAT IS THE DESIGN.\n\nA div with a draggable dot is about forty lines to make look right and\nseveral hundred to make correct. The native input already ships:\n\n - Arrow keys, Home, End, Page Up, Page Down, all with the right step\n - role=\"slider\" with aria-valuenow / valuemin / valuemax kept in sync\n - pointer capture, so a drag survives leaving the element\n - touch, pen and mouse without a line of code\n - correct behaviour in a form, including reset\n\nEvery one of those is a thing hand-rolled sliders get wrong. So this\ncomponent styles the native control rather than replacing it. The cost\nis four vendor pseudo-elements below; the alternative cost is the list\nabove.\n\n---------------------------------------------------------------------\nTWO EVENTS, BECAUSE THERE ARE TWO QUESTIONS.\n\n tt-input fires continuously while dragging. Use it to update a\n preview: a live number, a colour, a zoom level.\n tt-change fires once, when the drag is released. Use it to save.\n\nCollapsing them into one would force every consumer that writes to a\nserver to debounce, and every consumer that draws a preview to poll.\nThe platform already draws this line and this keeps it.\n\nIt owns its own `value`, like the native input it wraps. Setting the\nproperty from outside still wins.\n\n**Events:** tt-input, tt-change",
2163
+ "attributes": [
2164
+ {
2165
+ "name": "name",
2166
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-slider>`"
2167
+ },
2168
+ {
2169
+ "name": "value",
2170
+ "description": "Type: `number`\n\nDefault: `50`\n\nOn `<tt-slider>`"
2171
+ },
2172
+ {
2173
+ "name": "min",
2174
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-slider>`"
2175
+ },
2176
+ {
2177
+ "name": "max",
2178
+ "description": "Type: `number`\n\nDefault: `100`\n\nOn `<tt-slider>`"
2179
+ },
2180
+ {
2181
+ "name": "step",
2182
+ "description": "Type: `number`\n\nDefault: `1`\n\nOn `<tt-slider>`"
2183
+ },
2184
+ {
2185
+ "name": "label",
2186
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-slider>`"
2187
+ },
2188
+ {
2189
+ "name": "label-hidden",
2190
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-slider>`"
2191
+ },
2192
+ {
2193
+ "name": "show-value",
2194
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-slider>`"
2195
+ },
2196
+ {
2197
+ "name": "unit",
2198
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-slider>`"
2199
+ },
2200
+ {
2201
+ "name": "disabled",
2202
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-slider>`"
2203
+ }
2204
+ ]
2205
+ },
2206
+ {
2207
+ "name": "tt-social-links",
2208
+ "description": "A row of platform links. Trivial to write once and endlessly repeated,\nwhich is exactly what earns a component.\n\n`email` and `phone` are in the set on purpose. They are not social\nnetworks, but on a business profile they sit in the same row and behave\nthe same way, and splitting them into a second component would mean two\nrows that have to be styled to look like one.\n\nEvery href goes through safeUrl, because these come from user-entered\nprofile data. A company that types `javascript:...` into its website\nfield would otherwise get it rendered as a live link on its own page.",
2209
+ "attributes": [
2210
+ {
2211
+ "name": "links",
2212
+ "description": "Type: `SocialLink[]`\n\nDefault: `[]`\n\nOn `<tt-social-links>`"
2213
+ },
2214
+ {
2215
+ "name": "size",
2216
+ "description": "Type: `\"small\" | \"medium\"`\n\nDefault: `\"medium\"`\n\nOn `<tt-social-links>`",
2217
+ "values": [
2218
+ {
2219
+ "name": "small"
2220
+ },
2221
+ {
2222
+ "name": "medium"
2223
+ }
2224
+ ]
2225
+ },
2226
+ {
2227
+ "name": "labelled",
2228
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-social-links>`"
2229
+ }
2230
+ ]
2231
+ },
2232
+ {
2233
+ "name": "tt-sparkline",
2234
+ "description": "",
2235
+ "attributes": [
2236
+ {
2237
+ "name": "points",
2238
+ "description": "Type: `number[]`\n\nDefault: `[]`\n\nOn `<tt-sparkline>`"
2239
+ },
2240
+ {
2241
+ "name": "area",
2242
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-sparkline>`"
2243
+ },
2244
+ {
2245
+ "name": "trend",
2246
+ "description": "Type: `SparklineTrend`\n\nDefault: `\"neutral\"`\n\nOn `<tt-sparkline>`",
2247
+ "values": [
2248
+ {
2249
+ "name": "positive"
2250
+ },
2251
+ {
2252
+ "name": "negative"
2253
+ },
2254
+ {
2255
+ "name": "neutral"
2256
+ }
2257
+ ]
2258
+ },
2259
+ {
2260
+ "name": "label",
2261
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-sparkline>`"
2262
+ }
2263
+ ]
2264
+ },
2265
+ {
2266
+ "name": "tt-spinner",
2267
+ "description": "Indeterminate loading indicator, for when you cannot say how long\nsomething will take. Prefer tt-skeleton when you know the shape of what\nis coming: a skeleton tells the user what to expect, a spinner only\ntells them to wait.",
2268
+ "attributes": [
2269
+ {
2270
+ "name": "size",
2271
+ "description": "Type: `string`\n\nDefault: `\"20px\"`\n\nOn `<tt-spinner>`"
2272
+ },
2273
+ {
2274
+ "name": "label",
2275
+ "description": "Type: `string`\n\nDefault: `\"Loading\"`\n\nOn `<tt-spinner>`"
2276
+ }
2277
+ ]
2278
+ },
2279
+ {
2280
+ "name": "tt-stack",
2281
+ "description": "Lays its children out in a column or a row, with a gap from the\nspacing scale.\n\nThe layout every screen repeats, and the library had no general one:\ntt-grid is a responsive grid, tt-toolbar a row with two sides,\ntt-button-group joins controls into one unit. So the apps wrote their\nown `display: flex; gap: ...` in some 26 files, with the same gap\nspelled 0.75rem in one and 12px in the next. A stack can only take a\nstep of the scale, and because the steps are tokens, a stack also\nfollows the density modes, which a hand-written 12px never will.\n\nTHE HOST IS THE FLEX CONTAINER. The shadow root holds only a slot, and\na slot is display: contents, so the slotted children become flex items\nof the host itself. With no inner wrapper there is nothing to reach\nthrough: a consumer's own `gap` or `flex-wrap` on the element simply\nwins, because a rule from outside beats :host.\n\nNo reverse option, on purpose. A row drawn in the opposite order to\nits markup is read and tabbed through backwards by keyboard and screen\nreader users. Reorder the markup instead.",
2282
+ "attributes": [
2283
+ {
2284
+ "name": "orientation",
2285
+ "description": "Type: `StackOrientation`\n\nDefault: `\"vertical\"`\n\nOn `<tt-stack>`",
2286
+ "values": [
2287
+ {
2288
+ "name": "vertical"
2289
+ },
2290
+ {
2291
+ "name": "horizontal"
2292
+ }
2293
+ ]
2294
+ },
2295
+ {
2296
+ "name": "gap",
2297
+ "description": "Type: `StackGap`\n\nDefault: `\"medium\"`\n\nOn `<tt-stack>`",
2298
+ "values": [
2299
+ {
2300
+ "name": "none"
2301
+ },
2302
+ {
2303
+ "name": "small"
2304
+ },
2305
+ {
2306
+ "name": "medium"
2307
+ },
2308
+ {
2309
+ "name": "large"
2310
+ }
2311
+ ]
2312
+ },
2313
+ {
2314
+ "name": "align",
2315
+ "description": "Type: `StackAlign`\n\nDefault: `\"stretch\"`\n\nOn `<tt-stack>`",
2316
+ "values": [
2317
+ {
2318
+ "name": "start"
2319
+ },
2320
+ {
2321
+ "name": "center"
2322
+ },
2323
+ {
2324
+ "name": "end"
2325
+ },
2326
+ {
2327
+ "name": "stretch"
2328
+ }
2329
+ ]
2330
+ },
2331
+ {
2332
+ "name": "justify",
2333
+ "description": "Type: `StackJustify`\n\nDefault: `\"start\"`\n\nOn `<tt-stack>`",
2334
+ "values": [
2335
+ {
2336
+ "name": "start"
2337
+ },
2338
+ {
2339
+ "name": "center"
2340
+ },
2341
+ {
2342
+ "name": "end"
2343
+ },
2344
+ {
2345
+ "name": "between"
2346
+ }
2347
+ ]
2348
+ },
2349
+ {
2350
+ "name": "wrap",
2351
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-stack>`"
2352
+ }
2353
+ ]
2354
+ },
2355
+ {
2356
+ "name": "tt-stat",
2357
+ "description": "",
2358
+ "attributes": [
2359
+ {
2360
+ "name": "label",
2361
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-stat>`"
2362
+ },
2363
+ {
2364
+ "name": "value",
2365
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-stat>`"
2366
+ },
2367
+ {
2368
+ "name": "delta",
2369
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-stat>`"
2370
+ },
2371
+ {
2372
+ "name": "trend",
2373
+ "description": "Type: `StatTrend`\n\nDefault: `\"neutral\"`\n\nOn `<tt-stat>`",
2374
+ "values": [
2375
+ {
2376
+ "name": "positive"
2377
+ },
2378
+ {
2379
+ "name": "negative"
2380
+ },
2381
+ {
2382
+ "name": "neutral"
2383
+ }
2384
+ ]
2385
+ }
2386
+ ]
2387
+ },
2388
+ {
2389
+ "name": "tt-switch",
2390
+ "description": "A switch, not a checkbox. Use it for a setting that takes effect\nimmediately (\"Email notifications on\"). Use tt-checkbox for something\nconfirmed later by a submit (\"I accept the terms\").\n\n**Events:** tt-change",
2391
+ "attributes": [
2392
+ {
2393
+ "name": "name",
2394
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-switch>`"
2395
+ },
2396
+ {
2397
+ "name": "value",
2398
+ "description": "Type: `string`\n\nDefault: `\"on\"`\n\nOn `<tt-switch>`"
2399
+ },
2400
+ {
2401
+ "name": "label",
2402
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-switch>`"
2403
+ },
2404
+ {
2405
+ "name": "checked",
2406
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-switch>`"
2407
+ },
2408
+ {
2409
+ "name": "disabled",
2410
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-switch>`"
2411
+ },
2412
+ {
2413
+ "name": "label-first",
2414
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-switch>`"
2415
+ },
2416
+ {
2417
+ "name": "label-hidden",
2418
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-switch>`"
2419
+ }
2420
+ ]
2421
+ },
2422
+ {
2423
+ "name": "tt-switcher",
2424
+ "description": "",
2425
+ "attributes": [
2426
+ {
2427
+ "name": "items",
2428
+ "description": "Type: `SwitcherItem[]`\n\nDefault: `[]`\n\nOn `<tt-switcher>`"
2429
+ },
2430
+ {
2431
+ "name": "active-index",
2432
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-switcher>`"
2433
+ }
2434
+ ]
2435
+ },
2436
+ {
2437
+ "name": "tt-table",
2438
+ "description": "A read-only table, written one of two ways.\n\nDATA: pass `columns` and `rows` and it draws a real table element.\nFastest for text, and what every reference table in the docs uses.\n\nCOMPOSED: leave `columns` empty and put `tt-table-row` elements inside,\neach holding `tt-table-cell` elements. A cell takes any component, so\na checkbox, a badge or a button goes exactly where it is wanted.\n\nBoth look the same. Columns win when both are given.",
2439
+ "attributes": [
2440
+ {
2441
+ "name": "columns",
2442
+ "description": "Type: `TableColumn[]`\n\nDefault: `[]`\n\nOn `<tt-table>`"
2443
+ },
2444
+ {
2445
+ "name": "rows",
2446
+ "description": "Type: `TableRow[]`\n\nDefault: `[]`\n\nOn `<tt-table>`"
2447
+ },
2448
+ {
2449
+ "name": "label",
2450
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-table>`"
2451
+ }
2452
+ ]
2453
+ },
2454
+ {
2455
+ "name": "tt-table-cell",
2456
+ "description": "One cell of a composed `tt-table`, inside a `tt-table-row`.\n\nIt takes anything: text, a badge, a checkbox, a button, another\ncomponent. The cell only supplies what every cell needs, the padding,\nthe vertical centring and the alignment, so the content never has to\nknow it is in a table.\n\n`header` makes it a column heading, for screen readers as well as on\nscreen, the same as a th in a plain table.",
2457
+ "attributes": [
2458
+ {
2459
+ "name": "header",
2460
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-table-cell>`"
2461
+ },
2462
+ {
2463
+ "name": "align",
2464
+ "description": "Type: `TableCellAlign`\n\nDefault: `\"start\"`\n\nOn `<tt-table-cell>`",
2465
+ "values": [
2466
+ {
2467
+ "name": "start"
2468
+ },
2469
+ {
2470
+ "name": "center"
2471
+ },
2472
+ {
2473
+ "name": "end"
2474
+ }
2475
+ ]
2476
+ }
2477
+ ]
2478
+ },
2479
+ {
2480
+ "name": "tt-table-row",
2481
+ "description": "One row of a composed `tt-table`. Holds `tt-table-cell` elements.\n\nIt has no settings. Its whole job is to be a row twice over: a row to\na screen reader (role=\"row\") and a row of the table's grid, through\n`grid-template-columns: subgrid`. Subgrid is what makes the columns\nline up. Each row lays its cells on the TABLE's column tracks rather\nthan its own, so a wide cell in one row widens that column in every\nrow, the way a real table does.\n\n <tt-table>\n <tt-table-row>\n <tt-table-cell header>Name</tt-table-cell>\n </tt-table-row>\n <tt-table-row>\n <tt-table-cell>Ada Lovelace</tt-table-cell>\n </tt-table-row>\n </tt-table>",
2482
+ "attributes": []
2483
+ },
2484
+ {
2485
+ "name": "tt-tabs",
2486
+ "description": "Tabbed sections. Panels are slotted by id, so the content lives with\nwhoever is using the tabs rather than being passed in as data:\n\n <tt-tabs .tabs=${[{ id: \"about\", label: \"About\" }]} active=\"about\">\n <div slot=\"about\">...</div>\n </tt-tabs>\n\nOwns nothing. `active` comes in, a click emits the id you asked for.\n\n**Events:** tt-tab-change",
2487
+ "attributes": [
2488
+ {
2489
+ "name": "tabs",
2490
+ "description": "Type: `TabItem[]`\n\nDefault: `[]`\n\nOn `<tt-tabs>`"
2491
+ },
2492
+ {
2493
+ "name": "active",
2494
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-tabs>`"
2495
+ }
2496
+ ]
2497
+ },
2498
+ {
2499
+ "name": "tt-tag-list",
2500
+ "description": "",
2501
+ "attributes": [
2502
+ {
2503
+ "name": "tags",
2504
+ "description": "Type: `string[]`\n\nDefault: `[]`\n\nOn `<tt-tag-list>`"
2505
+ },
2506
+ {
2507
+ "name": "max",
2508
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-tag-list>`"
2509
+ },
2510
+ {
2511
+ "name": "expandable",
2512
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-tag-list>`"
2513
+ }
2514
+ ]
2515
+ },
2516
+ {
2517
+ "name": "tt-text",
2518
+ "description": "A heading, a paragraph or a run of text, on the type scale.\n\nEvery component styles its own text, so the library had no general\none, and the apps wrote `<h2 style=\"font-size: ...\">` by hand with a\nsize that matched no token. This one can only take a step of the\nscale, a weight token and a colour token, so it follows the theme,\ndark mode included, and never drifts.\n\n---------------------------------------------------------------------\nTWO SEPARATE QUESTIONS: WHAT IT IS, AND HOW IT LOOKS.\n\n`as` is meaning. It picks the real element in the shadow root, so an\nh2 is an h2 to a screen reader and in the page outline. `size` and\n`weight` are looks. They stay separate because the two disagree all\nthe time: the heading of a small card is an h3 for the outline but\nshould not be drawn at h3 size.\n\nLeft on \"auto\", size and weight follow the tag: h1 is 3xl bold down\nto h6 at sm semibold, a paragraph is md regular. Setting either one\noverrides only that one.\n\n---------------------------------------------------------------------\nTHE TYPE IS SET ON THE HOST.\n\nEvery rule below is a :host rule, and the element inside only\ninherits. So a consumer's own `font-size` or `color` on the element\nsimply wins, because a rule from outside beats :host, the same reason\ntt-stack keeps its layout on the host.",
2519
+ "attributes": [
2520
+ {
2521
+ "name": "as",
2522
+ "description": "Type: `TextAs`\n\nDefault: `\"p\"`\n\nOn `<tt-text>`",
2523
+ "values": [
2524
+ {
2525
+ "name": "p"
2526
+ },
2527
+ {
2528
+ "name": "span"
2529
+ },
2530
+ {
2531
+ "name": "h1"
2532
+ },
2533
+ {
2534
+ "name": "h2"
2535
+ },
2536
+ {
2537
+ "name": "h3"
2538
+ },
2539
+ {
2540
+ "name": "h4"
2541
+ },
2542
+ {
2543
+ "name": "h5"
2544
+ },
2545
+ {
2546
+ "name": "h6"
2547
+ }
2548
+ ]
2549
+ },
2550
+ {
2551
+ "name": "size",
2552
+ "description": "Type: `TextSize`\n\nDefault: `\"auto\"`\n\nOn `<tt-text>`",
2553
+ "values": [
2554
+ {
2555
+ "name": "auto"
2556
+ },
2557
+ {
2558
+ "name": "xs"
2559
+ },
2560
+ {
2561
+ "name": "sm"
2562
+ },
2563
+ {
2564
+ "name": "md"
2565
+ },
2566
+ {
2567
+ "name": "lg"
2568
+ },
2569
+ {
2570
+ "name": "xl"
2571
+ },
2572
+ {
2573
+ "name": "2xl"
2574
+ },
2575
+ {
2576
+ "name": "3xl"
2577
+ }
2578
+ ]
2579
+ },
2580
+ {
2581
+ "name": "weight",
2582
+ "description": "Type: `TextWeight`\n\nDefault: `\"auto\"`\n\nOn `<tt-text>`",
2583
+ "values": [
2584
+ {
2585
+ "name": "auto"
2586
+ },
2587
+ {
2588
+ "name": "regular"
2589
+ },
2590
+ {
2591
+ "name": "medium"
2592
+ },
2593
+ {
2594
+ "name": "semibold"
2595
+ },
2596
+ {
2597
+ "name": "bold"
2598
+ }
2599
+ ]
2600
+ },
2601
+ {
2602
+ "name": "tone",
2603
+ "description": "Type: `TextTone`\n\nDefault: `\"default\"`\n\nOn `<tt-text>`",
2604
+ "values": [
2605
+ {
2606
+ "name": "default"
2607
+ },
2608
+ {
2609
+ "name": "muted"
2610
+ },
2611
+ {
2612
+ "name": "brand"
2613
+ },
2614
+ {
2615
+ "name": "success"
2616
+ },
2617
+ {
2618
+ "name": "warning"
2619
+ },
2620
+ {
2621
+ "name": "danger"
2622
+ }
2623
+ ]
2624
+ },
2625
+ {
2626
+ "name": "align",
2627
+ "description": "Type: `TextAlign`\n\nDefault: `\"start\"`\n\nOn `<tt-text>`",
2628
+ "values": [
2629
+ {
2630
+ "name": "start"
2631
+ },
2632
+ {
2633
+ "name": "center"
2634
+ },
2635
+ {
2636
+ "name": "end"
2637
+ },
2638
+ {
2639
+ "name": "justify"
2640
+ }
2641
+ ]
2642
+ },
2643
+ {
2644
+ "name": "max-lines",
2645
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-text>`"
2646
+ }
2647
+ ]
2648
+ },
2649
+ {
2650
+ "name": "tt-textarea",
2651
+ "description": "**Events:** tt-input, tt-change",
2652
+ "attributes": [
2653
+ {
2654
+ "name": "label",
2655
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-textarea>`"
2656
+ },
2657
+ {
2658
+ "name": "placeholder",
2659
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-textarea>`"
2660
+ },
2661
+ {
2662
+ "name": "value",
2663
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-textarea>`"
2664
+ },
2665
+ {
2666
+ "name": "name",
2667
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-textarea>`"
2668
+ },
2669
+ {
2670
+ "name": "autocomplete",
2671
+ "description": "Type: `AutoCompleteToken | undefined`\n\nOn `<tt-textarea>`"
2672
+ },
2673
+ {
2674
+ "name": "error",
2675
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-textarea>`"
2676
+ },
2677
+ {
2678
+ "name": "label-hidden",
2679
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-textarea>`"
2680
+ },
2681
+ {
2682
+ "name": "rows",
2683
+ "description": "Type: `number`\n\nDefault: `4`\n\nOn `<tt-textarea>`"
2684
+ },
2685
+ {
2686
+ "name": "maxlength",
2687
+ "description": "Type: `number`\n\nDefault: `0`\n\nOn `<tt-textarea>`"
2688
+ },
2689
+ {
2690
+ "name": "disabled",
2691
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-textarea>`"
2692
+ },
2693
+ {
2694
+ "name": "required",
2695
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-textarea>`"
2696
+ },
2697
+ {
2698
+ "name": "full-width",
2699
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-textarea>`"
2700
+ },
2701
+ {
2702
+ "name": "auto-grow",
2703
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-textarea>`"
2704
+ }
2705
+ ]
2706
+ },
2707
+ {
2708
+ "name": "tt-thread",
2709
+ "description": "The reading side of a messaging surface. Pairs with tt-inbox.\n\nSplit from the list because the two sit in different places: side by\nside on a desktop, two separate routes on a phone. One component would\nhave to make that layout decision for the app.\n\nTHREE THINGS THAT ARE EASY TO GET WRONG AND ANNOYING TO LIVE WITH.\n\nIt scrolls to the bottom on new messages, because a thread is read\nnewest-last and opening one part-way up is disorienting. It only does\nso when the reader was ALREADY at the bottom, so it never yanks\nsomebody out of older messages they were deliberately reading.\n\nConsecutive messages from the same author collapse: the avatar and name\nappear once and the following bubbles are bare. Repeating the name on\nevery line of a burst is noise.\n\nThe composer is Enter to send, Shift+Enter for a newline. That is what\nevery messaging product does, and a thread that needs a mouse click to\nsend feels broken regardless of how correct it is.\n\n**Events:** tt-send",
2710
+ "attributes": [
2711
+ {
2712
+ "name": "messages",
2713
+ "description": "Type: `Message[]`\n\nDefault: `[]`\n\nOn `<tt-thread>`"
2714
+ },
2715
+ {
2716
+ "name": "heading",
2717
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-thread>`"
2718
+ },
2719
+ {
2720
+ "name": "placeholder",
2721
+ "description": "Type: `string`\n\nDefault: `\"Write a message\"`\n\nOn `<tt-thread>`"
2722
+ },
2723
+ {
2724
+ "name": "send-label",
2725
+ "description": "Type: `string`\n\nDefault: `\"Send\"`\n\nOn `<tt-thread>`"
2726
+ },
2727
+ {
2728
+ "name": "readonly",
2729
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-thread>`"
2730
+ },
2731
+ {
2732
+ "name": "sending",
2733
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-thread>`"
2734
+ },
2735
+ {
2736
+ "name": "empty-text",
2737
+ "description": "Type: `string`\n\nDefault: `\"No messages yet\"`\n\nOn `<tt-thread>`"
2738
+ }
2739
+ ]
2740
+ },
2741
+ {
2742
+ "name": "tt-toast",
2743
+ "description": "Drop one of these anywhere in the app, then call the module-level\ntoast() from anywhere else. Notifications are global by nature, so\nrouting every message down through props would mean every component\nin the tree carrying a notify callback it does not otherwise need.",
2744
+ "attributes": [
2745
+ {
2746
+ "name": "position",
2747
+ "description": "Type: `\"top-right\" | \"top-center\" | \"bottom-right\" | \"bottom-center\"`\n\nDefault: `\"top-right\"`\n\nOn `<tt-toast>`",
2748
+ "values": [
2749
+ {
2750
+ "name": "top-right"
2751
+ },
2752
+ {
2753
+ "name": "top-center"
2754
+ },
2755
+ {
2756
+ "name": "bottom-right"
2757
+ },
2758
+ {
2759
+ "name": "bottom-center"
2760
+ }
2761
+ ]
2762
+ }
2763
+ ]
2764
+ },
2765
+ {
2766
+ "name": "tt-toggle",
2767
+ "description": "A button that stays down.\n\nBold, italic, underline. Grid view or list view. A filter that is on.\nAnything whose state is visible in the control itself rather than\nsomewhere else on the page.\n\n---------------------------------------------------------------------\nNOT A CHECKBOX AND NOT A SWITCH, AND THE DIFFERENCE IS NOT COSMETIC.\n\n tt-checkbox a value being collected, confirmed later by a submit.\n It has a label beside it and it lives in a form.\n tt-switch a setting that takes effect immediately. Reads as a\n sentence: \"Email notifications, on\".\n tt-toggle a tool that is currently selected. Usually an icon,\n usually in a row of siblings, and its meaning comes\n from what it does to something else.\n\nThey carry different ARIA too, which is the real tell: a checkbox is\n`aria-checked`, a toggle is `aria-pressed`. A screen reader announces\n\"pressed\" rather than \"checked\", and that is the correct sentence for\na bold button.\n\n---------------------------------------------------------------------\nIT FLIPS ITSELF, UNLESS IT IS IN A GROUP.\n\nOn its own it toggles and announces, the same shape as tt-switch. That\nis the only sensible default for a control that has nothing\ncoordinating it.\n\nInside tt-toggle-group the group writes `pressed` back onto every\nchild after any change, so the group's answer is the one that lasts.\nThat is deliberate: single-select needs someone to un-press the\nprevious choice, and only the group can know which one that was.\n\n**Events:** tt-change",
2768
+ "attributes": [
2769
+ {
2770
+ "name": "pressed",
2771
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-toggle>`"
2772
+ },
2773
+ {
2774
+ "name": "disabled",
2775
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-toggle>`"
2776
+ },
2777
+ {
2778
+ "name": "size",
2779
+ "description": "Type: `ToggleSize`\n\nDefault: `\"medium\"`\n\nOn `<tt-toggle>`",
2780
+ "values": [
2781
+ {
2782
+ "name": "small"
2783
+ },
2784
+ {
2785
+ "name": "medium"
2786
+ },
2787
+ {
2788
+ "name": "large"
2789
+ }
2790
+ ]
2791
+ },
2792
+ {
2793
+ "name": "value",
2794
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-toggle>`"
2795
+ },
2796
+ {
2797
+ "name": "label",
2798
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-toggle>`"
2799
+ }
2800
+ ]
2801
+ },
2802
+ {
2803
+ "name": "tt-toggle-group",
2804
+ "description": "A row of tt-toggle that agree with each other.\n\n---------------------------------------------------------------------\n`values` IS ALWAYS AN ARRAY, EVEN IN SINGLE MODE.\n\nThe obvious API is `value: string` for single and `values: string[]`\nfor multiple, which is what most libraries do. It is rejected here.\n\nA property whose TYPE depends on another property is a property you\nhave to think about at every call site, and it makes the change event\ncarry two shapes as well. Every consumer then needs a branch, and half\nof them will forget it.\n\nOne shape instead: a single-select group holds an array of zero or one\nentries. `values[0] ?? null` is the whole cost, paid once by whoever\nactually wants a scalar, and `tt-change` always carries the complete\nnew array. Same contract as tt-checkbox-group.\n\n---------------------------------------------------------------------\nWHO OWNS THE SELECTION.\n\nBoth. `values` comes in, and `tt-change` goes out with the whole new\nset. The group also keeps that new set itself (Oct 2026). It used to\nstore nothing and wait for the page to echo `values` back, which\nmeant a group with no listener (a pasted snippet, a generated\ncomponent) started every click from the old set: `multiple` acted\nlike single, and `allow-empty` cleared instead of selecting. A page\nthat sets `values` still wins, the same as with a native input.\n\nBut it does WRITE to its children, immediately, in its own handler,\nrather than waiting for the page to echo `values` back. That is the\none thing worth understanding here.\n\nA tt-toggle flips itself when clicked. In single mode that leaves two\npressed toggles for as long as it takes the page to respond, and if\nthe page ignores the event it leaves them pressed forever. So the\ngroup corrects its children on the spot: the click is the child's, the\nANSWER is the group's.\n\nThat makes it work whether or not the page echoes the value back, and\n`updated()` re-applies the same result when it does, which is\nidempotent (applying it twice is the same as applying it once).\n\n**Events:** tt-change",
2805
+ "attributes": [
2806
+ {
2807
+ "name": "multiple",
2808
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-toggle-group>`"
2809
+ },
2810
+ {
2811
+ "name": "type",
2812
+ "description": "The older spelling of `multiple`; type=\"multiple\" still works.\n\nType: `ToggleGroupType`\n\nDefault: `\"single\"`\n\nOn `<tt-toggle-group>`",
2813
+ "values": [
2814
+ {
2815
+ "name": "single"
2816
+ },
2817
+ {
2818
+ "name": "multiple"
2819
+ }
2820
+ ]
2821
+ },
2822
+ {
2823
+ "name": "values",
2824
+ "description": "Type: `string[]`\n\nDefault: `[]`\n\nOn `<tt-toggle-group>`"
2825
+ },
2826
+ {
2827
+ "name": "disabled",
2828
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-toggle-group>`"
2829
+ },
2830
+ {
2831
+ "name": "label",
2832
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-toggle-group>`"
2833
+ },
2834
+ {
2835
+ "name": "detached",
2836
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-toggle-group>`"
2837
+ },
2838
+ {
2839
+ "name": "allow-empty",
2840
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-toggle-group>`"
2841
+ }
2842
+ ]
2843
+ },
2844
+ {
2845
+ "name": "tt-toolbar",
2846
+ "description": "The row above a list: something to filter with on the left, actions on\nthe right, and a gap between them that collapses when the row wraps.\n\nThis is the third copy of the same flex row in this repo, which is the\npoint at which a pattern earns a component. Directory, Members and Shop\neach had their own, and each had drifted: different gaps, different\nwrap behaviour, and a hand-rolled spacer div in two of them.\n\nPure layout. It has no idea what is in it, so a search box, a segmented\ncontrol or a count all work without it knowing.",
2847
+ "attributes": [
2848
+ {
2849
+ "name": "bordered",
2850
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-toolbar>`"
2851
+ },
2852
+ {
2853
+ "name": "stack",
2854
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-toolbar>`"
2855
+ },
2856
+ {
2857
+ "name": "align",
2858
+ "description": "Type: `\"center\" | \"start\"`\n\nDefault: `\"center\"`\n\nOn `<tt-toolbar>`",
2859
+ "values": [
2860
+ {
2861
+ "name": "center"
2862
+ },
2863
+ {
2864
+ "name": "start"
2865
+ }
2866
+ ]
2867
+ }
2868
+ ]
2869
+ },
2870
+ {
2871
+ "name": "tt-tooltip",
2872
+ "description": "A short hint attached to whatever you slot into it.\n\nOnly ever supplementary. A tooltip is invisible on touch devices and to\nanyone who does not hover, so never put information here that a user\nneeds in order to complete a task.",
2873
+ "attributes": [
2874
+ {
2875
+ "name": "content",
2876
+ "description": "Type: `string`\n\nDefault: `\"\"`\n\nOn `<tt-tooltip>`"
2877
+ },
2878
+ {
2879
+ "name": "placement",
2880
+ "description": "Type: `TooltipPlacement`\n\nDefault: `\"top\"`\n\nOn `<tt-tooltip>`",
2881
+ "values": [
2882
+ {
2883
+ "name": "top"
2884
+ },
2885
+ {
2886
+ "name": "bottom"
2887
+ },
2888
+ {
2889
+ "name": "left"
2890
+ },
2891
+ {
2892
+ "name": "right"
2893
+ }
2894
+ ]
2895
+ },
2896
+ {
2897
+ "name": "disabled",
2898
+ "description": "Type: `boolean`\n\nDefault: `false`\n\nOn `<tt-tooltip>`"
2899
+ },
2900
+ {
2901
+ "name": "delay",
2902
+ "description": "Type: `number`\n\nDefault: `150`\n\nOn `<tt-tooltip>`"
2903
+ }
2904
+ ]
2905
+ }
2906
+ ]
2907
+ }