@ui-sdk/web 0.0.0-stage → 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (467) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +10 -2
  3. package/browser/web/accordion.js +1 -0
  4. package/browser/web/alert-dialog.js +1 -0
  5. package/browser/web/autocomplete.js +1 -0
  6. package/browser/web/avatar.js +1 -0
  7. package/browser/web/button.js +1 -0
  8. package/browser/web/calendar.js +1 -0
  9. package/browser/web/carousel.js +1 -0
  10. package/browser/web/checkbox.js +1 -0
  11. package/browser/web/chunks/0eRGibL6.js +1 -0
  12. package/browser/web/chunks/2bIEUO6_.js +1 -0
  13. package/browser/web/chunks/5A9w2ULz.js +1 -0
  14. package/browser/web/chunks/5RSyydjV.js +1 -0
  15. package/browser/web/chunks/9pWTy2wl.js +1 -0
  16. package/browser/web/chunks/B0f2j6zz.js +1 -0
  17. package/browser/web/chunks/B1rux6br.js +1 -0
  18. package/browser/web/chunks/B3-APaNf.js +1 -0
  19. package/browser/web/chunks/B7EgSgjQ.js +1 -0
  20. package/browser/web/chunks/B8QcOzJU.js +1 -0
  21. package/browser/web/chunks/BFueEkwm.js +3 -0
  22. package/browser/web/chunks/BJj3oS29.js +1 -0
  23. package/browser/web/chunks/BNSvTCpr.js +1 -0
  24. package/browser/web/chunks/BPD0kAZB.js +1 -0
  25. package/browser/web/chunks/BQeduZqT.js +1 -0
  26. package/browser/web/chunks/B_CVFyiz.js +1 -0
  27. package/browser/web/chunks/B_ns1YHO.js +1 -0
  28. package/browser/web/chunks/BcwkVTsR.js +1 -0
  29. package/browser/web/chunks/BeaQ6TYM.js +1 -0
  30. package/browser/web/chunks/BgBB013u.js +1 -0
  31. package/browser/web/chunks/BgsKhHDm.js +1 -0
  32. package/browser/web/chunks/BjMcbuhi.js +9 -0
  33. package/browser/web/chunks/Bjiy_F2N.js +1 -0
  34. package/browser/web/chunks/BqScCLwv.js +1 -0
  35. package/browser/web/chunks/BqX3Utqx.js +1 -0
  36. package/browser/web/chunks/BtVkQf3z.js +1 -0
  37. package/browser/web/chunks/By30h-7B.js +1 -0
  38. package/browser/web/chunks/C1zqYpy2.js +1 -0
  39. package/browser/web/chunks/C436juFf.js +1 -0
  40. package/browser/web/chunks/C4_bULs1.js +1 -0
  41. package/browser/web/chunks/C4omqJEz.js +1 -0
  42. package/browser/web/chunks/C7tt0T3n.js +1 -0
  43. package/browser/web/chunks/C8w7s5dg.js +1 -0
  44. package/browser/web/chunks/CElY4erO.js +1 -0
  45. package/browser/web/chunks/CFODo-m2.js +1 -0
  46. package/browser/web/chunks/CL4wjam9.js +1 -0
  47. package/browser/web/chunks/CMg-8UVf.js +1 -0
  48. package/browser/web/chunks/COWKfakj.js +1 -0
  49. package/browser/web/chunks/CQBU0qZ4.js +1 -0
  50. package/browser/web/chunks/CV6uABgc.js +1 -0
  51. package/browser/web/chunks/C_SWFpWQ.js +1 -0
  52. package/browser/web/chunks/C_Uanbrl.js +1 -0
  53. package/browser/web/chunks/Ce_CSanC.js +1 -0
  54. package/browser/web/chunks/Cg-ZmRhS.js +1 -0
  55. package/browser/web/chunks/Cgf2wPI_.js +1 -0
  56. package/browser/web/chunks/Cuep_3Vf.js +1 -0
  57. package/browser/web/chunks/D02PaHn6.js +1 -0
  58. package/browser/web/chunks/D5LiaI5R.js +1 -0
  59. package/browser/web/chunks/D9UgVYvF.js +1 -0
  60. package/browser/web/chunks/DC08tnkE.js +2 -0
  61. package/browser/web/chunks/DG8YGSvu.js +1 -0
  62. package/browser/web/chunks/DIQd0FYD.js +1 -0
  63. package/browser/web/chunks/DMLqacE8.js +1 -0
  64. package/browser/web/chunks/DSUI3yI-.js +1 -0
  65. package/browser/web/chunks/DT3Hb76X.js +1 -0
  66. package/browser/web/chunks/DY75g3-W.js +1 -0
  67. package/browser/web/chunks/DZpNQKZ9.js +1 -0
  68. package/browser/web/chunks/Db-W1wrC.js +1 -0
  69. package/browser/web/chunks/Dc1xK3Ii.js +1 -0
  70. package/browser/web/chunks/DdF6awFs.js +1 -0
  71. package/browser/web/chunks/DdaCLml8.js +1 -0
  72. package/browser/web/chunks/Dh8MLjQO.js +1 -0
  73. package/browser/web/chunks/DiuslJRy.js +1 -0
  74. package/browser/web/chunks/DjRcw3Y0.js +1 -0
  75. package/browser/web/chunks/Djdv-16J.js +1 -0
  76. package/browser/web/chunks/DnFXe_lF.js +1 -0
  77. package/browser/web/chunks/DneGv1oC.js +1 -0
  78. package/browser/web/chunks/DsVxP-p-.js +1 -0
  79. package/browser/web/chunks/DwDilCo2.js +1 -0
  80. package/browser/web/chunks/DwV48AXv.js +1 -0
  81. package/browser/web/chunks/F37aF4-L.js +1 -0
  82. package/browser/web/chunks/LyB6XIbN.js +1 -0
  83. package/browser/web/chunks/NKnbYGjC.js +1 -0
  84. package/browser/web/chunks/Vk-rVi16.js +1 -0
  85. package/browser/web/chunks/XsM0J1Ex.js +1 -0
  86. package/browser/web/chunks/asSN9iEp.js +1 -0
  87. package/browser/web/chunks/c-AjHfdF.js +1 -0
  88. package/browser/web/chunks/dR-12TPY.js +1 -0
  89. package/browser/web/chunks/hR4xM0EC.js +1 -0
  90. package/browser/web/chunks/hqOaBxAg.js +1 -0
  91. package/browser/web/chunks/kMKqqeG4.js +1 -0
  92. package/browser/web/chunks/kXboBcfi.js +1 -0
  93. package/browser/web/chunks/l4aQIg22.js +1 -0
  94. package/browser/web/chunks/tJC0JSU4.js +1 -0
  95. package/browser/web/chunks/wHdS_QYM.js +1 -0
  96. package/browser/web/chunks/yv8dTvNI.js +1 -0
  97. package/browser/web/chunks/yw9M3nfi.js +1 -0
  98. package/browser/web/collapsible.js +1 -0
  99. package/browser/web/color-picker.js +1 -0
  100. package/browser/web/combobox.js +2 -0
  101. package/browser/web/command.js +1 -0
  102. package/browser/web/core.js +5 -0
  103. package/browser/web/date-input.js +1 -0
  104. package/browser/web/date-picker.js +1 -0
  105. package/browser/web/dialog.js +1 -0
  106. package/browser/web/drawer.js +1 -0
  107. package/browser/web/field.js +1 -0
  108. package/browser/web/file-input.js +1 -0
  109. package/browser/web/hover-card.js +1 -0
  110. package/browser/web/image-cropper.js +1 -0
  111. package/browser/web/input.js +1 -0
  112. package/browser/web/label.js +1 -0
  113. package/browser/web/listbox.js +1 -0
  114. package/browser/web/menu.js +1 -0
  115. package/browser/web/menubar.js +1 -0
  116. package/browser/web/meter.js +1 -0
  117. package/browser/web/navigation-menu.js +1 -0
  118. package/browser/web/number-input.js +1 -0
  119. package/browser/web/otp-input.js +2 -0
  120. package/browser/web/overlays.js +1 -0
  121. package/browser/web/pagination.js +1 -0
  122. package/browser/web/password-input.js +1 -0
  123. package/browser/web/popover.js +1 -0
  124. package/browser/web/preferences.js +1 -0
  125. package/browser/web/progress.js +1 -0
  126. package/browser/web/radio.js +1 -0
  127. package/browser/web/rating.js +1 -0
  128. package/browser/web/resizable.js +1 -0
  129. package/browser/web/scroll-area.js +1 -0
  130. package/browser/web/segmented-control.js +1 -0
  131. package/browser/web/select.js +1 -0
  132. package/browser/web/separator.js +1 -0
  133. package/browser/web/slider.js +1 -0
  134. package/browser/web/switch.js +1 -0
  135. package/browser/web/tabs.js +1 -0
  136. package/browser/web/textarea.js +1 -0
  137. package/browser/web/time-input.js +1 -0
  138. package/browser/web/timeline.js +1 -0
  139. package/browser/web/toast.js +1 -0
  140. package/browser/web/toggle.js +1 -0
  141. package/browser/web/token-input.js +8 -0
  142. package/browser/web/toolbar.js +1 -0
  143. package/browser/web/tooltip.js +1 -0
  144. package/browser/web/tree.js +1 -0
  145. package/browser/web/trigger-menu.js +4 -0
  146. package/browser/web/waterfall.js +1 -0
  147. package/browser/web.css +3378 -0
  148. package/browser/web.js +3 -0
  149. package/custom-elements.json +32315 -0
  150. package/dist/accordion.d.ts +2 -0
  151. package/dist/accordion.js +57 -0
  152. package/dist/action.d.ts +16 -0
  153. package/dist/action.js +39 -0
  154. package/dist/agent.d.ts +2 -0
  155. package/dist/agent.js +7 -0
  156. package/dist/autocomplete.d.ts +2 -0
  157. package/dist/autocomplete.js +120 -0
  158. package/dist/autoload.d.ts +18 -0
  159. package/dist/autoload.js +63 -0
  160. package/dist/avatar.d.ts +2 -0
  161. package/dist/avatar.js +27 -0
  162. package/dist/browser-core.d.ts +2 -0
  163. package/dist/browser-core.js +8 -0
  164. package/dist/button.d.ts +2 -0
  165. package/dist/button.js +35 -0
  166. package/dist/calendar.d.ts +23 -0
  167. package/dist/calendar.js +429 -0
  168. package/dist/carousel.d.ts +2 -0
  169. package/dist/carousel.js +54 -0
  170. package/dist/checkbox.d.ts +4 -0
  171. package/dist/checkbox.js +75 -0
  172. package/dist/collapsible.d.ts +2 -0
  173. package/dist/collapsible.js +28 -0
  174. package/dist/color-picker.d.ts +2 -0
  175. package/dist/color-picker.js +64 -0
  176. package/dist/combobox.d.ts +2 -0
  177. package/dist/combobox.js +334 -0
  178. package/dist/command.d.ts +2 -0
  179. package/dist/command.js +122 -0
  180. package/dist/date-input.d.ts +3 -0
  181. package/dist/date-input.js +87 -0
  182. package/dist/date-picker.d.ts +2 -0
  183. package/dist/date-picker.js +174 -0
  184. package/dist/default-text.d.ts +3 -0
  185. package/dist/default-text.js +24 -0
  186. package/dist/define-element.d.ts +404 -0
  187. package/dist/define-element.js +1489 -0
  188. package/dist/dialog.d.ts +3 -0
  189. package/dist/dialog.js +94 -0
  190. package/dist/drawer.d.ts +2 -0
  191. package/dist/drawer.js +96 -0
  192. package/dist/entries/accordion.d.ts +3 -0
  193. package/dist/entries/accordion.js +7 -0
  194. package/dist/entries/alert-dialog.d.ts +3 -0
  195. package/dist/entries/alert-dialog.js +13 -0
  196. package/dist/entries/autocomplete.d.ts +3 -0
  197. package/dist/entries/autocomplete.js +7 -0
  198. package/dist/entries/avatar.d.ts +2 -0
  199. package/dist/entries/avatar.js +3 -0
  200. package/dist/entries/button.d.ts +2 -0
  201. package/dist/entries/button.js +3 -0
  202. package/dist/entries/calendar.d.ts +3 -0
  203. package/dist/entries/calendar.js +7 -0
  204. package/dist/entries/carousel.d.ts +3 -0
  205. package/dist/entries/carousel.js +7 -0
  206. package/dist/entries/checkbox.d.ts +3 -0
  207. package/dist/entries/checkbox.js +15 -0
  208. package/dist/entries/collapsible.d.ts +3 -0
  209. package/dist/entries/collapsible.js +7 -0
  210. package/dist/entries/color-picker.d.ts +3 -0
  211. package/dist/entries/color-picker.js +7 -0
  212. package/dist/entries/combobox.d.ts +3 -0
  213. package/dist/entries/combobox.js +7 -0
  214. package/dist/entries/command.d.ts +3 -0
  215. package/dist/entries/command.js +7 -0
  216. package/dist/entries/date-input.d.ts +3 -0
  217. package/dist/entries/date-input.js +7 -0
  218. package/dist/entries/date-picker.d.ts +3 -0
  219. package/dist/entries/date-picker.js +7 -0
  220. package/dist/entries/dialog.d.ts +3 -0
  221. package/dist/entries/dialog.js +7 -0
  222. package/dist/entries/drawer.d.ts +3 -0
  223. package/dist/entries/drawer.js +8 -0
  224. package/dist/entries/field.d.ts +2 -0
  225. package/dist/entries/field.js +3 -0
  226. package/dist/entries/file-input.d.ts +3 -0
  227. package/dist/entries/file-input.js +13 -0
  228. package/dist/entries/hover-card.d.ts +3 -0
  229. package/dist/entries/hover-card.js +7 -0
  230. package/dist/entries/image-cropper.d.ts +3 -0
  231. package/dist/entries/image-cropper.js +7 -0
  232. package/dist/entries/input.d.ts +3 -0
  233. package/dist/entries/input.js +8 -0
  234. package/dist/entries/label.d.ts +2 -0
  235. package/dist/entries/label.js +3 -0
  236. package/dist/entries/listbox.d.ts +3 -0
  237. package/dist/entries/listbox.js +7 -0
  238. package/dist/entries/menu.d.ts +3 -0
  239. package/dist/entries/menu.js +7 -0
  240. package/dist/entries/menubar.d.ts +3 -0
  241. package/dist/entries/menubar.js +7 -0
  242. package/dist/entries/meter.d.ts +2 -0
  243. package/dist/entries/meter.js +3 -0
  244. package/dist/entries/navigation-menu.d.ts +3 -0
  245. package/dist/entries/navigation-menu.js +7 -0
  246. package/dist/entries/number-input.d.ts +3 -0
  247. package/dist/entries/number-input.js +7 -0
  248. package/dist/entries/otp-input.d.ts +3 -0
  249. package/dist/entries/otp-input.js +7 -0
  250. package/dist/entries/overlays.d.ts +2 -0
  251. package/dist/entries/overlays.js +3 -0
  252. package/dist/entries/pagination.d.ts +3 -0
  253. package/dist/entries/pagination.js +11 -0
  254. package/dist/entries/password-input.d.ts +3 -0
  255. package/dist/entries/password-input.js +7 -0
  256. package/dist/entries/popover.d.ts +3 -0
  257. package/dist/entries/popover.js +7 -0
  258. package/dist/entries/preferences.d.ts +3 -0
  259. package/dist/entries/preferences.js +13 -0
  260. package/dist/entries/progress.d.ts +2 -0
  261. package/dist/entries/progress.js +3 -0
  262. package/dist/entries/radio.d.ts +3 -0
  263. package/dist/entries/radio.js +7 -0
  264. package/dist/entries/rating.d.ts +3 -0
  265. package/dist/entries/rating.js +8 -0
  266. package/dist/entries/resizable.d.ts +3 -0
  267. package/dist/entries/resizable.js +11 -0
  268. package/dist/entries/scroll-area.d.ts +3 -0
  269. package/dist/entries/scroll-area.js +7 -0
  270. package/dist/entries/segmented-control.d.ts +3 -0
  271. package/dist/entries/segmented-control.js +7 -0
  272. package/dist/entries/select.d.ts +3 -0
  273. package/dist/entries/select.js +7 -0
  274. package/dist/entries/separator.d.ts +2 -0
  275. package/dist/entries/separator.js +3 -0
  276. package/dist/entries/slider.d.ts +3 -0
  277. package/dist/entries/slider.js +7 -0
  278. package/dist/entries/switch.d.ts +3 -0
  279. package/dist/entries/switch.js +7 -0
  280. package/dist/entries/tabs.d.ts +3 -0
  281. package/dist/entries/tabs.js +7 -0
  282. package/dist/entries/textarea.d.ts +3 -0
  283. package/dist/entries/textarea.js +7 -0
  284. package/dist/entries/time-input.d.ts +3 -0
  285. package/dist/entries/time-input.js +7 -0
  286. package/dist/entries/timeline.d.ts +3 -0
  287. package/dist/entries/timeline.js +7 -0
  288. package/dist/entries/toast.d.ts +2 -0
  289. package/dist/entries/toast.js +3 -0
  290. package/dist/entries/toggle.d.ts +3 -0
  291. package/dist/entries/toggle.js +12 -0
  292. package/dist/entries/token-input.d.ts +3 -0
  293. package/dist/entries/token-input.js +17 -0
  294. package/dist/entries/toolbar.d.ts +3 -0
  295. package/dist/entries/toolbar.js +7 -0
  296. package/dist/entries/tooltip.d.ts +3 -0
  297. package/dist/entries/tooltip.js +7 -0
  298. package/dist/entries/tree.d.ts +3 -0
  299. package/dist/entries/tree.js +17 -0
  300. package/dist/entries/trigger-menu.d.ts +3 -0
  301. package/dist/entries/trigger-menu.js +11 -0
  302. package/dist/entries/waterfall.d.ts +3 -0
  303. package/dist/entries/waterfall.js +11 -0
  304. package/dist/events.d.ts +1658 -0
  305. package/dist/events.js +0 -0
  306. package/dist/field.d.ts +2 -0
  307. package/dist/field.js +101 -0
  308. package/dist/file-input.d.ts +2 -0
  309. package/dist/file-input.js +140 -0
  310. package/dist/forward-attributes.d.ts +2 -0
  311. package/dist/forward-attributes.js +22 -0
  312. package/dist/history.d.ts +2 -0
  313. package/dist/history.js +11 -0
  314. package/dist/hover-card.d.ts +2 -0
  315. package/dist/hover-card.js +31 -0
  316. package/dist/image-cropper.d.ts +2 -0
  317. package/dist/image-cropper.js +66 -0
  318. package/dist/index.d.ts +66 -0
  319. package/dist/index.js +269 -0
  320. package/dist/input.d.ts +3 -0
  321. package/dist/input.js +69 -0
  322. package/dist/label.d.ts +2 -0
  323. package/dist/label.js +11 -0
  324. package/dist/list.d.ts +40 -0
  325. package/dist/list.js +192 -0
  326. package/dist/listbox.d.ts +2 -0
  327. package/dist/listbox.js +84 -0
  328. package/dist/menu.d.ts +4 -0
  329. package/dist/menu.js +295 -0
  330. package/dist/menubar.d.ts +4 -0
  331. package/dist/menubar.js +30 -0
  332. package/dist/meter.d.ts +2 -0
  333. package/dist/meter.js +22 -0
  334. package/dist/navigation-menu.d.ts +2 -0
  335. package/dist/navigation-menu.js +114 -0
  336. package/dist/number-input.d.ts +2 -0
  337. package/dist/number-input.js +73 -0
  338. package/dist/observe.d.ts +2 -0
  339. package/dist/observe.js +7 -0
  340. package/dist/otp-input.d.ts +2 -0
  341. package/dist/otp-input.js +72 -0
  342. package/dist/overlays.d.ts +13 -0
  343. package/dist/overlays.js +156 -0
  344. package/dist/pagination.d.ts +2 -0
  345. package/dist/pagination.js +127 -0
  346. package/dist/password-input.d.ts +2 -0
  347. package/dist/password-input.js +57 -0
  348. package/dist/popover.d.ts +2 -0
  349. package/dist/popover.js +64 -0
  350. package/dist/popup.d.ts +40 -0
  351. package/dist/popup.js +112 -0
  352. package/dist/preferences.d.ts +2 -0
  353. package/dist/preferences.js +56 -0
  354. package/dist/progress.d.ts +2 -0
  355. package/dist/progress.js +22 -0
  356. package/dist/radio.d.ts +2 -0
  357. package/dist/radio.js +33 -0
  358. package/dist/rating.d.ts +2 -0
  359. package/dist/rating.js +64 -0
  360. package/dist/resizable.d.ts +2 -0
  361. package/dist/resizable.js +42 -0
  362. package/dist/scroll-area.d.ts +2 -0
  363. package/dist/scroll-area.js +45 -0
  364. package/dist/segmented-control.d.ts +2 -0
  365. package/dist/segmented-control.js +28 -0
  366. package/dist/select.d.ts +2 -0
  367. package/dist/select.js +239 -0
  368. package/dist/separator.d.ts +2 -0
  369. package/dist/separator.js +11 -0
  370. package/dist/slider.d.ts +2 -0
  371. package/dist/slider.js +77 -0
  372. package/dist/tabs.d.ts +2 -0
  373. package/dist/tabs.js +37 -0
  374. package/dist/timeline.d.ts +2 -0
  375. package/dist/timeline.js +27 -0
  376. package/dist/toast.d.ts +20 -0
  377. package/dist/toast.js +177 -0
  378. package/dist/toggle.d.ts +3 -0
  379. package/dist/toggle.js +64 -0
  380. package/dist/token-input.d.ts +2 -0
  381. package/dist/token-input.js +103 -0
  382. package/dist/toolbar.d.ts +2 -0
  383. package/dist/toolbar.js +36 -0
  384. package/dist/tooltip.d.ts +2 -0
  385. package/dist/tooltip.js +35 -0
  386. package/dist/tree.d.ts +2 -0
  387. package/dist/tree.js +147 -0
  388. package/dist/trigger-menu.d.ts +2 -0
  389. package/dist/trigger-menu.js +133 -0
  390. package/dist/waterfall.d.ts +2 -0
  391. package/dist/waterfall.js +140 -0
  392. package/docs/README.md +89 -0
  393. package/docs/agents.md +1523 -0
  394. package/docs/components/accordion.md +1401 -0
  395. package/docs/components/alert-dialog.md +788 -0
  396. package/docs/components/autocomplete.md +1692 -0
  397. package/docs/components/avatar.md +261 -0
  398. package/docs/components/button.md +441 -0
  399. package/docs/components/calendar.md +1536 -0
  400. package/docs/components/carousel.md +1055 -0
  401. package/docs/components/checkbox.md +1045 -0
  402. package/docs/components/collapsible.md +535 -0
  403. package/docs/components/color-picker.md +651 -0
  404. package/docs/components/combobox.md +3274 -0
  405. package/docs/components/command.md +1431 -0
  406. package/docs/components/date-input.md +563 -0
  407. package/docs/components/date-picker.md +1136 -0
  408. package/docs/components/dialog.md +1360 -0
  409. package/docs/components/drawer.md +1201 -0
  410. package/docs/components/field.md +519 -0
  411. package/docs/components/file-input.md +617 -0
  412. package/docs/components/hover-card.md +486 -0
  413. package/docs/components/image-cropper.md +489 -0
  414. package/docs/components/input.md +327 -0
  415. package/docs/components/label.md +208 -0
  416. package/docs/components/listbox.md +1015 -0
  417. package/docs/components/menu.md +1212 -0
  418. package/docs/components/menubar.md +460 -0
  419. package/docs/components/meter.md +298 -0
  420. package/docs/components/navigation-menu.md +1573 -0
  421. package/docs/components/number-input.md +1087 -0
  422. package/docs/components/otp-input.md +558 -0
  423. package/docs/components/pagination.md +639 -0
  424. package/docs/components/password-input.md +649 -0
  425. package/docs/components/popover.md +1433 -0
  426. package/docs/components/preferences.md +243 -0
  427. package/docs/components/progress.md +406 -0
  428. package/docs/components/radio.md +855 -0
  429. package/docs/components/rating.md +431 -0
  430. package/docs/components/resizable.md +866 -0
  431. package/docs/components/scroll-area.md +898 -0
  432. package/docs/components/segmented-control.md +421 -0
  433. package/docs/components/select.md +1957 -0
  434. package/docs/components/separator.md +238 -0
  435. package/docs/components/slider.md +1018 -0
  436. package/docs/components/switch.md +583 -0
  437. package/docs/components/tabs.md +948 -0
  438. package/docs/components/textarea.md +331 -0
  439. package/docs/components/time-input.md +235 -0
  440. package/docs/components/timeline.md +622 -0
  441. package/docs/components/toast.md +1223 -0
  442. package/docs/components/toggle.md +522 -0
  443. package/docs/components/token-input.md +854 -0
  444. package/docs/components/toolbar.md +815 -0
  445. package/docs/components/tooltip.md +860 -0
  446. package/docs/components/tree.md +1243 -0
  447. package/docs/components/trigger-menu.md +1110 -0
  448. package/docs/components/waterfall.md +709 -0
  449. package/docs/controllers.md +66 -0
  450. package/docs/core.md +8027 -0
  451. package/docs/custom-parts.md +91 -0
  452. package/docs/first-component.md +88 -0
  453. package/docs/forms.md +125 -0
  454. package/docs/installation.md +141 -0
  455. package/docs/introduction.md +32 -0
  456. package/docs/lists-and-menus.md +166 -0
  457. package/docs/llms.txt +1566 -0
  458. package/docs/parts-and-composition.md +57 -0
  459. package/docs/popups.md +92 -0
  460. package/docs/rendering.md +71 -0
  461. package/docs/server-rendering.md +118 -0
  462. package/docs/state-and-events.md +134 -0
  463. package/docs/styling-and-animation.md +104 -0
  464. package/docs/utilities/async-options.md +332 -0
  465. package/docs/utilities/shortcuts.md +184 -0
  466. package/html-custom-data.json +14792 -0
  467. package/package.json +302 -3
@@ -0,0 +1,486 @@
1
+ # Hover Card
2
+
3
+ Preview a link on hover or keyboard focus while keeping its normal navigation.
4
+
5
+ A hover card shows a preview of where a link goes, like a person's profile, to someone who pauses on it. The link still works as a link.
6
+
7
+ ```ts title="basic.ts"
8
+ import "@ui-sdk/web/hover-card"
9
+
10
+ function mount(root: HTMLElement) {
11
+ root.innerHTML = `
12
+ <ui-hover-card>
13
+ <ui-hover-card-trigger><a href="https://example.com/people/hollis">@hollis</a></ui-hover-card-trigger>
14
+ <ui-hover-card-content hidden>
15
+ <div data-slot="row">
16
+ <span data-slot="initials" aria-hidden="true">HG</span>
17
+ <div data-slot="stack">
18
+ <p>Hollis Grant</p>
19
+ <p>Design engineer on the payments team. Writes about forms and motion.</p>
20
+ <p data-slot="hint">Joined March 2021</p>
21
+ </div>
22
+ </div>
23
+ </ui-hover-card-content>
24
+ </ui-hover-card>
25
+ `
26
+ }
27
+
28
+ export { mount }
29
+ ```
30
+
31
+ Hover @hollis, or Tab to it and wait, to open Hollis Grant's profile preview. Move the pointer away or press Escape to close it.
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ npm install @ui-sdk/web @ui-sdk/core
37
+ ```
38
+
39
+ Import the component to register its elements. The import is safe on the server.
40
+
41
+ ```ts
42
+ import "@ui-sdk/web/hover-card"
43
+ ```
44
+
45
+ ## Composition
46
+
47
+ Use the following composition to build a `ui-hover-card`:
48
+
49
+ ```text
50
+ ui-hover-card
51
+ ├── ui-hover-card-trigger
52
+ │ └── a
53
+ └── ui-hover-card-content
54
+ └── ui-hover-card-arrow
55
+ ```
56
+
57
+ The trigger wraps your own link (an `<a>`, so give it an `href`), and pressing it follows the link. The content is the preview, and the arrow is optional.
58
+
59
+ The card only adds a preview for people who pause on the link: everything in it should be reachable from the page the link goes to, since touch and screen reader users may never open it. For a tip on a button, use a [Tooltip](./tooltip.md). For content that opens with a press, use a [Popover](./popover.md).
60
+
61
+ ## Usage
62
+
63
+ Import the parts and put them together:
64
+
65
+ ```html
66
+ <script type="module">
67
+ import "@ui-sdk/web/hover-card"
68
+ </script>
69
+
70
+ <ui-hover-card>
71
+ <ui-hover-card-trigger
72
+ ><a href="/people/hollis">@hollis</a></ui-hover-card-trigger
73
+ >
74
+ <ui-hover-card-content hidden>
75
+ <p>Hollis Grant</p>
76
+ <p>Design engineer on the payments team.</p>
77
+ </ui-hover-card-content>
78
+ </ui-hover-card>
79
+ ```
80
+
81
+ ## Positioning
82
+
83
+ `side` picks where the card opens, `bottom` by default, and `align` lines it up with the start, center or end of the link. The card flips to the other side when there isn't room and shifts along the link to stay on screen.
84
+
85
+ `ui-hover-card-arrow` follows the side the card actually lands on, including after a flip, and gets the same `data-side`. It points at the middle of the link and keeps `arrow-padding` away from the corners; `data-arrow-clamped` tells you when it can't reach the middle.
86
+
87
+ ```ts title="side.ts"
88
+ import "@ui-sdk/web/hover-card"
89
+ import "@ui-sdk/web/select"
90
+ import { Check, ChevronDown, createElement } from "lucide"
91
+
92
+ const sides = [
93
+ { value: "top", label: "Top" },
94
+ { value: "right", label: "Right" },
95
+ { value: "bottom", label: "Bottom" },
96
+ { value: "left", label: "Left" },
97
+ ]
98
+ const aligns = [
99
+ { value: "start", label: "Start" },
100
+ { value: "center", label: "Center" },
101
+ { value: "end", label: "End" },
102
+ ]
103
+
104
+ const select = (
105
+ name: string,
106
+ label: string,
107
+ options: { value: string; label: string }[],
108
+ value: string
109
+ ) => `
110
+ <ui-select data-control="${name}" default-value="${value}">
111
+ <ui-select-label>${label}</ui-select-label>
112
+ <ui-select-trigger>
113
+ <button>
114
+ <ui-select-value></ui-select-value>
115
+ ${createElement(ChevronDown, { "aria-hidden": "true" }).outerHTML}
116
+ </button>
117
+ </ui-select-trigger>
118
+ <ui-select-content hidden>
119
+ ${options
120
+ .map(
121
+ (option) => `
122
+ <ui-select-item value="${option.value}">
123
+ ${option.label}
124
+ <ui-select-item-indicator>${createElement(Check, { "aria-hidden": "true" }).outerHTML}</ui-select-item-indicator>
125
+ </ui-select-item>
126
+ `
127
+ )
128
+ .join("")}
129
+ </ui-select-content>
130
+ </ui-select>
131
+ `
132
+
133
+ function mount(root: HTMLElement) {
134
+ root.innerHTML = `
135
+ <div data-slot="stack">
136
+ <div data-slot="controls">
137
+ ${select("side", "Side", sides, "bottom")}
138
+ ${select("align", "Align", aligns, "center")}
139
+ </div>
140
+ <ui-hover-card>
141
+ <ui-hover-card-trigger><a href="https://example.com/people/ines">@ines</a></ui-hover-card-trigger>
142
+ <ui-hover-card-content hidden side="bottom" align="center" side-offset="10">
143
+ <ui-hover-card-arrow></ui-hover-card-arrow>
144
+ <p>Inès Moreau</p>
145
+ <p>Product designer. Leads the checkout redesign.</p>
146
+ </ui-hover-card-content>
147
+ </ui-hover-card>
148
+ </div>
149
+ `
150
+ const content = root.querySelector("ui-hover-card-content")!
151
+ for (const control of root.querySelectorAll("ui-select")) {
152
+ control.addEventListener("valuechange", (event) => {
153
+ if (event.detail.value) {
154
+ content.setAttribute(
155
+ control.dataset.control!,
156
+ String(event.detail.value)
157
+ )
158
+ }
159
+ })
160
+ }
161
+ }
162
+
163
+ export { mount }
164
+ ```
165
+
166
+ Choose a side and an alignment, then hover @ines. The card opens there and its arrow points at the link.
167
+
168
+ `side-offset` is the gap to the link, 4 pixels by default. `align-offset` shifts the card along it, and `collision-padding` is the space kept from the edges of the window. `anchor` positions the card against something other than the link, named by a CSS selector.
169
+
170
+ ```html
171
+ <ui-hover-card-content
172
+ side="right"
173
+ align="start"
174
+ side-offset="8"
175
+ collision-padding="16"
176
+ anchor="#row"
177
+ hidden
178
+ ></ui-hover-card-content>
179
+ ```
180
+
181
+ ## Delays
182
+
183
+ `delay` is how long the pointer rests on the link, or keyboard focus stays on it, before the card opens: 600 milliseconds by default. `close-delay` is how long it stays open once the pointer leaves the link and the card: 300 milliseconds by default. The pointer can cross the gap between the link and the card without closing it.
184
+
185
+ `disabled` stops the card from opening and leaves a plain link.
186
+
187
+ ```html
188
+ <ui-hover-card delay="300" close-delay="150" disabled></ui-hover-card>
189
+ ```
190
+
191
+ ## Controlled
192
+
193
+ Set the element's `open` property and listen for `openchange`; the `open` attribute sets where it starts. Every change carries a [reason](#reasons) in `event.detail.reason`, like `trigger-hover`, `trigger-focus`, `focus-out`, `escape-key` or `outside-press`. Call `event.preventDefault()` to stop it.
194
+
195
+ ```html
196
+ <ui-hover-card></ui-hover-card>
197
+
198
+ <script type="module">
199
+ const card = document.querySelector("ui-hover-card")
200
+ card.addEventListener("openchange", (event) => (open = event.detail.value))
201
+ card.open = true
202
+ </script>
203
+ ```
204
+
205
+ ## One Card for Many Links
206
+
207
+ A feed or a list can share one card instead of rendering one per link. Give the card an `id` and name it from each trigger with `for`. Each trigger takes a `payload` property, like its person, read when it connects, so set it before the trigger goes into the page. The card's `payloadchange` event carries it in `event.detail.value`; render the content from it there. Only the link that opened the card gets `data-open`. The card's `api.open({ payload })` opens it from code.
208
+
209
+ ```html
210
+ <ui-hover-card id="profile">
211
+ <ui-hover-card-content hidden><p></p></ui-hover-card-content>
212
+ </ui-hover-card>
213
+
214
+ <script type="module">
215
+ const card = document.querySelector("#profile")
216
+ for (const person of people) {
217
+ const trigger = Object.assign(
218
+ document.createElement("ui-hover-card-trigger"),
219
+ { payload: person }
220
+ )
221
+ trigger.setAttribute("for", "profile")
222
+ trigger.innerHTML = `<a href="${person.url}">${person.name}</a>`
223
+ feed.append(trigger)
224
+ }
225
+ card.addEventListener("payloadchange", (event) => {
226
+ card.querySelector("p").textContent = event.detail.value?.bio
227
+ })
228
+ </script>
229
+ ```
230
+
231
+ A card can have links of its own. Tab from a link with an open card moves into the card, and Tab past its end moves on to the page after the link. Focus leaving the card closes it.
232
+
233
+ ## Container
234
+
235
+ Cards render in place and show in the top layer, so no ancestor clips or covers them. `container` renders the card somewhere else, named by a CSS selector, for iframes, shadow roots or a specific stacking context. See the shared [popup guide](../popups.md).
236
+
237
+ ```html
238
+ <ui-hover-card-content container="#card-host" hidden></ui-hover-card-content>
239
+ ```
240
+
241
+ ## Animation
242
+
243
+ The content has `data-starting-style` while it opens and `data-ending-style` while it closes. Transition from those states, and the card stays mounted until the exit finishes. `openchangecomplete` fires after the transition, and `keep-mounted` keeps the closed card in the page, hidden, for animation libraries that drive the exit from state.
244
+
245
+ ```css
246
+ [data-slot="hover-card-content"] {
247
+ transition:
248
+ opacity 150ms,
249
+ scale 150ms;
250
+
251
+ &:is([data-starting-style], [data-ending-style]) {
252
+ opacity: 0;
253
+ scale: 0.96;
254
+ }
255
+ }
256
+ ```
257
+
258
+ ## Custom Rendering
259
+
260
+ Elements have no render functions. The trigger wraps your own link, so the link can hold anything, like an avatar and a name. The link gets `data-open` while the card is open from it.
261
+
262
+ ```html
263
+ <ui-hover-card-trigger>
264
+ <a href="/people/hollis">
265
+ <span aria-hidden="true">HG</span>
266
+ Hollis Grant
267
+ </a>
268
+ </ui-hover-card-trigger>
269
+ ```
270
+
271
+ ## Styling
272
+
273
+ Each element has a `data-slot`, such as `hover-card-content`, and shows its state through the attributes listed under [Data Attributes](#data-attributes). Use `data-open` on the trigger's link to mark the link whose card is showing, and `data-side` to style the content and arrow for the side they landed on. Put `transform-origin: var(--transform-origin)` on the content so it scales from the link.
274
+
275
+ Keep overflow visible around an arrow that extends outside the card. If the body needs to scroll, put scrolling on an inner element.
276
+
277
+ ### `<ui-hover-card-content>`
278
+ - `--anchor-width`: Width of the anchor, usually the trigger. Use it to match widths.
279
+ - `--anchor-height`: Height of the anchor.
280
+ - `--available-width`: Space beside the popup, up to the viewport edge. Not inherited either.
281
+ - `--available-height`: Space between the anchor and the viewport edge. Use it for max-height. Not inherited, so a child that needs it copies it on the popup, like `[--list-height:var(--available-height)]`, and reads `max-h-(--list-height)`. The first popup registers both names for the whole page with `CSS.registerProperty`, so they don't inherit anywhere. A page that needs them to inherit calls it first, with `inherits: true`. An `@property` rule can't, since a registration in script wins.
282
+ - `--transform-origin`: The point on the anchor the popup opens from. Use it to scale from the right place.
283
+ - `--arrow-offset`: Where the anchor's center falls along the popup's edge, kept `arrowPadding` from the corners. Position a ::before arrow with it.
284
+
285
+ ## Data Attributes
286
+
287
+ ### `<ui-hover-card-trigger>`
288
+ `[data-slot="hover-card-trigger"]`
289
+
290
+ - `data-closed`: Present while the card is closed, including while it animates out.
291
+ - `data-open`: Present while the card is open. On a trigger, while it's open from that trigger.
292
+
293
+ ### `<ui-hover-card-content>`
294
+ `[data-slot="hover-card-content"]`
295
+
296
+ - `data-closed`: Present while the card is closed, including while it animates out.
297
+ - `data-open`: Present while the card is open. On a trigger, while it's open from that trigger.
298
+ - `data-starting-style`: Present for the first frame. Style the state you animate from.
299
+ - `data-ending-style`: Present while the card animates out. Style the state you animate to.
300
+
301
+ ### `<ui-hover-card-arrow>`
302
+ `[data-slot="hover-card-arrow"]`
303
+
304
+ - `data-closed`: Present while the card is closed, including while it animates out.
305
+ - `data-open`: Present while the card is open. On a trigger, while it's open from that trigger.
306
+
307
+ ## API Reference
308
+
309
+ Props are attributes in kebab case, like `close-delay` and `side-offset`: `"false"` is false, and numbers are numbers. `anchor` and `container` take CSS selectors, and `controller` is a property. Callbacks are DOM events.
310
+
311
+ ### HoverCard
312
+
313
+ - `container?` (`DocumentFragment | Element | null`): Renders the popup into this element instead of in place, like a container inside a shadow root or an iframe. On web components, a CSS selector. Nested popups stay inside their parent.
314
+ - `open?` (`boolean`): Whether the card is open. Pass it to control the card.
315
+ - `defaultOpen?` (`boolean`): Whether the card starts open, when uncontrolled.
316
+ - `openchange event`: Runs when the card wants to open or close. `details.reason` says why, and `details.cancel()` stops it.
317
+ - `openchangecomplete event`: Runs once the card has finished opening or closing, after any animation.
318
+ - `payloadchange event`: Runs when the payload the content shows changes: a trigger with another payload opens the card, or takes the open card over, which fires no `openchange`, and so does a controller's `open({ payload })` on the open card. `details.cancel()` keeps the previous payload.
319
+ - `delay?` (`number`): Milliseconds the pointer rests on the trigger, or keyboard focus stays on it, before the card opens.
320
+ - `closeDelay?` (`number`): Milliseconds before the card closes once the pointer leaves the trigger and the card.
321
+ - `disabled?` (`boolean`): Stops the card from opening. The trigger keeps working as a link.
322
+ - `controller?` (`PopupController<any, HoverCardOpenChangeReason, {}, string, HoverCardPayloadChangeReason>`): Opens, closes and inspects the card from anywhere, and connects triggers outside it. Create one with `createHoverCardController()`.
323
+ - `debug?` (`boolean`): Logs every state change with its reason to the console, in development builds.
324
+
325
+ ### HoverCardTrigger
326
+
327
+ A trigger outside the card names it with `for="card-id"`, and takes `payload` as a property.
328
+
329
+ - `payload?` (`unknown`): Data for the content to render when this trigger opens the card, like the profile it links to.
330
+ - `controller?` (`PopupController<any, HoverCardOpenChangeReason, {}, string, HoverCardPayloadChangeReason>`): Connects a trigger outside the card, like every author link in a feed, to the card with this controller.
331
+
332
+ ### HoverCardContent
333
+
334
+ - `side?` (`Side`): Which side of the anchor the popup opens on. Flips to the other side when there isn't room. Which side of the trigger the card opens on.
335
+ - `align?` (`Align`): How the popup lines up with the anchor along that side. `start` and `end` follow the reading direction. How the card lines up with the trigger along that side.
336
+ - `sideOffset?` (`number`): Gap between the anchor and the popup, in pixels. Gap between the trigger and the card, in pixels.
337
+ - `alignOffset?` (`number`): Shift along the anchor, in pixels. Shift along the trigger, in pixels.
338
+ - `collisionPadding?` (`number`): Space to keep from the viewport edges, in pixels.
339
+ - `arrowPadding?` (`number`): Space to keep between the arrow and the popup's corners, in pixels.
340
+ - `anchor?` (`string | Anchor | null`): Positions the popup against this instead of its trigger: an element, a CSS selector, a point like `{ x, y }`, or anything with `getBoundingClientRect()`. It's read on every check, so it can move. A controller's `open({ anchor })` wins for that open.
341
+ - `container?` (`DocumentFragment | Element | null`): Renders the popup into this element instead of in place, like a container inside a shadow root or an iframe. On web components, a CSS selector. Nested popups stay inside their parent.
342
+ - `keepMounted?` (`boolean`): Whether the card stays in the page, hidden, while closed. For animation libraries that drive the exit from state.
343
+
344
+ ### HoverCardArrow
345
+
346
+ Points at the link from the side the card landed on. `<ui-hover-card-arrow>` is positioned on the content's edge.
347
+
348
+ ### State
349
+
350
+ The same state shows as data attributes on each element.
351
+
352
+ `HoverCardTrigger`:
353
+
354
+ - `open` (`boolean`): Whether the card is open from this trigger.
355
+
356
+ `HoverCardContent`:
357
+
358
+ - `open` (`boolean`): Whether the card is open. False while it animates out.
359
+ - `payload` (`Payload | undefined`): The payload of the last open, from the trigger that opened it or a controller, typed as the controller's `Payload`.
360
+
361
+ `HoverCardArrow`:
362
+
363
+ - `open` (`boolean`): Whether the card is open. False as soon as it starts closing, while it still animates out.
364
+
365
+ ### Reasons
366
+
367
+ `event.detail.reason` says why the card opened or closed.
368
+
369
+ - `trigger-hover` (`PointerEvent`): The pointer rested on a trigger, or left it, with hover opening.
370
+ - `trigger-focus` (`FocusEvent`): Keyboard focus reached a trigger that opens on focus, like a tooltip's.
371
+ - `trigger-press` (`MouseEvent | KeyboardEvent | TouchEvent`): Click, tap, Enter or Space on the part that opens, closes or toggles. Arrow keys that open a menu or submenu count too. A tap on a combobox's input that opens a sheet reports its `touchend`.
372
+ - `focus-out` (`KeyboardEvent | FocusEvent`): Focus left the layer, or Tab moved it out.
373
+ - `escape-key` (`KeyboardEvent`): Escape, or a submenu's close key (ArrowLeft in left-to-right layouts).
374
+ - `close-press` (`MouseEvent | KeyboardEvent | SubmitEvent`): A Close part was pressed, or a form with `method="dialog"` was submitted.
375
+ - `outside-press` (`MouseEvent`): A press outside the layer.
376
+ - `window-blur` (`FocusEvent`): The window lost focus.
377
+ - `back` (`Event`): Going back: the Android back button or gesture, or Backspace in an empty command input, which returns to the previous page.
378
+ - `imperative` (`none`): A controller or `api` call, or a property set on a web component.
379
+
380
+ For a payload change, it says what opened the card or took it over.
381
+
382
+ - `trigger-hover` (`PointerEvent`): The pointer rested on a trigger, or left it, with hover opening.
383
+ - `trigger-focus` (`FocusEvent`): Keyboard focus reached a trigger that opens on focus, like a tooltip's.
384
+ - `trigger-press` (`MouseEvent | KeyboardEvent | TouchEvent`): Click, tap, Enter or Space on the part that opens, closes or toggles. Arrow keys that open a menu or submenu count too. A tap on a combobox's input that opens a sheet reports its `touchend`.
385
+ - `imperative` (`none`): A controller or `api` call, or a property set on a web component.
386
+
387
+ ### Controller
388
+
389
+ Create one with `createHoverCardController<Payload>()` from `@ui-sdk/web/hover-card` and assign it to the root
390
+ element's `controller` property. The root element's `api` property has the same methods, and its `open` property reads
391
+ and sets whether the card is open. `Payload` is the type of the data triggers and `open()` pass.
392
+
393
+ Every write method takes an optional `{ reason, event }`, passed to `openchange`.
394
+
395
+ - `isOpen()` (`() => boolean`): Whether it's open. False as soon as it starts closing, while it still animates out.
396
+ - `setOpen(open, options?)` (`(open: boolean, options?: PopupChangeOptions<HoverCardOpenChangeReason> | undefined) => boolean`): Opens or closes it. Returns false when the change was canceled or it was already open or closed.
397
+ - `open(options?)` (`(options?: (PopupChangeOptions<HoverCardPayloadChangeReason> & { payload?: Payload | undefined; anchor?: Anchor | undefined; signal?: AbortSignal | undefined; }) | undefined) => Promise<...>`): Opens it, and resolves once it closes, with why, how and any return value. Resolves exactly once and never rejects: on the next close from any source, when `signal` aborts, or with reason `"unmount"` when the component leaves the page.
398
+ - `close(options?)` (`(options?: (PopupChangeOptions<HoverCardOpenChangeReason> & { returnValue?: string | undefined; }) | undefined) => boolean`): Closes it. `returnValue` is passed to the promise `open()` returned. Returns false when the close was canceled or it was already closed.
399
+ - `toggle(options?)` (`(options?: PopupChangeOptions<HoverCardOpenChangeReason> | undefined) => boolean`): Opens it when it's closed, and closes it when it's open. Returns false when the change was canceled.
400
+ - `getPayload()` (`() => Payload | undefined`): The payload of the last open, from a controller or the trigger that opened it.
401
+ - `focus()` (`() => void`): Moves focus to the trigger that opened it last, or the first trigger.
402
+
403
+ ### Events
404
+
405
+ Events fire on their own element and don't bubble, with the new state in `event.detail.value` and the `reason` and `event` beside it. Calling `preventDefault()` on `openchange` cancels the change.
406
+
407
+ | Member | On | Description |
408
+ | -------------------------- | ----------------------- | ------------------------------------------------------------------------------- |
409
+ | `open` property, attribute | `ui-hover-card` | Whether the card is open. The attribute sets where it starts, and is live |
410
+ | `api` property | `ui-hover-card` | The [controller](#controller) |
411
+ | `controller` property | `ui-hover-card` | A controller from `createHoverCardController()`, to drive it from code |
412
+ | `openchange` event | `ui-hover-card` | `detail: { value: open, reason, event }` |
413
+ | `openchangecomplete` event | `ui-hover-card` | `detail: { value: open }`, after the animation |
414
+ | `payloadchange` event | `ui-hover-card` | `detail: { value: payload, reason, event }`, when the content's payload changes |
415
+ | `payload` property | `ui-hover-card-trigger` | Data for the content, read when the trigger connects |
416
+ | `for` attribute | `ui-hover-card-trigger` | The `id` of a card the trigger opens from outside it |
417
+
418
+ ## Accessibility
419
+
420
+ The trigger stays a plain link, and the card is a preview beside it, not a dialog. Every line below is an automated test.
421
+
422
+ ### Keyboard
423
+
424
+ | Key | Does |
425
+ | ------ | ---------------------------------------------------------------------------- |
426
+ | Tab | On the link, opens the card after `delay`; with the card open, moves into it |
427
+ | Enter | Follows the link |
428
+ | Escape | Closes the card and leaves focus on the link |
429
+
430
+ Keyboard focus opens the card after the same `delay` as the pointer, so tabbing through a page of links doesn't flash a card at every stop. Focus leaving the card closes it.
431
+
432
+ Touch screens have no hover, so a tap follows the link without opening the card. Anything in the card should be on the page the link goes to.
433
+
434
+ ### Tested Behavior
435
+
436
+ **Pointer**
437
+
438
+ - Resting the pointer on the link opens the card.
439
+ - The card waits for its delay before opening.
440
+ - Moving the pointer away closes the card after its close delay.
441
+ - Moving the pointer into the card keeps it open.
442
+ - Opening on hover leaves focus where it was.
443
+ - Clicking the link follows it.
444
+
445
+ **Keyboard**
446
+
447
+ - Keyboard focus on the link opens the card after the delay.
448
+ - Escape closes the card and leaves focus on the link.
449
+ - Enter follows the link.
450
+
451
+ **Positioning**
452
+
453
+ - The card opens below the link.
454
+ - The card opens on the requested side.
455
+
456
+ **Animation**
457
+
458
+ - The card animates in from its starting style.
459
+ - The card stays in the page while it animates out.
460
+
461
+ **Focus, touch and reasons**
462
+
463
+ - A click that focuses the link doesn't open the card from focus.
464
+ - Leaving the link before the delay keeps keyboard focus from opening it later.
465
+ - A tap follows the link without opening the card.
466
+ - Changes report why the card opened and closed.
467
+
468
+ Runs in React, Vue and web components.
469
+
470
+ Also tested:
471
+
472
+ **Enhancements**
473
+
474
+ - Tab from the link moves into the open card.
475
+ - Shift+Tab from the card returns to the link.
476
+ - Tab out of the card moves on past the link and closes it.
477
+ - Escape inside the card closes it and returns focus to the link.
478
+ - The card stays open while focus is in it, even when the pointer leaves.
479
+
480
+ Runs in React, Vue and web components.
481
+
482
+ Screen readers hear the same thing in each tested framework, recorded by a virtual screen reader:
483
+
484
+ - Announcements while tabbing into the card and out.
485
+
486
+ Runs in React, Vue and web components.