stimeo-ui 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/README.md +128 -1
  3. package/dist/cable/index.d.ts +79 -23
  4. package/dist/cable/index.js +392 -417
  5. package/dist/cable/index.js.map +1 -1
  6. package/dist/controllers/accordion_controller.d.ts +34 -5
  7. package/dist/controllers/accordion_controller.js +228 -28
  8. package/dist/controllers/accordion_controller.js.map +1 -1
  9. package/dist/controllers/alert_dialog_controller.d.ts +20 -9
  10. package/dist/controllers/alert_dialog_controller.js +862 -221
  11. package/dist/controllers/alert_dialog_controller.js.map +1 -1
  12. package/dist/controllers/announcer_controller.d.ts +38 -7
  13. package/dist/controllers/announcer_controller.js +135 -191
  14. package/dist/controllers/announcer_controller.js.map +1 -1
  15. package/dist/controllers/aspect_ratio_controller.js +0 -10
  16. package/dist/controllers/aspect_ratio_controller.js.map +1 -1
  17. package/dist/controllers/auto_submit_controller.d.ts +30 -6
  18. package/dist/controllers/auto_submit_controller.js +295 -110
  19. package/dist/controllers/auto_submit_controller.js.map +1 -1
  20. package/dist/controllers/avatar_controller.js +172 -106
  21. package/dist/controllers/avatar_controller.js.map +1 -1
  22. package/dist/controllers/breadcrumb_controller.d.ts +10 -7
  23. package/dist/controllers/breadcrumb_controller.js +0 -129
  24. package/dist/controllers/breadcrumb_controller.js.map +1 -1
  25. package/dist/controllers/bulk_select_controller.d.ts +22 -4
  26. package/dist/controllers/bulk_select_controller.js +264 -53
  27. package/dist/controllers/bulk_select_controller.js.map +1 -1
  28. package/dist/controllers/calendar_controller.d.ts +109 -28
  29. package/dist/controllers/calendar_controller.js +346 -180
  30. package/dist/controllers/calendar_controller.js.map +1 -1
  31. package/dist/controllers/carousel_controller.d.ts +99 -27
  32. package/dist/controllers/carousel_controller.js +587 -300
  33. package/dist/controllers/carousel_controller.js.map +1 -1
  34. package/dist/controllers/character_counter_controller.d.ts +18 -2
  35. package/dist/controllers/character_counter_controller.js +271 -143
  36. package/dist/controllers/character_counter_controller.js.map +1 -1
  37. package/dist/controllers/checkbox_controller.d.ts +7 -2
  38. package/dist/controllers/checkbox_controller.js +77 -75
  39. package/dist/controllers/checkbox_controller.js.map +1 -1
  40. package/dist/controllers/clipboard_controller.d.ts +44 -7
  41. package/dist/controllers/clipboard_controller.js +187 -108
  42. package/dist/controllers/clipboard_controller.js.map +1 -1
  43. package/dist/controllers/collapsible_controller.d.ts +41 -5
  44. package/dist/controllers/collapsible_controller.js +374 -108
  45. package/dist/controllers/collapsible_controller.js.map +1 -1
  46. package/dist/controllers/color_picker_controller.d.ts +47 -14
  47. package/dist/controllers/color_picker_controller.js +183 -127
  48. package/dist/controllers/color_picker_controller.js.map +1 -1
  49. package/dist/controllers/combobox_controller.d.ts +33 -6
  50. package/dist/controllers/combobox_controller.js +426 -109
  51. package/dist/controllers/combobox_controller.js.map +1 -1
  52. package/dist/controllers/command_palette_controller.d.ts +45 -14
  53. package/dist/controllers/command_palette_controller.js +994 -350
  54. package/dist/controllers/command_palette_controller.js.map +1 -1
  55. package/dist/controllers/conditional_fields_controller.d.ts +15 -2
  56. package/dist/controllers/conditional_fields_controller.js +212 -125
  57. package/dist/controllers/conditional_fields_controller.js.map +1 -1
  58. package/dist/controllers/confirm_controller.d.ts +49 -12
  59. package/dist/controllers/confirm_controller.js +939 -245
  60. package/dist/controllers/confirm_controller.js.map +1 -1
  61. package/dist/controllers/context_menu_controller.d.ts +36 -3
  62. package/dist/controllers/context_menu_controller.js +275 -127
  63. package/dist/controllers/context_menu_controller.js.map +1 -1
  64. package/dist/controllers/count_up_controller.d.ts +13 -1
  65. package/dist/controllers/count_up_controller.js +73 -21
  66. package/dist/controllers/count_up_controller.js.map +1 -1
  67. package/dist/controllers/countdown_controller.d.ts +75 -2
  68. package/dist/controllers/countdown_controller.js +235 -97
  69. package/dist/controllers/countdown_controller.js.map +1 -1
  70. package/dist/controllers/currency_input_controller.d.ts +93 -15
  71. package/dist/controllers/currency_input_controller.js +241 -118
  72. package/dist/controllers/currency_input_controller.js.map +1 -1
  73. package/dist/controllers/data_grid_controller.d.ts +78 -22
  74. package/dist/controllers/data_grid_controller.js +229 -135
  75. package/dist/controllers/data_grid_controller.js.map +1 -1
  76. package/dist/controllers/date_range_picker_controller.d.ts +64 -11
  77. package/dist/controllers/date_range_picker_controller.js +359 -165
  78. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  79. package/dist/controllers/dialog_controller.d.ts +22 -3
  80. package/dist/controllers/dialog_controller.js +887 -225
  81. package/dist/controllers/dialog_controller.js.map +1 -1
  82. package/dist/controllers/direct_upload_controller.d.ts +24 -7
  83. package/dist/controllers/direct_upload_controller.js +80 -142
  84. package/dist/controllers/direct_upload_controller.js.map +1 -1
  85. package/dist/controllers/dirty_form_controller.d.ts +2 -2
  86. package/dist/controllers/dirty_form_controller.js +26 -47
  87. package/dist/controllers/dirty_form_controller.js.map +1 -1
  88. package/dist/controllers/dismissible_controller.d.ts +19 -0
  89. package/dist/controllers/dismissible_controller.js +175 -20
  90. package/dist/controllers/dismissible_controller.js.map +1 -1
  91. package/dist/controllers/drawer_controller.d.ts +52 -16
  92. package/dist/controllers/drawer_controller.js +963 -336
  93. package/dist/controllers/drawer_controller.js.map +1 -1
  94. package/dist/controllers/dropdown_controller.d.ts +39 -3
  95. package/dist/controllers/dropdown_controller.js +342 -85
  96. package/dist/controllers/dropdown_controller.js.map +1 -1
  97. package/dist/controllers/editable_controller.d.ts +12 -1
  98. package/dist/controllers/editable_controller.js +182 -58
  99. package/dist/controllers/editable_controller.js.map +1 -1
  100. package/dist/controllers/empty_state_controller.js +67 -53
  101. package/dist/controllers/empty_state_controller.js.map +1 -1
  102. package/dist/controllers/file_dropzone_controller.d.ts +60 -18
  103. package/dist/controllers/file_dropzone_controller.js +426 -229
  104. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  105. package/dist/controllers/filter_controller.d.ts +10 -4
  106. package/dist/controllers/filter_controller.js +78 -36
  107. package/dist/controllers/filter_controller.js.map +1 -1
  108. package/dist/controllers/flash_controller.d.ts +57 -14
  109. package/dist/controllers/flash_controller.js +328 -211
  110. package/dist/controllers/flash_controller.js.map +1 -1
  111. package/dist/controllers/focus_controller.d.ts +12 -3
  112. package/dist/controllers/focus_controller.js +654 -239
  113. package/dist/controllers/focus_controller.js.map +1 -1
  114. package/dist/controllers/form_field_controller.js +153 -136
  115. package/dist/controllers/form_field_controller.js.map +1 -1
  116. package/dist/controllers/form_validation_controller.js +29 -96
  117. package/dist/controllers/form_validation_controller.js.map +1 -1
  118. package/dist/controllers/frame_loading_controller.d.ts +41 -9
  119. package/dist/controllers/frame_loading_controller.js +263 -198
  120. package/dist/controllers/frame_loading_controller.js.map +1 -1
  121. package/dist/controllers/highlight_controller.d.ts +22 -2
  122. package/dist/controllers/highlight_controller.js +119 -70
  123. package/dist/controllers/highlight_controller.js.map +1 -1
  124. package/dist/controllers/hover_card_controller.d.ts +65 -4
  125. package/dist/controllers/hover_card_controller.js +335 -118
  126. package/dist/controllers/hover_card_controller.js.map +1 -1
  127. package/dist/controllers/idle_controller.d.ts +58 -4
  128. package/dist/controllers/idle_controller.js +316 -65
  129. package/dist/controllers/idle_controller.js.map +1 -1
  130. package/dist/controllers/input_mask_controller.d.ts +5 -2
  131. package/dist/controllers/input_mask_controller.js +116 -61
  132. package/dist/controllers/input_mask_controller.js.map +1 -1
  133. package/dist/controllers/intersection_controller.d.ts +32 -13
  134. package/dist/controllers/intersection_controller.js +147 -103
  135. package/dist/controllers/intersection_controller.js.map +1 -1
  136. package/dist/controllers/lazy_frame_controller.d.ts +16 -0
  137. package/dist/controllers/lazy_frame_controller.js +9 -56
  138. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  139. package/dist/controllers/listbox_controller.d.ts +84 -10
  140. package/dist/controllers/listbox_controller.js +413 -153
  141. package/dist/controllers/listbox_controller.js.map +1 -1
  142. package/dist/controllers/local_time_controller.d.ts +1 -1
  143. package/dist/controllers/local_time_controller.js +54 -64
  144. package/dist/controllers/local_time_controller.js.map +1 -1
  145. package/dist/controllers/masonry_controller.d.ts +11 -3
  146. package/dist/controllers/masonry_controller.js +70 -95
  147. package/dist/controllers/masonry_controller.js.map +1 -1
  148. package/dist/controllers/menu_controller.d.ts +40 -9
  149. package/dist/controllers/menu_controller.js +254 -167
  150. package/dist/controllers/menu_controller.js.map +1 -1
  151. package/dist/controllers/menubar_controller.d.ts +15 -4
  152. package/dist/controllers/menubar_controller.js +206 -331
  153. package/dist/controllers/menubar_controller.js.map +1 -1
  154. package/dist/controllers/meter_controller.d.ts +20 -0
  155. package/dist/controllers/meter_controller.js +159 -71
  156. package/dist/controllers/meter_controller.js.map +1 -1
  157. package/dist/controllers/multi_select_controller.d.ts +50 -7
  158. package/dist/controllers/multi_select_controller.js +797 -388
  159. package/dist/controllers/multi_select_controller.js.map +1 -1
  160. package/dist/controllers/navigation_menu_controller.d.ts +19 -1
  161. package/dist/controllers/navigation_menu_controller.js +156 -231
  162. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  163. package/dist/controllers/nested_form_controller.d.ts +10 -0
  164. package/dist/controllers/nested_form_controller.js +373 -174
  165. package/dist/controllers/nested_form_controller.js.map +1 -1
  166. package/dist/controllers/network_status_controller.d.ts +23 -0
  167. package/dist/controllers/network_status_controller.js +241 -45
  168. package/dist/controllers/network_status_controller.js.map +1 -1
  169. package/dist/controllers/number_input_controller.d.ts +62 -10
  170. package/dist/controllers/number_input_controller.js +387 -227
  171. package/dist/controllers/number_input_controller.js.map +1 -1
  172. package/dist/controllers/optimistic_controller.js +28 -75
  173. package/dist/controllers/optimistic_controller.js.map +1 -1
  174. package/dist/controllers/otp_controller.d.ts +38 -7
  175. package/dist/controllers/otp_controller.js +344 -196
  176. package/dist/controllers/otp_controller.js.map +1 -1
  177. package/dist/controllers/overflow_indicator_controller.d.ts +13 -12
  178. package/dist/controllers/overflow_indicator_controller.js +167 -93
  179. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  180. package/dist/controllers/overflow_menu_controller.d.ts +66 -9
  181. package/dist/controllers/overflow_menu_controller.js +408 -277
  182. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  183. package/dist/controllers/pagination_controller.d.ts +52 -15
  184. package/dist/controllers/pagination_controller.js +342 -120
  185. package/dist/controllers/pagination_controller.js.map +1 -1
  186. package/dist/controllers/password_reveal_controller.d.ts +60 -9
  187. package/dist/controllers/password_reveal_controller.js +424 -99
  188. package/dist/controllers/password_reveal_controller.js.map +1 -1
  189. package/dist/controllers/password_strength_controller.d.ts +14 -5
  190. package/dist/controllers/password_strength_controller.js +99 -153
  191. package/dist/controllers/password_strength_controller.js.map +1 -1
  192. package/dist/controllers/persist_controller.d.ts +11 -4
  193. package/dist/controllers/persist_controller.js +252 -96
  194. package/dist/controllers/persist_controller.js.map +1 -1
  195. package/dist/controllers/pointer_drag_controller.d.ts +19 -7
  196. package/dist/controllers/pointer_drag_controller.js +263 -164
  197. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  198. package/dist/controllers/popover_controller.d.ts +46 -4
  199. package/dist/controllers/popover_controller.js +267 -94
  200. package/dist/controllers/popover_controller.js.map +1 -1
  201. package/dist/controllers/portal_controller.d.ts +44 -4
  202. package/dist/controllers/portal_controller.js +209 -72
  203. package/dist/controllers/portal_controller.js.map +1 -1
  204. package/dist/controllers/preview_guard_controller.d.ts +10 -4
  205. package/dist/controllers/preview_guard_controller.js +243 -112
  206. package/dist/controllers/preview_guard_controller.js.map +1 -1
  207. package/dist/controllers/progress_controller.d.ts +11 -0
  208. package/dist/controllers/progress_controller.js +132 -59
  209. package/dist/controllers/progress_controller.js.map +1 -1
  210. package/dist/controllers/radio_group_controller.d.ts +19 -8
  211. package/dist/controllers/radio_group_controller.js +138 -133
  212. package/dist/controllers/radio_group_controller.js.map +1 -1
  213. package/dist/controllers/range_slider_controller.d.ts +92 -4
  214. package/dist/controllers/range_slider_controller.js +245 -112
  215. package/dist/controllers/range_slider_controller.js.map +1 -1
  216. package/dist/controllers/rating_controller.d.ts +33 -6
  217. package/dist/controllers/rating_controller.js +429 -194
  218. package/dist/controllers/rating_controller.js.map +1 -1
  219. package/dist/controllers/read_more_controller.d.ts +26 -2
  220. package/dist/controllers/read_more_controller.js +185 -47
  221. package/dist/controllers/read_more_controller.js.map +1 -1
  222. package/dist/controllers/reading_progress_controller.d.ts +1 -1
  223. package/dist/controllers/reading_progress_controller.js +147 -135
  224. package/dist/controllers/reading_progress_controller.js.map +1 -1
  225. package/dist/controllers/relative_time_controller.d.ts +18 -4
  226. package/dist/controllers/relative_time_controller.js +145 -110
  227. package/dist/controllers/relative_time_controller.js.map +1 -1
  228. package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
  229. package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +97 -38
  230. package/dist/controllers/reset_on_restore_controller.js.map +1 -0
  231. package/dist/controllers/resizable_controller.d.ts +44 -4
  232. package/dist/controllers/resizable_controller.js +294 -118
  233. package/dist/controllers/resizable_controller.js.map +1 -1
  234. package/dist/controllers/roving_controller.js +39 -84
  235. package/dist/controllers/roving_controller.js.map +1 -1
  236. package/dist/controllers/scroll_area_controller.d.ts +7 -3
  237. package/dist/controllers/scroll_area_controller.js +428 -221
  238. package/dist/controllers/scroll_area_controller.js.map +1 -1
  239. package/dist/controllers/scroll_restore_controller.js +0 -53
  240. package/dist/controllers/scroll_restore_controller.js.map +1 -1
  241. package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
  242. package/dist/controllers/scroll_visibility_controller.js +395 -146
  243. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  244. package/dist/controllers/scrollspy_controller.d.ts +9 -3
  245. package/dist/controllers/scrollspy_controller.js +181 -236
  246. package/dist/controllers/scrollspy_controller.js.map +1 -1
  247. package/dist/controllers/separator_controller.d.ts +59 -17
  248. package/dist/controllers/separator_controller.js +288 -132
  249. package/dist/controllers/separator_controller.js.map +1 -1
  250. package/dist/controllers/sidebar_controller.d.ts +81 -7
  251. package/dist/controllers/sidebar_controller.js +1071 -375
  252. package/dist/controllers/sidebar_controller.js.map +1 -1
  253. package/dist/controllers/skeleton_controller.d.ts +23 -0
  254. package/dist/controllers/skeleton_controller.js +248 -92
  255. package/dist/controllers/skeleton_controller.js.map +1 -1
  256. package/dist/controllers/slider_controller.d.ts +72 -8
  257. package/dist/controllers/slider_controller.js +211 -96
  258. package/dist/controllers/slider_controller.js.map +1 -1
  259. package/dist/controllers/smart_sticky_header_controller.d.ts +21 -3
  260. package/dist/controllers/smart_sticky_header_controller.js +163 -54
  261. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  262. package/dist/controllers/sortable_controller.js +13 -110
  263. package/dist/controllers/sortable_controller.js.map +1 -1
  264. package/dist/controllers/spinner_controller.d.ts +39 -4
  265. package/dist/controllers/spinner_controller.js +277 -161
  266. package/dist/controllers/spinner_controller.js.map +1 -1
  267. package/dist/controllers/step_indicator_controller.d.ts +24 -17
  268. package/dist/controllers/step_indicator_controller.js +107 -53
  269. package/dist/controllers/step_indicator_controller.js.map +1 -1
  270. package/dist/controllers/stepper_controller.d.ts +43 -9
  271. package/dist/controllers/stepper_controller.js +171 -48
  272. package/dist/controllers/stepper_controller.js.map +1 -1
  273. package/dist/controllers/stick_to_bottom_controller.d.ts +25 -0
  274. package/dist/controllers/stick_to_bottom_controller.js +310 -116
  275. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  276. package/dist/controllers/sticky_observer_controller.d.ts +11 -0
  277. package/dist/controllers/sticky_observer_controller.js +214 -49
  278. package/dist/controllers/sticky_observer_controller.js.map +1 -1
  279. package/dist/controllers/submit_once_controller.d.ts +22 -6
  280. package/dist/controllers/submit_once_controller.js +294 -192
  281. package/dist/controllers/submit_once_controller.js.map +1 -1
  282. package/dist/controllers/switch_controller.d.ts +40 -7
  283. package/dist/controllers/switch_controller.js +107 -43
  284. package/dist/controllers/switch_controller.js.map +1 -1
  285. package/dist/controllers/tabs_controller.d.ts +13 -1
  286. package/dist/controllers/tabs_controller.js +50 -25
  287. package/dist/controllers/tabs_controller.js.map +1 -1
  288. package/dist/controllers/tags_input_controller.d.ts +27 -3
  289. package/dist/controllers/tags_input_controller.js +290 -149
  290. package/dist/controllers/tags_input_controller.js.map +1 -1
  291. package/dist/controllers/textarea_autosize_controller.d.ts +10 -0
  292. package/dist/controllers/textarea_autosize_controller.js +71 -58
  293. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  294. package/dist/controllers/theme_controller.d.ts +37 -8
  295. package/dist/controllers/theme_controller.js +148 -80
  296. package/dist/controllers/theme_controller.js.map +1 -1
  297. package/dist/controllers/time_picker_controller.d.ts +18 -1
  298. package/dist/controllers/time_picker_controller.js +162 -81
  299. package/dist/controllers/time_picker_controller.js.map +1 -1
  300. package/dist/controllers/toast_controller.d.ts +85 -23
  301. package/dist/controllers/toast_controller.js +365 -193
  302. package/dist/controllers/toast_controller.js.map +1 -1
  303. package/dist/controllers/toggle_group_controller.d.ts +60 -9
  304. package/dist/controllers/toggle_group_controller.js +194 -99
  305. package/dist/controllers/toggle_group_controller.js.map +1 -1
  306. package/dist/controllers/toolbar_controller.js +92 -90
  307. package/dist/controllers/toolbar_controller.js.map +1 -1
  308. package/dist/controllers/tooltip_controller.d.ts +52 -2
  309. package/dist/controllers/tooltip_controller.js +185 -125
  310. package/dist/controllers/tooltip_controller.js.map +1 -1
  311. package/dist/controllers/transition_controller.d.ts +22 -4
  312. package/dist/controllers/transition_controller.js +123 -115
  313. package/dist/controllers/transition_controller.js.map +1 -1
  314. package/dist/controllers/tree_view_controller.d.ts +59 -18
  315. package/dist/controllers/tree_view_controller.js +248 -290
  316. package/dist/controllers/tree_view_controller.js.map +1 -1
  317. package/dist/index.d.ts +33 -3
  318. package/dist/index.js +8649 -8572
  319. package/dist/index.js.map +1 -1
  320. package/dist/inspector/cli.d.ts +95 -9
  321. package/dist/inspector/cli.js +343 -77
  322. package/dist/inspector/cli.js.map +1 -1
  323. package/dist/inspector/cli_bin.js +390 -96
  324. package/dist/inspector/cli_bin.js.map +1 -1
  325. package/dist/inspector/examples.json +45 -45
  326. package/dist/inspector/manifest.json +1308 -155
  327. package/dist/positioning/index.d.ts +8 -0
  328. package/dist/positioning/index.js +148 -45
  329. package/dist/positioning/index.js.map +1 -1
  330. package/package.json +7 -7
  331. package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
  332. package/dist/controllers/reset_before_cache_controller.js.map +0 -1
@@ -22,6 +22,12 @@ import { Controller } from '@hotwired/stimulus';
22
22
  *
23
23
  * `reconcile` dispatches `{ value: string }`.
24
24
  *
25
+ * All published state is settled before its reports. A synchronous listener
26
+ * that confirms another value leaves that newer confirmation to report itself;
27
+ * reports still pending for the replaced value are not sent. A read-only listener
28
+ * or a confirmation that moves no published value leaves pending reports intact.
29
+ * An event already being dispatched still reaches its remaining listeners.
30
+ *
25
31
  * @remarks
26
32
  * `segment` targets declare the spinbuttons; the optional `field` target receives
27
33
  * the composed form value. `hourCycle` selects 12- or 24-hour presentation
@@ -36,7 +42,8 @@ import { Controller } from '@hotwired/stimulus';
36
42
  * step the focused spinbutton; wrapping seconds or minutes carries into the next
37
43
  * unit, and 12-hour stepping crosses AM/PM at noon and midnight. Typing digits
38
44
  * enters a value directly and advances after completion. The digit buffer is
39
- * discarded on another action, target replacement, or focus departure.
45
+ * discarded on another action, a segment target change, a page write taken in
46
+ * from a segment, or focus departure.
40
47
  *
41
48
  * A user action that changes the composed value dispatches exactly one bubbling
42
49
  * native `change` from the field, when present, and one
@@ -69,6 +76,16 @@ declare class TimePickerController extends Controller<HTMLElement> {
69
76
  default: boolean;
70
77
  };
71
78
  };
79
+ static valueConstraints: {
80
+ hourCycle: {
81
+ finite: true;
82
+ allowedValues: number[];
83
+ };
84
+ step: {
85
+ readonly finite: true;
86
+ readonly exclusiveMin: 0;
87
+ };
88
+ };
72
89
  static actions: readonly ["onKeydown"];
73
90
  static events: readonly ["change", "reconcile"];
74
91
  readonly segmentTargets: HTMLElement[];
@@ -1,13 +1,9 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/time_picker_controller.ts
4
-
5
- // src/utils/logical_scroll.ts
6
3
  function isRtl(element) {
7
4
  return window.getComputedStyle(element).direction === "rtl";
8
5
  }
9
6
 
10
- // src/utils/arrow_step.ts
11
7
  function logicalArrowKey(key, element) {
12
8
  if (key !== "ArrowRight" && key !== "ArrowLeft") return key;
13
9
  if (!isRtl(element)) return key;
@@ -18,27 +14,42 @@ function isReservedArrowChord(event, allow = []) {
18
14
  return event.altKey && !allow.includes("alt") || event.ctrlKey && !allow.includes("ctrl") || event.metaKey && !allow.includes("meta") || event.shiftKey && !allow.includes("shift");
19
15
  }
20
16
 
21
- // src/utils/microtask_coalescer.ts
17
+ function writeField(field, value) {
18
+ if (field.value === value) return false;
19
+ field.value = value;
20
+ return true;
21
+ }
22
+ function commitField(target) {
23
+ target.dispatchEvent(new Event("change", { bubbles: true }));
24
+ }
25
+
26
+ var ListenerSet = class {
27
+ #abort = new AbortController();
28
+ add(target, type, handler, options) {
29
+ target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
30
+ }
31
+ dispose() {
32
+ this.#abort.abort();
33
+ this.#abort = new AbortController();
34
+ }
35
+ };
36
+
22
37
  var MicrotaskCoalescer = class {
23
38
  #run;
24
39
  #queued = false;
25
40
  #active = false;
26
41
  #generation = 0;
27
- /** @param run - the single reconciliation pass, invoked at most once per batch. */
28
42
  constructor(run) {
29
43
  this.#run = run;
30
44
  }
31
- /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */
32
45
  activate() {
33
46
  this.#active = true;
34
47
  }
35
- /** Closes the window and drops any pending pass; call from `disconnect()`. */
36
48
  cancel() {
37
49
  this.#active = false;
38
50
  this.#queued = false;
39
51
  this.#generation += 1;
40
52
  }
41
- /** Requests one pass after the batch settles. Idempotent; inert outside the window. */
42
53
  schedule() {
43
54
  if (!this.#active || this.#queued) return;
44
55
  this.#queued = true;
@@ -51,14 +62,100 @@ var MicrotaskCoalescer = class {
51
62
  }
52
63
  };
53
64
 
54
- // src/controllers/time_picker_controller.ts
65
+ var MorphRenderWatcher = class {
66
+ #listeners = new ListenerSet();
67
+ #pass;
68
+ #element = null;
69
+ #onMorph = () => this.#pass.schedule();
70
+ constructor(run) {
71
+ this.#pass = new MicrotaskCoalescer(run);
72
+ }
73
+ observe(element) {
74
+ if (this.#element === element) return;
75
+ this.disconnect();
76
+ this.#element = element;
77
+ this.#pass.activate();
78
+ this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
79
+ }
80
+ schedule() {
81
+ this.#pass.schedule();
82
+ }
83
+ disconnect() {
84
+ this.#listeners.dispose();
85
+ this.#pass.cancel();
86
+ this.#element = null;
87
+ }
88
+ };
89
+
90
+ var MoveCounter = class {
91
+ #sequence = 0;
92
+ record() {
93
+ this.#sequence += 1;
94
+ return this.#sequence;
95
+ }
96
+ isLatest(token) {
97
+ return token === this.#sequence;
98
+ }
99
+ };
100
+
101
+ var NUMBER_BOUNDS = {
102
+ positive: { finite: true, exclusiveMin: 0 }};
103
+ function matchesNumberBounds(value, bounds) {
104
+ if (!Number.isFinite(value)) {
105
+ const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
106
+ if (direction === null) return false;
107
+ if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
108
+ }
109
+ if (bounds.min !== void 0 && value < bounds.min) return false;
110
+ if (bounds.max !== void 0 && value > bounds.max) return false;
111
+ if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
112
+ if (bounds.integer && !Number.isInteger(value)) return false;
113
+ if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
114
+ return true;
115
+ }
116
+
117
+ function readNumber(raw, fallback, bounds) {
118
+ return matchesNumberBounds(raw, bounds) ? raw : fallback;
119
+ }
120
+
121
+ var NumberValueReader = class {
122
+ #lastRejected = /* @__PURE__ */ new Map();
123
+ read(owner, name, raw, fallback, bounds) {
124
+ const resolved = readNumber(raw, fallback, bounds);
125
+ if (matchesNumberBounds(raw, bounds)) {
126
+ this.#lastRejected.delete(name);
127
+ return resolved;
128
+ }
129
+ const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;
130
+ const literal = owner.element.getAttribute(attribute);
131
+ if (literal === null) {
132
+ this.#lastRejected.delete(name);
133
+ return resolved;
134
+ }
135
+ if (this.#lastRejected.get(name) !== literal) {
136
+ this.#lastRejected.set(name, literal);
137
+ console.warn(
138
+ `Stimeo UI: "${owner.identifier}" has an invalid number Value "${name}" declaration ${JSON.stringify(literal)}; using ${fallback}.`
139
+ );
140
+ }
141
+ return resolved;
142
+ }
143
+ };
144
+
145
+ function targetSelector(identifier, name) {
146
+ return `[data-${identifier}-target~="${name}"]`;
147
+ }
148
+
55
149
  var AM = 0;
56
150
  var PM = 1;
57
151
  var SECONDS_PER_MINUTE = 60;
58
152
  var SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE;
59
153
  var SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR;
60
154
  var hasModifier = (event) => event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
61
- var TimePickerController = class extends Controller {
155
+ var TimePickerController = class _TimePickerController extends Controller {
156
+ #numbers = new NumberValueReader();
157
+ #moves = new MoveCounter();
158
+ #move = 0;
62
159
  static targets = ["segment", "field"];
63
160
  static values = {
64
161
  hourCycle: { type: Number, default: 24 },
@@ -66,34 +163,32 @@ var TimePickerController = class extends Controller {
66
163
  seconds: { type: Boolean, default: false },
67
164
  wrap: { type: Boolean, default: true }
68
165
  };
166
+ static valueConstraints = {
167
+ hourCycle: { finite: true, allowedValues: [12, 24] },
168
+ step: NUMBER_BOUNDS.positive
169
+ };
69
170
  static actions = ["onKeydown"];
70
171
  static events = ["change", "reconcile"];
71
- /** Collapses target, Value, and retained-attribute morphs into one silent render. */
72
- #reconcile = new MicrotaskCoalescer(() => this.#reconcileDom());
73
- /** Canonical state; the displayed hour and meridiem are derived from this value. */
172
+ #reconcile = new MorphRenderWatcher(() => this.#reconcileDom());
74
173
  #state = { hour: 0, minute: 0, second: 0 };
75
- /** Direct-entry digit buffer and the segment it belongs to. */
76
174
  #typeBuffer = "";
77
175
  #typeSegment = null;
78
- /** Last composed value, used to suppress duplicate user notifications. */
79
176
  #lastValue = "";
80
177
  #observer = null;
81
178
  #connected = false;
82
179
  #domDirty = false;
83
- /** Seeds state from the DOM, renders canonical ARIA, and starts morph observation. */
84
180
  connect() {
85
181
  this.#connected = true;
86
- this.#reconcile.activate();
182
+ this.#reconcile.observe(this.element);
87
183
  this.element.addEventListener("focusout", this.#onFocusOut);
88
184
  this.#domDirty = false;
89
185
  this.#adoptDomState();
90
186
  this.#render();
91
187
  this.#observeMutations();
92
188
  }
93
- /** Releases the observer, listener, queued reconciliation, and transient input state. */
94
189
  disconnect() {
95
190
  this.#connected = false;
96
- this.#reconcile.cancel();
191
+ this.#reconcile.disconnect();
97
192
  this.element.removeEventListener("focusout", this.#onFocusOut);
98
193
  this.#observer?.disconnect();
99
194
  this.#observer = null;
@@ -101,45 +196,37 @@ var TimePickerController = class extends Controller {
101
196
  this.#clearTypeBuffer();
102
197
  this.#lastValue = "";
103
198
  }
104
- /** Re-renders the canonical instant when 12/24-hour presentation changes at runtime. */
105
199
  hourCycleValueChanged() {
106
200
  this.#reconcile.schedule();
107
201
  }
108
- /** Recomposes the optional seconds portion after a runtime Value change. */
109
202
  secondsValueChanged() {
110
203
  this.#reconcile.schedule();
111
204
  }
112
- /** Adopts a segment inserted or replaced by a Turbo morph. */
113
205
  segmentTargetConnected() {
114
206
  this.#domDirty = true;
115
- this.#clearTypeBuffer();
116
207
  this.#reconcile.schedule();
117
208
  }
118
- /** Rebuilds state after a segment leaves the retained controller element. */
119
209
  segmentTargetDisconnected() {
120
210
  this.#domDirty = true;
121
- this.#clearTypeBuffer();
122
211
  this.#reconcile.schedule();
123
212
  }
124
- /** Reflects the current composed value into a field added or replaced at runtime. */
125
213
  fieldTargetConnected() {
126
214
  this.#reconcile.schedule();
127
215
  }
128
- /** Reconciles silently when the optional field leaves at runtime. */
129
216
  fieldTargetDisconnected() {
130
217
  this.#reconcile.schedule();
131
218
  }
132
- /** Handles APG stepping, inter-segment focus moves, jumps, and direct entry. */
133
219
  onKeydown(event) {
134
220
  if (isReservedArrowChord(event)) return;
135
221
  const segment = event.target?.closest(
136
- "[data-stimeo--time-picker-target~='segment']"
222
+ targetSelector(this.identifier, "segment")
137
223
  );
138
224
  if (!segment || !this.segmentTargets.includes(segment)) return;
139
225
  const kind = this.#kindOf(segment);
140
226
  if (!kind) return;
141
227
  const key = logicalArrowKey(event.key, this.element);
142
228
  if ((key === "Home" || key === "End") && hasModifier(event)) return;
229
+ if (this.#adoptPendingDom()) this.#reconcile.schedule();
143
230
  switch (key) {
144
231
  case "ArrowUp":
145
232
  event.preventDefault();
@@ -177,21 +264,18 @@ var TimePickerController = class extends Controller {
177
264
  }
178
265
  this.#clearTypeBuffer();
179
266
  }
180
- /** Clears direct-entry state when Tab, Shift+Tab, or pointer focus leaves a segment. */
181
267
  #onFocusOut = (event) => {
182
268
  const segment = event.target?.closest(
183
- "[data-stimeo--time-picker-target~='segment']"
269
+ targetSelector(this.identifier, "segment")
184
270
  );
185
271
  if (!segment || !this.segmentTargets.includes(segment)) return;
186
272
  this.#clearTypeBuffer();
187
273
  };
188
- /** Uses the normalized positive-integer minute step; other segments step by one. */
189
274
  #delta(kind) {
190
275
  if (kind !== "minute") return 1;
191
- const step = Math.trunc(this.stepValue);
192
- return Number.isFinite(step) && step > 0 ? step : 1;
276
+ const step = Math.trunc(this.#safeStep);
277
+ return step > 0 ? step : 1;
193
278
  }
194
- /** Mutates one complete action and then renders/notifies its final value once. */
195
279
  #step(kind, delta) {
196
280
  if (kind === "meridiem" && this.wrapValue) {
197
281
  this.#state.hour = modulo(this.#state.hour + 12, 24);
@@ -207,7 +291,6 @@ var TimePickerController = class extends Controller {
207
291
  }
208
292
  this.#commitRender();
209
293
  }
210
- /** Accumulates a typed digit, rendering once and advancing after completion. */
211
294
  #typeDigit(segment, kind, digit) {
212
295
  if (this.#typeSegment !== kind) this.#typeBuffer = "";
213
296
  this.#typeSegment = kind;
@@ -221,27 +304,30 @@ var TimePickerController = class extends Controller {
221
304
  this.#focusSibling(segment, 1);
222
305
  }
223
306
  }
224
- /** Moves focus to the previous/next valid segment, if one exists. */
225
307
  #focusSibling(segment, direction) {
226
308
  const segments = this.segmentTargets.filter((candidate) => this.#kindOf(candidate) !== null);
227
309
  const index = segments.indexOf(segment);
228
310
  segments[index + direction]?.focus();
229
311
  }
230
- /** Clears the direct-entry buffer and its owning segment together. */
231
312
  #clearTypeBuffer() {
232
313
  this.#typeBuffer = "";
233
314
  this.#typeSegment = null;
234
315
  }
235
- /** Reconciles one coalesced target, Value, or retained-attribute mutation batch. */
236
- #reconcileDom() {
237
- if (this.#domDirty) {
238
- this.#domDirty = false;
239
- this.#clearTypeBuffer();
240
- this.#adoptDomState();
316
+ #adoptPendingDom() {
317
+ const pending = this.#observer?.takeRecords() ?? [];
318
+ if (pending.some(({ target }) => this.segmentTargets.includes(target))) {
319
+ this.#domDirty = true;
241
320
  }
321
+ if (!this.#domDirty) return false;
322
+ this.#domDirty = false;
323
+ this.#clearTypeBuffer();
324
+ this.#adoptDomState();
325
+ return true;
326
+ }
327
+ #reconcileDom() {
328
+ this.#adoptPendingDom();
242
329
  this.#render();
243
330
  }
244
- /** Rebuilds canonical state from the targets; an absent hour represents midnight. */
245
331
  #adoptDomState() {
246
332
  let displayedHour = 0;
247
333
  let meridiem = AM;
@@ -257,51 +343,39 @@ var TimePickerController = class extends Controller {
257
343
  else meridiem = value;
258
344
  }
259
345
  this.#state = {
260
- hour: this.hourCycleValue === 12 ? displayedHour % 12 + (meridiem === PM ? 12 : 0) : displayedHour,
346
+ hour: this.#safeHourCycle === 12 ? displayedHour % 12 + (meridiem === PM ? 12 : 0) : displayedHour,
261
347
  minute,
262
348
  second
263
349
  };
264
350
  }
265
- /** Reads and integer-clamps one authored `aria-valuenow`. */
266
351
  #authoredValue(segment, kind) {
267
352
  const raw = Number(segment.getAttribute("aria-valuenow"));
268
353
  const { min, max } = this.#bounds(kind);
269
354
  if (!Number.isFinite(raw)) return min;
270
355
  return Math.min(max, Math.max(min, Math.trunc(raw)));
271
356
  }
272
- /** Writes a displayed segment value back into canonical state without rendering. */
273
357
  #setDisplayed(kind, raw) {
274
358
  const { min, max } = this.#bounds(kind);
275
359
  const value = Math.min(max, Math.max(min, Math.trunc(raw)));
276
360
  if (kind === "hour") {
277
- this.#state.hour = this.hourCycleValue === 12 ? value % 12 + (this.#state.hour >= 12 ? 12 : 0) : value;
361
+ this.#state.hour = this.#safeHourCycle === 12 ? value % 12 + (this.#state.hour >= 12 ? 12 : 0) : value;
278
362
  } else if (kind === "minute" || kind === "second") {
279
363
  this.#state[kind] = value;
280
364
  } else {
281
365
  this.#state.hour = this.#state.hour % 12 + (value === PM ? 12 : 0);
282
366
  }
283
367
  }
284
- /** Converts seconds with day wrapping into the canonical three-unit state. */
285
368
  #setFromSeconds(raw) {
286
369
  const seconds = modulo(raw, SECONDS_PER_DAY);
287
370
  this.#state.hour = Math.floor(seconds / SECONDS_PER_HOUR);
288
371
  this.#state.minute = Math.floor(seconds % SECONDS_PER_HOUR / SECONDS_PER_MINUTE);
289
372
  this.#state.second = seconds % SECONDS_PER_MINUTE;
290
373
  }
291
- /** Reflects canonical state to every segment without dispatching user events. */
292
374
  #renderSegments() {
293
375
  this.#withoutObservation(() => {
294
376
  for (const segment of this.segmentTargets) this.#renderSegment(segment);
295
377
  });
296
378
  }
297
- /**
298
- * Reflects canonical state during connection or DOM reconciliation.
299
- *
300
- * No user edit reaches here, so `change` never fires from this path. A pass
301
- * that moves the committed value reports `reconcile` instead.
302
- *
303
- * @stimeoRenderRoot
304
- */
305
379
  #render() {
306
380
  this.#renderSegments();
307
381
  const value = this.#composedValue;
@@ -309,19 +383,21 @@ var TimePickerController = class extends Controller {
309
383
  this.#writeField(value);
310
384
  this.#lastValue = value;
311
385
  if (previous !== "" && value !== previous) {
386
+ this.#move = this.#moves.record();
312
387
  this.dispatch("reconcile", { detail: { value } });
313
388
  }
314
389
  }
315
- /** Reflects one completed user action and dispatches its final change exactly once. */
316
390
  #commitRender() {
317
391
  this.#renderSegments();
318
392
  const value = this.#composedValue;
319
- const fieldChanged = this.#writeField(value);
320
- if (fieldChanged) this.fieldTarget.dispatchEvent(new Event("change", { bubbles: true }));
321
- if (value !== this.#lastValue) this.dispatch("change", { detail: { value } });
393
+ const changed = value !== this.#lastValue;
322
394
  this.#lastValue = value;
395
+ if (changed) this.#move = this.#moves.record();
396
+ const move = this.#move;
397
+ if (this.#writeField(value)) commitField(this.fieldTarget);
398
+ if (!this.#moves.isLatest(move)) return;
399
+ if (changed) this.dispatch("change", { detail: { value } });
323
400
  }
324
- /** Reflects one segment's value and controller-owned ARIA bounds/text. */
325
401
  #renderSegment(segment) {
326
402
  const kind = this.#kindOf(segment);
327
403
  if (!kind) return;
@@ -334,31 +410,25 @@ var TimePickerController = class extends Controller {
334
410
  segment.setAttribute("aria-valuemax", String(max));
335
411
  segment.textContent = text;
336
412
  }
337
- /** Writes a composed value to the optional form field and reports whether it changed. */
338
413
  #writeField(value) {
339
- if (!this.hasFieldTarget || this.fieldTarget.value === value) return false;
340
- this.fieldTarget.value = value;
341
- return true;
414
+ return this.hasFieldTarget && writeField(this.fieldTarget, value);
342
415
  }
343
- /** The canonical form value composed as `HH:MM[:SS]`. */
344
416
  get #composedValue() {
345
417
  const parts = [pad(this.#state.hour), pad(this.#state.minute)];
346
418
  if (this.secondsValue) parts.push(pad(this.#state.second));
347
419
  return parts.join(":");
348
420
  }
349
- /** Returns a canonical unit in the presentation form exposed by its segment. */
350
421
  #displayValue(kind) {
351
422
  if (kind === "hour") {
352
- return this.hourCycleValue === 12 ? this.#state.hour % 12 || 12 : this.#state.hour;
423
+ return this.#safeHourCycle === 12 ? this.#state.hour % 12 || 12 : this.#state.hour;
353
424
  }
354
425
  if (kind === "meridiem") return this.#state.hour >= 12 ? PM : AM;
355
426
  return this.#state[kind];
356
427
  }
357
- /** The inclusive controller-owned bounds for a segment kind. */
358
428
  #bounds(kind) {
359
429
  switch (kind) {
360
430
  case "hour":
361
- return this.hourCycleValue === 12 ? { min: 1, max: 12 } : { min: 0, max: 23 };
431
+ return this.#safeHourCycle === 12 ? { min: 1, max: 12 } : { min: 0, max: 23 };
362
432
  case "minute":
363
433
  case "second":
364
434
  return { min: 0, max: 59 };
@@ -366,7 +436,6 @@ var TimePickerController = class extends Controller {
366
436
  return { min: AM, max: PM };
367
437
  }
368
438
  }
369
- /** Watches retained segment state while excluding this controller's own reflections. */
370
439
  #observeMutations() {
371
440
  const observer = new MutationObserver((records) => {
372
441
  const changed = records.some(
@@ -374,13 +443,11 @@ var TimePickerController = class extends Controller {
374
443
  );
375
444
  if (!changed) return;
376
445
  this.#domDirty = true;
377
- this.#clearTypeBuffer();
378
446
  this.#reconcile.schedule();
379
447
  });
380
448
  this.#observer = observer;
381
449
  this.#observeWith(observer);
382
450
  }
383
- /** Registers retained attribute observation on the controller subtree. */
384
451
  #observeWith(observer) {
385
452
  observer.observe(this.element, {
386
453
  subtree: true,
@@ -388,7 +455,6 @@ var TimePickerController = class extends Controller {
388
455
  attributeFilter: ["aria-valuenow", "data-segment"]
389
456
  });
390
457
  }
391
- /** Temporarily pauses observation so derived ARIA writes cannot become DOM input. */
392
458
  #withoutObservation(run) {
393
459
  const observer = this.#observer;
394
460
  observer?.disconnect();
@@ -398,7 +464,6 @@ var TimePickerController = class extends Controller {
398
464
  if (observer && this.#connected) this.#observeWith(observer);
399
465
  }
400
466
  }
401
- /** Reads a segment's declared kind, or null when absent/invalid. */
402
467
  #kindOf(segment) {
403
468
  const kind = segment.getAttribute("data-segment");
404
469
  if (kind === "hour" || kind === "minute" || kind === "second" || kind === "meridiem") {
@@ -406,10 +471,27 @@ var TimePickerController = class extends Controller {
406
471
  }
407
472
  return null;
408
473
  }
409
- /** Canonical state as seconds since the start of its nominal day. */
410
474
  get #secondsOfDay() {
411
475
  return this.#state.hour * SECONDS_PER_HOUR + this.#state.minute * SECONDS_PER_MINUTE + this.#state.second;
412
476
  }
477
+ get #safeHourCycle() {
478
+ return this.#numbers.read(
479
+ this,
480
+ "hourCycle",
481
+ this.hourCycleValue,
482
+ _TimePickerController.values.hourCycle.default,
483
+ _TimePickerController.valueConstraints.hourCycle
484
+ );
485
+ }
486
+ get #safeStep() {
487
+ return this.#numbers.read(
488
+ this,
489
+ "step",
490
+ this.stepValue,
491
+ _TimePickerController.values.step.default,
492
+ _TimePickerController.valueConstraints.step
493
+ );
494
+ }
413
495
  };
414
496
  function modulo(value, modulus) {
415
497
  return (value % modulus + modulus) % modulus;
@@ -419,5 +501,4 @@ function pad(value) {
419
501
  }
420
502
 
421
503
  export { TimePickerController };
422
- //# sourceMappingURL=time_picker_controller.js.map
423
504
  //# sourceMappingURL=time_picker_controller.js.map