@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,1136 @@
1
+ # Date Picker
2
+
3
+ Type a date or choose one from a calendar, with support for ranges and forms.
4
+
5
+ Date Picker combines a text field with [Calendar](./calendar.md). People can type a date in their language or choose it from the popup. Your application receives an ISO date string either way.
6
+
7
+ ```ts title="basic.ts"
8
+ import "@ui-sdk/web/date-picker"
9
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
10
+
11
+ function mount(root: HTMLElement) {
12
+ root.innerHTML = `
13
+ <ui-date-picker default-value="2026-10-16">
14
+ <div data-slot="row">
15
+ <ui-date-picker-input><input aria-label="Due date" /></ui-date-picker-input>
16
+ <ui-date-picker-trigger>
17
+ <button data-variant="ghost">
18
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
19
+ </button>
20
+ </ui-date-picker-trigger>
21
+ </div>
22
+ <ui-date-picker-hint></ui-date-picker-hint>
23
+ <ui-date-picker-content hidden>
24
+ <div data-slot="row">
25
+ <ui-calendar-previous>
26
+ <button data-variant="ghost">
27
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
28
+ </button>
29
+ </ui-calendar-previous>
30
+ <ui-calendar-heading></ui-calendar-heading>
31
+ <ui-calendar-next>
32
+ <button data-variant="ghost">
33
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
34
+ </button>
35
+ </ui-calendar-next>
36
+ </div>
37
+ <ui-calendar-grid>
38
+ <ui-calendar-weekdays>
39
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
40
+ </ui-calendar-weekdays>
41
+ <ui-calendar-weeks>
42
+ <template><ui-calendar-day></ui-calendar-day></template>
43
+ </ui-calendar-weeks>
44
+ </ui-calendar-grid>
45
+ </ui-date-picker-content>
46
+ </ui-date-picker>
47
+ `
48
+ }
49
+
50
+ export { mount }
51
+ ```
52
+
53
+ Type a date and press Enter, or open the calendar and choose a day. The field formats the date when you commit it.
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ npm install @ui-sdk/web @ui-sdk/core
59
+ ```
60
+
61
+ Import the component to register its elements, the Calendar elements included. The import is safe on the server.
62
+
63
+ ```ts
64
+ import "@ui-sdk/web/date-picker"
65
+ ```
66
+
67
+ ## Composition
68
+
69
+ Use the following composition to build a `ui-date-picker`:
70
+
71
+ ```text
72
+ ui-date-picker
73
+ ├── ui-date-picker-input
74
+ │ └── input
75
+ ├── ui-date-picker-trigger
76
+ │ └── button
77
+ ├── ui-date-picker-hint
78
+ └── ui-date-picker-content
79
+ ```
80
+
81
+ The input accepts a date, the trigger opens the calendar, and the hint describes the expected format. An empty content part renders a calendar for you.
82
+
83
+ Every [Calendar part](./calendar.md#composition) also works inside `ui-date-picker-content` and is defined by the Date Picker import. Write those parts out when you need to add styles, change the layout, or include custom day content.
84
+
85
+ An empty `ui-date-picker` renders the input, trigger, and calendar too. In range mode, it renders an input for each end. An input element wraps your native `<input>` or creates one. The trigger, Clear, and presets wrap a `<button>` or create one around their content.
86
+
87
+ ## Usage
88
+
89
+ Import the parts and put them together:
90
+
91
+ ```html
92
+ <script type="module">
93
+ import "@ui-sdk/web/date-picker"
94
+ </script>
95
+
96
+ <ui-date-picker default-value="2026-10-16">
97
+ <ui-date-picker-input><input aria-label="Due date" /></ui-date-picker-input>
98
+ <ui-date-picker-trigger><button>Choose date</button></ui-date-picker-trigger>
99
+ <ui-date-picker-hint></ui-date-picker-hint>
100
+ <ui-date-picker-content hidden></ui-date-picker-content>
101
+ </ui-date-picker>
102
+ ```
103
+
104
+ ## Values
105
+
106
+ Dates are strings such as `"2026-10-16"`, with no time or time zone attached. No date library is needed.
107
+
108
+ | Mode | Value |
109
+ | -------------------- | ----------------------------------------------------- |
110
+ | `"single"` (default) | A date string or `null`. |
111
+ | `"range"` | `[start, end]` or `null`, with an input for each end. |
112
+
113
+ ## Typing a Date
114
+
115
+ The input parses text when you press Enter or leave the field. It uses the locale’s date order, such as `10/16/2026` in American English or `16.10.2026` in German. It also accepts ISO dates, digits without separators, two-digit years, and month names in the locale or English. Dates without a year use the current year.
116
+
117
+ The field formats a valid date after it is committed, leaving your typing alone until then. Invalid text stays visible and sets `aria-invalid` and `data-invalid`; the previous value stays unchanged. Until the text is a date again, or empty, the input reports "Enter a valid date." as its validation message, so its form won't submit. The hint’s state includes an example date you can show alongside the field.
118
+
119
+ ```ts title="invalid.ts"
120
+ import { pageLocale } from "@ui-sdk/core"
121
+ import { datePattern } from "@ui-sdk/core/date"
122
+ import "@ui-sdk/web/date-picker"
123
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
124
+
125
+ function mount(root: HTMLElement) {
126
+ const { example } = datePattern(pageLocale(root) ?? "en-US")
127
+ root.innerHTML = `
128
+ <ui-date-picker default-value="2026-10-16">
129
+ <div data-slot="row">
130
+ <ui-date-picker-input><input aria-label="Due date" /></ui-date-picker-input>
131
+ <ui-date-picker-trigger>
132
+ <button data-variant="ghost">
133
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
134
+ </button>
135
+ </ui-date-picker-trigger>
136
+ </div>
137
+ <ui-date-picker-content hidden>
138
+ <div data-slot="row">
139
+ <ui-calendar-previous>
140
+ <button data-variant="ghost">
141
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
142
+ </button>
143
+ </ui-calendar-previous>
144
+ <ui-calendar-heading></ui-calendar-heading>
145
+ <ui-calendar-next>
146
+ <button data-variant="ghost">
147
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
148
+ </button>
149
+ </ui-calendar-next>
150
+ </div>
151
+ <ui-calendar-grid>
152
+ <ui-calendar-weekdays>
153
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
154
+ </ui-calendar-weekdays>
155
+ <ui-calendar-weeks>
156
+ <template><ui-calendar-day></ui-calendar-day></template>
157
+ </ui-calendar-weeks>
158
+ </ui-calendar-grid>
159
+ </ui-date-picker-content>
160
+ <ui-date-picker-hint>Like ${example}</ui-date-picker-hint>
161
+ </ui-date-picker>
162
+ `
163
+ }
164
+
165
+ export { mount }
166
+ ```
167
+
168
+ Type not a date and press Enter to mark the field invalid. Replace it with 10/18/2026 to clear the invalid state.
169
+
170
+ ## Range
171
+
172
+ `mode="range"` uses one input for the start and another with `end` for the end. The calendar stays open after the start is picked and closes once both dates are chosen. A typed end before the start is invalid.
173
+
174
+ The range is `null` until both ends are valid. Clearing either input clears the complete value while leaving the other input’s date visible.
175
+
176
+ For two months side by side, set `months="2"` and add a second `ui-calendar-grid` with `offset="1"`. `page-by="page"` moves both months together.
177
+
178
+ ```ts title="range.ts"
179
+ import "@ui-sdk/web/date-picker"
180
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
181
+
182
+ let count = 0
183
+
184
+ function mount(root: HTMLElement) {
185
+ const id = `date-picker-range-${++count}`
186
+ root.innerHTML = `
187
+ <ui-date-picker mode="range" months="2" month-format="short" default-value="2026-10-12,2026-10-16">
188
+ <div data-slot="row" id="${id}-field">
189
+ <ui-date-picker-input><input aria-label="Check in" placeholder="Check in" /></ui-date-picker-input>
190
+ <span data-slot="hint">–</span>
191
+ <ui-date-picker-input end><input aria-label="Check out" placeholder="Check out" /></ui-date-picker-input>
192
+ <ui-date-picker-trigger>
193
+ <button data-variant="ghost">
194
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
195
+ </button>
196
+ </ui-date-picker-trigger>
197
+ </div>
198
+ <ui-date-picker-content hidden anchor="#${id}-field" align="center">
199
+ <div data-slot="row">
200
+ <ui-calendar-previous>
201
+ <button data-variant="ghost">
202
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
203
+ </button>
204
+ </ui-calendar-previous>
205
+ <ui-calendar-heading></ui-calendar-heading>
206
+ <ui-calendar-next>
207
+ <button data-variant="ghost">
208
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
209
+ </button>
210
+ </ui-calendar-next>
211
+ </div>
212
+ <div data-slot="row">
213
+ <ui-calendar-grid>
214
+ <ui-calendar-weekdays>
215
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
216
+ </ui-calendar-weekdays>
217
+ <ui-calendar-weeks>
218
+ <template><ui-calendar-day></ui-calendar-day></template>
219
+ </ui-calendar-weeks>
220
+ </ui-calendar-grid>
221
+ <ui-calendar-grid offset="1">
222
+ <ui-calendar-weekdays>
223
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
224
+ </ui-calendar-weekdays>
225
+ <ui-calendar-weeks>
226
+ <template><ui-calendar-day></ui-calendar-day></template>
227
+ </ui-calendar-weeks>
228
+ </ui-calendar-grid>
229
+ </div>
230
+ </ui-date-picker-content>
231
+ </ui-date-picker>
232
+ `
233
+ }
234
+
235
+ export { mount }
236
+ ```
237
+
238
+ Choose October 20, then October 23. The calendar stays open after the first date and closes after the second.
239
+
240
+ ## Presets
241
+
242
+ `ui-date-picker-preset` chooses its `value` and closes the popup. It exposes `aria-pressed` and `data-selected` when that value matches the selection. Your application calculates relative dates, such as the last seven days. In markup, a range preset holds two comma-separated ISO dates.
243
+
244
+ ```ts title="presets.ts"
245
+ import "@ui-sdk/web/date-picker"
246
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
247
+
248
+ function mount(root: HTMLElement) {
249
+ root.innerHTML = `
250
+ <ui-date-picker mode="range" today="2026-10-16">
251
+ <div data-slot="row">
252
+ <ui-date-picker-input><input aria-label="Check in" placeholder="Check in" /></ui-date-picker-input>
253
+ <span data-slot="hint">–</span>
254
+ <ui-date-picker-input end><input aria-label="Check out" placeholder="Check out" /></ui-date-picker-input>
255
+ <ui-date-picker-trigger>
256
+ <button data-variant="ghost">
257
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
258
+ </button>
259
+ </ui-date-picker-trigger>
260
+ </div>
261
+ <ui-date-picker-content hidden>
262
+ <div data-slot="row">
263
+ <ui-calendar-previous>
264
+ <button data-variant="ghost">
265
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
266
+ </button>
267
+ </ui-calendar-previous>
268
+ <ui-calendar-heading></ui-calendar-heading>
269
+ <ui-calendar-next>
270
+ <button data-variant="ghost">
271
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
272
+ </button>
273
+ </ui-calendar-next>
274
+ </div>
275
+ <ui-calendar-grid>
276
+ <ui-calendar-weekdays>
277
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
278
+ </ui-calendar-weekdays>
279
+ <ui-calendar-weeks>
280
+ <template><ui-calendar-day></ui-calendar-day></template>
281
+ </ui-calendar-weeks>
282
+ </ui-calendar-grid>
283
+ <div data-slot="row">
284
+ <ui-date-picker-preset value="2026-10-10,2026-10-16"><button data-variant="ghost">Last 7 Days</button></ui-date-picker-preset>
285
+ <ui-date-picker-preset value="2026-09-17,2026-10-16"><button data-variant="ghost">Last 30 Days</button></ui-date-picker-preset>
286
+ <ui-date-picker-preset value="2026-10-01,2026-10-31"><button data-variant="ghost">This Month</button></ui-date-picker-preset>
287
+ </div>
288
+ </ui-date-picker-content>
289
+ </ui-date-picker>
290
+ `
291
+ }
292
+
293
+ export { mount }
294
+ ```
295
+
296
+ Open the calendar and choose Last 7 Days. Reopen it to see the selected preset.
297
+
298
+ ## Min, Max and Unavailable Dates
299
+
300
+ `min`, `max`, and `unavailable` apply to typing, calendar selection, presets, and the controller. A date outside those rules is invalid when typed, a preset that holds one is disabled, and the controller refuses it. The controller also refuses a value while the picker is disabled or read-only. [Calendar](./calendar.md#unavailable-dates) explains the available matchers and how unavailable dates differ from the bounds.
301
+
302
+ For ranges, `min-days` and `max-days` count both endpoints. `allow-unavailable` permits unavailable dates between them, but never as an endpoint. See [Range Limits](./calendar.md#range-limits).
303
+
304
+ ```ts title="min-max.ts"
305
+ import "@ui-sdk/web/date-picker"
306
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
307
+
308
+ function mount(root: HTMLElement) {
309
+ root.innerHTML = `
310
+ <ui-date-picker min="2026-10-05" max="2026-11-20" default-value="2026-10-16">
311
+ <div data-slot="row">
312
+ <ui-date-picker-input><input aria-label="Delivery date" /></ui-date-picker-input>
313
+ <ui-date-picker-trigger>
314
+ <button data-variant="ghost">
315
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
316
+ </button>
317
+ </ui-date-picker-trigger>
318
+ </div>
319
+ <ui-date-picker-hint></ui-date-picker-hint>
320
+ <ui-date-picker-content hidden>
321
+ <div data-slot="row">
322
+ <ui-calendar-previous>
323
+ <button data-variant="ghost">
324
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
325
+ </button>
326
+ </ui-calendar-previous>
327
+ <ui-calendar-heading></ui-calendar-heading>
328
+ <ui-calendar-next>
329
+ <button data-variant="ghost">
330
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
331
+ </button>
332
+ </ui-calendar-next>
333
+ </div>
334
+ <ui-calendar-grid>
335
+ <ui-calendar-weekdays>
336
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
337
+ </ui-calendar-weekdays>
338
+ <ui-calendar-weeks>
339
+ <template><ui-calendar-day></ui-calendar-day></template>
340
+ </ui-calendar-weeks>
341
+ </ui-calendar-grid>
342
+ </ui-date-picker-content>
343
+ </ui-date-picker>
344
+ `
345
+ root.querySelector("ui-date-picker")!.unavailable = [{ weekday: [0, 6] }]
346
+ }
347
+
348
+ export { mount }
349
+ ```
350
+
351
+ Try typing 11/21/2026, past the last allowed date, then 10/17/2026, a Saturday. Both are invalid and can't be picked; 10/19/2026 is accepted.
352
+
353
+ ## Language
354
+
355
+ `locale` sets the input’s format, hint, month names, and date labels. If you omit it, Date Picker reads the surrounding page’s `lang` after it mounts, with the browser’s language as a fallback. The initial server and client render use English, so they always match. Date strings remain Gregorian ISO dates.
356
+
357
+ The trigger, popup, and calendar navigation have English accessible labels by default. Pass `aria-label` to translate those controls too.
358
+
359
+ Calendar’s `week-starts-on`, `weekday-format`, `fixed-weeks`, `show-outside-days`, and `time-zone` options apply here too. [Calendar](./calendar.md#language) shows these options without the popup.
360
+
361
+ ```ts title="locale.ts"
362
+ import "@ui-sdk/web/date-picker"
363
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
364
+
365
+ function mount(root: HTMLElement) {
366
+ root.innerHTML = `
367
+ <div lang="de">
368
+ <ui-date-picker default-value="2026-10-16">
369
+ <div data-slot="row">
370
+ <ui-date-picker-input><input aria-label="Fälligkeitsdatum" /></ui-date-picker-input>
371
+ <ui-date-picker-trigger>
372
+ <button data-variant="ghost">
373
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
374
+ </button>
375
+ </ui-date-picker-trigger>
376
+ </div>
377
+ <ui-date-picker-hint></ui-date-picker-hint>
378
+ <ui-date-picker-content hidden>
379
+ <div data-slot="row">
380
+ <ui-calendar-previous>
381
+ <button data-variant="ghost">
382
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
383
+ </button>
384
+ </ui-calendar-previous>
385
+ <ui-calendar-heading></ui-calendar-heading>
386
+ <ui-calendar-next>
387
+ <button data-variant="ghost">
388
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
389
+ </button>
390
+ </ui-calendar-next>
391
+ </div>
392
+ <ui-calendar-grid>
393
+ <ui-calendar-weekdays>
394
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
395
+ </ui-calendar-weekdays>
396
+ <ui-calendar-weeks>
397
+ <template><ui-calendar-day></ui-calendar-day></template>
398
+ </ui-calendar-weeks>
399
+ </ui-calendar-grid>
400
+ </ui-date-picker-content>
401
+ </ui-date-picker>
402
+ </div>
403
+ `
404
+ }
405
+
406
+ export { mount }
407
+ ```
408
+
409
+ Enter 3.12.2026 and press Enter. The field, format hint, and calendar use German dates.
410
+
411
+ ## Clear
412
+
413
+ `ui-date-picker-clear` clears the value and focuses the input. It gets `data-empty` when there is nothing to clear. Emptying a single-date input clears its value too.
414
+
415
+ ```ts title="clear.ts"
416
+ import "@ui-sdk/web/date-picker"
417
+ import { Calendar, ChevronLeft, ChevronRight, createElement, X } from "lucide"
418
+
419
+ function mount(root: HTMLElement) {
420
+ root.innerHTML = `
421
+ <ui-date-picker default-value="2026-10-16">
422
+ <div data-slot="row">
423
+ <ui-date-picker-input><input aria-label="Due date" /></ui-date-picker-input>
424
+ <ui-date-picker-clear>
425
+ <button data-variant="ghost" aria-label="Clear date">
426
+ ${createElement(X, { "aria-hidden": "true" }).outerHTML}
427
+ </button>
428
+ </ui-date-picker-clear>
429
+ <ui-date-picker-trigger>
430
+ <button data-variant="ghost">
431
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
432
+ </button>
433
+ </ui-date-picker-trigger>
434
+ </div>
435
+ <ui-date-picker-hint></ui-date-picker-hint>
436
+ <ui-date-picker-content hidden>
437
+ <div data-slot="row">
438
+ <ui-calendar-previous>
439
+ <button data-variant="ghost">
440
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
441
+ </button>
442
+ </ui-calendar-previous>
443
+ <ui-calendar-heading></ui-calendar-heading>
444
+ <ui-calendar-next>
445
+ <button data-variant="ghost">
446
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
447
+ </button>
448
+ </ui-calendar-next>
449
+ </div>
450
+ <ui-calendar-grid>
451
+ <ui-calendar-weekdays>
452
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
453
+ </ui-calendar-weekdays>
454
+ <ui-calendar-weeks>
455
+ <template><ui-calendar-day></ui-calendar-day></template>
456
+ </ui-calendar-weeks>
457
+ </ui-calendar-grid>
458
+ </ui-date-picker-content>
459
+ </ui-date-picker>
460
+ `
461
+ }
462
+
463
+ export { mount }
464
+ ```
465
+
466
+ Press Clear to empty the value and focus the input. The Clear button disappears until there is a value again.
467
+
468
+ ## Disabled and Read Only
469
+
470
+ `disabled` prevents typing, opening, and selection. `read-only` lets people open the calendar and inspect its dates without changing the value.
471
+
472
+ ```html
473
+ <ui-date-picker disabled default-value="2026-10-16"></ui-date-picker>
474
+ <ui-date-picker read-only default-value="2026-10-16"></ui-date-picker>
475
+ ```
476
+
477
+ ## Staying Open
478
+
479
+ Set `close-on-select` to `false` to keep the calendar open after choosing a date, completing a range, or pressing a preset.
480
+
481
+ ```html
482
+ <ui-date-picker close-on-select="false"></ui-date-picker>
483
+ ```
484
+
485
+ ## Keep It Open Until Both Dates Are Picked
486
+
487
+ Set `dismissible` to `false` while a choice is incomplete. Escape, an outside press, or the system back gesture then leave the popup open. `dismissattempt` reports intentional attempts, so you can explain what is missing. Focus leaving is refused quietly. The trigger and imperative controls can still close it.
488
+
489
+ ```ts title="dismissible.ts"
490
+ import "@ui-sdk/web/date-picker"
491
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
492
+
493
+ function mount(root: HTMLElement) {
494
+ root.innerHTML = `
495
+ <ui-date-picker mode="range" default-month="2026-10" dismissible="false">
496
+ <div data-slot="row">
497
+ <ui-date-picker-input><input aria-label="Check in" placeholder="Check in" /></ui-date-picker-input>
498
+ <span data-slot="hint">–</span>
499
+ <ui-date-picker-input end><input aria-label="Check out" placeholder="Check out" /></ui-date-picker-input>
500
+ <ui-date-picker-trigger>
501
+ <button data-variant="ghost">
502
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
503
+ </button>
504
+ </ui-date-picker-trigger>
505
+ </div>
506
+ <ui-date-picker-content hidden>
507
+ <div data-slot="row">
508
+ <ui-calendar-previous>
509
+ <button data-variant="ghost">
510
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
511
+ </button>
512
+ </ui-calendar-previous>
513
+ <ui-calendar-heading></ui-calendar-heading>
514
+ <ui-calendar-next>
515
+ <button data-variant="ghost">
516
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
517
+ </button>
518
+ </ui-calendar-next>
519
+ </div>
520
+ <ui-calendar-grid>
521
+ <ui-calendar-weekdays>
522
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
523
+ </ui-calendar-weekdays>
524
+ <ui-calendar-weeks>
525
+ <template><ui-calendar-day></ui-calendar-day></template>
526
+ </ui-calendar-weeks>
527
+ </ui-calendar-grid>
528
+ <p data-slot="hint" role="alert" hidden>Pick a check-out date to finish your stay.</p>
529
+ </ui-date-picker-content>
530
+ </ui-date-picker>
531
+ `
532
+ const picker = root.querySelector("ui-date-picker")!
533
+ const alert = root.querySelector<HTMLElement>('[role="alert"]')!
534
+ picker.addEventListener("valuechange", (event) => {
535
+ alert.hidden = true
536
+ if (event.detail.value === null) {
537
+ picker.setAttribute("dismissible", "false")
538
+ } else {
539
+ picker.removeAttribute("dismissible")
540
+ }
541
+ })
542
+ picker.addEventListener("dismissattempt", () => (alert.hidden = false))
543
+ picker.addEventListener("openchange", (event) => {
544
+ if (event.detail.value) {
545
+ alert.hidden = true
546
+ }
547
+ })
548
+ }
549
+
550
+ export { mount }
551
+ ```
552
+
553
+ Choose a check-in date, then press outside the calendar. The message asks for a check-out date before the popup can be dismissed.
554
+
555
+ ## Popup and Presentation
556
+
557
+ `ui-date-picker-content` opens below the input by default. Position it with `side`, `align`, and offsets, or provide a custom `anchor`. `container` changes where it renders; `keep-mounted` retains it while closed, and `final-focus` controls focus after it closes. [Popups](../popups.md) covers these shared options.
558
+
559
+ `presentation="auto"` uses a sheet on small touch screens and a popover elsewhere. `presentation="sheet"` always uses a sheet. Style the two layouts using `data-presentation`.
560
+
561
+ ```ts title="popup.ts"
562
+ import "@ui-sdk/web/date-picker"
563
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
564
+ import { log } from "./log"
565
+
566
+ let count = 0
567
+
568
+ function mount(root: HTMLElement) {
569
+ const id = `date-picker-popup-${++count}`
570
+ root.innerHTML = `
571
+ <div data-slot="stack">
572
+ <ui-date-picker default-open="false" presentation="auto" container="#${id}-container">
573
+ <div data-slot="row" id="${id}-anchor">
574
+ <ui-date-picker-input><input aria-label="Due date" /></ui-date-picker-input>
575
+ <ui-date-picker-trigger>
576
+ <button data-variant="ghost">
577
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
578
+ </button>
579
+ </ui-date-picker-trigger>
580
+ </div>
581
+ <ui-date-picker-hint></ui-date-picker-hint>
582
+ <ui-date-picker-content hidden anchor="#${id}-anchor" side-offset="6" collision-padding="16" keep-mounted>
583
+ <div data-slot="row">
584
+ <ui-calendar-previous>
585
+ <button data-variant="ghost">
586
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
587
+ </button>
588
+ </ui-calendar-previous>
589
+ <ui-calendar-heading></ui-calendar-heading>
590
+ <ui-calendar-next>
591
+ <button data-variant="ghost">
592
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
593
+ </button>
594
+ </ui-calendar-next>
595
+ </div>
596
+ <ui-calendar-grid>
597
+ <ui-calendar-weekdays>
598
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
599
+ </ui-calendar-weekdays>
600
+ <ui-calendar-weeks>
601
+ <template><ui-calendar-day></ui-calendar-day></template>
602
+ </ui-calendar-weeks>
603
+ </ui-calendar-grid>
604
+ </ui-date-picker-content>
605
+ </ui-date-picker>
606
+ <div id="${id}-container"></div>
607
+ </div>
608
+ `
609
+ const picker = root.querySelector("ui-date-picker")!
610
+ picker.addEventListener("openchange", (event) => {
611
+ log(
612
+ root,
613
+ `${event.detail.value ? "Opened" : "Closed"} (${event.detail.reason})`
614
+ )
615
+ })
616
+ picker.addEventListener("openchangecomplete", (event) => {
617
+ if (!event.detail.value) {
618
+ log(root, "Finished closing")
619
+ }
620
+ })
621
+ picker.addEventListener("monthchange", (event) => {
622
+ log(root, `Showing ${event.detail.value} (${event.detail.reason})`)
623
+ })
624
+ }
625
+
626
+ export { mount }
627
+ ```
628
+
629
+ Open the calendar. On a small touch screen it opens as a sheet, and the console logs each open, close and month change.
630
+
631
+ ## Forms
632
+
633
+ `name` submits an ISO date. In range mode, use `start-name` and `end-name` for separate fields, or `name` to submit both ends under the same name. `required` blocks an empty submission, text that isn't a date blocks one too, a form reset restores `default-value`, and a disabled `fieldset` disables the picker. Form participation begins once the custom elements are defined.
634
+
635
+ In a [Field](./field.md), the field connects the label, description, and errors to the input, and shows an error for an empty required date or text that isn't a date. Its `name` is used when the picker has none, and a disabled field disables the picker.
636
+
637
+ ```ts title="form.ts"
638
+ import "@ui-sdk/web/date-picker"
639
+ import "@ui-sdk/web/field"
640
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
641
+ import { log } from "./log"
642
+
643
+ function mount(root: HTMLElement) {
644
+ root.innerHTML = `
645
+ <form data-slot="stack">
646
+ <ui-field name="due">
647
+ <ui-field-label>Due date</ui-field-label>
648
+ <ui-date-picker required>
649
+ <div data-slot="row">
650
+ <ui-date-picker-input><input /></ui-date-picker-input>
651
+ <ui-date-picker-trigger>
652
+ <button data-variant="ghost">
653
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
654
+ </button>
655
+ </ui-date-picker-trigger>
656
+ </div>
657
+ <ui-date-picker-content hidden>
658
+ <div data-slot="row">
659
+ <ui-calendar-previous>
660
+ <button data-variant="ghost">
661
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
662
+ </button>
663
+ </ui-calendar-previous>
664
+ <ui-calendar-heading></ui-calendar-heading>
665
+ <ui-calendar-next>
666
+ <button data-variant="ghost">
667
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
668
+ </button>
669
+ </ui-calendar-next>
670
+ </div>
671
+ <ui-calendar-grid>
672
+ <ui-calendar-weekdays>
673
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
674
+ </ui-calendar-weekdays>
675
+ <ui-calendar-weeks>
676
+ <template><ui-calendar-day></ui-calendar-day></template>
677
+ </ui-calendar-weeks>
678
+ </ui-calendar-grid>
679
+ </ui-date-picker-content>
680
+ </ui-date-picker>
681
+ <ui-field-description>When the invoice is due.</ui-field-description>
682
+ <div>
683
+ <ui-field-error match="valueMissing">Choose a due date.</ui-field-error>
684
+ </div>
685
+ </ui-field>
686
+ <button type="submit">Submit</button>
687
+ </form>
688
+ `
689
+ const form = root.querySelector("form")!
690
+ form.addEventListener("submit", (event) => {
691
+ event.preventDefault()
692
+ log(root, `Submitted due=${new FormData(form).get("due")}`)
693
+ })
694
+ }
695
+
696
+ export { mount }
697
+ ```
698
+
699
+ Press Submit with an empty field to see the inline error, then choose a date and submit. The console logs the ISO date.
700
+
701
+ ## Controlled
702
+
703
+ The selected value, displayed month, and open state are separate. `value` uses the shape for the chosen mode; `month` is the first displayed month, such as `"2026-10"`; `open` is a boolean.
704
+
705
+ Read and write the element’s `value`, `month`, and `open` properties. Listen for `valuechange`, `monthchange`, and `openchange`, and call `event.preventDefault()` to reject a change. Use `default-value`, `default-month`, and `default-open` for initial state. [State and Events](../state-and-events.md) covers the binding pattern, and the [reason tables](#reasons) list Date Picker’s reasons.
706
+
707
+ ```ts title="controlled.ts"
708
+ import "@ui-sdk/web/date-picker"
709
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
710
+ import { log } from "./log"
711
+
712
+ function mount(root: HTMLElement) {
713
+ root.innerHTML = `
714
+ <ui-date-picker default-value="2026-10-16">
715
+ <div data-slot="row">
716
+ <ui-date-picker-input><input aria-label="Due date" /></ui-date-picker-input>
717
+ <ui-date-picker-trigger>
718
+ <button data-variant="ghost">
719
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
720
+ </button>
721
+ </ui-date-picker-trigger>
722
+ </div>
723
+ <ui-date-picker-hint></ui-date-picker-hint>
724
+ <ui-date-picker-content hidden>
725
+ <div data-slot="row">
726
+ <ui-calendar-previous>
727
+ <button data-variant="ghost">
728
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
729
+ </button>
730
+ </ui-calendar-previous>
731
+ <ui-calendar-heading></ui-calendar-heading>
732
+ <ui-calendar-next>
733
+ <button data-variant="ghost">
734
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
735
+ </button>
736
+ </ui-calendar-next>
737
+ </div>
738
+ <ui-calendar-grid>
739
+ <ui-calendar-weekdays>
740
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
741
+ </ui-calendar-weekdays>
742
+ <ui-calendar-weeks>
743
+ <template><ui-calendar-day></ui-calendar-day></template>
744
+ </ui-calendar-weeks>
745
+ </ui-calendar-grid>
746
+ </ui-date-picker-content>
747
+ </ui-date-picker>
748
+ `
749
+ root
750
+ .querySelector("ui-date-picker")!
751
+ .addEventListener("valuechange", (event) => {
752
+ log(root, `${event.detail.value ?? "No date"} (${event.detail.reason})`)
753
+ })
754
+ }
755
+
756
+ export { mount }
757
+ ```
758
+
759
+ Type or choose a date. The console logs each value and the reason for the change.
760
+
761
+ ## Driving It from Anywhere
762
+
763
+ A `createDatePickerController()` instance, set as the element's `controller` property, can set the value, show a month, open or close the popup, and focus a date in the open calendar. The element's `api` has the same methods. [Controllers](../controllers.md) covers setup and lifecycle; the [controller reference](#controller) lists the methods.
764
+
765
+ ```ts title="controller.ts"
766
+ import { createDatePickerController } from "@ui-sdk/web/date-picker"
767
+ import { Calendar, ChevronLeft, ChevronRight, createElement } from "lucide"
768
+
769
+ function mount(root: HTMLElement) {
770
+ root.innerHTML = `
771
+ <div data-slot="stack">
772
+ <div data-slot="controls">
773
+ <button type="button" data-action="christmas">Choose Christmas</button>
774
+ <button type="button" data-action="open">Open</button>
775
+ </div>
776
+ <ui-date-picker default-value="2026-10-16">
777
+ <div data-slot="row">
778
+ <ui-date-picker-input><input aria-label="Due date" /></ui-date-picker-input>
779
+ <ui-date-picker-trigger>
780
+ <button data-variant="ghost">
781
+ ${createElement(Calendar, { "aria-hidden": "true" }).outerHTML}
782
+ </button>
783
+ </ui-date-picker-trigger>
784
+ </div>
785
+ <ui-date-picker-hint></ui-date-picker-hint>
786
+ <ui-date-picker-content hidden>
787
+ <div data-slot="row">
788
+ <ui-calendar-previous>
789
+ <button data-variant="ghost">
790
+ ${createElement(ChevronLeft, { "aria-hidden": "true" }).outerHTML}
791
+ </button>
792
+ </ui-calendar-previous>
793
+ <ui-calendar-heading></ui-calendar-heading>
794
+ <ui-calendar-next>
795
+ <button data-variant="ghost">
796
+ ${createElement(ChevronRight, { "aria-hidden": "true" }).outerHTML}
797
+ </button>
798
+ </ui-calendar-next>
799
+ </div>
800
+ <ui-calendar-grid>
801
+ <ui-calendar-weekdays>
802
+ <template><ui-calendar-weekday></ui-calendar-weekday></template>
803
+ </ui-calendar-weekdays>
804
+ <ui-calendar-weeks>
805
+ <template><ui-calendar-day></ui-calendar-day></template>
806
+ </ui-calendar-weeks>
807
+ </ui-calendar-grid>
808
+ </ui-date-picker-content>
809
+ </ui-date-picker>
810
+ </div>
811
+ `
812
+ const controller = createDatePickerController()
813
+ root.querySelector("ui-date-picker")!.controller = controller
814
+ root
815
+ .querySelector('[data-action="christmas"]')!
816
+ .addEventListener("click", () => controller.setValue("2026-12-25"))
817
+ root
818
+ .querySelector('[data-action="open"]')!
819
+ .addEventListener("click", () => controller.open())
820
+ }
821
+
822
+ export { mount }
823
+ ```
824
+
825
+ Press Choose Christmas to set the date from outside, or Open to open the calendar.
826
+
827
+ ## Styling
828
+
829
+ The root, inputs, and trigger expose `data-disabled`. Invalid input sets `data-invalid` on that input and the root. The root and trigger expose `data-open`; presets expose `data-selected`, and Clear exposes `data-empty`. Calendar days carry [Calendar’s state attributes](./calendar.md#styling).
830
+
831
+ Each part has a `data-slot`, such as `date-picker-input`, and its state attributes are listed under [Data Attributes](#data-attributes).
832
+
833
+ ### `<ui-date-picker-content>`
834
+ - `--anchor-width`: Width of the anchor, usually the trigger. Use it to match widths.
835
+ - `--anchor-height`: Height of the anchor.
836
+ - `--available-width`: Space beside the popup, up to the viewport edge. Not inherited either.
837
+ - `--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.
838
+ - `--transform-origin`: The point on the anchor the popup opens from. Use it to scale from the right place.
839
+ - `--arrow-offset`: Where the anchor's center falls along the popup's edge, kept `arrowPadding` from the corners. Position a ::before arrow with it.
840
+ - `--drawer-progress`: While it presents as a sheet: how far open the sheet is, from 0 closed to 1 at its largest snap point. Never past 1.
841
+ - `--drawer-dim`: While it presents as a sheet: how dim the page behind is, from 0 to 1. The backdrop's opacity follows it.
842
+ - `--drawer-expand`: While it presents as a sheet: 0 at the second-largest snap point and below, 1 at the largest. With one snap point, the whole travel.
843
+ - `--drawer-stack`: While it presents as a sheet: how many sheets opened from inside this one are open above it, rising smoothly as each one opens. Push it back with it.
844
+ - `--sheet-backdrop`: Set it yourself: the color the page dims to while it presents as a sheet. Black at 0.2 by default.
845
+
846
+ ### `<ui-date-picker-viewport>`
847
+ - `--keyboard-inset`: While it presents as a sheet: how many pixels of the page the on-screen keyboard covers, 0 without one.
848
+ - `--visual-viewport-width`: While it presents as a sheet: the width of the part of the page you can see.
849
+ - `--visual-viewport-height`: While it presents as a sheet: the height of the part of the page you can see, above the keyboard.
850
+ - `--visual-viewport-top`: While it presents as a sheet: how far the part of the page you can see is scrolled from the top of the layout, as when the keyboard pushes it up.
851
+
852
+ ## Data Attributes
853
+
854
+ ### `<ui-date-picker>`
855
+ `[data-slot="date-picker"]`
856
+
857
+ - `data-mode` (`single`, `range`): How the date picker selects.
858
+ - `data-open`: Present while the popup is open.
859
+ - `data-closed`: Present while the popup is closed, including while it animates out.
860
+ - `data-readonly`: Present when the date can be seen but not changed.
861
+ - `data-disabled`: Present when the date picker is disabled.
862
+ - `data-invalid`: Present when an input holds text that isn't a date, or a date that can't be picked.
863
+
864
+ ### `<ui-date-picker-input>`
865
+ `[data-slot="date-picker-input"]`
866
+
867
+ - `data-disabled`: Present when the date picker is disabled.
868
+ - `data-invalid`: Present when an input holds text that isn't a date, or a date that can't be picked.
869
+
870
+ ### `<ui-date-picker-trigger>`
871
+ `[data-slot="date-picker-trigger"]`
872
+
873
+ - `data-open`: Present while the popup is open.
874
+ - `data-closed`: Present while the popup is closed, including while it animates out.
875
+ - `data-disabled`: Present when the date picker is disabled.
876
+
877
+ ### `<ui-date-picker-content>`
878
+ `[data-slot="date-picker-content"]`
879
+
880
+ - `data-open`: Present while the popup is open.
881
+ - `data-presentation` (`popover`, `sheet`): How the popup presents this time it's open.
882
+ - `data-closed`: Present while the popup is closed, including while it animates out.
883
+ - `data-starting-style`: Present for the first frame. Style the state you animate from.
884
+ - `data-ending-style`: Present while the popup animates out. Style the state you animate to.
885
+
886
+ ### `<ui-date-picker-clear>`
887
+ `[data-slot="date-picker-clear"]`
888
+
889
+ - `data-empty`: Present when there's no date to clear.
890
+
891
+ ### `<ui-date-picker-preset>`
892
+ `[data-slot="date-picker-preset"]`
893
+
894
+ - `data-selected`: Present while the preset's value is the one selected.
895
+
896
+ ## API Reference
897
+
898
+ Props are attributes in kebab case, like `default-value`, `close-on-select` and `start-name`: `"false"` is false, and numbers are numbers. `value`, `default-value` and `unavailable` take comma-separated dates, and the `unavailable` property takes any matcher, like `{ weekday: [0, 6] }`. `container` and `anchor` take CSS selectors, and `controller` is a property. Callbacks are DOM events. The element is form-associated, so it submits with no hidden input.
899
+
900
+ ### DatePicker
901
+
902
+ - `debug?` (`boolean`): Logs every state change with its reason to the console, in development builds.
903
+ - `month?` (`string`): The first month shown, like `"2026-10"`. Pass it to control the calendar.
904
+ - `defaultMonth?` (`string`): The first month it shows, when uncontrolled. Defaults to the selected date's month, else today's.
905
+ - `min?` (`string`): The earliest date that can be picked. Keys stop there, and Previous stops at its month.
906
+ - `max?` (`string`): The latest date that can be picked.
907
+ - `unavailable?` (`DateMatchers`): Dates that can't be picked, like booked days, as data: ISO dates, `{ from, to }`, `{ weekday: [0, 6] }` for weekends, `{ before }`, `{ after }`, or a function. They stay focusable, so keyboard users hear them.
908
+ - `disabled?` (`boolean`): Whether nothing can be picked or focused.
909
+ - `readOnly?` (`boolean`): Whether dates can be focused but not picked.
910
+ - `months?` (`number`): How many months show side by side, each in its own grid.
911
+ - `pageBy?` (`"month" | "page"`): Whether Previous, Next and keys turn one month, or all the months shown.
912
+ - `locale?` (`string`): The language of the names and labels. Defaults to the page's `lang`, then the browser's.
913
+ - `weekStartsOn?` (`number`): The first day of the week, 0 for Sunday. Defaults to the locale's.
914
+ - `weekdayFormat?` (`"long" | "narrow" | "short"`): How weekday headers are written.
915
+ - `monthFormat?` (`"long" | "narrow" | "short"`): How month names are written, in the heading and the month select.
916
+ - `fixedWeeks?` (`boolean`): Whether every month shows six weeks, so the calendar doesn't change height.
917
+ - `showOutsideDays?` (`boolean`): Whether the days of the months before and after show at the edges.
918
+ - `today?` (`string`): Today's date, for `aria-current` and the starting month. Defaults to today in `timeZone`, read on the client.
919
+ - `timeZone?` (`string`): The time zone that says what day today is, like `"America/New_York"`. Defaults to the browser's.
920
+ - `minDays?` (`number`): The fewest days a range can span, counting both ends.
921
+ - `maxDays?` (`number`): The most days a range can span, counting both ends.
922
+ - `allowUnavailable?` (`boolean`): Whether a range may hold unavailable dates, like a stay over a booked night.
923
+ - `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.
924
+ - `mode?` (`DatePickerMode`): How many dates it selects: one, or a range from a start to an end, with an input for each.
925
+ - `value?` (`DatePickerValue`): The selected value: an ISO date, `[start, end]` in range mode, or `null`. Pass it to control the date picker.
926
+ - `defaultValue?` (`DatePickerValue`): The value it starts with, when uncontrolled, and goes back to when its form resets.
927
+ - `valuechange event`: Runs when a date is picked in the calendar (`"item-press"`), a typed date is committed on Enter or blur (`"input-commit"`), a preset or Clear is pressed, the form resets, or a controller sets it. A range changes once both ends are set. `details.cancel()` keeps the value.
928
+ - `monthchange event`: Runs when the months the calendar shows want to change, as in Calendar, or a typed date or a preset turns them.
929
+ - `open?` (`boolean`): Whether the popup is open. Pass it to control the popup.
930
+ - `defaultOpen?` (`boolean`): Whether the popup starts open, when uncontrolled.
931
+ - `openchange event`: Runs when the popup wants to open or close. `details.reason` says why, and `details.cancel()` stops it.
932
+ - `openchangecomplete event`: Runs once the popup has finished opening or closing, after any animation.
933
+ - `closeOnSelect?` (`boolean`): Whether picking a date, or a range's end, or pressing a preset closes the popup.
934
+ - `presentation?` (`PresentationSetting<"popover">`): How the popup presents. `"sheet"` slides it up from the bottom of the screen, and `"auto"` does that on small touch screens.
935
+ - `name?` (`string`): The name the date submits under, as an ISO date. In range mode, both ends submit under it unless `startName` and `endName` are set.
936
+ - `startName?` (`string`): The name a range's start submits under.
937
+ - `endName?` (`string`): The name a range's end submits under.
938
+ - `form?` (`string`): The id of the form it belongs to, when it isn't inside it.
939
+ - `required?` (`boolean`): Whether a date must be entered before its form submits.
940
+ - `controller?` (`object`): Drives it from anywhere. Create one with `createDatePickerController()`.
941
+ - `dismissible?` (`boolean`): Whether Escape, an outside press, focus or the window leaving, Android's back gesture and a sheet's swipe can close it. Triggers, Close parts and the controller always can. Pass `false` while it holds unsaved work, and ask in `dismissattempt`.
942
+ - `dismissattempt event`: Runs when `dismissible` refused a dismissal made on purpose: Escape, an outside press, back or a swipe. Focus or the window leaving is refused without it. Ask "Discard changes?" here.
943
+
944
+ ### DatePickerInput
945
+
946
+ - `end?` (`boolean`): Whether it's a range's end. The input without it holds the start, or the date.
947
+
948
+ ### DatePickerTrigger
949
+
950
+ Opens and closes the calendar. `<ui-date-picker-trigger>` wraps a native `button` with `aria-haspopup="dialog"`, named by the chosen date, and makes one if you write none.
951
+
952
+ ### DatePickerHint
953
+
954
+ Describes the expected format, and its state includes an example date. `<ui-date-picker-hint>` describes the input, and shows the format when left empty.
955
+
956
+ ### DatePickerClear
957
+
958
+ Clears the value and focuses the input. `<ui-date-picker-clear>` wraps a native `button`, and makes one if you write none.
959
+
960
+ ### DatePickerContent
961
+
962
+ - `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 input the popup opens on.
963
+ - `align?` (`Align`): How the popup lines up with the anchor along that side. `start` and `end` follow the reading direction. How the popup lines up with the input along that side.
964
+ - `sideOffset?` (`number`): Gap between the anchor and the popup, in pixels. Gap between the input and the popup, in pixels.
965
+ - `alignOffset?` (`number`): Shift along the anchor, in pixels. Shift along the input, in pixels.
966
+ - `collisionPadding?` (`number`): Space to keep from the viewport edges, in pixels.
967
+ - `arrowPadding?` (`number`): Space to keep between the arrow and the popup's corners, in pixels.
968
+ - `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.
969
+ - `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.
970
+ - `finalFocus?` (`PopupFocusTarget`): Where focus goes when the popup closes while focus is inside it.
971
+ - `keepMounted?` (`boolean`): Whether the popup stays in the page, hidden, while closed. For animation libraries that drive the exit from state.
972
+ ### DatePickerPreset
973
+
974
+ - `value` (`DatePickerValue`): The value it selects: an ISO date, or `[start, end]` in range mode.
975
+
976
+ `DatePickerTrigger`, `DatePickerHint` and `DatePickerClear` take no props of their own.
977
+
978
+ ### State
979
+
980
+ What render functions, state-based class names and children functions receive, per part.
981
+
982
+ `DatePicker`:
983
+
984
+ - `value` (`DatePickerValue`): The selected value.
985
+ - `mode` (`DatePickerMode`): How it selects.
986
+ - `open` (`boolean`): Whether the popup is open.
987
+ - `disabled` (`boolean`): Whether it can't be used.
988
+ - `readOnly` (`boolean`): Whether dates can be seen but not changed.
989
+ - `invalid` (`boolean`): Whether an input holds text that isn't a date that can be picked.
990
+
991
+ `DatePickerInput`:
992
+
993
+ - `invalid` (`boolean`): Whether its text isn't a date that can be picked, after Enter or blur.
994
+ - `disabled` (`boolean`): Whether it can't be used.
995
+ - `readOnly` (`boolean`): Whether its text can't be changed.
996
+
997
+ `DatePickerTrigger`:
998
+
999
+ - `open` (`boolean`): Whether the popup is open.
1000
+ - `disabled` (`boolean`): Whether it can't be pressed.
1001
+
1002
+ `DatePickerContent`:
1003
+
1004
+ - `open` (`boolean`): Whether the popup is open. False while it animates out.
1005
+ - `presentation` (`"popover" | "sheet"`): How it presents this time it's open.
1006
+
1007
+ `DatePickerHint`:
1008
+
1009
+ - `placeholder` (`string`): The format, with a letter for each digit, like "MM/DD/YYYY", "TT.MM.JJJJ" in German.
1010
+ - `example` (`string`): December 31 of this year in the format, like "12/31/2026".
1011
+
1012
+ `DatePickerPreset`:
1013
+
1014
+ - `selected` (`boolean`): Whether its value is the one selected.
1015
+ - `disabled` (`boolean`): Whether it can't be pressed.
1016
+
1017
+ `DatePickerClear`:
1018
+
1019
+ - `empty` (`boolean`): Whether there's nothing to clear.
1020
+ - `disabled` (`boolean`): Whether it can't be pressed.
1021
+
1022
+ ### Reasons
1023
+
1024
+ `event.detail.reason` says why the value changed:
1025
+
1026
+ - `item-press` (`MouseEvent | KeyboardEvent`): A member of a collection was chosen: a menu item, a tab, a radio or a checkbox item.
1027
+ - `input-commit` (`KeyboardEvent | FocusEvent`): Enter, or leaving a number input, committed what was typed: a number input parses, clamps and snaps it to the step, and an autocomplete closes its suggestions on it.
1028
+ - `preset-press`
1029
+ - `clear-press` (`MouseEvent | KeyboardEvent`): A Clear part was pressed, like on an input, a select or a combobox.
1030
+ - `reset` (`none`): A form reset.
1031
+ - `restore` (`none`): The browser restored state, like after going back, or a saved value was read back from storage.
1032
+ - `imperative` (`none`): A controller or `api` call, or a property set on a web component.
1033
+
1034
+ Why the popup opened or closed:
1035
+
1036
+ - `item-press` (`MouseEvent | KeyboardEvent`): A member of a collection was chosen: a menu item, a tab, a radio or a checkbox item.
1037
+ - `preset-press`
1038
+ - `imperative` (`none`): A controller or `api` call, or a property set on a web component.
1039
+ - `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`.
1040
+ - `outside-press` (`MouseEvent`): A press outside the layer.
1041
+ - `escape-key` (`KeyboardEvent`): Escape, or a submenu's close key (ArrowLeft in left-to-right layouts).
1042
+ - `focus-out` (`KeyboardEvent | FocusEvent`): Focus left the layer, or Tab moved it out.
1043
+ - `window-blur` (`FocusEvent`): The window lost focus.
1044
+ - `close-press` (`MouseEvent | KeyboardEvent | SubmitEvent`): A Close part was pressed, or a form with `method="dialog"` was submitted.
1045
+ - `back` (`Event`): Going back: the Android back button or gesture, or Backspace in an empty command input, which returns to the previous page.
1046
+ - `swipe` (`TouchEvent | PointerEvent`): A swipe gesture: a finger, mouse or pen dragged it.
1047
+
1048
+ With `dismissible` false, the refused dismissals `dismissattempt` reports:
1049
+
1050
+ - `outside-press` (`MouseEvent`): A press outside the layer.
1051
+ - `escape-key` (`KeyboardEvent`): Escape, or a submenu's close key (ArrowLeft in left-to-right layouts).
1052
+ - `back` (`Event`): Going back: the Android back button or gesture, or Backspace in an empty command input, which returns to the previous page.
1053
+ - `swipe` (`TouchEvent | PointerEvent`): A swipe gesture: a finger, mouse or pen dragged it.
1054
+
1055
+ ### Controller
1056
+
1057
+ Create one with `createDatePickerController()` and pass it as `controller`.
1058
+
1059
+ - `getValue()` (`() => DatePickerValue`): The selected value: an ISO date, a `[start, end]` range, or `null`.
1060
+ - `setValue(value, options?)` (`(value: DatePickerValue, options?: DatePickerChangeOptions<DatePickerValueChangeReason> | undefined) => boolean`): Selects a value. Returns false when canceled, unchanged, disabled, read-only, or holding a date people can't pick, like one past `max`.
1061
+ - `clear(options?)` (`(options?: DatePickerChangeOptions<DatePickerValueChangeReason> | undefined) => boolean`): Selects nothing, as the Clear part does. Returns false when canceled or unchanged.
1062
+ - `getMonth()` (`() => string`): The first month the calendar shows, like `"2026-10"`.
1063
+ - `setMonth(month, options?)` (`(month: string, options?: DatePickerChangeOptions<DatePickerMonthChangeReason> | undefined) => boolean`): Shows a month first. Returns false when canceled or unchanged.
1064
+ - `previous(options?)` (`(options?: DatePickerChangeOptions<DatePickerMonthChangeReason> | undefined) => boolean`): Shows the months before, as the Previous part does.
1065
+ - `next(options?)` (`(options?: DatePickerChangeOptions<DatePickerMonthChangeReason> | undefined) => boolean`): Shows the months after, as the Next part does.
1066
+ - `focus(date?)` (`(date?: string | undefined) => void`): Focuses a date in the open calendar, turning the months to show it, or the date with the tab stop.
1067
+ - `isOpen()` (`() => boolean`): Whether the popup is open.
1068
+ - `setOpen(open, options?)` (`(open: boolean, options?: DatePickerChangeOptions<DatePickerOpenChangeReason> | undefined) => boolean`): Opens or closes the popup. Returns false when the change was canceled or it was already open or closed.
1069
+ - `open(options?)` (`(options?: (DatePickerChangeOptions<DatePickerOpenChangeReason> & { signal?: AbortSignal | undefined; }) | undefined) => Promise<...>`): Opens the popup, and resolves once it closes, with why and how. Resolves exactly once and never rejects: on the next close from any source, when `signal` aborts, or with reason `"unmount"` when the date picker leaves the page.
1070
+ - `close(options?)` (`(options?: DatePickerChangeOptions<DatePickerOpenChangeReason> | undefined) => boolean`): Closes the popup. Returns false when the close was canceled or it was already closed.
1071
+ - `toggle(options?)` (`(options?: DatePickerChangeOptions<DatePickerOpenChangeReason> | undefined) => boolean`): Opens the popup if it's closed, and closes it if it's open. Returns false when the change was canceled.
1072
+
1073
+ ### Events
1074
+
1075
+ Events fire on their own element and don't bubble, with the new value in `event.detail.value` and the `reason` and `event` beside it. Calling `preventDefault()` cancels the change. Type the element as `UiDatePickerElement` for typed listeners.
1076
+
1077
+ | Member | On | Description |
1078
+ | -------------------------- | ---------------- | --------------------------------------------------------- |
1079
+ | `value` property | `ui-date-picker` | The selected value. Setting it selects it |
1080
+ | `open` property | `ui-date-picker` | Whether the popup is open. Setting it opens or closes it |
1081
+ | `month` property | `ui-date-picker` | The calendar's first month. Setting it turns there |
1082
+ | `api` property | `ui-date-picker` | The [controller](#controller) |
1083
+ | `controller` property | `ui-date-picker` | A controller from `createDatePickerController()` |
1084
+ | `valuechange` event | `ui-date-picker` | `detail: { value, reason, event, source }` |
1085
+ | `openchange` event | `ui-date-picker` | `detail: { value: open, reason, event, source }` |
1086
+ | `openchangecomplete` event | `ui-date-picker` | `detail: { value: open }`, once any animation finished |
1087
+ | `monthchange` event | `ui-date-picker` | `detail: { value: month, reason, event, source }` |
1088
+ | `dismissattempt` event | `ui-date-picker` | `detail: { reason, event }`, when a dismissal was refused |
1089
+
1090
+ ## Accessibility
1091
+
1092
+ It follows the [WAI-ARIA date picker dialog](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/): a plain text input that every screen reader handles, a button with `aria-haspopup="dialog"` and `aria-expanded` named by the date chosen, and a dialog holding the calendar's grid. Focus moves into the grid when the dialog opens and back to the button when a date is picked or Escape closes it. Every line below is an automated test.
1093
+
1094
+ ### Keyboard
1095
+
1096
+ | Key | Where | Action |
1097
+ | --------------- | ------- | ----------------------------------------------------------------------------- |
1098
+ | Enter | Input | Commit the typed date. |
1099
+ | Alt+Down Arrow | Input | Open the calendar. |
1100
+ | Enter / Space | Trigger | Open or close the calendar. |
1101
+ | Escape | Popup | Cancel an unfinished range first; otherwise close the popup. |
1102
+ | Tab / Shift+Tab | Popup | Move through controls. Leaving the popup closes it when dismissal is allowed. |
1103
+
1104
+ Opening focuses the selected date, otherwise today, otherwise the first focusable date. The calendar’s [arrow keys and month navigation](./calendar.md#keyboard) work here too. An ancestor’s `dir="rtl"` reverses Left and Right Arrow to follow the visual order.
1105
+
1106
+ ### Tested Behavior
1107
+
1108
+ - A typed date in the page's format becomes the value on Enter, and the form submits it as ISO.
1109
+ - Text that isn't a date stays as typed and marks the input invalid.
1110
+ - Text that isn't a date blocks the form's submit until it's fixed.
1111
+ - Clearing text that isn't a date lets the form submit.
1112
+ - A message the app set on the input comes back once the text is a date.
1113
+ - The date picker element reports text that isn't a date as its own bad input. Web components only.
1114
+ - The format hint describes the input.
1115
+ - The trigger opens a dialog with focus on the selected date, and Escape closes it back to the trigger.
1116
+ - With nothing selected, focus goes to today.
1117
+ - Picking a day fills the input, closes the dialog and returns focus to the trigger.
1118
+ - With closeOnSelect off, the dialog stays open after a pick.
1119
+ - Alt+ArrowDown in the input opens the calendar.
1120
+ - A typed date opens the calendar on its month.
1121
+ - A press outside closes the dialog.
1122
+ - A preset selects its value and closes the dialog.
1123
+ - Clear empties the value and focuses the input.
1124
+ - A form reset puts the default value back.
1125
+ - A required date picker blocks an empty submit.
1126
+ - Days past min and max can't be typed or picked.
1127
+ - German reads and writes dates day first.
1128
+
1129
+ **Range**
1130
+
1131
+ - Picking a start and an end fills both inputs and closes after the end.
1132
+ - Each end can be typed, and the value changes once both are set.
1133
+ - An end before the start is invalid.
1134
+ - An end that isn't a date blocks the form's submit until it's fixed.
1135
+
1136
+ Runs in React, Vue and web components.