@vielzeug/refine 26.10.0 → 26.10.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 (463) hide show
  1. package/README.md +1 -1
  2. package/dist/accordion-item.cjs.map +1 -1
  3. package/dist/accordion-item.js.map +1 -1
  4. package/dist/accordion.cjs.map +1 -1
  5. package/dist/accordion.js.map +1 -1
  6. package/dist/async.cjs.map +1 -1
  7. package/dist/async.js.map +1 -1
  8. package/dist/badge.cjs.map +1 -1
  9. package/dist/badge.js.map +1 -1
  10. package/dist/box.cjs.map +1 -1
  11. package/dist/box.js.map +1 -1
  12. package/dist/button.cjs +3 -3
  13. package/dist/button.cjs.map +1 -1
  14. package/dist/button.js +3 -3
  15. package/dist/button.js.map +1 -1
  16. package/dist/calendar.cjs.map +1 -1
  17. package/dist/calendar.js.map +1 -1
  18. package/dist/carousel.cjs.map +1 -1
  19. package/dist/carousel.js.map +1 -1
  20. package/dist/chat-message.cjs.map +1 -1
  21. package/dist/chat-message.js.map +1 -1
  22. package/dist/chat-panel.cjs.map +1 -1
  23. package/dist/chat-panel.js.map +1 -1
  24. package/dist/checkbox-group.cjs.map +1 -1
  25. package/dist/checkbox-group.js.map +1 -1
  26. package/dist/chip.cjs.map +1 -1
  27. package/dist/chip.js.map +1 -1
  28. package/dist/code-window.cjs.map +1 -1
  29. package/dist/code-window.js.map +1 -1
  30. package/dist/combobox.cjs.map +1 -1
  31. package/dist/combobox.js.map +1 -1
  32. package/dist/command-palette.cjs.map +1 -1
  33. package/dist/command-palette.js.map +1 -1
  34. package/dist/content/card/card.css.cjs.map +1 -1
  35. package/dist/content/card/card.css.js.map +1 -1
  36. package/dist/content/carousel/carousel-slide.css.cjs.map +1 -1
  37. package/dist/content/carousel/carousel-slide.css.js.map +1 -1
  38. package/dist/content/carousel/carousel.css.cjs.map +1 -1
  39. package/dist/content/carousel/carousel.css.js.map +1 -1
  40. package/dist/content/carousel/carousel.d.ts +5 -5
  41. package/dist/content/chat-message/chat-message.css.cjs +1 -1
  42. package/dist/content/chat-message/chat-message.css.cjs.map +1 -1
  43. package/dist/content/chat-message/chat-message.css.js +1 -1
  44. package/dist/content/chat-message/chat-message.css.js.map +1 -1
  45. package/dist/content/chat-message/chat-message.d.ts +4 -4
  46. package/dist/content/chat-message/chat-message.d.ts.map +1 -1
  47. package/dist/content/chat-panel/chat-panel.d.ts +1 -1
  48. package/dist/content/code-window/code-window.css.cjs.map +1 -1
  49. package/dist/content/code-window/code-window.css.js.map +1 -1
  50. package/dist/content/code-window/code-window.d.ts +4 -4
  51. package/dist/content/index.d.ts +4 -0
  52. package/dist/content/index.d.ts.map +1 -1
  53. package/dist/content/list/_list-item-reveal.cjs.map +1 -1
  54. package/dist/content/list/_list-item-reveal.d.ts +4 -4
  55. package/dist/content/list/_list-item-reveal.d.ts.map +1 -1
  56. package/dist/content/list/_list-item-reveal.js.map +1 -1
  57. package/dist/content/list/list-item.css.cjs.map +1 -1
  58. package/dist/content/list/list-item.css.js.map +1 -1
  59. package/dist/content/list/list-item.d.ts +8 -8
  60. package/dist/content/list/list-item.d.ts.map +1 -1
  61. package/dist/content/list/list.d.ts +8 -8
  62. package/dist/content/list/list.d.ts.map +1 -1
  63. package/dist/content/qr-code/qr-code.d.ts +1 -1
  64. package/dist/content/rank-list/rank-item.css.cjs +2 -0
  65. package/dist/content/rank-list/rank-item.css.cjs.map +1 -0
  66. package/dist/content/rank-list/rank-item.css.js +2 -0
  67. package/dist/content/rank-list/rank-item.css.js.map +1 -0
  68. package/dist/content/rank-list/rank-item.d.ts +68 -0
  69. package/dist/content/rank-list/rank-item.d.ts.map +1 -0
  70. package/dist/content/rank-list/rank-list.css.cjs +2 -0
  71. package/dist/content/rank-list/rank-list.css.cjs.map +1 -0
  72. package/dist/content/rank-list/rank-list.css.js +2 -0
  73. package/dist/content/rank-list/rank-list.css.js.map +1 -0
  74. package/dist/content/rank-list/rank-list.d.ts +44 -0
  75. package/dist/content/rank-list/rank-list.d.ts.map +1 -0
  76. package/dist/content/separator/separator.d.ts +1 -1
  77. package/dist/content/separator/separator.d.ts.map +1 -1
  78. package/dist/content/speech-player/speech-player.css.cjs.map +1 -1
  79. package/dist/content/speech-player/speech-player.css.js.map +1 -1
  80. package/dist/content/speech-player/speech-player.d.ts +12 -12
  81. package/dist/content/speech-player/speech-player.d.ts.map +1 -1
  82. package/dist/content/stepper/step.css.cjs.map +1 -1
  83. package/dist/content/stepper/step.css.js.map +1 -1
  84. package/dist/content/stepper/step.d.ts +3 -3
  85. package/dist/content/stepper/step.d.ts.map +1 -1
  86. package/dist/content/stepper/stepper.css.cjs.map +1 -1
  87. package/dist/content/stepper/stepper.css.js.map +1 -1
  88. package/dist/content/stepper/stepper.d.ts +3 -3
  89. package/dist/content/stepper/stepper.d.ts.map +1 -1
  90. package/dist/content/table/table.css.cjs.map +1 -1
  91. package/dist/content/table/table.css.js.map +1 -1
  92. package/dist/content/table/table.d.ts +3 -3
  93. package/dist/content/table/table.d.ts.map +1 -1
  94. package/dist/content/text/text.css.cjs.map +1 -1
  95. package/dist/content/text/text.css.js.map +1 -1
  96. package/dist/content/text/text.d.ts +2 -2
  97. package/dist/content/text/text.d.ts.map +1 -1
  98. package/dist/cookie-banner.cjs.map +1 -1
  99. package/dist/cookie-banner.js.map +1 -1
  100. package/dist/copy-command.cjs +1 -1
  101. package/dist/copy-command.cjs.map +1 -1
  102. package/dist/copy-command.js +1 -1
  103. package/dist/copy-command.js.map +1 -1
  104. package/dist/core/announcer.cjs.map +1 -1
  105. package/dist/core/announcer.d.ts +2 -2
  106. package/dist/core/announcer.js.map +1 -1
  107. package/dist/core/aria-reflection.cjs.map +1 -1
  108. package/dist/core/aria-reflection.d.ts +3 -3
  109. package/dist/core/aria-reflection.js.map +1 -1
  110. package/dist/core/auto-resize.cjs.map +1 -1
  111. package/dist/core/auto-resize.d.ts +1 -1
  112. package/dist/core/auto-resize.js.map +1 -1
  113. package/dist/core/checkable.cjs.map +1 -1
  114. package/dist/core/checkable.d.ts +2 -2
  115. package/dist/core/checkable.d.ts.map +1 -1
  116. package/dist/core/checkable.js.map +1 -1
  117. package/dist/core/choice-field.cjs.map +1 -1
  118. package/dist/core/choice-field.d.ts +3 -3
  119. package/dist/core/choice-field.d.ts.map +1 -1
  120. package/dist/core/choice-field.js.map +1 -1
  121. package/dist/core/composer.cjs.map +1 -1
  122. package/dist/core/composer.d.ts +4 -4
  123. package/dist/core/composer.d.ts.map +1 -1
  124. package/dist/core/composer.js.map +1 -1
  125. package/dist/core/date-picker.cjs.map +1 -1
  126. package/dist/core/date-picker.d.ts +5 -5
  127. package/dist/core/date-picker.d.ts.map +1 -1
  128. package/dist/core/date-picker.js.map +1 -1
  129. package/dist/core/direction.cjs.map +1 -1
  130. package/dist/core/direction.d.ts +1 -1
  131. package/dist/core/direction.js.map +1 -1
  132. package/dist/core/field-base.cjs.map +1 -1
  133. package/dist/core/field-base.d.ts +9 -9
  134. package/dist/core/field-base.d.ts.map +1 -1
  135. package/dist/core/field-base.js.map +1 -1
  136. package/dist/core/focus.cjs.map +1 -1
  137. package/dist/core/focus.d.ts +1 -1
  138. package/dist/core/focus.js.map +1 -1
  139. package/dist/core/icon-registry.cjs.map +1 -1
  140. package/dist/core/icon-registry.d.ts +1 -1
  141. package/dist/core/icon-registry.js.map +1 -1
  142. package/dist/core/icons.cjs.map +1 -1
  143. package/dist/core/icons.js.map +1 -1
  144. package/dist/core/keyboard.cjs.map +1 -1
  145. package/dist/core/keyboard.d.ts +1 -1
  146. package/dist/core/keyboard.js.map +1 -1
  147. package/dist/core/numbers.cjs.map +1 -1
  148. package/dist/core/numbers.d.ts +1 -1
  149. package/dist/core/numbers.js.map +1 -1
  150. package/dist/core/overlay.cjs.map +1 -1
  151. package/dist/core/overlay.d.ts +6 -6
  152. package/dist/core/overlay.js.map +1 -1
  153. package/dist/core/parse.cjs.map +1 -1
  154. package/dist/core/parse.d.ts +1 -1
  155. package/dist/core/parse.js.map +1 -1
  156. package/dist/core/positioner.cjs.map +1 -1
  157. package/dist/core/positioner.d.ts +3 -3
  158. package/dist/core/positioner.js.map +1 -1
  159. package/dist/core/ref-callback.cjs.map +1 -1
  160. package/dist/core/ref-callback.d.ts +2 -2
  161. package/dist/core/ref-callback.d.ts.map +1 -1
  162. package/dist/core/ref-callback.js.map +1 -1
  163. package/dist/core/text-field.cjs.map +1 -1
  164. package/dist/core/text-field.d.ts +6 -6
  165. package/dist/core/text-field.d.ts.map +1 -1
  166. package/dist/core/text-field.js.map +1 -1
  167. package/dist/counter.cjs +1 -0
  168. package/dist/counter.cjs.map +1 -1
  169. package/dist/counter.js +1 -0
  170. package/dist/counter.js.map +1 -1
  171. package/dist/custom-elements.json +315 -87
  172. package/dist/datagrid.cjs.map +1 -1
  173. package/dist/datagrid.js.map +1 -1
  174. package/dist/date-picker.cjs +1 -1
  175. package/dist/date-picker.cjs.map +1 -1
  176. package/dist/date-picker.js +1 -1
  177. package/dist/date-picker.js.map +1 -1
  178. package/dist/dialog.cjs.map +1 -1
  179. package/dist/dialog.js.map +1 -1
  180. package/dist/disclosure/accordion-item/accordion-item.css.cjs +1 -1
  181. package/dist/disclosure/accordion-item/accordion-item.css.cjs.map +1 -1
  182. package/dist/disclosure/accordion-item/accordion-item.css.js +1 -1
  183. package/dist/disclosure/accordion-item/accordion-item.css.js.map +1 -1
  184. package/dist/disclosure/tab-item/tab-item.d.ts +1 -1
  185. package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
  186. package/dist/drawer.cjs.map +1 -1
  187. package/dist/drawer.js.map +1 -1
  188. package/dist/feedback/alert/alert.css.cjs.map +1 -1
  189. package/dist/feedback/alert/alert.css.js.map +1 -1
  190. package/dist/feedback/badge/badge.css.cjs.map +1 -1
  191. package/dist/feedback/badge/badge.css.js.map +1 -1
  192. package/dist/feedback/badge/badge.d.ts +1 -1
  193. package/dist/feedback/badge/badge.d.ts.map +1 -1
  194. package/dist/feedback/chip/chip.css.cjs.map +1 -1
  195. package/dist/feedback/chip/chip.css.js.map +1 -1
  196. package/dist/feedback/chip/chip.d.ts +3 -3
  197. package/dist/feedback/chip/chip.d.ts.map +1 -1
  198. package/dist/feedback/cookie-banner/cookie-banner.css.cjs.map +1 -1
  199. package/dist/feedback/cookie-banner/cookie-banner.css.js.map +1 -1
  200. package/dist/feedback/cookie-banner/cookie-banner.d.ts +8 -8
  201. package/dist/feedback/cookie-banner/cookie-banner.d.ts.map +1 -1
  202. package/dist/feedback/progress/progress.css.cjs.map +1 -1
  203. package/dist/feedback/progress/progress.css.js.map +1 -1
  204. package/dist/feedback/progress/progress.d.ts +1 -1
  205. package/dist/feedback/progress/progress.d.ts.map +1 -1
  206. package/dist/feedback/skeleton/skeleton.css.cjs.map +1 -1
  207. package/dist/feedback/skeleton/skeleton.css.js.map +1 -1
  208. package/dist/feedback/skeleton/skeleton.d.ts +1 -1
  209. package/dist/feedback/skeleton/skeleton.d.ts.map +1 -1
  210. package/dist/feedback/toast/toast.css.cjs +1 -1
  211. package/dist/feedback/toast/toast.css.cjs.map +1 -1
  212. package/dist/feedback/toast/toast.css.js +1 -1
  213. package/dist/feedback/toast/toast.css.js.map +1 -1
  214. package/dist/feedback/toast/toast.d.ts +1 -1
  215. package/dist/feedback/toast/toast.d.ts.map +1 -1
  216. package/dist/feedback/typing-indicator/typing-indicator.d.ts +2 -2
  217. package/dist/file-input.cjs +1 -1
  218. package/dist/file-input.cjs.map +1 -1
  219. package/dist/file-input.js +1 -1
  220. package/dist/file-input.js.map +1 -1
  221. package/dist/frameworks/elements.d.ts +1 -1
  222. package/dist/grid-item.cjs.map +1 -1
  223. package/dist/grid-item.js.map +1 -1
  224. package/dist/grid.cjs.map +1 -1
  225. package/dist/grid.js.map +1 -1
  226. package/dist/icon.cjs.map +1 -1
  227. package/dist/icon.js.map +1 -1
  228. package/dist/input.cjs.map +1 -1
  229. package/dist/input.js.map +1 -1
  230. package/dist/inputs/button/button.css.cjs.map +1 -1
  231. package/dist/inputs/button/button.css.js.map +1 -1
  232. package/dist/inputs/button/button.d.ts +3 -3
  233. package/dist/inputs/button/button.d.ts.map +1 -1
  234. package/dist/inputs/calendar/calendar.css.cjs.map +1 -1
  235. package/dist/inputs/calendar/calendar.css.js.map +1 -1
  236. package/dist/inputs/calendar/calendar.d.ts +2 -2
  237. package/dist/inputs/checkbox-group/checkbox-group.d.ts +2 -2
  238. package/dist/inputs/checkbox-group/checkbox-group.d.ts.map +1 -1
  239. package/dist/inputs/combobox/combobox.css.cjs.map +1 -1
  240. package/dist/inputs/combobox/combobox.css.js.map +1 -1
  241. package/dist/inputs/counter/counter.css.cjs +1 -1
  242. package/dist/inputs/counter/counter.css.cjs.map +1 -1
  243. package/dist/inputs/counter/counter.css.js +1 -1
  244. package/dist/inputs/counter/counter.css.js.map +1 -1
  245. package/dist/inputs/counter/counter.d.ts +2 -1
  246. package/dist/inputs/counter/counter.d.ts.map +1 -1
  247. package/dist/inputs/datagrid/datagrid.css.cjs.map +1 -1
  248. package/dist/inputs/datagrid/datagrid.css.js.map +1 -1
  249. package/dist/inputs/datagrid/datagrid.d.ts +5 -5
  250. package/dist/inputs/date-picker/date-picker.css.cjs.map +1 -1
  251. package/dist/inputs/date-picker/date-picker.css.js.map +1 -1
  252. package/dist/inputs/date-picker/date-picker.d.ts +1 -1
  253. package/dist/inputs/file-input/file-input-upload.cjs.map +1 -1
  254. package/dist/inputs/file-input/file-input-upload.d.ts +6 -6
  255. package/dist/inputs/file-input/file-input-upload.js.map +1 -1
  256. package/dist/inputs/file-input/file-input.css.cjs.map +1 -1
  257. package/dist/inputs/file-input/file-input.css.js.map +1 -1
  258. package/dist/inputs/file-input/file-input.d.ts +6 -6
  259. package/dist/inputs/input/input.css.cjs +1 -1
  260. package/dist/inputs/input/input.css.cjs.map +1 -1
  261. package/dist/inputs/input/input.css.js +1 -1
  262. package/dist/inputs/input/input.css.js.map +1 -1
  263. package/dist/inputs/input/input.d.ts +6 -6
  264. package/dist/inputs/input/input.d.ts.map +1 -1
  265. package/dist/inputs/message-composer/message-composer.css.cjs.map +1 -1
  266. package/dist/inputs/message-composer/message-composer.css.js.map +1 -1
  267. package/dist/inputs/message-composer/message-composer.d.ts +7 -7
  268. package/dist/inputs/message-composer/message-composer.d.ts.map +1 -1
  269. package/dist/inputs/number-input/number-input.css.cjs.map +1 -1
  270. package/dist/inputs/number-input/number-input.css.js.map +1 -1
  271. package/dist/inputs/number-input/number-input.d.ts +2 -2
  272. package/dist/inputs/otp-input/otp-input.css.cjs.map +1 -1
  273. package/dist/inputs/otp-input/otp-input.css.js.map +1 -1
  274. package/dist/inputs/qr-scanner/qr-scanner.d.ts +1 -1
  275. package/dist/inputs/qr-scanner/qr-scanner.d.ts.map +1 -1
  276. package/dist/inputs/rating/rating.d.ts +1 -1
  277. package/dist/inputs/rating/rating.d.ts.map +1 -1
  278. package/dist/inputs/select/select.css.cjs +1 -1
  279. package/dist/inputs/select/select.css.cjs.map +1 -1
  280. package/dist/inputs/select/select.css.js +1 -1
  281. package/dist/inputs/select/select.css.js.map +1 -1
  282. package/dist/inputs/select/select.d.ts +1 -1
  283. package/dist/inputs/select/select.d.ts.map +1 -1
  284. package/dist/inputs/shared/field-binding.cjs.map +1 -1
  285. package/dist/inputs/shared/field-binding.d.ts +2 -2
  286. package/dist/inputs/shared/field-binding.d.ts.map +1 -1
  287. package/dist/inputs/shared/field-binding.js.map +1 -1
  288. package/dist/inputs/shared/native-field-event.cjs.map +1 -1
  289. package/dist/inputs/shared/native-field-event.d.ts +1 -1
  290. package/dist/inputs/shared/native-field-event.js.map +1 -1
  291. package/dist/inputs/shared/templates.cjs.map +1 -1
  292. package/dist/inputs/shared/templates.d.ts +3 -3
  293. package/dist/inputs/shared/templates.js.map +1 -1
  294. package/dist/inputs/slider/slider.css.cjs.map +1 -1
  295. package/dist/inputs/slider/slider.css.js.map +1 -1
  296. package/dist/inputs/slider/slider.d.ts +1 -1
  297. package/dist/inputs/slider/slider.d.ts.map +1 -1
  298. package/dist/inputs/textarea/textarea.css.cjs.map +1 -1
  299. package/dist/inputs/textarea/textarea.css.js.map +1 -1
  300. package/dist/inputs/textarea/textarea.d.ts +1 -1
  301. package/dist/inputs/time-picker/time-picker.css.cjs.map +1 -1
  302. package/dist/inputs/time-picker/time-picker.css.js.map +1 -1
  303. package/dist/inputs/time-picker/time-picker.d.ts +1 -1
  304. package/dist/layout/box/box.css.cjs.map +1 -1
  305. package/dist/layout/box/box.css.js.map +1 -1
  306. package/dist/layout/box/box.d.ts +1 -1
  307. package/dist/layout/grid/grid.d.ts +1 -1
  308. package/dist/layout/grid-item/grid-item.d.ts +3 -3
  309. package/dist/layout/grid-item/grid-item.d.ts.map +1 -1
  310. package/dist/layout/navbar/navbar.css.cjs +1 -1
  311. package/dist/layout/navbar/navbar.css.cjs.map +1 -1
  312. package/dist/layout/navbar/navbar.css.js +1 -1
  313. package/dist/layout/navbar/navbar.css.js.map +1 -1
  314. package/dist/layout/navbar/navbar.d.ts +3 -3
  315. package/dist/layout/sidebar/sidebar-item.css.cjs.map +1 -1
  316. package/dist/layout/sidebar/sidebar-item.css.js.map +1 -1
  317. package/dist/layout/sidebar/sidebar.d.ts +5 -5
  318. package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
  319. package/dist/list-item.cjs.map +1 -1
  320. package/dist/list-item.js.map +1 -1
  321. package/dist/list.cjs.map +1 -1
  322. package/dist/list.js.map +1 -1
  323. package/dist/menu.cjs +6 -5
  324. package/dist/menu.cjs.map +1 -1
  325. package/dist/menu.js +6 -5
  326. package/dist/menu.js.map +1 -1
  327. package/dist/message-composer.cjs.map +1 -1
  328. package/dist/message-composer.js.map +1 -1
  329. package/dist/navbar.cjs.map +1 -1
  330. package/dist/navbar.js.map +1 -1
  331. package/dist/number-input.cjs.map +1 -1
  332. package/dist/number-input.js.map +1 -1
  333. package/dist/otp-input.cjs.map +1 -1
  334. package/dist/otp-input.js.map +1 -1
  335. package/dist/overlay/command-palette/command-palette-items.cjs.map +1 -1
  336. package/dist/overlay/command-palette/command-palette-items.d.ts +1 -1
  337. package/dist/overlay/command-palette/command-palette-items.js.map +1 -1
  338. package/dist/overlay/command-palette/command-palette.css.cjs.map +1 -1
  339. package/dist/overlay/command-palette/command-palette.css.js.map +1 -1
  340. package/dist/overlay/command-palette/command-palette.d.ts +3 -3
  341. package/dist/overlay/command-palette/command-palette.types.d.ts +6 -6
  342. package/dist/overlay/command-palette/command-palette.types.d.ts.map +1 -1
  343. package/dist/overlay/dialog/dialog.css.cjs +1 -1
  344. package/dist/overlay/dialog/dialog.css.cjs.map +1 -1
  345. package/dist/overlay/dialog/dialog.css.js +1 -1
  346. package/dist/overlay/dialog/dialog.css.js.map +1 -1
  347. package/dist/overlay/dialog/dialog.d.ts +2 -2
  348. package/dist/overlay/dialog/dialog.d.ts.map +1 -1
  349. package/dist/overlay/drawer/drawer.css.cjs.map +1 -1
  350. package/dist/overlay/drawer/drawer.css.js.map +1 -1
  351. package/dist/overlay/drawer/drawer.d.ts +1 -1
  352. package/dist/overlay/drawer/drawer.d.ts.map +1 -1
  353. package/dist/overlay/menu/menu-item.css.cjs.map +1 -1
  354. package/dist/overlay/menu/menu-item.css.js.map +1 -1
  355. package/dist/overlay/menu/menu.d.ts.map +1 -1
  356. package/dist/overlay/shared/use-dialog.cjs.map +1 -1
  357. package/dist/overlay/shared/use-dialog.d.ts +6 -6
  358. package/dist/overlay/shared/use-dialog.d.ts.map +1 -1
  359. package/dist/overlay/shared/use-dialog.js.map +1 -1
  360. package/dist/overlay/shared/use-floating-trigger.cjs.map +1 -1
  361. package/dist/overlay/shared/use-floating-trigger.d.ts +1 -1
  362. package/dist/overlay/shared/use-floating-trigger.d.ts.map +1 -1
  363. package/dist/overlay/shared/use-floating-trigger.js.map +1 -1
  364. package/dist/overlay/tooltip/tooltip.css.cjs.map +1 -1
  365. package/dist/overlay/tooltip/tooltip.css.js.map +1 -1
  366. package/dist/progress.cjs.map +1 -1
  367. package/dist/progress.js.map +1 -1
  368. package/dist/qr-code.cjs.map +1 -1
  369. package/dist/qr-code.js.map +1 -1
  370. package/dist/qr-scanner.cjs.map +1 -1
  371. package/dist/qr-scanner.js.map +1 -1
  372. package/dist/radio-group.cjs.map +1 -1
  373. package/dist/radio-group.js.map +1 -1
  374. package/dist/radio.cjs.map +1 -1
  375. package/dist/radio.js.map +1 -1
  376. package/dist/rank-item.cjs +21 -0
  377. package/dist/rank-item.cjs.map +1 -0
  378. package/dist/rank-item.js +21 -0
  379. package/dist/rank-item.js.map +1 -0
  380. package/dist/rank-list.cjs +4 -0
  381. package/dist/rank-list.cjs.map +1 -0
  382. package/dist/rank-list.js +4 -0
  383. package/dist/rank-list.js.map +1 -0
  384. package/dist/rating.cjs.map +1 -1
  385. package/dist/rating.js.map +1 -1
  386. package/dist/refine.cjs +103 -80
  387. package/dist/refine.cjs.map +1 -1
  388. package/dist/refine.iife.js +103 -80
  389. package/dist/refine.iife.js.map +1 -1
  390. package/dist/refine.js +104 -81
  391. package/dist/refine.js.map +1 -1
  392. package/dist/select.cjs.map +1 -1
  393. package/dist/select.js.map +1 -1
  394. package/dist/separator.cjs.map +1 -1
  395. package/dist/separator.js.map +1 -1
  396. package/dist/shared/index.d.ts +3 -3
  397. package/dist/shared/size-presets.cjs.map +1 -1
  398. package/dist/shared/size-presets.d.ts +4 -4
  399. package/dist/shared/size-presets.js.map +1 -1
  400. package/dist/shared/types.d.ts +1 -1
  401. package/dist/sidebar.cjs.map +1 -1
  402. package/dist/sidebar.js.map +1 -1
  403. package/dist/skeleton.cjs.map +1 -1
  404. package/dist/skeleton.js.map +1 -1
  405. package/dist/slider.cjs.map +1 -1
  406. package/dist/slider.js.map +1 -1
  407. package/dist/speech-player.cjs.map +1 -1
  408. package/dist/speech-player.js.map +1 -1
  409. package/dist/step.cjs.map +1 -1
  410. package/dist/step.js.map +1 -1
  411. package/dist/stepper.cjs.map +1 -1
  412. package/dist/stepper.js.map +1 -1
  413. package/dist/styles/fouc.css +2 -2
  414. package/dist/styles/mixins/accessibility.css.cjs.map +1 -1
  415. package/dist/styles/mixins/accessibility.css.d.ts +4 -4
  416. package/dist/styles/mixins/accessibility.css.js.map +1 -1
  417. package/dist/styles/mixins/animation.css.cjs +2 -2
  418. package/dist/styles/mixins/animation.css.cjs.map +1 -1
  419. package/dist/styles/mixins/animation.css.d.ts +4 -4
  420. package/dist/styles/mixins/animation.css.js +2 -2
  421. package/dist/styles/mixins/animation.css.js.map +1 -1
  422. package/dist/styles/mixins/field-variants.css.cjs +2 -2
  423. package/dist/styles/mixins/field-variants.css.cjs.map +1 -1
  424. package/dist/styles/mixins/field-variants.css.d.ts +6 -6
  425. package/dist/styles/mixins/field-variants.css.d.ts.map +1 -1
  426. package/dist/styles/mixins/field-variants.css.js +2 -2
  427. package/dist/styles/mixins/field-variants.css.js.map +1 -1
  428. package/dist/styles/mixins/shape.css.cjs.map +1 -1
  429. package/dist/styles/mixins/shape.css.d.ts +9 -9
  430. package/dist/styles/mixins/shape.css.d.ts.map +1 -1
  431. package/dist/styles/mixins/shape.css.js.map +1 -1
  432. package/dist/styles/mixins/variants.css.cjs.map +1 -1
  433. package/dist/styles/mixins/variants.css.d.ts +1 -1
  434. package/dist/styles/mixins/variants.css.js.map +1 -1
  435. package/dist/styles/theme.css +36 -28
  436. package/dist/tab-item.cjs.map +1 -1
  437. package/dist/tab-item.js.map +1 -1
  438. package/dist/tab-panel.cjs.map +1 -1
  439. package/dist/tab-panel.js.map +1 -1
  440. package/dist/table.cjs.map +1 -1
  441. package/dist/table.js.map +1 -1
  442. package/dist/text.cjs.map +1 -1
  443. package/dist/text.js.map +1 -1
  444. package/dist/textarea.cjs.map +1 -1
  445. package/dist/textarea.js.map +1 -1
  446. package/dist/theme.cjs.map +1 -1
  447. package/dist/theme.d.ts +2 -2
  448. package/dist/theme.js.map +1 -1
  449. package/dist/time-picker.cjs +1 -1
  450. package/dist/time-picker.cjs.map +1 -1
  451. package/dist/time-picker.js +1 -1
  452. package/dist/time-picker.js.map +1 -1
  453. package/dist/toast.cjs.map +1 -1
  454. package/dist/toast.js.map +1 -1
  455. package/dist/types/elements.d.ts +6 -2
  456. package/dist/typing-indicator.cjs.map +1 -1
  457. package/dist/typing-indicator.js.map +1 -1
  458. package/dist/utils/css.cjs.map +1 -1
  459. package/dist/utils/css.js.map +1 -1
  460. package/dist/utils/link.cjs.map +1 -1
  461. package/dist/utils/link.d.ts +2 -2
  462. package/dist/utils/link.js.map +1 -1
  463. package/package.json +31 -14
@@ -1 +1 @@
1
- {"version":3,"file":"theme.cjs","names":[],"sources":["../src/theme.ts"],"sourcesContent":["import { computed, effect, fromSubscribable, type Readable, type Signal, signal } from '@vielzeug/ripple';\nimport { createMediaQuery } from '@vielzeug/sentinel';\n\n/** User-selectable theme: an explicit mode, or follow the OS. */\nexport type ThemePreference = 'dark' | 'light' | 'system';\n\n/** The mode actually in effect after resolving `system` against the OS preference. */\nexport type ResolvedTheme = 'dark' | 'light';\n\nexport interface ThemeControllerOptions {\n /** Starting preference. @default 'system' */\n readonly initial?: ThemePreference;\n /** Element that carries the theme classes and `color-scheme`. @default document.documentElement */\n readonly root?: HTMLElement;\n /** Window whose `matchMedia` backs `system`. @default globalThis */\n readonly target?: Window;\n}\n\n/**\n * Owns the light/dark/system theme for the document: a reactive preference, the effective\n * (resolved) mode, and the DOM application refine's `styles/theme.css` expects — the `.dark`\n * class plus the `color-scheme` property on the root element, so every `light-dark()` token\n * resolves to the right branch.\n *\n * The controller does NOT persist the preference or expose an accent color — those are consumer\n * concerns (wire `watch(controller.preference, save)` for persistence; set `--color-primary-hue`\n * yourself). It only tracks the OS `prefers-color-scheme` while in `system` mode and applies the\n * result.\n */\nexport interface ThemeController {\n readonly disposalSignal: AbortSignal;\n /** Stops applying and releases the OS listener. */\n dispose(): void;\n readonly disposed: boolean;\n /** The user's selection. Write through {@link setPreference} or `preference.value = …`. */\n readonly preference: Signal<ThemePreference>;\n /** The effective mode after resolving `system`. */\n readonly resolved: Readable<ResolvedTheme>;\n setPreference(preference: ThemePreference): void;\n [Symbol.dispose](): void;\n}\n\nconst DARK_SCHEME_QUERY = '(prefers-color-scheme: dark)';\n\n/** Creates a document theme controller. Call once at app startup. */\nexport function createThemeController(options: ThemeControllerOptions = {}): ThemeController {\n const root = options.root ?? document.documentElement;\n const controller = new AbortController();\n const preference = signal<ThemePreference>(options.initial ?? 'system');\n\n const hasMatchMedia = typeof (options.target ?? globalThis).matchMedia === 'function';\n const systemDark = hasMatchMedia\n ? fromSubscribable(createMediaQuery(DARK_SCHEME_QUERY, { signal: controller.signal, target: options.target }))\n : null;\n\n const resolved = computed<ResolvedTheme>(() => {\n const selected = preference.value;\n if (selected !== 'system') return selected;\n return systemDark?.value.matches === true ? 'dark' : 'light';\n });\n\n const apply = effect(() => {\n const dark = resolved.value === 'dark';\n root.classList.toggle('dark', dark);\n root.classList.toggle('light', !dark);\n root.style.colorScheme = dark ? 'dark' : 'light';\n });\n\n let disposed = false;\n\n return {\n disposalSignal: controller.signal,\n dispose() {\n if (disposed) return;\n disposed = true;\n apply.dispose();\n systemDark?.dispose();\n controller.abort();\n },\n get disposed() {\n return disposed;\n },\n preference,\n resolved,\n setPreference(next) {\n preference.value = next;\n },\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n"],"mappings":"qIA0CA,IAAM,EAAoB,+BAG1B,SAAgB,sBAAsB,EAAkC,CAAC,EAAoB,CAC3F,IAAM,EAAO,EAAQ,MAAQ,SAAS,gBAChC,EAAa,IAAI,gBACjB,GAAA,EAAa,EAAA,OAAA,CAAwB,EAAQ,SAAW,QAAQ,EAGhE,EADgB,OAAQ,EAAQ,QAAU,WAAA,CAAY,YAAe,YAAA,EAEvE,EAAA,iBAAA,EAAA,EAAiB,EAAA,iBAAA,CAAiB,EAAmB,CAAE,OAAQ,EAAW,OAAQ,OAAQ,EAAQ,MAAO,CAAC,CAAC,EAC3G,KAEE,GAAA,EAAW,EAAA,SAAA,KAA8B,CAC7C,IAAM,EAAW,EAAW,MAE5B,OADI,IAAa,SACV,GAAY,MAAM,UAAY,GAAO,OAAS,QADnB,CAEpC,CAAC,EAEK,GAAA,EAAQ,EAAA,OAAA,KAAa,CACzB,IAAM,EAAO,EAAS,QAAU,OAChC,EAAK,UAAU,OAAO,OAAQ,CAAI,EAClC,EAAK,UAAU,OAAO,QAAS,CAAC,CAAI,EACpC,EAAK,MAAM,YAAc,EAAO,OAAS,OAC3C,CAAC,EAEG,EAAW,GAEf,MAAO,CACL,eAAgB,EAAW,OAC3B,SAAU,CACJ,IACJ,EAAW,GACX,EAAM,QAAQ,EACd,GAAY,QAAQ,EACpB,EAAW,MAAM,EACnB,EACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aACA,WACA,cAAc,EAAM,CAClB,EAAW,MAAQ,CACrB,EACA,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,CACF,CACF"}
1
+ {"version":3,"file":"theme.cjs","names":[],"sources":["../src/theme.ts"],"sourcesContent":["import { computed, effect, fromSubscribable, type Readable, type Signal, signal } from '@vielzeug/ripple';\nimport { createMediaQuery } from '@vielzeug/sentinel';\n\n/** User-selectable theme: an explicit mode, or follow the OS. */\nexport type ThemePreference = 'dark' | 'light' | 'system';\n\n/** The mode actually in effect after resolving `system` against the OS preference. */\nexport type ResolvedTheme = 'dark' | 'light';\n\nexport interface ThemeControllerOptions {\n /** Starting preference. @default 'system' */\n readonly initial?: ThemePreference;\n /** Element that carries the theme classes and `color-scheme`. @default document.documentElement */\n readonly root?: HTMLElement;\n /** Window whose `matchMedia` backs `system`. @default globalThis */\n readonly target?: Window;\n}\n\n/**\n * Owns the light/dark/system theme for the document: a reactive preference, the effective\n * (resolved) mode, and the DOM application refine's `styles/theme.css` expects: the `.dark`\n * class plus the `color-scheme` property on the root element, so every `light-dark()` token\n * resolves to the right branch.\n *\n * The controller does NOT persist the preference or expose an accent color: those are consumer\n * concerns (wire `watch(controller.preference, save)` for persistence; set `--color-primary-hue`\n * yourself). It only tracks the OS `prefers-color-scheme` while in `system` mode and applies the\n * result.\n */\nexport interface ThemeController {\n readonly disposalSignal: AbortSignal;\n /** Stops applying and releases the OS listener. */\n dispose(): void;\n readonly disposed: boolean;\n /** The user's selection. Write through {@link setPreference} or `preference.value = …`. */\n readonly preference: Signal<ThemePreference>;\n /** The effective mode after resolving `system`. */\n readonly resolved: Readable<ResolvedTheme>;\n setPreference(preference: ThemePreference): void;\n [Symbol.dispose](): void;\n}\n\nconst DARK_SCHEME_QUERY = '(prefers-color-scheme: dark)';\n\n/** Creates a document theme controller. Call once at app startup. */\nexport function createThemeController(options: ThemeControllerOptions = {}): ThemeController {\n const root = options.root ?? document.documentElement;\n const controller = new AbortController();\n const preference = signal<ThemePreference>(options.initial ?? 'system');\n\n const hasMatchMedia = typeof (options.target ?? globalThis).matchMedia === 'function';\n const systemDark = hasMatchMedia\n ? fromSubscribable(createMediaQuery(DARK_SCHEME_QUERY, { signal: controller.signal, target: options.target }))\n : null;\n\n const resolved = computed<ResolvedTheme>(() => {\n const selected = preference.value;\n if (selected !== 'system') return selected;\n return systemDark?.value.matches === true ? 'dark' : 'light';\n });\n\n const apply = effect(() => {\n const dark = resolved.value === 'dark';\n root.classList.toggle('dark', dark);\n root.classList.toggle('light', !dark);\n root.style.colorScheme = dark ? 'dark' : 'light';\n });\n\n let disposed = false;\n\n return {\n disposalSignal: controller.signal,\n dispose() {\n if (disposed) return;\n disposed = true;\n apply.dispose();\n systemDark?.dispose();\n controller.abort();\n },\n get disposed() {\n return disposed;\n },\n preference,\n resolved,\n setPreference(next) {\n preference.value = next;\n },\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n"],"mappings":"qIA0CA,IAAM,EAAoB,+BAG1B,SAAgB,sBAAsB,EAAkC,CAAC,EAAoB,CAC3F,IAAM,EAAO,EAAQ,MAAQ,SAAS,gBAChC,EAAa,IAAI,gBACjB,GAAA,EAAa,EAAA,OAAA,CAAwB,EAAQ,SAAW,QAAQ,EAGhE,EADgB,OAAQ,EAAQ,QAAU,WAAA,CAAY,YAAe,YAAA,EAEvE,EAAA,iBAAA,EAAA,EAAiB,EAAA,iBAAA,CAAiB,EAAmB,CAAE,OAAQ,EAAW,OAAQ,OAAQ,EAAQ,MAAO,CAAC,CAAC,EAC3G,KAEE,GAAA,EAAW,EAAA,SAAA,KAA8B,CAC7C,IAAM,EAAW,EAAW,MAE5B,OADI,IAAa,SACV,GAAY,MAAM,UAAY,GAAO,OAAS,QADnB,CAEpC,CAAC,EAEK,GAAA,EAAQ,EAAA,OAAA,KAAa,CACzB,IAAM,EAAO,EAAS,QAAU,OAChC,EAAK,UAAU,OAAO,OAAQ,CAAI,EAClC,EAAK,UAAU,OAAO,QAAS,CAAC,CAAI,EACpC,EAAK,MAAM,YAAc,EAAO,OAAS,OAC3C,CAAC,EAEG,EAAW,GAEf,MAAO,CACL,eAAgB,EAAW,OAC3B,SAAU,CACJ,IACJ,EAAW,GACX,EAAM,QAAQ,EACd,GAAY,QAAQ,EACpB,EAAW,MAAM,EACnB,EACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aACA,WACA,cAAc,EAAM,CAClB,EAAW,MAAQ,CACrB,EACA,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,CACF,CACF"}
package/dist/theme.d.ts CHANGED
@@ -13,11 +13,11 @@ export interface ThemeControllerOptions {
13
13
  }
14
14
  /**
15
15
  * Owns the light/dark/system theme for the document: a reactive preference, the effective
16
- * (resolved) mode, and the DOM application refine's `styles/theme.css` expects — the `.dark`
16
+ * (resolved) mode, and the DOM application refine's `styles/theme.css` expects: the `.dark`
17
17
  * class plus the `color-scheme` property on the root element, so every `light-dark()` token
18
18
  * resolves to the right branch.
19
19
  *
20
- * The controller does NOT persist the preference or expose an accent color — those are consumer
20
+ * The controller does NOT persist the preference or expose an accent color: those are consumer
21
21
  * concerns (wire `watch(controller.preference, save)` for persistence; set `--color-primary-hue`
22
22
  * yourself). It only tracks the OS `prefers-color-scheme` while in `system` mode and applies the
23
23
  * result.
package/dist/theme.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","names":[],"sources":["../src/theme.ts"],"sourcesContent":["import { computed, effect, fromSubscribable, type Readable, type Signal, signal } from '@vielzeug/ripple';\nimport { createMediaQuery } from '@vielzeug/sentinel';\n\n/** User-selectable theme: an explicit mode, or follow the OS. */\nexport type ThemePreference = 'dark' | 'light' | 'system';\n\n/** The mode actually in effect after resolving `system` against the OS preference. */\nexport type ResolvedTheme = 'dark' | 'light';\n\nexport interface ThemeControllerOptions {\n /** Starting preference. @default 'system' */\n readonly initial?: ThemePreference;\n /** Element that carries the theme classes and `color-scheme`. @default document.documentElement */\n readonly root?: HTMLElement;\n /** Window whose `matchMedia` backs `system`. @default globalThis */\n readonly target?: Window;\n}\n\n/**\n * Owns the light/dark/system theme for the document: a reactive preference, the effective\n * (resolved) mode, and the DOM application refine's `styles/theme.css` expects — the `.dark`\n * class plus the `color-scheme` property on the root element, so every `light-dark()` token\n * resolves to the right branch.\n *\n * The controller does NOT persist the preference or expose an accent color — those are consumer\n * concerns (wire `watch(controller.preference, save)` for persistence; set `--color-primary-hue`\n * yourself). It only tracks the OS `prefers-color-scheme` while in `system` mode and applies the\n * result.\n */\nexport interface ThemeController {\n readonly disposalSignal: AbortSignal;\n /** Stops applying and releases the OS listener. */\n dispose(): void;\n readonly disposed: boolean;\n /** The user's selection. Write through {@link setPreference} or `preference.value = …`. */\n readonly preference: Signal<ThemePreference>;\n /** The effective mode after resolving `system`. */\n readonly resolved: Readable<ResolvedTheme>;\n setPreference(preference: ThemePreference): void;\n [Symbol.dispose](): void;\n}\n\nconst DARK_SCHEME_QUERY = '(prefers-color-scheme: dark)';\n\n/** Creates a document theme controller. Call once at app startup. */\nexport function createThemeController(options: ThemeControllerOptions = {}): ThemeController {\n const root = options.root ?? document.documentElement;\n const controller = new AbortController();\n const preference = signal<ThemePreference>(options.initial ?? 'system');\n\n const hasMatchMedia = typeof (options.target ?? globalThis).matchMedia === 'function';\n const systemDark = hasMatchMedia\n ? fromSubscribable(createMediaQuery(DARK_SCHEME_QUERY, { signal: controller.signal, target: options.target }))\n : null;\n\n const resolved = computed<ResolvedTheme>(() => {\n const selected = preference.value;\n if (selected !== 'system') return selected;\n return systemDark?.value.matches === true ? 'dark' : 'light';\n });\n\n const apply = effect(() => {\n const dark = resolved.value === 'dark';\n root.classList.toggle('dark', dark);\n root.classList.toggle('light', !dark);\n root.style.colorScheme = dark ? 'dark' : 'light';\n });\n\n let disposed = false;\n\n return {\n disposalSignal: controller.signal,\n dispose() {\n if (disposed) return;\n disposed = true;\n apply.dispose();\n systemDark?.dispose();\n controller.abort();\n },\n get disposed() {\n return disposed;\n },\n preference,\n resolved,\n setPreference(next) {\n preference.value = next;\n },\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n"],"mappings":"gJA0CA,IAAM,EAAoB,+BAG1B,SAAgB,sBAAsB,EAAkC,CAAC,EAAoB,CAC3F,IAAM,EAAO,EAAQ,MAAQ,SAAS,gBAChC,EAAa,IAAI,gBACjB,EAAa,EAAwB,EAAQ,SAAW,QAAQ,EAGhE,EADgB,OAAQ,EAAQ,QAAU,WAAA,CAAY,YAAe,WAEvE,EAAiB,EAAiB,EAAmB,CAAE,OAAQ,EAAW,OAAQ,OAAQ,EAAQ,MAAO,CAAC,CAAC,EAC3G,KAEE,EAAW,MAA8B,CAC7C,IAAM,EAAW,EAAW,MAE5B,OADI,IAAa,SACV,GAAY,MAAM,UAAY,GAAO,OAAS,QADnB,CAEpC,CAAC,EAEK,EAAQ,MAAa,CACzB,IAAM,EAAO,EAAS,QAAU,OAChC,EAAK,UAAU,OAAO,OAAQ,CAAI,EAClC,EAAK,UAAU,OAAO,QAAS,CAAC,CAAI,EACpC,EAAK,MAAM,YAAc,EAAO,OAAS,OAC3C,CAAC,EAEG,EAAW,GAEf,MAAO,CACL,eAAgB,EAAW,OAC3B,SAAU,CACJ,IACJ,EAAW,GACX,EAAM,QAAQ,EACd,GAAY,QAAQ,EACpB,EAAW,MAAM,EACnB,EACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aACA,WACA,cAAc,EAAM,CAClB,EAAW,MAAQ,CACrB,EACA,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,CACF,CACF"}
1
+ {"version":3,"file":"theme.js","names":[],"sources":["../src/theme.ts"],"sourcesContent":["import { computed, effect, fromSubscribable, type Readable, type Signal, signal } from '@vielzeug/ripple';\nimport { createMediaQuery } from '@vielzeug/sentinel';\n\n/** User-selectable theme: an explicit mode, or follow the OS. */\nexport type ThemePreference = 'dark' | 'light' | 'system';\n\n/** The mode actually in effect after resolving `system` against the OS preference. */\nexport type ResolvedTheme = 'dark' | 'light';\n\nexport interface ThemeControllerOptions {\n /** Starting preference. @default 'system' */\n readonly initial?: ThemePreference;\n /** Element that carries the theme classes and `color-scheme`. @default document.documentElement */\n readonly root?: HTMLElement;\n /** Window whose `matchMedia` backs `system`. @default globalThis */\n readonly target?: Window;\n}\n\n/**\n * Owns the light/dark/system theme for the document: a reactive preference, the effective\n * (resolved) mode, and the DOM application refine's `styles/theme.css` expects: the `.dark`\n * class plus the `color-scheme` property on the root element, so every `light-dark()` token\n * resolves to the right branch.\n *\n * The controller does NOT persist the preference or expose an accent color: those are consumer\n * concerns (wire `watch(controller.preference, save)` for persistence; set `--color-primary-hue`\n * yourself). It only tracks the OS `prefers-color-scheme` while in `system` mode and applies the\n * result.\n */\nexport interface ThemeController {\n readonly disposalSignal: AbortSignal;\n /** Stops applying and releases the OS listener. */\n dispose(): void;\n readonly disposed: boolean;\n /** The user's selection. Write through {@link setPreference} or `preference.value = …`. */\n readonly preference: Signal<ThemePreference>;\n /** The effective mode after resolving `system`. */\n readonly resolved: Readable<ResolvedTheme>;\n setPreference(preference: ThemePreference): void;\n [Symbol.dispose](): void;\n}\n\nconst DARK_SCHEME_QUERY = '(prefers-color-scheme: dark)';\n\n/** Creates a document theme controller. Call once at app startup. */\nexport function createThemeController(options: ThemeControllerOptions = {}): ThemeController {\n const root = options.root ?? document.documentElement;\n const controller = new AbortController();\n const preference = signal<ThemePreference>(options.initial ?? 'system');\n\n const hasMatchMedia = typeof (options.target ?? globalThis).matchMedia === 'function';\n const systemDark = hasMatchMedia\n ? fromSubscribable(createMediaQuery(DARK_SCHEME_QUERY, { signal: controller.signal, target: options.target }))\n : null;\n\n const resolved = computed<ResolvedTheme>(() => {\n const selected = preference.value;\n if (selected !== 'system') return selected;\n return systemDark?.value.matches === true ? 'dark' : 'light';\n });\n\n const apply = effect(() => {\n const dark = resolved.value === 'dark';\n root.classList.toggle('dark', dark);\n root.classList.toggle('light', !dark);\n root.style.colorScheme = dark ? 'dark' : 'light';\n });\n\n let disposed = false;\n\n return {\n disposalSignal: controller.signal,\n dispose() {\n if (disposed) return;\n disposed = true;\n apply.dispose();\n systemDark?.dispose();\n controller.abort();\n },\n get disposed() {\n return disposed;\n },\n preference,\n resolved,\n setPreference(next) {\n preference.value = next;\n },\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n}\n"],"mappings":"gJA0CA,IAAM,EAAoB,+BAG1B,SAAgB,sBAAsB,EAAkC,CAAC,EAAoB,CAC3F,IAAM,EAAO,EAAQ,MAAQ,SAAS,gBAChC,EAAa,IAAI,gBACjB,EAAa,EAAwB,EAAQ,SAAW,QAAQ,EAGhE,EADgB,OAAQ,EAAQ,QAAU,WAAA,CAAY,YAAe,WAEvE,EAAiB,EAAiB,EAAmB,CAAE,OAAQ,EAAW,OAAQ,OAAQ,EAAQ,MAAO,CAAC,CAAC,EAC3G,KAEE,EAAW,MAA8B,CAC7C,IAAM,EAAW,EAAW,MAE5B,OADI,IAAa,SACV,GAAY,MAAM,UAAY,GAAO,OAAS,QADnB,CAEpC,CAAC,EAEK,EAAQ,MAAa,CACzB,IAAM,EAAO,EAAS,QAAU,OAChC,EAAK,UAAU,OAAO,OAAQ,CAAI,EAClC,EAAK,UAAU,OAAO,QAAS,CAAC,CAAI,EACpC,EAAK,MAAM,YAAc,EAAO,OAAS,OAC3C,CAAC,EAEG,EAAW,GAEf,MAAO,CACL,eAAgB,EAAW,OAC3B,SAAU,CACJ,IACJ,EAAW,GACX,EAAM,QAAQ,EACd,GAAY,QAAQ,EACpB,EAAW,MAAM,EACnB,EACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aACA,WACA,cAAc,EAAM,CAClB,EAAW,MAAQ,CACrB,EACA,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,CACF,CACF"}
@@ -35,7 +35,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
35
35
  ref="${s}"
36
36
  id="${v}"
37
37
  role="listbox"
38
- aria-label="${()=>t.label.value?`${t.label.value} — select time`:`Select time`}"
38
+ aria-label="${()=>t.label.value?`${t.label.value}: select time`:`Select time`}"
39
39
  ?data-open="${i}"
40
40
  @keydown="${handleDropdownKeydown}">
41
41
  <div class="cols-row">
@@ -1 +1 @@
1
- {"version":3,"file":"time-picker.cjs","names":[],"sources":["../src/inputs/time-picker/time-picker.ts"],"sourcesContent":["import { bind, define, getHost, html, onMounted, prop, ref, useField } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { createDropdownPositioner } from '../../core';\nimport type { VisualVariant } from '../../shared';\n\nimport { disablableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin } from '../../styles';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './time-picker.css?inline';\n\nexport { ICON_TAG } from '../../content/icon/icon';\nexport { INPUT_TAG } from '../input/input';\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type OreTimePickerEvents = {\n change: Event;\n input: Event;\n};\n\nexport type OreTimePickerProps = {\n /** Theme color */\n color?: string;\n /** Disable the picker */\n disabled?: boolean;\n /** Validation error message */\n error?: string;\n /** Expand to container width */\n fullwidth?: boolean;\n /** Helper text below the field */\n helper?: string;\n /** Visible label */\n label?: string;\n /** Label placement */\n 'label-placement'?: 'inset' | 'outside';\n /** Maximum selectable time in HH:MM format (24-hour) */\n max?: string;\n /** Minimum selectable time in HH:MM format (24-hour) */\n min?: string;\n /** Minute step interval (1–59) */\n 'minute-step'?: number;\n /** Form field name */\n name?: string;\n /** Placeholder shown in the trigger */\n placeholder?: string;\n /** Mark field as required */\n required?: boolean;\n /** Border radius */\n rounded?: string;\n /** Component size */\n size?: string;\n /**\n * Shows an inline green check icon inside the field to confirm the value has\n * passed validation. Ignored while `error` is set — an error always wins.\n */\n success?: boolean;\n /** Display format: '12' for AM/PM, '24' for 24-hour (default: '24') */\n 'time-format'?: '12' | '24';\n /** Selected time in HH:MM format (24-hour) */\n value?: string;\n /** Visual variant */\n variant?: Exclude<VisualVariant, 'text' | 'frost'>;\n};\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/** Parse \"HH:MM\" → { hours: 0-23, minutes: 0-59 } | null */\nfunction parseTime(val: string | undefined | null): { hours: number; minutes: number } | null {\n if (!val) return null;\n\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(val.trim());\n\n if (!match) return null;\n\n const h = Number(match[1]);\n const m = Number(match[2]);\n\n if (h < 0 || h > 23 || m < 0 || m > 59) return null;\n\n return { hours: h, minutes: m };\n}\n\n/** Format { hours, minutes } → \"HH:MM\" (24-hour, zero-padded) */\nfunction formatTime(h: number, m: number): string {\n return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n}\n\n/** Format for display label (respects 12/24 mode) */\nfunction formatDisplay(h: number, m: number, format: '12' | '24'): string {\n if (format === '12') {\n const period = h >= 12 ? 'PM' : 'AM';\n const displayH = h % 12 === 0 ? 12 : h % 12;\n\n return `${String(displayH).padStart(2, '0')}:${String(m).padStart(2, '0')} ${period}`;\n }\n\n return formatTime(h, m);\n}\n\n/** Clamp value to [min, max] in total minutes */\nfunction clampTime(\n h: number,\n m: number,\n minVal: string | undefined | null,\n maxVal: string | undefined | null,\n): { hours: number; minutes: number } {\n const total = h * 60 + m;\n const minParsed = parseTime(minVal);\n const maxParsed = parseTime(maxVal);\n const minMins = minParsed ? minParsed.hours * 60 + minParsed.minutes : 0;\n const maxMins = maxParsed ? maxParsed.hours * 60 + maxParsed.minutes : 23 * 60 + 59;\n const clamped = Math.min(Math.max(total, minMins), maxMins);\n\n return { hours: Math.floor(clamped / 60), minutes: clamped % 60 };\n}\n\n/**\n * An accessible time picker with a scrollable clock dropdown.\n * Supports 12/24-hour display formats, min/max bounds, minute steps, and form association.\n *\n * @element ore-time-picker\n *\n * @attr {string} value - Selected time in HH:MM (24-hour) format\n * @attr {string} min - Minimum selectable time (HH:MM)\n * @attr {string} max - Maximum selectable time (HH:MM)\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {string} placeholder - Trigger placeholder\n * @attr {boolean} disabled - Disable the picker\n * @attr {boolean} required - Required field\n * @attr {string} name - Form field name\n * @attr {string} error - Error message\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} helper - Helper text\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} time-format - '12' or '24' (default: '24')\n * @attr {number} minute-step - Minute increment (default: 5)\n *\n * @fires input - Fired when a time is selected.\n * @fires change - Fired when a time is selected.\n *\n * @slot label - Custom label for the trigger field\n * @slot prefix - Content before the trigger text (e.g. icon)\n * @slot helper - Custom helper text\n * @slot error - Custom error content\n *\n * @cssprop --time-picker-bg - Dropdown background\n * @cssprop --time-picker-border-color - Dropdown border color\n * @cssprop --time-picker-radius - Dropdown border radius\n * @cssprop --time-picker-shadow - Dropdown shadow\n * @cssprop --time-picker-selected-bg - Selected option background\n * @cssprop --time-picker-option-hover-bg - Option hover background\n *\n * @part field - The trigger field\n * @part dropdown - The floating time dropdown\n * @part column - A scrollable column (hours / minutes / period)\n * @part option - An individual time option cell\n *\n * @example\n * ```html\n * <!-- 24-hour clock, 15-minute steps -->\n * <ore-time-picker label=\"Meeting time\" value=\"09:30\" minute-step=\"15\" color=\"primary\"></ore-time-picker>\n *\n * <!-- 12-hour AM/PM format -->\n * <ore-time-picker label=\"Appointment\" time-format=\"12\" minute-step=\"30\"></ore-time-picker>\n *\n * <!-- Outside label, bordered variant -->\n * <ore-time-picker label=\"Start time\" label-placement=\"outside\" variant=\"bordered\"></ore-time-picker>\n * ```\n */\nexport const TIME_PICKER_TAG = 'ore-time-picker' as const;\n\ndefine<OreTimePickerProps>(TIME_PICKER_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n max: prop.string(),\n min: prop.string(),\n 'minute-step': prop.number(5),\n name: prop.string(),\n placeholder: prop.string(),\n required: prop.bool(false),\n success: prop.bool(false),\n 'time-format': prop.oneOf(['12', '24'] as const, '24'),\n value: prop.string(),\n variant: prop.string<'flat' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n\n setup(props) {\n const el = getHost();\n\n // ── Signals ──────────────────────────────────────────────────────────────\n\n const isOpen = signal(false);\n const selectedTime = signal<{ hours: number; minutes: number } | null>(parseTime(props.value.value));\n\n defineFieldValue(\n el,\n () => {\n const value = selectedTime.value;\n\n return value ? formatTime(value.hours, value.minutes) : '';\n },\n (value) => {\n selectedTime.value = parseTime(value);\n },\n );\n\n // ── Floating position ────────────────────────────────────────────────────\n // Same Orbit-powered positioner ore-date-picker's `.calendar` popup uses (see its own\n // comment for the full rationale) — `fixed` + computed `top`/`left` instead of a static\n // `position: absolute; top: 100%`, so the dropdown flips/shifts to stay within the nearest\n // clipping ancestor instead of silently overflowing it.\n const triggerRef = ref<HTMLElement>();\n const dropdownRef = ref<HTMLElement>();\n\n const positioner = createDropdownPositioner({\n getFloating: () => dropdownRef.value ?? null,\n getOffsetPx: () => 4,\n getReference: () => triggerRef.value ?? null,\n matchWidth: false,\n });\n\n let stopAutoUpdate: (() => void) | null = null;\n\n const isDisabled = computed(() => Boolean(props.disabled.value));\n\n // ── Form value ────────────────────────────────────────────────────────────\n\n useField<string>({\n disabled: isDisabled,\n toFormValue: (v) => v || null,\n value: computed(() => {\n const t = selectedTime.value;\n\n return t ? formatTime(t.hours, t.minutes) : '';\n }),\n });\n\n // ── Computed helpers ──────────────────────────────────────────────────────\n\n const fmt = computed(() => props['time-format'].value ?? '24');\n const minuteStep = computed(() => Math.max(1, Math.min(59, props['minute-step'].value ?? 5)));\n\n const triggerText = computed(() => {\n if (!selectedTime.value) return props.placeholder.value || '';\n\n return formatDisplay(selectedTime.value.hours, selectedTime.value.minutes, fmt.value as '12' | '24');\n });\n\n /** All hour options for the column (0-23 in 24h; 1-12 in 12h) */\n const hourOptions = computed<number[]>(() => {\n if (fmt.value === '12') {\n return Array.from({ length: 12 }, (_, i) => i + 1);\n }\n\n return Array.from({ length: 24 }, (_, i) => i);\n });\n\n /** All minute options for the column, stepped */\n const minuteOptions = computed<number[]>(() => {\n const step = minuteStep.value;\n const opts: number[] = [];\n\n for (let m = 0; m < 60; m += step) opts.push(m);\n\n return opts;\n });\n\n const dialogId = `time-picker-${Math.random().toString(36).slice(2, 9)}-dropdown`;\n\n /** Convert 24h hour to display hour in current format */\n function toDisplayHour(h24: number): number {\n if (fmt.value === '24') return h24;\n\n const h12 = h24 % 12;\n\n return h12 === 0 ? 12 : h12;\n }\n\n /** Convert display hour + period → 24h hour */\n function to24Hour(displayHour: number, period: 'AM' | 'PM'): number {\n if (fmt.value === '24') return displayHour;\n\n if (period === 'AM') return displayHour === 12 ? 0 : displayHour;\n\n return displayHour === 12 ? 12 : displayHour + 12;\n }\n\n /** Whether a given HH:MM is out of [min, max] */\n function isTimeDisabled(h: number, m: number): boolean {\n const total = h * 60 + m;\n const minParsed = parseTime(props.min.value);\n const maxParsed = parseTime(props.max.value);\n\n if (minParsed && total < minParsed.hours * 60 + minParsed.minutes) return true;\n\n if (maxParsed && total > maxParsed.hours * 60 + maxParsed.minutes) return true;\n\n return false;\n }\n\n // ── State for focused/pending selection ───────────────────────────────────\n\n /** Pending hour (24h) while user is navigating columns */\n const pendingHour = signal<number>(selectedTime.value?.hours ?? 0);\n /** Pending minute */\n const pendingMinute = signal<number>(selectedTime.value?.minutes ?? 0);\n /** Pending period (12h mode) */\n const pendingPeriod = signal<'AM' | 'PM'>((selectedTime.value?.hours ?? 0) >= 12 ? 'PM' : 'AM');\n\n // ── Sync value prop externally ────────────────────────────────────────────\n\n let lastValueProp = props.value.value;\n\n onMounted(() => {\n const interval = setInterval(() => {\n const current = props.value.value;\n\n if (current !== lastValueProp) {\n lastValueProp = current;\n\n const parsed = parseTime(current);\n\n selectedTime.value = parsed;\n\n if (parsed) {\n pendingHour.value = parsed.hours;\n pendingMinute.value = parsed.minutes;\n pendingPeriod.value = parsed.hours >= 12 ? 'PM' : 'AM';\n }\n }\n }, 50);\n\n return () => clearInterval(interval);\n });\n\n // ── Commit ────────────────────────────────────────────────────────────────\n\n function commit(h24: number, m: number): void {\n const clamped = clampTime(h24, m, props.min.value, props.max.value);\n const snapped = Math.round(clamped.minutes / minuteStep.value) * minuteStep.value;\n const snappedMin = Math.min(snapped, 59);\n\n selectedTime.value = { hours: clamped.hours, minutes: snappedMin };\n setFieldValue(el, formatTime(clamped.hours, snappedMin));\n dispatchNativeFieldEvent(el, 'input');\n dispatchNativeFieldEvent(el, 'change');\n }\n\n function commitFromMinute(m: number): void {\n const h24 = fmt.value === '12' ? to24Hour(pendingHour.value, pendingPeriod.value) : pendingHour.value;\n\n pendingMinute.value = m;\n commit(h24, m);\n closePicker();\n }\n\n // ── Open / close ──────────────────────────────────────────────────────────\n\n function openPicker(): void {\n if (isDisabled.value) return;\n\n const current = selectedTime.value;\n\n if (current) {\n pendingHour.value = fmt.value === '12' ? toDisplayHour(current.hours) : current.hours;\n pendingMinute.value = current.minutes;\n pendingPeriod.value = current.hours >= 12 ? 'PM' : 'AM';\n } else {\n pendingHour.value = fmt.value === '12' ? 12 : 0;\n pendingMinute.value = 0;\n pendingPeriod.value = 'AM';\n }\n\n isOpen.value = true;\n positioner.update();\n stopAutoUpdate = positioner.startAutoUpdate?.() ?? null;\n }\n\n function closePicker(): void {\n isOpen.value = false;\n stopAutoUpdate?.();\n stopAutoUpdate = null;\n }\n\n function handleTriggerClick(): void {\n if (isOpen.value) closePicker();\n else openPicker();\n }\n\n // ── Outside click ─────────────────────────────────────────────────────────\n\n function handleOutsideClick(e: PointerEvent | MouseEvent): void {\n if (!isOpen.value) return;\n\n if (!e.composedPath().includes(el)) closePicker();\n }\n\n onMounted(() => {\n document.addEventListener('pointerdown', handleOutsideClick, { capture: true });\n\n return () => {\n document.removeEventListener('pointerdown', handleOutsideClick, { capture: true });\n stopAutoUpdate?.();\n stopAutoUpdate = null;\n };\n });\n\n // ── Keyboard ──────────────────────────────────────────────────────────────\n\n function handleTriggerKeydown(e: KeyboardEvent): void {\n if (isDisabled.value) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleTriggerClick();\n } else if (e.key === 'Escape' && isOpen.value) {\n e.preventDefault();\n closePicker();\n } else if ((e.key === 'ArrowDown' || e.key === 'ArrowUp') && !isOpen.value) {\n e.preventDefault();\n openPicker();\n }\n }\n\n function handleDropdownKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n closePicker();\n }\n }\n\n function handleHourKeydown(e: KeyboardEvent): void {\n const opts = hourOptions.value;\n const idx = opts.indexOf(pendingHour.value);\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n pendingHour.value = opts[(idx - 1 + opts.length) % opts.length];\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n pendingHour.value = opts[(idx + 1) % opts.length];\n }\n }\n\n function handleMinuteKeydown(e: KeyboardEvent): void {\n const opts = minuteOptions.value;\n const idx = opts.indexOf(pendingMinute.value);\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n pendingMinute.value = opts[(idx - 1 + opts.length) % opts.length];\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n pendingMinute.value = opts[(idx + 1) % opts.length];\n }\n }\n\n function handlePeriodKeydown(e: KeyboardEvent): void {\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n e.preventDefault();\n pendingPeriod.value = pendingPeriod.value === 'AM' ? 'PM' : 'AM';\n }\n }\n\n // ── Host bindings ─────────────────────────────────────────────────────────\n\n bind({\n attr: {\n open: () => (isOpen.value ? true : undefined),\n },\n });\n\n // ── ore-input prop helpers ────────────────────────────────────────────────\n\n const inputValue = () => triggerText.value;\n const inputLabel = () => props.label.value ?? '';\n const inputPlaceholder = () => props.placeholder.value ?? '';\n const inputLabelPlacement = () => props['label-placement'].value ?? 'inset';\n const inputColor = () => props.color?.value ?? undefined;\n const inputSize = () => props.size?.value ?? undefined;\n const inputVariant = () => props.variant?.value ?? undefined;\n const inputRounded = () => props.rounded?.value ?? undefined;\n const inputHelper = () => props.helper.value ?? '';\n const inputError = () => props.error.value ?? '';\n const inputDisabled = () => (isDisabled.value ? true : undefined);\n const inputRequired = () => (props.required.value ? true : undefined);\n const inputFullwidth = () => (props.fullwidth.value ? true : undefined);\n\n return html`\n <!-- Trigger -->\n <ore-input\n class=\"trigger\"\n ref=\"${triggerRef}\"\n readonly\n tabindex=\"0\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-controls=\"${dialogId}\"\n aria-expanded=\"${() => String(isOpen.value)}\"\n aria-disabled=\"${() => (isDisabled.value ? 'true' : null)}\"\n value=\"${inputValue}\"\n label=\"${inputLabel}\"\n placeholder=\"${inputPlaceholder}\"\n label-placement=\"${inputLabelPlacement}\"\n color=\"${inputColor}\"\n size=\"${inputSize}\"\n variant=\"${inputVariant}\"\n rounded=\"${inputRounded}\"\n helper=\"${inputHelper}\"\n error=\"${inputError}\"\n ?disabled=\"${inputDisabled}\"\n ?required=\"${inputRequired}\"\n ?fullwidth=\"${inputFullwidth}\"\n ?success=\"${() => props.success.value}\"\n @click=\"${handleTriggerClick}\"\n @keydown=\"${handleTriggerKeydown}\">\n <ore-icon slot=\"suffix\" name=\"clock\" size=\"16\" stroke-width=\"1.75\" aria-hidden=\"true\"></ore-icon>\n </ore-input>\n\n <!-- Dropdown -->\n <div\n class=\"dropdown\"\n ref=\"${dropdownRef}\"\n id=\"${dialogId}\"\n role=\"listbox\"\n aria-label=\"${() => (props.label.value ? `${props.label.value} — select time` : 'Select time')}\"\n ?data-open=\"${isOpen}\"\n @keydown=\"${handleDropdownKeydown}\">\n <div class=\"cols-row\">\n <!-- Hours column -->\n <div class=\"col\" part=\"column\" role=\"group\" aria-label=\"Hours\">\n <div class=\"col-label\" aria-hidden=\"true\">HH</div>\n <div class=\"col-scroll\">\n ${() =>\n hourOptions.value.map((h) => {\n const h24 = fmt.value === '12' ? to24Hour(h, pendingPeriod.value) : h;\n const disabled = isTimeDisabled(h24, pendingMinute.value);\n\n return html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingHour.value === h && !disabled ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingHour.value === h)}\"\n aria-disabled=\"${() => String(disabled)}\"\n ?data-disabled=\"${() => disabled}\"\n @click=\"${() => {\n if (!disabled) pendingHour.value = h;\n }}\"\n @keydown=\"${handleHourKeydown}\">\n ${String(h).padStart(2, '0')}\n </div>\n `;\n })}\n </div>\n </div>\n\n <div class=\"col-sep\" aria-hidden=\"true\">:</div>\n\n <!-- Minutes column -->\n <div class=\"col\" part=\"column\" role=\"group\" aria-label=\"Minutes\">\n <div class=\"col-label\" aria-hidden=\"true\">MM</div>\n <div class=\"col-scroll\">\n ${() =>\n minuteOptions.value.map((m) => {\n const h24 = fmt.value === '12' ? to24Hour(pendingHour.value, pendingPeriod.value) : pendingHour.value;\n const disabled = isTimeDisabled(h24, m);\n\n return html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingMinute.value === m && !disabled ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingMinute.value === m)}\"\n aria-disabled=\"${() => String(disabled)}\"\n ?data-disabled=\"${() => disabled}\"\n @click=\"${() => {\n if (!disabled) commitFromMinute(m);\n }}\"\n @keydown=\"${handleMinuteKeydown}\">\n ${String(m).padStart(2, '0')}\n </div>\n `;\n })}\n </div>\n </div>\n\n <!-- AM/PM column (12h mode only) -->\n ${() =>\n fmt.value === '12'\n ? html`\n <div class=\"col col-period\" part=\"column\" role=\"group\" aria-label=\"Period\">\n <div class=\"col-label\" aria-hidden=\"true\">AM/PM</div>\n <div class=\"col-scroll\">\n ${(['AM', 'PM'] as const).map(\n (p) => html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingPeriod.value === p ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingPeriod.value === p)}\"\n @click=\"${() => {\n pendingPeriod.value = p;\n }}\"\n @keydown=\"${handlePeriodKeydown}\">\n ${p}\n </div>\n `,\n )}\n </div>\n </div>\n `\n : html``}\n </div>\n </div>\n `;\n },\n\n shadow: { delegatesFocus: true },\n styles: [colorThemeMixin, reducedMotionMixin, componentStyles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"time-picker.cjs","names":[],"sources":["../src/inputs/time-picker/time-picker.ts"],"sourcesContent":["import { bind, define, getHost, html, onMounted, prop, ref, useField } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { createDropdownPositioner } from '../../core';\nimport type { VisualVariant } from '../../shared';\n\nimport { disablableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin } from '../../styles';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './time-picker.css?inline';\n\nexport { ICON_TAG } from '../../content/icon/icon';\nexport { INPUT_TAG } from '../input/input';\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type OreTimePickerEvents = {\n change: Event;\n input: Event;\n};\n\nexport type OreTimePickerProps = {\n /** Theme color */\n color?: string;\n /** Disable the picker */\n disabled?: boolean;\n /** Validation error message */\n error?: string;\n /** Expand to container width */\n fullwidth?: boolean;\n /** Helper text below the field */\n helper?: string;\n /** Visible label */\n label?: string;\n /** Label placement */\n 'label-placement'?: 'inset' | 'outside';\n /** Maximum selectable time in HH:MM format (24-hour) */\n max?: string;\n /** Minimum selectable time in HH:MM format (24-hour) */\n min?: string;\n /** Minute step interval (1–59) */\n 'minute-step'?: number;\n /** Form field name */\n name?: string;\n /** Placeholder shown in the trigger */\n placeholder?: string;\n /** Mark field as required */\n required?: boolean;\n /** Border radius */\n rounded?: string;\n /** Component size */\n size?: string;\n /**\n * Shows an inline green check icon inside the field to confirm the value has\n * passed validation. Ignored while `error` is set: an error always wins.\n */\n success?: boolean;\n /** Display format: '12' for AM/PM, '24' for 24-hour (default: '24') */\n 'time-format'?: '12' | '24';\n /** Selected time in HH:MM format (24-hour) */\n value?: string;\n /** Visual variant */\n variant?: Exclude<VisualVariant, 'text' | 'frost'>;\n};\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/** Parse \"HH:MM\" → { hours: 0-23, minutes: 0-59 } | null */\nfunction parseTime(val: string | undefined | null): { hours: number; minutes: number } | null {\n if (!val) return null;\n\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(val.trim());\n\n if (!match) return null;\n\n const h = Number(match[1]);\n const m = Number(match[2]);\n\n if (h < 0 || h > 23 || m < 0 || m > 59) return null;\n\n return { hours: h, minutes: m };\n}\n\n/** Format { hours, minutes } → \"HH:MM\" (24-hour, zero-padded) */\nfunction formatTime(h: number, m: number): string {\n return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n}\n\n/** Format for display label (respects 12/24 mode) */\nfunction formatDisplay(h: number, m: number, format: '12' | '24'): string {\n if (format === '12') {\n const period = h >= 12 ? 'PM' : 'AM';\n const displayH = h % 12 === 0 ? 12 : h % 12;\n\n return `${String(displayH).padStart(2, '0')}:${String(m).padStart(2, '0')} ${period}`;\n }\n\n return formatTime(h, m);\n}\n\n/** Clamp value to [min, max] in total minutes */\nfunction clampTime(\n h: number,\n m: number,\n minVal: string | undefined | null,\n maxVal: string | undefined | null,\n): { hours: number; minutes: number } {\n const total = h * 60 + m;\n const minParsed = parseTime(minVal);\n const maxParsed = parseTime(maxVal);\n const minMins = minParsed ? minParsed.hours * 60 + minParsed.minutes : 0;\n const maxMins = maxParsed ? maxParsed.hours * 60 + maxParsed.minutes : 23 * 60 + 59;\n const clamped = Math.min(Math.max(total, minMins), maxMins);\n\n return { hours: Math.floor(clamped / 60), minutes: clamped % 60 };\n}\n\n/**\n * An accessible time picker with a scrollable clock dropdown.\n * Supports 12/24-hour display formats, min/max bounds, minute steps, and form association.\n *\n * @element ore-time-picker\n *\n * @attr {string} value - Selected time in HH:MM (24-hour) format\n * @attr {string} min - Minimum selectable time (HH:MM)\n * @attr {string} max - Maximum selectable time (HH:MM)\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {string} placeholder - Trigger placeholder\n * @attr {boolean} disabled - Disable the picker\n * @attr {boolean} required - Required field\n * @attr {string} name - Form field name\n * @attr {string} error - Error message\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} helper - Helper text\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} time-format - '12' or '24' (default: '24')\n * @attr {number} minute-step - Minute increment (default: 5)\n *\n * @fires input - Fired when a time is selected.\n * @fires change - Fired when a time is selected.\n *\n * @slot label - Custom label for the trigger field\n * @slot prefix - Content before the trigger text (e.g. icon)\n * @slot helper - Custom helper text\n * @slot error - Custom error content\n *\n * @cssprop --time-picker-bg - Dropdown background\n * @cssprop --time-picker-border-color - Dropdown border color\n * @cssprop --time-picker-radius - Dropdown border radius\n * @cssprop --time-picker-shadow - Dropdown shadow\n * @cssprop --time-picker-selected-bg - Selected option background\n * @cssprop --time-picker-option-hover-bg - Option hover background\n *\n * @part field - The trigger field\n * @part dropdown - The floating time dropdown\n * @part column - A scrollable column (hours / minutes / period)\n * @part option - An individual time option cell\n *\n * @example\n * ```html\n * <!-- 24-hour clock, 15-minute steps -->\n * <ore-time-picker label=\"Meeting time\" value=\"09:30\" minute-step=\"15\" color=\"primary\"></ore-time-picker>\n *\n * <!-- 12-hour AM/PM format -->\n * <ore-time-picker label=\"Appointment\" time-format=\"12\" minute-step=\"30\"></ore-time-picker>\n *\n * <!-- Outside label, bordered variant -->\n * <ore-time-picker label=\"Start time\" label-placement=\"outside\" variant=\"bordered\"></ore-time-picker>\n * ```\n */\nexport const TIME_PICKER_TAG = 'ore-time-picker' as const;\n\ndefine<OreTimePickerProps>(TIME_PICKER_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n max: prop.string(),\n min: prop.string(),\n 'minute-step': prop.number(5),\n name: prop.string(),\n placeholder: prop.string(),\n required: prop.bool(false),\n success: prop.bool(false),\n 'time-format': prop.oneOf(['12', '24'] as const, '24'),\n value: prop.string(),\n variant: prop.string<'flat' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n\n setup(props) {\n const el = getHost();\n\n // ── Signals ──────────────────────────────────────────────────────────────\n\n const isOpen = signal(false);\n const selectedTime = signal<{ hours: number; minutes: number } | null>(parseTime(props.value.value));\n\n defineFieldValue(\n el,\n () => {\n const value = selectedTime.value;\n\n return value ? formatTime(value.hours, value.minutes) : '';\n },\n (value) => {\n selectedTime.value = parseTime(value);\n },\n );\n\n // ── Floating position ────────────────────────────────────────────────────\n // Same Orbit-powered positioner ore-date-picker's `.calendar` popup uses (see its own\n // comment for the full rationale): `fixed` + computed `top`/`left` instead of a static\n // `position: absolute; top: 100%`, so the dropdown flips/shifts to stay within the nearest\n // clipping ancestor instead of silently overflowing it.\n const triggerRef = ref<HTMLElement>();\n const dropdownRef = ref<HTMLElement>();\n\n const positioner = createDropdownPositioner({\n getFloating: () => dropdownRef.value ?? null,\n getOffsetPx: () => 4,\n getReference: () => triggerRef.value ?? null,\n matchWidth: false,\n });\n\n let stopAutoUpdate: (() => void) | null = null;\n\n const isDisabled = computed(() => Boolean(props.disabled.value));\n\n // ── Form value ────────────────────────────────────────────────────────────\n\n useField<string>({\n disabled: isDisabled,\n toFormValue: (v) => v || null,\n value: computed(() => {\n const t = selectedTime.value;\n\n return t ? formatTime(t.hours, t.minutes) : '';\n }),\n });\n\n // ── Computed helpers ──────────────────────────────────────────────────────\n\n const fmt = computed(() => props['time-format'].value ?? '24');\n const minuteStep = computed(() => Math.max(1, Math.min(59, props['minute-step'].value ?? 5)));\n\n const triggerText = computed(() => {\n if (!selectedTime.value) return props.placeholder.value || '';\n\n return formatDisplay(selectedTime.value.hours, selectedTime.value.minutes, fmt.value as '12' | '24');\n });\n\n /** All hour options for the column (0-23 in 24h; 1-12 in 12h) */\n const hourOptions = computed<number[]>(() => {\n if (fmt.value === '12') {\n return Array.from({ length: 12 }, (_, i) => i + 1);\n }\n\n return Array.from({ length: 24 }, (_, i) => i);\n });\n\n /** All minute options for the column, stepped */\n const minuteOptions = computed<number[]>(() => {\n const step = minuteStep.value;\n const opts: number[] = [];\n\n for (let m = 0; m < 60; m += step) opts.push(m);\n\n return opts;\n });\n\n const dialogId = `time-picker-${Math.random().toString(36).slice(2, 9)}-dropdown`;\n\n /** Convert 24h hour to display hour in current format */\n function toDisplayHour(h24: number): number {\n if (fmt.value === '24') return h24;\n\n const h12 = h24 % 12;\n\n return h12 === 0 ? 12 : h12;\n }\n\n /** Convert display hour + period → 24h hour */\n function to24Hour(displayHour: number, period: 'AM' | 'PM'): number {\n if (fmt.value === '24') return displayHour;\n\n if (period === 'AM') return displayHour === 12 ? 0 : displayHour;\n\n return displayHour === 12 ? 12 : displayHour + 12;\n }\n\n /** Whether a given HH:MM is out of [min, max] */\n function isTimeDisabled(h: number, m: number): boolean {\n const total = h * 60 + m;\n const minParsed = parseTime(props.min.value);\n const maxParsed = parseTime(props.max.value);\n\n if (minParsed && total < minParsed.hours * 60 + minParsed.minutes) return true;\n\n if (maxParsed && total > maxParsed.hours * 60 + maxParsed.minutes) return true;\n\n return false;\n }\n\n // ── State for focused/pending selection ───────────────────────────────────\n\n /** Pending hour (24h) while user is navigating columns */\n const pendingHour = signal<number>(selectedTime.value?.hours ?? 0);\n /** Pending minute */\n const pendingMinute = signal<number>(selectedTime.value?.minutes ?? 0);\n /** Pending period (12h mode) */\n const pendingPeriod = signal<'AM' | 'PM'>((selectedTime.value?.hours ?? 0) >= 12 ? 'PM' : 'AM');\n\n // ── Sync value prop externally ────────────────────────────────────────────\n\n let lastValueProp = props.value.value;\n\n onMounted(() => {\n const interval = setInterval(() => {\n const current = props.value.value;\n\n if (current !== lastValueProp) {\n lastValueProp = current;\n\n const parsed = parseTime(current);\n\n selectedTime.value = parsed;\n\n if (parsed) {\n pendingHour.value = parsed.hours;\n pendingMinute.value = parsed.minutes;\n pendingPeriod.value = parsed.hours >= 12 ? 'PM' : 'AM';\n }\n }\n }, 50);\n\n return () => clearInterval(interval);\n });\n\n // ── Commit ────────────────────────────────────────────────────────────────\n\n function commit(h24: number, m: number): void {\n const clamped = clampTime(h24, m, props.min.value, props.max.value);\n const snapped = Math.round(clamped.minutes / minuteStep.value) * minuteStep.value;\n const snappedMin = Math.min(snapped, 59);\n\n selectedTime.value = { hours: clamped.hours, minutes: snappedMin };\n setFieldValue(el, formatTime(clamped.hours, snappedMin));\n dispatchNativeFieldEvent(el, 'input');\n dispatchNativeFieldEvent(el, 'change');\n }\n\n function commitFromMinute(m: number): void {\n const h24 = fmt.value === '12' ? to24Hour(pendingHour.value, pendingPeriod.value) : pendingHour.value;\n\n pendingMinute.value = m;\n commit(h24, m);\n closePicker();\n }\n\n // ── Open / close ──────────────────────────────────────────────────────────\n\n function openPicker(): void {\n if (isDisabled.value) return;\n\n const current = selectedTime.value;\n\n if (current) {\n pendingHour.value = fmt.value === '12' ? toDisplayHour(current.hours) : current.hours;\n pendingMinute.value = current.minutes;\n pendingPeriod.value = current.hours >= 12 ? 'PM' : 'AM';\n } else {\n pendingHour.value = fmt.value === '12' ? 12 : 0;\n pendingMinute.value = 0;\n pendingPeriod.value = 'AM';\n }\n\n isOpen.value = true;\n positioner.update();\n stopAutoUpdate = positioner.startAutoUpdate?.() ?? null;\n }\n\n function closePicker(): void {\n isOpen.value = false;\n stopAutoUpdate?.();\n stopAutoUpdate = null;\n }\n\n function handleTriggerClick(): void {\n if (isOpen.value) closePicker();\n else openPicker();\n }\n\n // ── Outside click ─────────────────────────────────────────────────────────\n\n function handleOutsideClick(e: PointerEvent | MouseEvent): void {\n if (!isOpen.value) return;\n\n if (!e.composedPath().includes(el)) closePicker();\n }\n\n onMounted(() => {\n document.addEventListener('pointerdown', handleOutsideClick, { capture: true });\n\n return () => {\n document.removeEventListener('pointerdown', handleOutsideClick, { capture: true });\n stopAutoUpdate?.();\n stopAutoUpdate = null;\n };\n });\n\n // ── Keyboard ──────────────────────────────────────────────────────────────\n\n function handleTriggerKeydown(e: KeyboardEvent): void {\n if (isDisabled.value) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleTriggerClick();\n } else if (e.key === 'Escape' && isOpen.value) {\n e.preventDefault();\n closePicker();\n } else if ((e.key === 'ArrowDown' || e.key === 'ArrowUp') && !isOpen.value) {\n e.preventDefault();\n openPicker();\n }\n }\n\n function handleDropdownKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n closePicker();\n }\n }\n\n function handleHourKeydown(e: KeyboardEvent): void {\n const opts = hourOptions.value;\n const idx = opts.indexOf(pendingHour.value);\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n pendingHour.value = opts[(idx - 1 + opts.length) % opts.length];\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n pendingHour.value = opts[(idx + 1) % opts.length];\n }\n }\n\n function handleMinuteKeydown(e: KeyboardEvent): void {\n const opts = minuteOptions.value;\n const idx = opts.indexOf(pendingMinute.value);\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n pendingMinute.value = opts[(idx - 1 + opts.length) % opts.length];\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n pendingMinute.value = opts[(idx + 1) % opts.length];\n }\n }\n\n function handlePeriodKeydown(e: KeyboardEvent): void {\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n e.preventDefault();\n pendingPeriod.value = pendingPeriod.value === 'AM' ? 'PM' : 'AM';\n }\n }\n\n // ── Host bindings ─────────────────────────────────────────────────────────\n\n bind({\n attr: {\n open: () => (isOpen.value ? true : undefined),\n },\n });\n\n // ── ore-input prop helpers ────────────────────────────────────────────────\n\n const inputValue = () => triggerText.value;\n const inputLabel = () => props.label.value ?? '';\n const inputPlaceholder = () => props.placeholder.value ?? '';\n const inputLabelPlacement = () => props['label-placement'].value ?? 'inset';\n const inputColor = () => props.color?.value ?? undefined;\n const inputSize = () => props.size?.value ?? undefined;\n const inputVariant = () => props.variant?.value ?? undefined;\n const inputRounded = () => props.rounded?.value ?? undefined;\n const inputHelper = () => props.helper.value ?? '';\n const inputError = () => props.error.value ?? '';\n const inputDisabled = () => (isDisabled.value ? true : undefined);\n const inputRequired = () => (props.required.value ? true : undefined);\n const inputFullwidth = () => (props.fullwidth.value ? true : undefined);\n\n return html`\n <!-- Trigger -->\n <ore-input\n class=\"trigger\"\n ref=\"${triggerRef}\"\n readonly\n tabindex=\"0\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-controls=\"${dialogId}\"\n aria-expanded=\"${() => String(isOpen.value)}\"\n aria-disabled=\"${() => (isDisabled.value ? 'true' : null)}\"\n value=\"${inputValue}\"\n label=\"${inputLabel}\"\n placeholder=\"${inputPlaceholder}\"\n label-placement=\"${inputLabelPlacement}\"\n color=\"${inputColor}\"\n size=\"${inputSize}\"\n variant=\"${inputVariant}\"\n rounded=\"${inputRounded}\"\n helper=\"${inputHelper}\"\n error=\"${inputError}\"\n ?disabled=\"${inputDisabled}\"\n ?required=\"${inputRequired}\"\n ?fullwidth=\"${inputFullwidth}\"\n ?success=\"${() => props.success.value}\"\n @click=\"${handleTriggerClick}\"\n @keydown=\"${handleTriggerKeydown}\">\n <ore-icon slot=\"suffix\" name=\"clock\" size=\"16\" stroke-width=\"1.75\" aria-hidden=\"true\"></ore-icon>\n </ore-input>\n\n <!-- Dropdown -->\n <div\n class=\"dropdown\"\n ref=\"${dropdownRef}\"\n id=\"${dialogId}\"\n role=\"listbox\"\n aria-label=\"${() => (props.label.value ? `${props.label.value}: select time` : 'Select time')}\"\n ?data-open=\"${isOpen}\"\n @keydown=\"${handleDropdownKeydown}\">\n <div class=\"cols-row\">\n <!-- Hours column -->\n <div class=\"col\" part=\"column\" role=\"group\" aria-label=\"Hours\">\n <div class=\"col-label\" aria-hidden=\"true\">HH</div>\n <div class=\"col-scroll\">\n ${() =>\n hourOptions.value.map((h) => {\n const h24 = fmt.value === '12' ? to24Hour(h, pendingPeriod.value) : h;\n const disabled = isTimeDisabled(h24, pendingMinute.value);\n\n return html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingHour.value === h && !disabled ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingHour.value === h)}\"\n aria-disabled=\"${() => String(disabled)}\"\n ?data-disabled=\"${() => disabled}\"\n @click=\"${() => {\n if (!disabled) pendingHour.value = h;\n }}\"\n @keydown=\"${handleHourKeydown}\">\n ${String(h).padStart(2, '0')}\n </div>\n `;\n })}\n </div>\n </div>\n\n <div class=\"col-sep\" aria-hidden=\"true\">:</div>\n\n <!-- Minutes column -->\n <div class=\"col\" part=\"column\" role=\"group\" aria-label=\"Minutes\">\n <div class=\"col-label\" aria-hidden=\"true\">MM</div>\n <div class=\"col-scroll\">\n ${() =>\n minuteOptions.value.map((m) => {\n const h24 = fmt.value === '12' ? to24Hour(pendingHour.value, pendingPeriod.value) : pendingHour.value;\n const disabled = isTimeDisabled(h24, m);\n\n return html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingMinute.value === m && !disabled ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingMinute.value === m)}\"\n aria-disabled=\"${() => String(disabled)}\"\n ?data-disabled=\"${() => disabled}\"\n @click=\"${() => {\n if (!disabled) commitFromMinute(m);\n }}\"\n @keydown=\"${handleMinuteKeydown}\">\n ${String(m).padStart(2, '0')}\n </div>\n `;\n })}\n </div>\n </div>\n\n <!-- AM/PM column (12h mode only) -->\n ${() =>\n fmt.value === '12'\n ? html`\n <div class=\"col col-period\" part=\"column\" role=\"group\" aria-label=\"Period\">\n <div class=\"col-label\" aria-hidden=\"true\">AM/PM</div>\n <div class=\"col-scroll\">\n ${(['AM', 'PM'] as const).map(\n (p) => html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingPeriod.value === p ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingPeriod.value === p)}\"\n @click=\"${() => {\n pendingPeriod.value = p;\n }}\"\n @keydown=\"${handlePeriodKeydown}\">\n ${p}\n </div>\n `,\n )}\n </div>\n </div>\n `\n : html``}\n </div>\n </div>\n `;\n },\n\n shadow: { delegatesFocus: true },\n styles: [colorThemeMixin, reducedMotionMixin, componentStyles],\n});\n"],"mappings":"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"}
@@ -35,7 +35,7 @@ import{defineFieldValue as e,dispatchNativeFieldEvent as t,setFieldValue as n}fr
35
35
  ref="${l}"
36
36
  id="${E}"
37
37
  role="listbox"
38
- aria-label="${()=>r.label.value?`${r.label.value} — select time`:`Select time`}"
38
+ aria-label="${()=>r.label.value?`${r.label.value}: select time`:`Select time`}"
39
39
  ?data-open="${o}"
40
40
  @keydown="${handleDropdownKeydown}">
41
41
  <div class="cols-row">
@@ -1 +1 @@
1
- {"version":3,"file":"time-picker.js","names":[],"sources":["../src/inputs/time-picker/time-picker.ts"],"sourcesContent":["import { bind, define, getHost, html, onMounted, prop, ref, useField } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { createDropdownPositioner } from '../../core';\nimport type { VisualVariant } from '../../shared';\n\nimport { disablableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin } from '../../styles';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './time-picker.css?inline';\n\nexport { ICON_TAG } from '../../content/icon/icon';\nexport { INPUT_TAG } from '../input/input';\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type OreTimePickerEvents = {\n change: Event;\n input: Event;\n};\n\nexport type OreTimePickerProps = {\n /** Theme color */\n color?: string;\n /** Disable the picker */\n disabled?: boolean;\n /** Validation error message */\n error?: string;\n /** Expand to container width */\n fullwidth?: boolean;\n /** Helper text below the field */\n helper?: string;\n /** Visible label */\n label?: string;\n /** Label placement */\n 'label-placement'?: 'inset' | 'outside';\n /** Maximum selectable time in HH:MM format (24-hour) */\n max?: string;\n /** Minimum selectable time in HH:MM format (24-hour) */\n min?: string;\n /** Minute step interval (1–59) */\n 'minute-step'?: number;\n /** Form field name */\n name?: string;\n /** Placeholder shown in the trigger */\n placeholder?: string;\n /** Mark field as required */\n required?: boolean;\n /** Border radius */\n rounded?: string;\n /** Component size */\n size?: string;\n /**\n * Shows an inline green check icon inside the field to confirm the value has\n * passed validation. Ignored while `error` is set — an error always wins.\n */\n success?: boolean;\n /** Display format: '12' for AM/PM, '24' for 24-hour (default: '24') */\n 'time-format'?: '12' | '24';\n /** Selected time in HH:MM format (24-hour) */\n value?: string;\n /** Visual variant */\n variant?: Exclude<VisualVariant, 'text' | 'frost'>;\n};\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/** Parse \"HH:MM\" → { hours: 0-23, minutes: 0-59 } | null */\nfunction parseTime(val: string | undefined | null): { hours: number; minutes: number } | null {\n if (!val) return null;\n\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(val.trim());\n\n if (!match) return null;\n\n const h = Number(match[1]);\n const m = Number(match[2]);\n\n if (h < 0 || h > 23 || m < 0 || m > 59) return null;\n\n return { hours: h, minutes: m };\n}\n\n/** Format { hours, minutes } → \"HH:MM\" (24-hour, zero-padded) */\nfunction formatTime(h: number, m: number): string {\n return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n}\n\n/** Format for display label (respects 12/24 mode) */\nfunction formatDisplay(h: number, m: number, format: '12' | '24'): string {\n if (format === '12') {\n const period = h >= 12 ? 'PM' : 'AM';\n const displayH = h % 12 === 0 ? 12 : h % 12;\n\n return `${String(displayH).padStart(2, '0')}:${String(m).padStart(2, '0')} ${period}`;\n }\n\n return formatTime(h, m);\n}\n\n/** Clamp value to [min, max] in total minutes */\nfunction clampTime(\n h: number,\n m: number,\n minVal: string | undefined | null,\n maxVal: string | undefined | null,\n): { hours: number; minutes: number } {\n const total = h * 60 + m;\n const minParsed = parseTime(minVal);\n const maxParsed = parseTime(maxVal);\n const minMins = minParsed ? minParsed.hours * 60 + minParsed.minutes : 0;\n const maxMins = maxParsed ? maxParsed.hours * 60 + maxParsed.minutes : 23 * 60 + 59;\n const clamped = Math.min(Math.max(total, minMins), maxMins);\n\n return { hours: Math.floor(clamped / 60), minutes: clamped % 60 };\n}\n\n/**\n * An accessible time picker with a scrollable clock dropdown.\n * Supports 12/24-hour display formats, min/max bounds, minute steps, and form association.\n *\n * @element ore-time-picker\n *\n * @attr {string} value - Selected time in HH:MM (24-hour) format\n * @attr {string} min - Minimum selectable time (HH:MM)\n * @attr {string} max - Maximum selectable time (HH:MM)\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {string} placeholder - Trigger placeholder\n * @attr {boolean} disabled - Disable the picker\n * @attr {boolean} required - Required field\n * @attr {string} name - Form field name\n * @attr {string} error - Error message\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} helper - Helper text\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} time-format - '12' or '24' (default: '24')\n * @attr {number} minute-step - Minute increment (default: 5)\n *\n * @fires input - Fired when a time is selected.\n * @fires change - Fired when a time is selected.\n *\n * @slot label - Custom label for the trigger field\n * @slot prefix - Content before the trigger text (e.g. icon)\n * @slot helper - Custom helper text\n * @slot error - Custom error content\n *\n * @cssprop --time-picker-bg - Dropdown background\n * @cssprop --time-picker-border-color - Dropdown border color\n * @cssprop --time-picker-radius - Dropdown border radius\n * @cssprop --time-picker-shadow - Dropdown shadow\n * @cssprop --time-picker-selected-bg - Selected option background\n * @cssprop --time-picker-option-hover-bg - Option hover background\n *\n * @part field - The trigger field\n * @part dropdown - The floating time dropdown\n * @part column - A scrollable column (hours / minutes / period)\n * @part option - An individual time option cell\n *\n * @example\n * ```html\n * <!-- 24-hour clock, 15-minute steps -->\n * <ore-time-picker label=\"Meeting time\" value=\"09:30\" minute-step=\"15\" color=\"primary\"></ore-time-picker>\n *\n * <!-- 12-hour AM/PM format -->\n * <ore-time-picker label=\"Appointment\" time-format=\"12\" minute-step=\"30\"></ore-time-picker>\n *\n * <!-- Outside label, bordered variant -->\n * <ore-time-picker label=\"Start time\" label-placement=\"outside\" variant=\"bordered\"></ore-time-picker>\n * ```\n */\nexport const TIME_PICKER_TAG = 'ore-time-picker' as const;\n\ndefine<OreTimePickerProps>(TIME_PICKER_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n max: prop.string(),\n min: prop.string(),\n 'minute-step': prop.number(5),\n name: prop.string(),\n placeholder: prop.string(),\n required: prop.bool(false),\n success: prop.bool(false),\n 'time-format': prop.oneOf(['12', '24'] as const, '24'),\n value: prop.string(),\n variant: prop.string<'flat' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n\n setup(props) {\n const el = getHost();\n\n // ── Signals ──────────────────────────────────────────────────────────────\n\n const isOpen = signal(false);\n const selectedTime = signal<{ hours: number; minutes: number } | null>(parseTime(props.value.value));\n\n defineFieldValue(\n el,\n () => {\n const value = selectedTime.value;\n\n return value ? formatTime(value.hours, value.minutes) : '';\n },\n (value) => {\n selectedTime.value = parseTime(value);\n },\n );\n\n // ── Floating position ────────────────────────────────────────────────────\n // Same Orbit-powered positioner ore-date-picker's `.calendar` popup uses (see its own\n // comment for the full rationale) — `fixed` + computed `top`/`left` instead of a static\n // `position: absolute; top: 100%`, so the dropdown flips/shifts to stay within the nearest\n // clipping ancestor instead of silently overflowing it.\n const triggerRef = ref<HTMLElement>();\n const dropdownRef = ref<HTMLElement>();\n\n const positioner = createDropdownPositioner({\n getFloating: () => dropdownRef.value ?? null,\n getOffsetPx: () => 4,\n getReference: () => triggerRef.value ?? null,\n matchWidth: false,\n });\n\n let stopAutoUpdate: (() => void) | null = null;\n\n const isDisabled = computed(() => Boolean(props.disabled.value));\n\n // ── Form value ────────────────────────────────────────────────────────────\n\n useField<string>({\n disabled: isDisabled,\n toFormValue: (v) => v || null,\n value: computed(() => {\n const t = selectedTime.value;\n\n return t ? formatTime(t.hours, t.minutes) : '';\n }),\n });\n\n // ── Computed helpers ──────────────────────────────────────────────────────\n\n const fmt = computed(() => props['time-format'].value ?? '24');\n const minuteStep = computed(() => Math.max(1, Math.min(59, props['minute-step'].value ?? 5)));\n\n const triggerText = computed(() => {\n if (!selectedTime.value) return props.placeholder.value || '';\n\n return formatDisplay(selectedTime.value.hours, selectedTime.value.minutes, fmt.value as '12' | '24');\n });\n\n /** All hour options for the column (0-23 in 24h; 1-12 in 12h) */\n const hourOptions = computed<number[]>(() => {\n if (fmt.value === '12') {\n return Array.from({ length: 12 }, (_, i) => i + 1);\n }\n\n return Array.from({ length: 24 }, (_, i) => i);\n });\n\n /** All minute options for the column, stepped */\n const minuteOptions = computed<number[]>(() => {\n const step = minuteStep.value;\n const opts: number[] = [];\n\n for (let m = 0; m < 60; m += step) opts.push(m);\n\n return opts;\n });\n\n const dialogId = `time-picker-${Math.random().toString(36).slice(2, 9)}-dropdown`;\n\n /** Convert 24h hour to display hour in current format */\n function toDisplayHour(h24: number): number {\n if (fmt.value === '24') return h24;\n\n const h12 = h24 % 12;\n\n return h12 === 0 ? 12 : h12;\n }\n\n /** Convert display hour + period → 24h hour */\n function to24Hour(displayHour: number, period: 'AM' | 'PM'): number {\n if (fmt.value === '24') return displayHour;\n\n if (period === 'AM') return displayHour === 12 ? 0 : displayHour;\n\n return displayHour === 12 ? 12 : displayHour + 12;\n }\n\n /** Whether a given HH:MM is out of [min, max] */\n function isTimeDisabled(h: number, m: number): boolean {\n const total = h * 60 + m;\n const minParsed = parseTime(props.min.value);\n const maxParsed = parseTime(props.max.value);\n\n if (minParsed && total < minParsed.hours * 60 + minParsed.minutes) return true;\n\n if (maxParsed && total > maxParsed.hours * 60 + maxParsed.minutes) return true;\n\n return false;\n }\n\n // ── State for focused/pending selection ───────────────────────────────────\n\n /** Pending hour (24h) while user is navigating columns */\n const pendingHour = signal<number>(selectedTime.value?.hours ?? 0);\n /** Pending minute */\n const pendingMinute = signal<number>(selectedTime.value?.minutes ?? 0);\n /** Pending period (12h mode) */\n const pendingPeriod = signal<'AM' | 'PM'>((selectedTime.value?.hours ?? 0) >= 12 ? 'PM' : 'AM');\n\n // ── Sync value prop externally ────────────────────────────────────────────\n\n let lastValueProp = props.value.value;\n\n onMounted(() => {\n const interval = setInterval(() => {\n const current = props.value.value;\n\n if (current !== lastValueProp) {\n lastValueProp = current;\n\n const parsed = parseTime(current);\n\n selectedTime.value = parsed;\n\n if (parsed) {\n pendingHour.value = parsed.hours;\n pendingMinute.value = parsed.minutes;\n pendingPeriod.value = parsed.hours >= 12 ? 'PM' : 'AM';\n }\n }\n }, 50);\n\n return () => clearInterval(interval);\n });\n\n // ── Commit ────────────────────────────────────────────────────────────────\n\n function commit(h24: number, m: number): void {\n const clamped = clampTime(h24, m, props.min.value, props.max.value);\n const snapped = Math.round(clamped.minutes / minuteStep.value) * minuteStep.value;\n const snappedMin = Math.min(snapped, 59);\n\n selectedTime.value = { hours: clamped.hours, minutes: snappedMin };\n setFieldValue(el, formatTime(clamped.hours, snappedMin));\n dispatchNativeFieldEvent(el, 'input');\n dispatchNativeFieldEvent(el, 'change');\n }\n\n function commitFromMinute(m: number): void {\n const h24 = fmt.value === '12' ? to24Hour(pendingHour.value, pendingPeriod.value) : pendingHour.value;\n\n pendingMinute.value = m;\n commit(h24, m);\n closePicker();\n }\n\n // ── Open / close ──────────────────────────────────────────────────────────\n\n function openPicker(): void {\n if (isDisabled.value) return;\n\n const current = selectedTime.value;\n\n if (current) {\n pendingHour.value = fmt.value === '12' ? toDisplayHour(current.hours) : current.hours;\n pendingMinute.value = current.minutes;\n pendingPeriod.value = current.hours >= 12 ? 'PM' : 'AM';\n } else {\n pendingHour.value = fmt.value === '12' ? 12 : 0;\n pendingMinute.value = 0;\n pendingPeriod.value = 'AM';\n }\n\n isOpen.value = true;\n positioner.update();\n stopAutoUpdate = positioner.startAutoUpdate?.() ?? null;\n }\n\n function closePicker(): void {\n isOpen.value = false;\n stopAutoUpdate?.();\n stopAutoUpdate = null;\n }\n\n function handleTriggerClick(): void {\n if (isOpen.value) closePicker();\n else openPicker();\n }\n\n // ── Outside click ─────────────────────────────────────────────────────────\n\n function handleOutsideClick(e: PointerEvent | MouseEvent): void {\n if (!isOpen.value) return;\n\n if (!e.composedPath().includes(el)) closePicker();\n }\n\n onMounted(() => {\n document.addEventListener('pointerdown', handleOutsideClick, { capture: true });\n\n return () => {\n document.removeEventListener('pointerdown', handleOutsideClick, { capture: true });\n stopAutoUpdate?.();\n stopAutoUpdate = null;\n };\n });\n\n // ── Keyboard ──────────────────────────────────────────────────────────────\n\n function handleTriggerKeydown(e: KeyboardEvent): void {\n if (isDisabled.value) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleTriggerClick();\n } else if (e.key === 'Escape' && isOpen.value) {\n e.preventDefault();\n closePicker();\n } else if ((e.key === 'ArrowDown' || e.key === 'ArrowUp') && !isOpen.value) {\n e.preventDefault();\n openPicker();\n }\n }\n\n function handleDropdownKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n closePicker();\n }\n }\n\n function handleHourKeydown(e: KeyboardEvent): void {\n const opts = hourOptions.value;\n const idx = opts.indexOf(pendingHour.value);\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n pendingHour.value = opts[(idx - 1 + opts.length) % opts.length];\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n pendingHour.value = opts[(idx + 1) % opts.length];\n }\n }\n\n function handleMinuteKeydown(e: KeyboardEvent): void {\n const opts = minuteOptions.value;\n const idx = opts.indexOf(pendingMinute.value);\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n pendingMinute.value = opts[(idx - 1 + opts.length) % opts.length];\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n pendingMinute.value = opts[(idx + 1) % opts.length];\n }\n }\n\n function handlePeriodKeydown(e: KeyboardEvent): void {\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n e.preventDefault();\n pendingPeriod.value = pendingPeriod.value === 'AM' ? 'PM' : 'AM';\n }\n }\n\n // ── Host bindings ─────────────────────────────────────────────────────────\n\n bind({\n attr: {\n open: () => (isOpen.value ? true : undefined),\n },\n });\n\n // ── ore-input prop helpers ────────────────────────────────────────────────\n\n const inputValue = () => triggerText.value;\n const inputLabel = () => props.label.value ?? '';\n const inputPlaceholder = () => props.placeholder.value ?? '';\n const inputLabelPlacement = () => props['label-placement'].value ?? 'inset';\n const inputColor = () => props.color?.value ?? undefined;\n const inputSize = () => props.size?.value ?? undefined;\n const inputVariant = () => props.variant?.value ?? undefined;\n const inputRounded = () => props.rounded?.value ?? undefined;\n const inputHelper = () => props.helper.value ?? '';\n const inputError = () => props.error.value ?? '';\n const inputDisabled = () => (isDisabled.value ? true : undefined);\n const inputRequired = () => (props.required.value ? true : undefined);\n const inputFullwidth = () => (props.fullwidth.value ? true : undefined);\n\n return html`\n <!-- Trigger -->\n <ore-input\n class=\"trigger\"\n ref=\"${triggerRef}\"\n readonly\n tabindex=\"0\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-controls=\"${dialogId}\"\n aria-expanded=\"${() => String(isOpen.value)}\"\n aria-disabled=\"${() => (isDisabled.value ? 'true' : null)}\"\n value=\"${inputValue}\"\n label=\"${inputLabel}\"\n placeholder=\"${inputPlaceholder}\"\n label-placement=\"${inputLabelPlacement}\"\n color=\"${inputColor}\"\n size=\"${inputSize}\"\n variant=\"${inputVariant}\"\n rounded=\"${inputRounded}\"\n helper=\"${inputHelper}\"\n error=\"${inputError}\"\n ?disabled=\"${inputDisabled}\"\n ?required=\"${inputRequired}\"\n ?fullwidth=\"${inputFullwidth}\"\n ?success=\"${() => props.success.value}\"\n @click=\"${handleTriggerClick}\"\n @keydown=\"${handleTriggerKeydown}\">\n <ore-icon slot=\"suffix\" name=\"clock\" size=\"16\" stroke-width=\"1.75\" aria-hidden=\"true\"></ore-icon>\n </ore-input>\n\n <!-- Dropdown -->\n <div\n class=\"dropdown\"\n ref=\"${dropdownRef}\"\n id=\"${dialogId}\"\n role=\"listbox\"\n aria-label=\"${() => (props.label.value ? `${props.label.value} — select time` : 'Select time')}\"\n ?data-open=\"${isOpen}\"\n @keydown=\"${handleDropdownKeydown}\">\n <div class=\"cols-row\">\n <!-- Hours column -->\n <div class=\"col\" part=\"column\" role=\"group\" aria-label=\"Hours\">\n <div class=\"col-label\" aria-hidden=\"true\">HH</div>\n <div class=\"col-scroll\">\n ${() =>\n hourOptions.value.map((h) => {\n const h24 = fmt.value === '12' ? to24Hour(h, pendingPeriod.value) : h;\n const disabled = isTimeDisabled(h24, pendingMinute.value);\n\n return html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingHour.value === h && !disabled ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingHour.value === h)}\"\n aria-disabled=\"${() => String(disabled)}\"\n ?data-disabled=\"${() => disabled}\"\n @click=\"${() => {\n if (!disabled) pendingHour.value = h;\n }}\"\n @keydown=\"${handleHourKeydown}\">\n ${String(h).padStart(2, '0')}\n </div>\n `;\n })}\n </div>\n </div>\n\n <div class=\"col-sep\" aria-hidden=\"true\">:</div>\n\n <!-- Minutes column -->\n <div class=\"col\" part=\"column\" role=\"group\" aria-label=\"Minutes\">\n <div class=\"col-label\" aria-hidden=\"true\">MM</div>\n <div class=\"col-scroll\">\n ${() =>\n minuteOptions.value.map((m) => {\n const h24 = fmt.value === '12' ? to24Hour(pendingHour.value, pendingPeriod.value) : pendingHour.value;\n const disabled = isTimeDisabled(h24, m);\n\n return html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingMinute.value === m && !disabled ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingMinute.value === m)}\"\n aria-disabled=\"${() => String(disabled)}\"\n ?data-disabled=\"${() => disabled}\"\n @click=\"${() => {\n if (!disabled) commitFromMinute(m);\n }}\"\n @keydown=\"${handleMinuteKeydown}\">\n ${String(m).padStart(2, '0')}\n </div>\n `;\n })}\n </div>\n </div>\n\n <!-- AM/PM column (12h mode only) -->\n ${() =>\n fmt.value === '12'\n ? html`\n <div class=\"col col-period\" part=\"column\" role=\"group\" aria-label=\"Period\">\n <div class=\"col-label\" aria-hidden=\"true\">AM/PM</div>\n <div class=\"col-scroll\">\n ${(['AM', 'PM'] as const).map(\n (p) => html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingPeriod.value === p ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingPeriod.value === p)}\"\n @click=\"${() => {\n pendingPeriod.value = p;\n }}\"\n @keydown=\"${handlePeriodKeydown}\">\n ${p}\n </div>\n `,\n )}\n </div>\n </div>\n `\n : html``}\n </div>\n </div>\n `;\n },\n\n shadow: { delegatesFocus: true },\n styles: [colorThemeMixin, reducedMotionMixin, componentStyles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"time-picker.js","names":[],"sources":["../src/inputs/time-picker/time-picker.ts"],"sourcesContent":["import { bind, define, getHost, html, onMounted, prop, ref, useField } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { createDropdownPositioner } from '../../core';\nimport type { VisualVariant } from '../../shared';\n\nimport { disablableBundle, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, reducedMotionMixin } from '../../styles';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport componentStyles from './time-picker.css?inline';\n\nexport { ICON_TAG } from '../../content/icon/icon';\nexport { INPUT_TAG } from '../input/input';\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type OreTimePickerEvents = {\n change: Event;\n input: Event;\n};\n\nexport type OreTimePickerProps = {\n /** Theme color */\n color?: string;\n /** Disable the picker */\n disabled?: boolean;\n /** Validation error message */\n error?: string;\n /** Expand to container width */\n fullwidth?: boolean;\n /** Helper text below the field */\n helper?: string;\n /** Visible label */\n label?: string;\n /** Label placement */\n 'label-placement'?: 'inset' | 'outside';\n /** Maximum selectable time in HH:MM format (24-hour) */\n max?: string;\n /** Minimum selectable time in HH:MM format (24-hour) */\n min?: string;\n /** Minute step interval (1–59) */\n 'minute-step'?: number;\n /** Form field name */\n name?: string;\n /** Placeholder shown in the trigger */\n placeholder?: string;\n /** Mark field as required */\n required?: boolean;\n /** Border radius */\n rounded?: string;\n /** Component size */\n size?: string;\n /**\n * Shows an inline green check icon inside the field to confirm the value has\n * passed validation. Ignored while `error` is set: an error always wins.\n */\n success?: boolean;\n /** Display format: '12' for AM/PM, '24' for 24-hour (default: '24') */\n 'time-format'?: '12' | '24';\n /** Selected time in HH:MM format (24-hour) */\n value?: string;\n /** Visual variant */\n variant?: Exclude<VisualVariant, 'text' | 'frost'>;\n};\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\n/** Parse \"HH:MM\" → { hours: 0-23, minutes: 0-59 } | null */\nfunction parseTime(val: string | undefined | null): { hours: number; minutes: number } | null {\n if (!val) return null;\n\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(val.trim());\n\n if (!match) return null;\n\n const h = Number(match[1]);\n const m = Number(match[2]);\n\n if (h < 0 || h > 23 || m < 0 || m > 59) return null;\n\n return { hours: h, minutes: m };\n}\n\n/** Format { hours, minutes } → \"HH:MM\" (24-hour, zero-padded) */\nfunction formatTime(h: number, m: number): string {\n return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n}\n\n/** Format for display label (respects 12/24 mode) */\nfunction formatDisplay(h: number, m: number, format: '12' | '24'): string {\n if (format === '12') {\n const period = h >= 12 ? 'PM' : 'AM';\n const displayH = h % 12 === 0 ? 12 : h % 12;\n\n return `${String(displayH).padStart(2, '0')}:${String(m).padStart(2, '0')} ${period}`;\n }\n\n return formatTime(h, m);\n}\n\n/** Clamp value to [min, max] in total minutes */\nfunction clampTime(\n h: number,\n m: number,\n minVal: string | undefined | null,\n maxVal: string | undefined | null,\n): { hours: number; minutes: number } {\n const total = h * 60 + m;\n const minParsed = parseTime(minVal);\n const maxParsed = parseTime(maxVal);\n const minMins = minParsed ? minParsed.hours * 60 + minParsed.minutes : 0;\n const maxMins = maxParsed ? maxParsed.hours * 60 + maxParsed.minutes : 23 * 60 + 59;\n const clamped = Math.min(Math.max(total, minMins), maxMins);\n\n return { hours: Math.floor(clamped / 60), minutes: clamped % 60 };\n}\n\n/**\n * An accessible time picker with a scrollable clock dropdown.\n * Supports 12/24-hour display formats, min/max bounds, minute steps, and form association.\n *\n * @element ore-time-picker\n *\n * @attr {string} value - Selected time in HH:MM (24-hour) format\n * @attr {string} min - Minimum selectable time (HH:MM)\n * @attr {string} max - Maximum selectable time (HH:MM)\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {string} placeholder - Trigger placeholder\n * @attr {boolean} disabled - Disable the picker\n * @attr {boolean} required - Required field\n * @attr {string} name - Form field name\n * @attr {string} error - Error message\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} helper - Helper text\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n * @attr {string} time-format - '12' or '24' (default: '24')\n * @attr {number} minute-step - Minute increment (default: 5)\n *\n * @fires input - Fired when a time is selected.\n * @fires change - Fired when a time is selected.\n *\n * @slot label - Custom label for the trigger field\n * @slot prefix - Content before the trigger text (e.g. icon)\n * @slot helper - Custom helper text\n * @slot error - Custom error content\n *\n * @cssprop --time-picker-bg - Dropdown background\n * @cssprop --time-picker-border-color - Dropdown border color\n * @cssprop --time-picker-radius - Dropdown border radius\n * @cssprop --time-picker-shadow - Dropdown shadow\n * @cssprop --time-picker-selected-bg - Selected option background\n * @cssprop --time-picker-option-hover-bg - Option hover background\n *\n * @part field - The trigger field\n * @part dropdown - The floating time dropdown\n * @part column - A scrollable column (hours / minutes / period)\n * @part option - An individual time option cell\n *\n * @example\n * ```html\n * <!-- 24-hour clock, 15-minute steps -->\n * <ore-time-picker label=\"Meeting time\" value=\"09:30\" minute-step=\"15\" color=\"primary\"></ore-time-picker>\n *\n * <!-- 12-hour AM/PM format -->\n * <ore-time-picker label=\"Appointment\" time-format=\"12\" minute-step=\"30\"></ore-time-picker>\n *\n * <!-- Outside label, bordered variant -->\n * <ore-time-picker label=\"Start time\" label-placement=\"outside\" variant=\"bordered\"></ore-time-picker>\n * ```\n */\nexport const TIME_PICKER_TAG = 'ore-time-picker' as const;\n\ndefine<OreTimePickerProps>(TIME_PICKER_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n max: prop.string(),\n min: prop.string(),\n 'minute-step': prop.number(5),\n name: prop.string(),\n placeholder: prop.string(),\n required: prop.bool(false),\n success: prop.bool(false),\n 'time-format': prop.oneOf(['12', '24'] as const, '24'),\n value: prop.string(),\n variant: prop.string<'flat' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n\n setup(props) {\n const el = getHost();\n\n // ── Signals ──────────────────────────────────────────────────────────────\n\n const isOpen = signal(false);\n const selectedTime = signal<{ hours: number; minutes: number } | null>(parseTime(props.value.value));\n\n defineFieldValue(\n el,\n () => {\n const value = selectedTime.value;\n\n return value ? formatTime(value.hours, value.minutes) : '';\n },\n (value) => {\n selectedTime.value = parseTime(value);\n },\n );\n\n // ── Floating position ────────────────────────────────────────────────────\n // Same Orbit-powered positioner ore-date-picker's `.calendar` popup uses (see its own\n // comment for the full rationale): `fixed` + computed `top`/`left` instead of a static\n // `position: absolute; top: 100%`, so the dropdown flips/shifts to stay within the nearest\n // clipping ancestor instead of silently overflowing it.\n const triggerRef = ref<HTMLElement>();\n const dropdownRef = ref<HTMLElement>();\n\n const positioner = createDropdownPositioner({\n getFloating: () => dropdownRef.value ?? null,\n getOffsetPx: () => 4,\n getReference: () => triggerRef.value ?? null,\n matchWidth: false,\n });\n\n let stopAutoUpdate: (() => void) | null = null;\n\n const isDisabled = computed(() => Boolean(props.disabled.value));\n\n // ── Form value ────────────────────────────────────────────────────────────\n\n useField<string>({\n disabled: isDisabled,\n toFormValue: (v) => v || null,\n value: computed(() => {\n const t = selectedTime.value;\n\n return t ? formatTime(t.hours, t.minutes) : '';\n }),\n });\n\n // ── Computed helpers ──────────────────────────────────────────────────────\n\n const fmt = computed(() => props['time-format'].value ?? '24');\n const minuteStep = computed(() => Math.max(1, Math.min(59, props['minute-step'].value ?? 5)));\n\n const triggerText = computed(() => {\n if (!selectedTime.value) return props.placeholder.value || '';\n\n return formatDisplay(selectedTime.value.hours, selectedTime.value.minutes, fmt.value as '12' | '24');\n });\n\n /** All hour options for the column (0-23 in 24h; 1-12 in 12h) */\n const hourOptions = computed<number[]>(() => {\n if (fmt.value === '12') {\n return Array.from({ length: 12 }, (_, i) => i + 1);\n }\n\n return Array.from({ length: 24 }, (_, i) => i);\n });\n\n /** All minute options for the column, stepped */\n const minuteOptions = computed<number[]>(() => {\n const step = minuteStep.value;\n const opts: number[] = [];\n\n for (let m = 0; m < 60; m += step) opts.push(m);\n\n return opts;\n });\n\n const dialogId = `time-picker-${Math.random().toString(36).slice(2, 9)}-dropdown`;\n\n /** Convert 24h hour to display hour in current format */\n function toDisplayHour(h24: number): number {\n if (fmt.value === '24') return h24;\n\n const h12 = h24 % 12;\n\n return h12 === 0 ? 12 : h12;\n }\n\n /** Convert display hour + period → 24h hour */\n function to24Hour(displayHour: number, period: 'AM' | 'PM'): number {\n if (fmt.value === '24') return displayHour;\n\n if (period === 'AM') return displayHour === 12 ? 0 : displayHour;\n\n return displayHour === 12 ? 12 : displayHour + 12;\n }\n\n /** Whether a given HH:MM is out of [min, max] */\n function isTimeDisabled(h: number, m: number): boolean {\n const total = h * 60 + m;\n const minParsed = parseTime(props.min.value);\n const maxParsed = parseTime(props.max.value);\n\n if (minParsed && total < minParsed.hours * 60 + minParsed.minutes) return true;\n\n if (maxParsed && total > maxParsed.hours * 60 + maxParsed.minutes) return true;\n\n return false;\n }\n\n // ── State for focused/pending selection ───────────────────────────────────\n\n /** Pending hour (24h) while user is navigating columns */\n const pendingHour = signal<number>(selectedTime.value?.hours ?? 0);\n /** Pending minute */\n const pendingMinute = signal<number>(selectedTime.value?.minutes ?? 0);\n /** Pending period (12h mode) */\n const pendingPeriod = signal<'AM' | 'PM'>((selectedTime.value?.hours ?? 0) >= 12 ? 'PM' : 'AM');\n\n // ── Sync value prop externally ────────────────────────────────────────────\n\n let lastValueProp = props.value.value;\n\n onMounted(() => {\n const interval = setInterval(() => {\n const current = props.value.value;\n\n if (current !== lastValueProp) {\n lastValueProp = current;\n\n const parsed = parseTime(current);\n\n selectedTime.value = parsed;\n\n if (parsed) {\n pendingHour.value = parsed.hours;\n pendingMinute.value = parsed.minutes;\n pendingPeriod.value = parsed.hours >= 12 ? 'PM' : 'AM';\n }\n }\n }, 50);\n\n return () => clearInterval(interval);\n });\n\n // ── Commit ────────────────────────────────────────────────────────────────\n\n function commit(h24: number, m: number): void {\n const clamped = clampTime(h24, m, props.min.value, props.max.value);\n const snapped = Math.round(clamped.minutes / minuteStep.value) * minuteStep.value;\n const snappedMin = Math.min(snapped, 59);\n\n selectedTime.value = { hours: clamped.hours, minutes: snappedMin };\n setFieldValue(el, formatTime(clamped.hours, snappedMin));\n dispatchNativeFieldEvent(el, 'input');\n dispatchNativeFieldEvent(el, 'change');\n }\n\n function commitFromMinute(m: number): void {\n const h24 = fmt.value === '12' ? to24Hour(pendingHour.value, pendingPeriod.value) : pendingHour.value;\n\n pendingMinute.value = m;\n commit(h24, m);\n closePicker();\n }\n\n // ── Open / close ──────────────────────────────────────────────────────────\n\n function openPicker(): void {\n if (isDisabled.value) return;\n\n const current = selectedTime.value;\n\n if (current) {\n pendingHour.value = fmt.value === '12' ? toDisplayHour(current.hours) : current.hours;\n pendingMinute.value = current.minutes;\n pendingPeriod.value = current.hours >= 12 ? 'PM' : 'AM';\n } else {\n pendingHour.value = fmt.value === '12' ? 12 : 0;\n pendingMinute.value = 0;\n pendingPeriod.value = 'AM';\n }\n\n isOpen.value = true;\n positioner.update();\n stopAutoUpdate = positioner.startAutoUpdate?.() ?? null;\n }\n\n function closePicker(): void {\n isOpen.value = false;\n stopAutoUpdate?.();\n stopAutoUpdate = null;\n }\n\n function handleTriggerClick(): void {\n if (isOpen.value) closePicker();\n else openPicker();\n }\n\n // ── Outside click ─────────────────────────────────────────────────────────\n\n function handleOutsideClick(e: PointerEvent | MouseEvent): void {\n if (!isOpen.value) return;\n\n if (!e.composedPath().includes(el)) closePicker();\n }\n\n onMounted(() => {\n document.addEventListener('pointerdown', handleOutsideClick, { capture: true });\n\n return () => {\n document.removeEventListener('pointerdown', handleOutsideClick, { capture: true });\n stopAutoUpdate?.();\n stopAutoUpdate = null;\n };\n });\n\n // ── Keyboard ──────────────────────────────────────────────────────────────\n\n function handleTriggerKeydown(e: KeyboardEvent): void {\n if (isDisabled.value) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleTriggerClick();\n } else if (e.key === 'Escape' && isOpen.value) {\n e.preventDefault();\n closePicker();\n } else if ((e.key === 'ArrowDown' || e.key === 'ArrowUp') && !isOpen.value) {\n e.preventDefault();\n openPicker();\n }\n }\n\n function handleDropdownKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n closePicker();\n }\n }\n\n function handleHourKeydown(e: KeyboardEvent): void {\n const opts = hourOptions.value;\n const idx = opts.indexOf(pendingHour.value);\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n pendingHour.value = opts[(idx - 1 + opts.length) % opts.length];\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n pendingHour.value = opts[(idx + 1) % opts.length];\n }\n }\n\n function handleMinuteKeydown(e: KeyboardEvent): void {\n const opts = minuteOptions.value;\n const idx = opts.indexOf(pendingMinute.value);\n\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n pendingMinute.value = opts[(idx - 1 + opts.length) % opts.length];\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n pendingMinute.value = opts[(idx + 1) % opts.length];\n }\n }\n\n function handlePeriodKeydown(e: KeyboardEvent): void {\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n e.preventDefault();\n pendingPeriod.value = pendingPeriod.value === 'AM' ? 'PM' : 'AM';\n }\n }\n\n // ── Host bindings ─────────────────────────────────────────────────────────\n\n bind({\n attr: {\n open: () => (isOpen.value ? true : undefined),\n },\n });\n\n // ── ore-input prop helpers ────────────────────────────────────────────────\n\n const inputValue = () => triggerText.value;\n const inputLabel = () => props.label.value ?? '';\n const inputPlaceholder = () => props.placeholder.value ?? '';\n const inputLabelPlacement = () => props['label-placement'].value ?? 'inset';\n const inputColor = () => props.color?.value ?? undefined;\n const inputSize = () => props.size?.value ?? undefined;\n const inputVariant = () => props.variant?.value ?? undefined;\n const inputRounded = () => props.rounded?.value ?? undefined;\n const inputHelper = () => props.helper.value ?? '';\n const inputError = () => props.error.value ?? '';\n const inputDisabled = () => (isDisabled.value ? true : undefined);\n const inputRequired = () => (props.required.value ? true : undefined);\n const inputFullwidth = () => (props.fullwidth.value ? true : undefined);\n\n return html`\n <!-- Trigger -->\n <ore-input\n class=\"trigger\"\n ref=\"${triggerRef}\"\n readonly\n tabindex=\"0\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-controls=\"${dialogId}\"\n aria-expanded=\"${() => String(isOpen.value)}\"\n aria-disabled=\"${() => (isDisabled.value ? 'true' : null)}\"\n value=\"${inputValue}\"\n label=\"${inputLabel}\"\n placeholder=\"${inputPlaceholder}\"\n label-placement=\"${inputLabelPlacement}\"\n color=\"${inputColor}\"\n size=\"${inputSize}\"\n variant=\"${inputVariant}\"\n rounded=\"${inputRounded}\"\n helper=\"${inputHelper}\"\n error=\"${inputError}\"\n ?disabled=\"${inputDisabled}\"\n ?required=\"${inputRequired}\"\n ?fullwidth=\"${inputFullwidth}\"\n ?success=\"${() => props.success.value}\"\n @click=\"${handleTriggerClick}\"\n @keydown=\"${handleTriggerKeydown}\">\n <ore-icon slot=\"suffix\" name=\"clock\" size=\"16\" stroke-width=\"1.75\" aria-hidden=\"true\"></ore-icon>\n </ore-input>\n\n <!-- Dropdown -->\n <div\n class=\"dropdown\"\n ref=\"${dropdownRef}\"\n id=\"${dialogId}\"\n role=\"listbox\"\n aria-label=\"${() => (props.label.value ? `${props.label.value}: select time` : 'Select time')}\"\n ?data-open=\"${isOpen}\"\n @keydown=\"${handleDropdownKeydown}\">\n <div class=\"cols-row\">\n <!-- Hours column -->\n <div class=\"col\" part=\"column\" role=\"group\" aria-label=\"Hours\">\n <div class=\"col-label\" aria-hidden=\"true\">HH</div>\n <div class=\"col-scroll\">\n ${() =>\n hourOptions.value.map((h) => {\n const h24 = fmt.value === '12' ? to24Hour(h, pendingPeriod.value) : h;\n const disabled = isTimeDisabled(h24, pendingMinute.value);\n\n return html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingHour.value === h && !disabled ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingHour.value === h)}\"\n aria-disabled=\"${() => String(disabled)}\"\n ?data-disabled=\"${() => disabled}\"\n @click=\"${() => {\n if (!disabled) pendingHour.value = h;\n }}\"\n @keydown=\"${handleHourKeydown}\">\n ${String(h).padStart(2, '0')}\n </div>\n `;\n })}\n </div>\n </div>\n\n <div class=\"col-sep\" aria-hidden=\"true\">:</div>\n\n <!-- Minutes column -->\n <div class=\"col\" part=\"column\" role=\"group\" aria-label=\"Minutes\">\n <div class=\"col-label\" aria-hidden=\"true\">MM</div>\n <div class=\"col-scroll\">\n ${() =>\n minuteOptions.value.map((m) => {\n const h24 = fmt.value === '12' ? to24Hour(pendingHour.value, pendingPeriod.value) : pendingHour.value;\n const disabled = isTimeDisabled(h24, m);\n\n return html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingMinute.value === m && !disabled ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingMinute.value === m)}\"\n aria-disabled=\"${() => String(disabled)}\"\n ?data-disabled=\"${() => disabled}\"\n @click=\"${() => {\n if (!disabled) commitFromMinute(m);\n }}\"\n @keydown=\"${handleMinuteKeydown}\">\n ${String(m).padStart(2, '0')}\n </div>\n `;\n })}\n </div>\n </div>\n\n <!-- AM/PM column (12h mode only) -->\n ${() =>\n fmt.value === '12'\n ? html`\n <div class=\"col col-period\" part=\"column\" role=\"group\" aria-label=\"Period\">\n <div class=\"col-label\" aria-hidden=\"true\">AM/PM</div>\n <div class=\"col-scroll\">\n ${(['AM', 'PM'] as const).map(\n (p) => html`\n <div\n class=\"option\"\n part=\"option\"\n role=\"option\"\n tabindex=\"${() => (pendingPeriod.value === p ? '0' : '-1')}\"\n aria-selected=\"${() => String(pendingPeriod.value === p)}\"\n @click=\"${() => {\n pendingPeriod.value = p;\n }}\"\n @keydown=\"${handlePeriodKeydown}\">\n ${p}\n </div>\n `,\n )}\n </div>\n </div>\n `\n : html``}\n </div>\n </div>\n `;\n },\n\n shadow: { delegatesFocus: true },\n styles: [colorThemeMixin, reducedMotionMixin, componentStyles],\n});\n"],"mappings":"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"}