stimeo-ui 0.16.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 (328) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +8 -1
  3. package/dist/cable/index.d.ts +79 -23
  4. package/dist/cable/index.js +363 -436
  5. package/dist/cable/index.js.map +1 -1
  6. package/dist/controllers/accordion_controller.d.ts +4 -2
  7. package/dist/controllers/accordion_controller.js +166 -55
  8. package/dist/controllers/accordion_controller.js.map +1 -1
  9. package/dist/controllers/alert_dialog_controller.d.ts +12 -2
  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 +35 -5
  13. package/dist/controllers/announcer_controller.js +135 -198
  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 +271 -127
  19. package/dist/controllers/auto_submit_controller.js.map +1 -1
  20. package/dist/controllers/avatar_controller.js +171 -105
  21. package/dist/controllers/avatar_controller.js.map +1 -1
  22. package/dist/controllers/breadcrumb_controller.js +0 -130
  23. package/dist/controllers/breadcrumb_controller.js.map +1 -1
  24. package/dist/controllers/bulk_select_controller.d.ts +18 -0
  25. package/dist/controllers/bulk_select_controller.js +262 -52
  26. package/dist/controllers/bulk_select_controller.js.map +1 -1
  27. package/dist/controllers/calendar_controller.d.ts +24 -5
  28. package/dist/controllers/calendar_controller.js +175 -209
  29. package/dist/controllers/calendar_controller.js.map +1 -1
  30. package/dist/controllers/carousel_controller.d.ts +34 -7
  31. package/dist/controllers/carousel_controller.js +461 -399
  32. package/dist/controllers/carousel_controller.js.map +1 -1
  33. package/dist/controllers/character_counter_controller.d.ts +17 -1
  34. package/dist/controllers/character_counter_controller.js +246 -156
  35. package/dist/controllers/character_counter_controller.js.map +1 -1
  36. package/dist/controllers/checkbox_controller.d.ts +7 -2
  37. package/dist/controllers/checkbox_controller.js +32 -74
  38. package/dist/controllers/checkbox_controller.js.map +1 -1
  39. package/dist/controllers/clipboard_controller.d.ts +16 -5
  40. package/dist/controllers/clipboard_controller.js +168 -147
  41. package/dist/controllers/clipboard_controller.js.map +1 -1
  42. package/dist/controllers/collapsible_controller.d.ts +16 -4
  43. package/dist/controllers/collapsible_controller.js +301 -120
  44. package/dist/controllers/collapsible_controller.js.map +1 -1
  45. package/dist/controllers/color_picker_controller.d.ts +18 -6
  46. package/dist/controllers/color_picker_controller.js +149 -139
  47. package/dist/controllers/color_picker_controller.js.map +1 -1
  48. package/dist/controllers/combobox_controller.d.ts +23 -5
  49. package/dist/controllers/combobox_controller.js +360 -133
  50. package/dist/controllers/combobox_controller.js.map +1 -1
  51. package/dist/controllers/command_palette_controller.d.ts +45 -14
  52. package/dist/controllers/command_palette_controller.js +970 -358
  53. package/dist/controllers/command_palette_controller.js.map +1 -1
  54. package/dist/controllers/conditional_fields_controller.d.ts +15 -2
  55. package/dist/controllers/conditional_fields_controller.js +166 -124
  56. package/dist/controllers/conditional_fields_controller.js.map +1 -1
  57. package/dist/controllers/confirm_controller.d.ts +49 -12
  58. package/dist/controllers/confirm_controller.js +939 -248
  59. package/dist/controllers/confirm_controller.js.map +1 -1
  60. package/dist/controllers/context_menu_controller.d.ts +31 -4
  61. package/dist/controllers/context_menu_controller.js +256 -128
  62. package/dist/controllers/context_menu_controller.js.map +1 -1
  63. package/dist/controllers/count_up_controller.d.ts +13 -1
  64. package/dist/controllers/count_up_controller.js +73 -21
  65. package/dist/controllers/count_up_controller.js.map +1 -1
  66. package/dist/controllers/countdown_controller.d.ts +45 -1
  67. package/dist/controllers/countdown_controller.js +183 -148
  68. package/dist/controllers/countdown_controller.js.map +1 -1
  69. package/dist/controllers/currency_input_controller.d.ts +21 -2
  70. package/dist/controllers/currency_input_controller.js +134 -158
  71. package/dist/controllers/currency_input_controller.js.map +1 -1
  72. package/dist/controllers/data_grid_controller.d.ts +15 -4
  73. package/dist/controllers/data_grid_controller.js +114 -186
  74. package/dist/controllers/data_grid_controller.js.map +1 -1
  75. package/dist/controllers/date_range_picker_controller.d.ts +30 -5
  76. package/dist/controllers/date_range_picker_controller.js +288 -206
  77. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  78. package/dist/controllers/dialog_controller.d.ts +13 -1
  79. package/dist/controllers/dialog_controller.js +858 -223
  80. package/dist/controllers/dialog_controller.js.map +1 -1
  81. package/dist/controllers/direct_upload_controller.d.ts +24 -7
  82. package/dist/controllers/direct_upload_controller.js +73 -153
  83. package/dist/controllers/direct_upload_controller.js.map +1 -1
  84. package/dist/controllers/dirty_form_controller.js +14 -48
  85. package/dist/controllers/dirty_form_controller.js.map +1 -1
  86. package/dist/controllers/dismissible_controller.d.ts +19 -0
  87. package/dist/controllers/dismissible_controller.js +175 -21
  88. package/dist/controllers/dismissible_controller.js.map +1 -1
  89. package/dist/controllers/drawer_controller.d.ts +39 -11
  90. package/dist/controllers/drawer_controller.js +933 -341
  91. package/dist/controllers/drawer_controller.js.map +1 -1
  92. package/dist/controllers/dropdown_controller.d.ts +31 -1
  93. package/dist/controllers/dropdown_controller.js +312 -82
  94. package/dist/controllers/dropdown_controller.js.map +1 -1
  95. package/dist/controllers/editable_controller.d.ts +12 -1
  96. package/dist/controllers/editable_controller.js +158 -68
  97. package/dist/controllers/editable_controller.js.map +1 -1
  98. package/dist/controllers/empty_state_controller.js +67 -53
  99. package/dist/controllers/empty_state_controller.js.map +1 -1
  100. package/dist/controllers/file_dropzone_controller.d.ts +60 -18
  101. package/dist/controllers/file_dropzone_controller.js +311 -207
  102. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  103. package/dist/controllers/filter_controller.js +67 -39
  104. package/dist/controllers/filter_controller.js.map +1 -1
  105. package/dist/controllers/flash_controller.d.ts +31 -8
  106. package/dist/controllers/flash_controller.js +172 -314
  107. package/dist/controllers/flash_controller.js.map +1 -1
  108. package/dist/controllers/focus_controller.d.ts +12 -3
  109. package/dist/controllers/focus_controller.js +654 -240
  110. package/dist/controllers/focus_controller.js.map +1 -1
  111. package/dist/controllers/form_field_controller.js +147 -132
  112. package/dist/controllers/form_field_controller.js.map +1 -1
  113. package/dist/controllers/form_validation_controller.js +13 -86
  114. package/dist/controllers/form_validation_controller.js.map +1 -1
  115. package/dist/controllers/frame_loading_controller.d.ts +41 -9
  116. package/dist/controllers/frame_loading_controller.js +264 -213
  117. package/dist/controllers/frame_loading_controller.js.map +1 -1
  118. package/dist/controllers/highlight_controller.d.ts +22 -2
  119. package/dist/controllers/highlight_controller.js +107 -75
  120. package/dist/controllers/highlight_controller.js.map +1 -1
  121. package/dist/controllers/hover_card_controller.d.ts +56 -3
  122. package/dist/controllers/hover_card_controller.js +309 -118
  123. package/dist/controllers/hover_card_controller.js.map +1 -1
  124. package/dist/controllers/idle_controller.d.ts +42 -1
  125. package/dist/controllers/idle_controller.js +267 -101
  126. package/dist/controllers/idle_controller.js.map +1 -1
  127. package/dist/controllers/input_mask_controller.js +71 -72
  128. package/dist/controllers/input_mask_controller.js.map +1 -1
  129. package/dist/controllers/intersection_controller.d.ts +32 -13
  130. package/dist/controllers/intersection_controller.js +147 -106
  131. package/dist/controllers/intersection_controller.js.map +1 -1
  132. package/dist/controllers/lazy_frame_controller.d.ts +16 -0
  133. package/dist/controllers/lazy_frame_controller.js +9 -65
  134. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  135. package/dist/controllers/listbox_controller.d.ts +34 -2
  136. package/dist/controllers/listbox_controller.js +306 -204
  137. package/dist/controllers/listbox_controller.js.map +1 -1
  138. package/dist/controllers/local_time_controller.d.ts +1 -1
  139. package/dist/controllers/local_time_controller.js +54 -64
  140. package/dist/controllers/local_time_controller.js.map +1 -1
  141. package/dist/controllers/masonry_controller.d.ts +11 -3
  142. package/dist/controllers/masonry_controller.js +70 -93
  143. package/dist/controllers/masonry_controller.js.map +1 -1
  144. package/dist/controllers/menu_controller.d.ts +32 -7
  145. package/dist/controllers/menu_controller.js +214 -156
  146. package/dist/controllers/menu_controller.js.map +1 -1
  147. package/dist/controllers/menubar_controller.d.ts +4 -4
  148. package/dist/controllers/menubar_controller.js +170 -329
  149. package/dist/controllers/menubar_controller.js.map +1 -1
  150. package/dist/controllers/meter_controller.d.ts +20 -0
  151. package/dist/controllers/meter_controller.js +151 -67
  152. package/dist/controllers/meter_controller.js.map +1 -1
  153. package/dist/controllers/multi_select_controller.d.ts +32 -4
  154. package/dist/controllers/multi_select_controller.js +593 -358
  155. package/dist/controllers/multi_select_controller.js.map +1 -1
  156. package/dist/controllers/navigation_menu_controller.d.ts +8 -1
  157. package/dist/controllers/navigation_menu_controller.js +124 -232
  158. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  159. package/dist/controllers/nested_form_controller.d.ts +10 -0
  160. package/dist/controllers/nested_form_controller.js +352 -182
  161. package/dist/controllers/nested_form_controller.js.map +1 -1
  162. package/dist/controllers/network_status_controller.d.ts +23 -0
  163. package/dist/controllers/network_status_controller.js +242 -54
  164. package/dist/controllers/network_status_controller.js.map +1 -1
  165. package/dist/controllers/number_input_controller.d.ts +26 -2
  166. package/dist/controllers/number_input_controller.js +320 -263
  167. package/dist/controllers/number_input_controller.js.map +1 -1
  168. package/dist/controllers/optimistic_controller.js +16 -76
  169. package/dist/controllers/optimistic_controller.js.map +1 -1
  170. package/dist/controllers/otp_controller.d.ts +20 -4
  171. package/dist/controllers/otp_controller.js +198 -193
  172. package/dist/controllers/otp_controller.js.map +1 -1
  173. package/dist/controllers/overflow_indicator_controller.d.ts +5 -0
  174. package/dist/controllers/overflow_indicator_controller.js +116 -113
  175. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  176. package/dist/controllers/overflow_menu_controller.d.ts +48 -11
  177. package/dist/controllers/overflow_menu_controller.js +343 -283
  178. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  179. package/dist/controllers/pagination_controller.d.ts +35 -6
  180. package/dist/controllers/pagination_controller.js +295 -119
  181. package/dist/controllers/pagination_controller.js.map +1 -1
  182. package/dist/controllers/password_reveal_controller.d.ts +45 -8
  183. package/dist/controllers/password_reveal_controller.js +389 -121
  184. package/dist/controllers/password_reveal_controller.js.map +1 -1
  185. package/dist/controllers/password_strength_controller.d.ts +14 -5
  186. package/dist/controllers/password_strength_controller.js +99 -153
  187. package/dist/controllers/password_strength_controller.js.map +1 -1
  188. package/dist/controllers/persist_controller.d.ts +11 -4
  189. package/dist/controllers/persist_controller.js +237 -103
  190. package/dist/controllers/persist_controller.js.map +1 -1
  191. package/dist/controllers/pointer_drag_controller.d.ts +19 -7
  192. package/dist/controllers/pointer_drag_controller.js +185 -165
  193. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  194. package/dist/controllers/popover_controller.d.ts +38 -2
  195. package/dist/controllers/popover_controller.js +236 -97
  196. package/dist/controllers/popover_controller.js.map +1 -1
  197. package/dist/controllers/portal_controller.d.ts +44 -4
  198. package/dist/controllers/portal_controller.js +209 -76
  199. package/dist/controllers/portal_controller.js.map +1 -1
  200. package/dist/controllers/preview_guard_controller.d.ts +10 -4
  201. package/dist/controllers/preview_guard_controller.js +232 -116
  202. package/dist/controllers/preview_guard_controller.js.map +1 -1
  203. package/dist/controllers/progress_controller.d.ts +11 -0
  204. package/dist/controllers/progress_controller.js +125 -56
  205. package/dist/controllers/progress_controller.js.map +1 -1
  206. package/dist/controllers/radio_group_controller.d.ts +14 -5
  207. package/dist/controllers/radio_group_controller.js +117 -137
  208. package/dist/controllers/radio_group_controller.js.map +1 -1
  209. package/dist/controllers/range_slider_controller.d.ts +43 -3
  210. package/dist/controllers/range_slider_controller.js +192 -105
  211. package/dist/controllers/range_slider_controller.js.map +1 -1
  212. package/dist/controllers/rating_controller.d.ts +20 -4
  213. package/dist/controllers/rating_controller.js +418 -207
  214. package/dist/controllers/rating_controller.js.map +1 -1
  215. package/dist/controllers/read_more_controller.d.ts +2 -0
  216. package/dist/controllers/read_more_controller.js +134 -63
  217. package/dist/controllers/read_more_controller.js.map +1 -1
  218. package/dist/controllers/reading_progress_controller.d.ts +1 -1
  219. package/dist/controllers/reading_progress_controller.js +147 -135
  220. package/dist/controllers/reading_progress_controller.js.map +1 -1
  221. package/dist/controllers/relative_time_controller.d.ts +18 -4
  222. package/dist/controllers/relative_time_controller.js +145 -110
  223. package/dist/controllers/relative_time_controller.js.map +1 -1
  224. package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
  225. package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +97 -38
  226. package/dist/controllers/reset_on_restore_controller.js.map +1 -0
  227. package/dist/controllers/resizable_controller.d.ts +28 -2
  228. package/dist/controllers/resizable_controller.js +255 -139
  229. package/dist/controllers/resizable_controller.js.map +1 -1
  230. package/dist/controllers/roving_controller.js +39 -84
  231. package/dist/controllers/roving_controller.js.map +1 -1
  232. package/dist/controllers/scroll_area_controller.d.ts +7 -3
  233. package/dist/controllers/scroll_area_controller.js +428 -225
  234. package/dist/controllers/scroll_area_controller.js.map +1 -1
  235. package/dist/controllers/scroll_restore_controller.js +0 -53
  236. package/dist/controllers/scroll_restore_controller.js.map +1 -1
  237. package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
  238. package/dist/controllers/scroll_visibility_controller.js +395 -145
  239. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  240. package/dist/controllers/scrollspy_controller.d.ts +6 -1
  241. package/dist/controllers/scrollspy_controller.js +181 -242
  242. package/dist/controllers/scrollspy_controller.js.map +1 -1
  243. package/dist/controllers/separator_controller.d.ts +19 -4
  244. package/dist/controllers/separator_controller.js +267 -140
  245. package/dist/controllers/separator_controller.js.map +1 -1
  246. package/dist/controllers/sidebar_controller.d.ts +64 -7
  247. package/dist/controllers/sidebar_controller.js +1023 -386
  248. package/dist/controllers/sidebar_controller.js.map +1 -1
  249. package/dist/controllers/skeleton_controller.d.ts +23 -0
  250. package/dist/controllers/skeleton_controller.js +248 -97
  251. package/dist/controllers/skeleton_controller.js.map +1 -1
  252. package/dist/controllers/slider_controller.d.ts +27 -1
  253. package/dist/controllers/slider_controller.js +159 -79
  254. package/dist/controllers/slider_controller.js.map +1 -1
  255. package/dist/controllers/smart_sticky_header_controller.d.ts +21 -3
  256. package/dist/controllers/smart_sticky_header_controller.js +162 -63
  257. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  258. package/dist/controllers/sortable_controller.js +0 -112
  259. package/dist/controllers/sortable_controller.js.map +1 -1
  260. package/dist/controllers/spinner_controller.d.ts +39 -4
  261. package/dist/controllers/spinner_controller.js +277 -169
  262. package/dist/controllers/spinner_controller.js.map +1 -1
  263. package/dist/controllers/step_indicator_controller.d.ts +5 -0
  264. package/dist/controllers/step_indicator_controller.js +99 -46
  265. package/dist/controllers/step_indicator_controller.js.map +1 -1
  266. package/dist/controllers/stepper_controller.d.ts +12 -3
  267. package/dist/controllers/stepper_controller.js +114 -73
  268. package/dist/controllers/stepper_controller.js.map +1 -1
  269. package/dist/controllers/stick_to_bottom_controller.d.ts +6 -0
  270. package/dist/controllers/stick_to_bottom_controller.js +262 -138
  271. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  272. package/dist/controllers/sticky_observer_controller.d.ts +11 -0
  273. package/dist/controllers/sticky_observer_controller.js +214 -49
  274. package/dist/controllers/sticky_observer_controller.js.map +1 -1
  275. package/dist/controllers/submit_once_controller.d.ts +23 -8
  276. package/dist/controllers/submit_once_controller.js +294 -205
  277. package/dist/controllers/submit_once_controller.js.map +1 -1
  278. package/dist/controllers/switch_controller.d.ts +12 -1
  279. package/dist/controllers/switch_controller.js +33 -60
  280. package/dist/controllers/switch_controller.js.map +1 -1
  281. package/dist/controllers/tabs_controller.d.ts +2 -2
  282. package/dist/controllers/tabs_controller.js +35 -29
  283. package/dist/controllers/tabs_controller.js.map +1 -1
  284. package/dist/controllers/tags_input_controller.d.ts +12 -0
  285. package/dist/controllers/tags_input_controller.js +136 -145
  286. package/dist/controllers/tags_input_controller.js.map +1 -1
  287. package/dist/controllers/textarea_autosize_controller.d.ts +10 -0
  288. package/dist/controllers/textarea_autosize_controller.js +71 -58
  289. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  290. package/dist/controllers/theme_controller.d.ts +21 -9
  291. package/dist/controllers/theme_controller.js +130 -112
  292. package/dist/controllers/theme_controller.js.map +1 -1
  293. package/dist/controllers/time_picker_controller.d.ts +18 -1
  294. package/dist/controllers/time_picker_controller.js +146 -80
  295. package/dist/controllers/time_picker_controller.js.map +1 -1
  296. package/dist/controllers/toast_controller.d.ts +36 -11
  297. package/dist/controllers/toast_controller.js +186 -297
  298. package/dist/controllers/toast_controller.js.map +1 -1
  299. package/dist/controllers/toggle_group_controller.d.ts +12 -3
  300. package/dist/controllers/toggle_group_controller.js +95 -136
  301. package/dist/controllers/toggle_group_controller.js.map +1 -1
  302. package/dist/controllers/toolbar_controller.js +68 -98
  303. package/dist/controllers/toolbar_controller.js.map +1 -1
  304. package/dist/controllers/tooltip_controller.d.ts +45 -3
  305. package/dist/controllers/tooltip_controller.js +158 -124
  306. package/dist/controllers/tooltip_controller.js.map +1 -1
  307. package/dist/controllers/transition_controller.d.ts +22 -4
  308. package/dist/controllers/transition_controller.js +123 -119
  309. package/dist/controllers/transition_controller.js.map +1 -1
  310. package/dist/controllers/tree_view_controller.d.ts +21 -11
  311. package/dist/controllers/tree_view_controller.js +150 -345
  312. package/dist/controllers/tree_view_controller.js.map +1 -1
  313. package/dist/index.d.ts +8 -5
  314. package/dist/index.js +6370 -9346
  315. package/dist/index.js.map +1 -1
  316. package/dist/inspector/cli.d.ts +23 -3
  317. package/dist/inspector/cli.js +92 -37
  318. package/dist/inspector/cli.js.map +1 -1
  319. package/dist/inspector/cli_bin.js +92 -56
  320. package/dist/inspector/cli_bin.js.map +1 -1
  321. package/dist/inspector/examples.json +8 -8
  322. package/dist/inspector/manifest.json +787 -100
  323. package/dist/positioning/index.d.ts +8 -0
  324. package/dist/positioning/index.js +148 -47
  325. package/dist/positioning/index.js.map +1 -1
  326. package/package.json +6 -6
  327. package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
  328. package/dist/controllers/reset_before_cache_controller.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logical_scroll.ts","../../src/utils/arrow_step.ts","../../src/utils/field_mirror.ts","../../src/utils/microtask_coalescer.ts","../../src/utils/owned_pointer_session.ts","../../src/utils/range.ts","../../src/utils/stepped_value.ts","../../src/controllers/slider_controller.ts"],"names":["position"],"mappings":"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","file":"slider_controller.js","sourcesContent":["/** Normalized scroll position and maximum distance on one logical axis. */\nexport interface LogicalScrollMetrics {\n position: number;\n max: number;\n}\n\n/**\n * Whether horizontal scrolling on `element` follows right-to-left inline flow.\n *\n * Resolved from the **computed** `direction`, so the authoring contract is the\n * usual `dir=\"rtl\"` (or a stylesheet) on the element or any ancestor.\n *\n * Scope: horizontal writing modes. A vertical writing mode (`writing-mode:\n * vertical-rl`) also inverts the horizontal axis, which this check does not\n * model — vertical writing modes are out of scope for the scroll utilities\n * (their consumers describe axes as horizontal/vertical, not inline/block).\n */\nexport function isRtl(element: Element): boolean {\n return window.getComputedStyle(element).direction === \"rtl\";\n}\n\n/**\n * Returns scroll distance from the logical start edge.\n *\n * CSSOM View exposes standards-mode RTL horizontal offsets as `0` at the inline\n * start (right) and increasingly negative values toward the inline end (left).\n * The normalized position is always clamped to `[0, max]`, which also absorbs\n * Safari's elastic overscroll values.\n */\nexport function logicalScrollMetrics(\n element: HTMLElement,\n horizontal: boolean,\n): LogicalScrollMetrics {\n const max = Math.max(\n 0,\n horizontal\n ? element.scrollWidth - element.clientWidth\n : element.scrollHeight - element.clientHeight,\n );\n const raw = horizontal ? element.scrollLeft : element.scrollTop;\n const position = horizontal && isRtl(element) ? -raw : raw;\n return { position: Math.min(max, Math.max(0, position)), max };\n}\n\n/**\n * Converts a logical start/end delta to the physical value accepted by\n * `Element.scrollBy`.\n */\nexport function physicalScrollDelta(\n element: HTMLElement,\n horizontal: boolean,\n logicalDelta: number,\n): number {\n return horizontal && isRtl(element) ? -logicalDelta : logicalDelta;\n}\n","import { isRtl } from \"./logical_scroll\";\n\n/**\n * Turns an arrow key into a **logical** step: `+1` for \"next\", `-1` for\n * \"previous\", `0` when the key names neither.\n *\n * APG defines the horizontal pair as *next / previous* and says a vertical\n * arrangement swaps in Down/Up for the same meaning — so the pair is one axis's\n * spelling of an order, and the order reverses with the writing direction. Only\n * the horizontal pair reverses. Down/Up name an axis the writing direction does\n * not mirror, and returning them unchanged is the point: many controllers fold\n * both pairs into one branch, where swapping the branches under RTL would flip\n * the vertical axis too — a bug that reads as \"the arrows work\" until someone\n * presses Down.\n *\n * **Direction is read from the element the caller passes, which should be the\n * container that lays the items out** — not the focused child. A child may carry\n * its own `dir` (an LTR input inside an RTL form is ordinary authoring), and\n * probing per handler makes two handlers disagree at the boundary between them.\n *\n * This decides direction only. Whether the axis is even active (an\n * `orientation=\"horizontal\"` widget ignoring Down/Up), how far the step lands,\n * and what wrapping does all stay with the caller.\n *\n * **It encodes the list-order convention: `ArrowDown` is *next*.** Widgets that\n * pair the arrows by *value* instead — `ArrowUp` meaning \"more\", as a rating or a\n * slider does — must not use this, or their vertical axis inverts. Reverse the\n * horizontal pair on its own there.\n *\n * @example\n * ```ts\n * const step = logicalArrowStep(event.key, this.element);\n * if (step === 0) return;\n * this.#roving.setActive(rovingMove(current, length, step, \"wrap\"), { focus: true });\n * ```\n */\nexport function logicalArrowStep(key: string, element: Element): 1 | -1 | 0 {\n if (key === \"ArrowDown\") return 1;\n if (key === \"ArrowUp\") return -1;\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\") return 0;\n const forward = isRtl(element) ? \"ArrowLeft\" : \"ArrowRight\";\n return key === forward ? 1 : -1;\n}\n\n/**\n * Rewrites `key` so an existing LTR-shaped branch keeps working under RTL:\n * `ArrowRight` and `ArrowLeft` trade places, everything else passes through.\n *\n * The alternative — negating a delta — silently breaks handlers whose two\n * horizontal branches are **not mirror images**. A grid that clamps one edge but\n * not the other, or a segmented field guarding `index > 0` on one side and\n * `index < length - 1` on the other, ends up applying the wrong guard to the\n * wrong direction. Swapping the key leaves each branch, guards and all, exactly\n * where its author put it.\n *\n * Same rule as {@link logicalArrowStep} about which element to read: pass the\n * container that lays the items out, not the focused child.\n *\n * @example\n * ```ts\n * switch (logicalArrowKey(event.key, this.element)) {\n * case \"ArrowLeft\": // \"previous\" — whatever direction that is on screen\n * ```\n */\nexport function logicalArrowKey(key: string, element: Element): string {\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\") return key;\n if (!isRtl(element)) return key;\n return key === \"ArrowRight\" ? \"ArrowLeft\" : \"ArrowRight\";\n}\n\n/** Modifiers a widget may claim on an arrow key, named for the `allow` list. */\nexport type ArrowModifier = \"alt\" | \"ctrl\" | \"meta\" | \"shift\";\n\n/**\n * True when an arrow key arrived carrying a modifier the widget must leave to\n * the browser: return without calling `preventDefault()` and without moving any\n * state.\n *\n * A bare arrow belongs to the widget; a chorded one usually does not.\n * `Alt`/`Meta` plus a horizontal arrow is history back/forward on every desktop\n * browser, and a widget that swallows it makes the shortcut work or not\n * depending on where focus happens to sit — a coin-flip the user cannot see.\n *\n * `allow` is for the combinations APG assigns to a pattern **and the widget\n * actually implements** — today only Combobox's optional `Alt+Down`/`Alt+Up`.\n * Listing one the widget does not implement defeats the point: the chord then\n * runs the plain-arrow branch, which is exactly what this guard exists to stop.\n * Non-arrow keys return `false`, so chorded letters and\n * `Control+Home`/`Control+End` are untouched.\n *\n * @example\n * ```ts\n * if (isReservedArrowChord(event)) return;\n * ```\n */\nexport function isReservedArrowChord(\n event: KeyboardEvent,\n allow: readonly ArrowModifier[] = [],\n): boolean {\n if (!event.key.startsWith(\"Arrow\")) return false;\n return (\n (event.altKey && !allow.includes(\"alt\")) ||\n (event.ctrlKey && !allow.includes(\"ctrl\")) ||\n (event.metaKey && !allow.includes(\"meta\")) ||\n (event.shiftKey && !allow.includes(\"shift\"))\n );\n}\n\n/**\n * True when a press arrived carrying any modifier, for the keys the browser and\n * the OS own outright: return without calling `preventDefault()` and without\n * moving any state.\n *\n * `Control+Home` and `Control+End` jump the document to its ends, and a widget\n * that swallows them makes the shortcut work or not depending on where focus\n * happens to sit. {@link isReservedArrowChord} answers the same question for the\n * arrows, but returns `false` for every other key so that this one can decide.\n *\n * There is no `allow` list here on purpose. APG assigns no modifier chord to\n * `Home`/`End`, so a widget that wanted one would be claiming a combination the\n * pattern never gave it.\n *\n * @example\n * ```ts\n * case \"Home\":\n * case \"End\":\n * if (hasModifierChord(event)) return;\n * ```\n */\nexport function hasModifierChord(event: KeyboardEvent): boolean {\n return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n}\n","/**\n * The hidden form fields a widget keeps in step with the state it owns.\n *\n * A widget whose value lives in ARIA attributes submits nothing on its own, so\n * it mirrors that value into `<input type=\"hidden\">` — one field for a single\n * value, a container of generated fields for a set. The mirror is one-way: the\n * widget's own state stays the source of truth and the field is what the form\n * reads.\n *\n * The write and the report are separate calls because they answer to different\n * rules. A mirror is refreshed on connect, after a morph, and whenever the\n * widget repairs itself — none of which a form should treat as an edit. Only\n * the user's own commit reports one, which is why {@link commitField} is never\n * folded into the writes.\n */\n\n/** How a widget's generated fields identify themselves to the form. */\nexport interface GeneratedFieldOptions {\n /** The `name` every generated input submits under. */\n readonly name: string;\n /** The `form` id, for a widget that sits outside the form it submits to. */\n readonly form?: string;\n}\n\n/**\n * Mirrors one value into a hidden field.\n *\n * @returns Whether the field's value moved.\n *\n * @example\n * ```ts\n * if (writeField(this.fieldTarget, String(value)) && userDriven) {\n * commitField(this.fieldTarget);\n * }\n * ```\n */\nexport function writeField(field: HTMLInputElement, value: string): boolean {\n if (field.value === value) return false;\n field.value = value;\n return true;\n}\n\n/**\n * Mirrors a set of values into `container` as generated hidden fields, in the\n * order given.\n *\n * A container that already submits exactly this set is left untouched, children\n * and all — the mirror is refreshed far more often than it moves (every connect,\n * morph and repair), and a rebuild that changes nothing is still a DOM mutation\n * a consumer's observer and a `:empty` rule can see.\n *\n * @returns Whether the submitted set moved — its values, their order, the\n * `name`, or the `form`.\n */\nexport function writeFields(\n container: HTMLElement,\n values: readonly string[],\n { name, form = \"\" }: GeneratedFieldOptions,\n): boolean {\n const current = [...container.children];\n const submits =\n current.length === values.length &&\n current.every(\n (child, index) =>\n child instanceof HTMLInputElement &&\n child.type === \"hidden\" &&\n child.value === values[index] &&\n child.name === name &&\n (child.getAttribute(\"form\") ?? \"\") === form,\n );\n if (submits) return false;\n\n container.replaceChildren(\n ...values.map((value) => {\n const input = document.createElement(\"input\");\n input.type = \"hidden\";\n input.name = name;\n input.value = value;\n if (form !== \"\") input.setAttribute(\"form\", form);\n return input;\n }),\n );\n return true;\n}\n\n/**\n * Reports a committed value from `target` the way a native form control does:\n * one bubbling, non-cancelable `change`.\n *\n * Call it only for a move the user made. Form-level behaviors listen for this —\n * validation re-checks, auto-submit — and a mirror refreshed by a morph or a\n * repair is not something the user submitted.\n *\n * `target` is the element that carries the value: the hidden field for a single\n * mirrored value, the container for a generated set (whose own inputs are\n * replaced on every write), or a widget's own native control where that is what\n * the form reads.\n */\nexport function commitField(target: HTMLElement): void {\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\n/**\n * Reports an edit a widget made on the user's behalf, the way the browser\n * reports its own: one bubbling `input`, then one bubbling `change`.\n *\n * This is for a widget that owns the stepping or picking its *own* native\n * control would otherwise do — writing `control.value` from script fires\n * nothing, so a form listening for either event never hears the edit. Use\n * {@link commitField} instead where the element is a mirror of state held\n * elsewhere: a hidden field has no native edit to imitate, so it reports the\n * commit alone.\n *\n * Call it only for a move the user made, and only where the widget really did\n * the writing — an edit the browser already reported would be doubled.\n */\nexport function commitEdit(control: HTMLElement): void {\n control.dispatchEvent(new Event(\"input\", { bubbles: true }));\n control.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n","/**\n * Collapses many Stimulus lifecycle callbacks from one DOM mutation into a\n * single pass.\n *\n * Stimulus fires `<name>TargetConnected` / `Disconnected` once per element and\n * `<name>ValueChanged` once per changed attribute. Replacing a list of N options\n * or morphing several render Values therefore delivers N callbacks — but the\n * useful unit of work is \"reconcile against the resulting declarative input\",\n * once, after the batch has settled. Every controller with reconcilable targets\n * or render Values needs the same shape: a `queued` flag plus `queueMicrotask`.\n *\n * **A microtask is the right horizon, and the reason is specific.** Stimulus\n * drives these callbacks from a `MutationObserver`, whose own callback already\n * runs as a microtask with the whole batch in hand; scheduling one more lands\n * after the last sibling callback of that batch and still before paint or any\n * event handler. A timer would be later than it needs to be, and reconciling\n * synchronously would run once per element against a half-applied DOM.\n *\n * **The two guards are not the same guard.** Scheduling is refused before the\n * controller connects, and running is refused after it disconnects:\n *\n * - **Before `connect()`** — Stimulus delivers initial target and Value callbacks\n * ahead of `connect()`. Reconciling there would compute output against a\n * controller whose own state has not been initialised, and `connect()` is\n * about to do a full pass anyway.\n * - **After `disconnect()`** — Stimulus fires a callback for **every** target\n * during teardown, and a microtask queued just before it would otherwise run\n * against a detached tree. {@link MicrotaskCoalescer.cancel} exists for the\n * teardown path to drop the pending pass outright.\n *\n * Both guards are part of one contract here rather than something each consumer\n * has to remember separately.\n *\n * Scope is the scheduling only. *What* to reconcile — keep the surviving active\n * option, fall back to the next / previous / first visible one, rebuild derived\n * chips or hidden fields — stays in the controller, because no two consumers\n * answer it the same way.\n *\n * This file's own doc block is dropped from `dist`, but every member comment is\n * inlined into each consumer entry (`tsup` builds with `splitting: false`), so\n * rationale belongs here and only the contract belongs on the members.\n *\n * @example\n * ```ts\n * readonly #reconcile = new MicrotaskCoalescer(() => this.#reconcileOptions());\n *\n * connect() { this.#reconcile.activate(); }\n * disconnect() { this.#reconcile.cancel(); }\n *\n * optionTargetConnected() { this.#reconcile.schedule(); }\n * optionTargetDisconnected() { this.#reconcile.schedule(); }\n * ```\n */\nexport class MicrotaskCoalescer {\n readonly #run: () => void;\n #queued = false;\n #active = false;\n #generation = 0;\n\n /** @param run - the single reconciliation pass, invoked at most once per batch. */\n constructor(run: () => void) {\n this.#run = run;\n }\n\n /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */\n activate(): void {\n this.#active = true;\n }\n\n /** Closes the window and drops any pending pass; call from `disconnect()`. */\n cancel(): void {\n this.#active = false;\n this.#queued = false;\n this.#generation += 1;\n }\n\n /** Requests one pass after the batch settles. Idempotent; inert outside the window. */\n schedule(): void {\n if (!this.#active || this.#queued) return;\n this.#queued = true;\n const generation = this.#generation;\n queueMicrotask(() => {\n // A cancelled callback must not consume a pass queued after reconnect.\n if (generation !== this.#generation || !this.#queued || !this.#active) return;\n this.#queued = false;\n this.#run();\n });\n }\n}\n","/** What ended an owned pointer session. */\nexport type OwnedPointerSessionEnd = \"up\" | \"cancel\" | \"teardown\";\n\n/** Callbacks driven by one owned pointer until it ends or is cancelled. */\nexport interface OwnedPointerSessionHandlers {\n /** Receives movement from the initiating pointer only. */\n readonly move: (event: PointerEvent) => void;\n /**\n * Runs once after every listener and pointer capture have been released,\n * naming what ended the session.\n */\n readonly end?: (kind: OwnedPointerSessionEnd) => void;\n}\n\n/**\n * Owns one pointer across document-level movement and termination events.\n *\n * A controller may have at most one instance at a time. The session filters\n * every event by the initiating `pointerId` and binds all document listeners to\n * one abort signal, so exactly one callback runs when the session ends.\n *\n * **Pointer capture is delivery, not lifetime.** It is taken when the DOM\n * implementation supports it, and losing it — a consumer re-inserting the owner\n * mid-gesture, another element claiming the pointer — never ends the session:\n * the document listeners receive the pointer either way, because a captured\n * event still bubbles to the document and an uncaptured one fires there anyway.\n * An owner that actually left the tree is the owner's own business; every\n * consumer already answers that question with its own detach probe, and a\n * second answer here would cut gestures the consumer means to keep.\n */\nexport class OwnedPointerSession {\n readonly #pointerId: number;\n readonly #owner: HTMLElement;\n readonly #handlers: OwnedPointerSessionHandlers;\n readonly #abort = new AbortController();\n #active = true;\n\n constructor(start: PointerEvent, owner: HTMLElement, handlers: OwnedPointerSessionHandlers) {\n this.#pointerId = start.pointerId;\n this.#owner = owner;\n this.#handlers = handlers;\n\n const { signal } = this.#abort;\n owner.ownerDocument.addEventListener(\"pointermove\", this.#onMove, { signal });\n owner.ownerDocument.addEventListener(\"pointerup\", this.#onEndEvent, { signal });\n owner.ownerDocument.addEventListener(\"pointercancel\", this.#onEndEvent, { signal });\n\n // Pointer capture is progressive here: happy-dom and older DOM shims may not\n // implement it, while the document listeners still preserve ownership.\n try {\n owner.setPointerCapture?.(this.#pointerId);\n } catch {\n // A synthetic or already-ended pointer cannot be captured; filtering and\n // AbortController teardown remain sufficient for that environment.\n }\n }\n\n /** Releases capture and listeners, then reports the end exactly once. */\n end(): void {\n this.#finish(\"teardown\");\n }\n\n #finish(kind: OwnedPointerSessionEnd): void {\n if (!this.#active) return;\n this.#active = false;\n this.#abort.abort();\n try {\n this.#owner.releasePointerCapture?.(this.#pointerId);\n } catch {\n // Losing capture because the owner detached is already an ended session.\n }\n this.#handlers.end?.(kind);\n }\n\n #owns(event: PointerEvent): boolean {\n return this.#active && event.pointerId === this.#pointerId;\n }\n\n readonly #onMove = (event: PointerEvent): void => {\n if (this.#owns(event)) this.#handlers.move(event);\n };\n\n readonly #onEndEvent = (event: PointerEvent): void => {\n if (this.#owns(event)) this.#finish(event.type === \"pointerup\" ? \"up\" : \"cancel\");\n };\n}\n","/**\n * Range normalization shared by the value-bearing controllers (progress, meter,\n * slider, range-slider).\n *\n * Each of them publishes \"where the value sits inside `[min, max]`\" as a CSS\n * custom property the consumer multiplies a track by, and each has to answer the\n * same degenerate cases: empty and inverted ranges cannot express progress, and\n * malformed Number Values can produce `NaN`. Keeping the rule in one place is\n * what makes those answers identical across the four.\n */\n\n/**\n * Fraction of `[min, max]` that `value` occupies, always within `[0, 1]`.\n *\n * `value` is clamped into the range first, so a value outside it reports a full\n * or empty track rather than pushing the fraction past the ends.\n *\n * An empty, inverted, or non-numeric range yields `0`. That is a deliberate\n * floor rather than a computed result: `min === max` would produce `NaN`, and\n * `min > max` would report a full track for a value that is really out of range.\n * Non-finite results are floored for the same reason. These results reach\n * assistive tech, because the same fraction drives the percentage substituted\n * into `aria-valuetext`.\n */\nexport function rangeFraction(value: number, min: number, max: number): number {\n const span = max - min;\n if (!(span > 0)) return 0;\n\n const clamped = Math.min(max, Math.max(min, value));\n let fraction: number;\n if (Number.isFinite(span)) {\n fraction = (clamped - min) / span;\n } else {\n // Scaling preserves the ratio when two finite endpoints straddle zero so\n // widely that their subtraction overflows to Infinity.\n const scale = Math.max(Math.abs(min), Math.abs(max));\n fraction = (clamped / scale - min / scale) / (max / scale - min / scale);\n }\n\n if (!Number.isFinite(fraction)) return 0;\n return Math.min(1, Math.max(0, fraction));\n}\n","/** Configuration for a value constrained to a stepped numeric range. */\nexport interface SteppedRange {\n /** Inclusive lower endpoint. May be infinite for an unbounded control. */\n readonly min: number;\n /** Inclusive upper endpoint. May be infinite for an unbounded control. */\n readonly max: number;\n /** Requested step. Non-finite and non-positive values fall back to `1`. */\n readonly step: number;\n /** Step-grid origin. Defaults to a finite `min`, otherwise `0`. */\n readonly base?: number;\n}\n\n/** The positive finite step used at runtime and by keyboard stepping. */\nexport function effectiveStep(step: number): number {\n return Number.isFinite(step) && step > 0 ? step : 1;\n}\n\n/**\n * Clamps a raw value and selects its nearest allowed value.\n *\n * The allowed set is the step grid plus each finite range endpoint. Keeping the\n * endpoints in that set makes an authored `aria-valuemin`/`aria-valuemax`\n * truthful even when the upper endpoint is not aligned to the grid. A value\n * exactly between two allowed values resolves upward.\n */\nexport function snapSteppedValue(raw: number, range: SteppedRange): number {\n if (!(range.min <= range.max)) return finiteFallback(range.min, range.max);\n\n const input = Number.isNaN(raw) ? finiteFallback(range.min, range.max) : raw;\n const clamped = Math.min(range.max, Math.max(range.min, input));\n const step = effectiveStep(range.step);\n const base = stepBase(range);\n const candidates: number[] = [];\n\n if (Number.isFinite(range.min)) candidates.push(range.min);\n if (Number.isFinite(range.max)) candidates.push(range.max);\n\n const gridPosition = (clamped - base) / step;\n if (Number.isFinite(gridPosition)) {\n addGridCandidate(candidates, Math.floor(gridPosition), range, base, step);\n addGridCandidate(candidates, Math.ceil(gridPosition), range, base, step);\n }\n\n if (candidates.length === 0) return clamped;\n let nearest = candidates[0] as number;\n let nearestDistance = Math.abs(clamped - nearest);\n for (const candidate of candidates.slice(1)) {\n const distance = Math.abs(clamped - candidate);\n if (\n distance < nearestDistance ||\n (nearlyEqual(distance, nearestDistance) && candidate > nearest)\n ) {\n nearest = candidate;\n nearestDistance = distance;\n }\n }\n return nearest;\n}\n\n/**\n * Moves through the ordered allowed-value set by an integer number of steps.\n *\n * This differs from adding `step * count` and snapping afterward at an\n * off-grid endpoint: with `max=94, step=10`, one decrement from `94` must land\n * on `90`, and one increment from `90` must reach the advertised maximum `94`.\n */\nexport function stepSteppedValue(current: number, count: number, range: SteppedRange): number {\n const value = snapSteppedValue(current, range);\n const distance = Math.abs(Math.trunc(count));\n if (!Number.isFinite(distance) || distance === 0) return value;\n const direction = Math.sign(count);\n const adjacent = adjacentSteppedValue(value, direction, range);\n\n // The first move accounts for a possibly off-grid endpoint. From there a\n // direct grid jump is equivalent to repeated adjacency, and avoids work that\n // grows with Page-step magnitudes or programmatic counts.\n const raw = adjacent + direction * (distance - 1) * effectiveStep(range.step);\n return snapSteppedValue(raw, range);\n}\n\n/** Returns the next member of the ordered endpoint-plus-grid set. */\nfunction adjacentSteppedValue(current: number, direction: number, range: SteppedRange): number {\n const step = effectiveStep(range.step);\n const base = stepBase(range);\n const candidates: number[] = [];\n\n if (direction > 0) {\n const position = (current - base) / step;\n if (Number.isFinite(position)) {\n let gridIndex = Math.floor(position) + 1;\n let candidate = cleanGridValue(base + gridIndex * step, base, step);\n if (candidate < current || nearlyEqual(candidate, current)) {\n gridIndex += 1;\n candidate = cleanGridValue(base + gridIndex * step, base, step);\n }\n if (\n candidate > current &&\n !nearlyEqual(candidate, current) &&\n within(candidate, range.min, range.max)\n ) {\n candidates.push(clamp(candidate, range));\n }\n }\n return clamp(Math.min(...candidates), range);\n }\n\n const position = (current - base) / step;\n if (Number.isFinite(position)) {\n let gridIndex = Math.ceil(position) - 1;\n let candidate = cleanGridValue(base + gridIndex * step, base, step);\n if (candidate > current || nearlyEqual(candidate, current)) {\n gridIndex -= 1;\n candidate = cleanGridValue(base + gridIndex * step, base, step);\n }\n if (\n candidate < current &&\n !nearlyEqual(candidate, current) &&\n within(candidate, range.min, range.max)\n ) {\n candidates.push(clamp(candidate, range));\n }\n }\n return clamp(Math.max(...candidates), range);\n}\n\n/** Adds one grid value when it falls inside the inclusive range. */\nfunction addGridCandidate(\n candidates: number[],\n index: number,\n range: SteppedRange,\n base: number,\n step: number,\n): void {\n const candidate = cleanGridValue(base + index * step, base, step);\n if (within(candidate, range.min, range.max)) candidates.push(clamp(candidate, range));\n}\n\n/** A finite authored base wins; otherwise the finite lower bound or zero does. */\nfunction stepBase(range: SteppedRange): number {\n if (range.base !== undefined && Number.isFinite(range.base)) return range.base;\n return Number.isFinite(range.min) ? range.min : 0;\n}\n\n/** Removes binary noise without discarding significant integer-place digits. */\nfunction cleanGridValue(value: number, base: number, step: number): number {\n const precision = Math.max(decimalPlaces(base), decimalPlaces(step));\n // `toFixed` accepts at most 100 fractional digits. Below that limit it rounds\n // according to the authored grid precision rather than an arbitrary total\n // significant-digit count, which keeps unit steps distinct at large bases.\n return precision <= 100 ? Number(value.toFixed(precision)) : value;\n}\n\n/** Number of fractional decimal places represented by a finite JS number. */\nfunction decimalPlaces(value: number): number {\n const [coefficient = \"\", exponentText] = Math.abs(value).toString().toLowerCase().split(\"e\");\n const fractionLength = coefficient.split(\".\")[1]?.length ?? 0;\n const exponent = exponentText === undefined ? 0 : Number(exponentText);\n return Math.max(0, fractionLength - exponent);\n}\n\n/** Inclusive range check tolerant only of arithmetic noise at an endpoint. */\nfunction within(value: number, min: number, max: number): boolean {\n return (value > min || nearlyEqual(value, min)) && (value < max || nearlyEqual(value, max));\n}\n\n/** Clamps a candidate whose only overshoot may be floating-point noise. */\nfunction clamp(value: number, range: SteppedRange): number {\n return Math.min(range.max, Math.max(range.min, value));\n}\n\n/** Relative comparison used only to collapse arithmetic noise, not real steps. */\nfunction nearlyEqual(left: number, right: number): boolean {\n const scale = Math.max(Math.abs(left), Math.abs(right));\n return (\n Number.isFinite(left) &&\n Number.isFinite(right) &&\n Math.abs(left - right) <= Number.EPSILON * scale\n );\n}\n\n/** Stable fallback for malformed ranges or `NaN` input. */\nfunction finiteFallback(min: number, max: number): number {\n if (Number.isFinite(min)) return min;\n if (Number.isFinite(max)) return max;\n return 0;\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { isReservedArrowChord, logicalArrowKey } from \"../utils/arrow_step\";\nimport { commitField, writeField } from \"../utils/field_mirror\";\nimport { isRtl } from \"../utils/logical_scroll\";\nimport { MicrotaskCoalescer } from \"../utils/microtask_coalescer\";\nimport { OwnedPointerSession } from \"../utils/owned_pointer_session\";\nimport { rangeFraction } from \"../utils/range\";\nimport { snapSteppedValue, stepSteppedValue } from \"../utils/stepped_value\";\n\n/** Name of the CSS custom property exposing the thumb position (0..1). */\nconst FRACTION_PROPERTY = \"--stimeo--slider-fraction\";\n\n/**\n * Headless, accessible slider (single-thumb range) behavior.\n *\n * Markup contract (identifier: `stimeo--slider`):\n * <div data-controller=\"stimeo--slider\"\n * data-stimeo--slider-min-value=\"0\"\n * data-stimeo--slider-max-value=\"100\"\n * data-stimeo--slider-step-value=\"1\"\n * data-stimeo--slider-value-value=\"40\">\n * <input type=\"hidden\" name=\"volume\" data-stimeo--slider-target=\"field\" />\n * <div data-stimeo--slider-target=\"track\"\n * data-action=\"pointerdown->stimeo--slider#onPointerDown\">\n * <div data-stimeo--slider-target=\"thumb\" role=\"slider\" tabindex=\"0\" aria-label=\"Volume\"\n * aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"40\"\n * data-action=\"keydown->stimeo--slider#onKeydown\"></div>\n * </div>\n * </div>\n *\n * Implements the WAI-ARIA APG **Slider** pattern. The current value is exposed\n * to assistive tech via `aria-valuenow`/`aria-valuemin`/`aria-valuemax` on the\n * thumb, and to the consumer's CSS via the `--stimeo--slider-fraction` custom\n * property (a number in `[0, 1]`) set on the controller element — the library\n * positions nothing itself.\n *\n * `change` dispatches `{ value: number }`; `reconcile` dispatches `{ value: number }`.\n *\n * The Values are inputs. A declared `value` outside `[min, max]` or off the step\n * grid stays in its attribute as the page wrote it; the thumb's ARIA, the\n * fraction and the field publish the normalized value instead, and only a move\n * the user makes writes `value`. `change` reports a move the user made that left\n * the value somewhere other than the value last published. When a Value the page\n * changes at runtime — a Turbo morph or application code — moves the published\n * value, `reconcile` reports it once per batch with the same detail, so a\n * consumer can tell its user's move from the page's. Connecting reports\n * neither. A move handled before a page write is repainted reads the written\n * value, so its `change` covers the write as well, and a move that ends on the\n * value last published reports nothing. An event dispatched from script runs\n * every listener with no microtask between them, so a write made just before\n * it, or by a listener that runs ahead of the slider, is handled that way. An\n * event the browser dispatches runs microtasks between the listeners it calls\n * separately, so a write made by one called ahead of the slider's — a capture\n * listener on an ancestor or on `document`, a `:capture` action, or a listener\n * added to the thumb or the track before the slider's action was bound — is\n * repainted, and reported as `reconcile`, before the move is measured from it.\n * Stimulus calls the actions an element declares for one event and one set of\n * listener options from a single listener, in declaration order, so a write\n * made by an action declared before the slider's own on the thumb or the track\n * is handled like a write within an event dispatched from script.\n *\n * The optional `field` target mirrors the normalized value so the slider can be\n * submitted and read server-side. A value the user moved emits a native\n * bubbling `change` from that field, the way a form control does, so\n * `stimeo--auto-submit` and form-level validation hear it. The mirror is\n * refreshed silently on connect, on a replacement field, and whenever a morph\n * or application code writes a Value.\n *\n * @remarks\n * Behavior only. The consumer owns all layout (e.g. positioning the thumb from\n * the fraction). Only the horizontal orientation is handled.\n *\n * Behavior provided:\n * - `ArrowRight`/`ArrowUp` increase and `ArrowLeft`/`ArrowDown` decrease by one\n * step; `Home`/`End` jump to the min/max; `PageUp`/`PageDown` move by ten steps.\n * - Pointer press/drag on the track sets the value from the pointer position.\n * - `step` must be finite and positive; invalid runtime input falls back to `1`.\n * Finite endpoints remain allowed even when they do not align to the step grid.\n *\n * The fraction is a value ratio, not a position, so only the consumer knows\n * whether their track mirrors under RTL. Set `logicalTrack` to declare that it\n * does: the pointer mapping and the horizontal arrow pair then follow the\n * writing direction. Left unset, nothing here reads `direction`.\n */\nexport class SliderController extends Controller<HTMLElement> {\n static override targets = [\"track\", \"thumb\", \"field\"];\n static override values = {\n min: { type: Number, default: 0 },\n max: { type: Number, default: 100 },\n step: { type: Number, default: 1 },\n value: { type: Number, default: 0 },\n logicalTrack: { type: Boolean, default: false },\n };\n static actions = [\"onKeydown\", \"onPointerDown\"] as const;\n static events = [\"change\", \"reconcile\"] as const;\n\n declare readonly trackTarget: HTMLElement;\n declare readonly thumbTarget: HTMLElement;\n declare readonly fieldTarget: HTMLInputElement;\n declare readonly hasTrackTarget: boolean;\n declare readonly hasThumbTarget: boolean;\n declare readonly hasFieldTarget: boolean;\n declare minValue: number;\n declare maxValue: number;\n declare stepValue: number;\n declare valueValue: number;\n declare logicalTrackValue: boolean;\n\n /** One initiating pointer owns each live drag and its stable target snapshot. */\n #drag: SliderDrag | null = null;\n\n /**\n * The value last published: taken on connect, then moved by each user commit\n * and by each repaint that reports a page-driven move.\n */\n #settled = 0;\n\n /** Collapses a morph that swaps several render Values into one repaint. */\n readonly #repaint = new MicrotaskCoalescer(() => this.#render());\n\n /** Whether the consumer declared a mirroring track and the direction mirrors it. */\n get #mirrored(): boolean {\n return this.logicalTrackValue && isRtl(this.element);\n }\n\n /**\n * Renders the normalized value as the starting position without writing it\n * back, and takes it as the baseline, so connecting reports nothing.\n */\n override connect(): void {\n this.#repaint.activate();\n this.#settled = this.#currentValue();\n this.#render();\n }\n\n /** Cancels any active pointer drag so document listeners never leak. */\n override disconnect(): void {\n this.#repaint.cancel();\n this.#endDrag();\n }\n\n /** Repaints a minimum changed by application code or a Turbo morph. */\n minValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Repaints a maximum changed by application code or a Turbo morph. */\n maxValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Repaints a step changed by application code or a Turbo morph. */\n stepValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Repaints a value changed by application code or a Turbo morph. */\n valueValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Hydrates a thumb inserted or replaced at runtime with the current ARIA state. */\n thumbTargetConnected(thumb: HTMLElement): void {\n const value = this.#currentValue();\n this.#renderThumb(thumb, value);\n this.#renderFraction(value);\n if (this.#drag && this.#drag.thumb === null) {\n this.#drag.thumb = thumb;\n thumb.focus();\n }\n this.#repaint.schedule();\n }\n\n /** Fills a form field inserted or replaced at runtime on the next repaint. */\n fieldTargetConnected(): void {\n this.#repaint.schedule();\n }\n\n /** Drops the stale focus owner while allowing a live track gesture to continue. */\n thumbTargetDisconnected(thumb: HTMLElement): void {\n if (this.#drag?.thumb === thumb) this.#drag.thumb = null;\n }\n\n /** Ends a gesture whose geometry target disappeared or ceased being a target. */\n trackTargetDisconnected(track: HTMLElement): void {\n if (this.#drag?.track === track) this.#endDrag();\n }\n\n /** Handles keyboard stepping per the APG slider model. */\n onKeydown(event: KeyboardEvent): void {\n if (isReservedArrowChord(event)) return;\n let next: number | null = null;\n // Stepping snaps the declaration onto the value it publishes before moving.\n const declared = this.valueValue;\n const range = this.#steppedRange;\n // On a mirrored track the greater value sits at the visual left, so the\n // horizontal pair trades places; the vertical pair passes through.\n switch (this.#mirrored ? logicalArrowKey(event.key, this.element) : event.key) {\n case \"ArrowRight\":\n case \"ArrowUp\":\n next = stepSteppedValue(declared, 1, range);\n break;\n case \"ArrowLeft\":\n case \"ArrowDown\":\n next = stepSteppedValue(declared, -1, range);\n break;\n case \"PageUp\":\n next = stepSteppedValue(declared, 10, range);\n break;\n case \"PageDown\":\n next = stepSteppedValue(declared, -10, range);\n break;\n case \"Home\":\n next = this.minValue;\n break;\n case \"End\":\n next = this.maxValue;\n break;\n default:\n return;\n }\n event.preventDefault();\n this.#commit(next);\n }\n\n /** Begins a pointer drag: sets the value and tracks subsequent movement. */\n onPointerDown(event: PointerEvent): void {\n if (event.button !== 0 || this.#drag || !this.hasTrackTarget || !this.hasThumbTarget) return;\n const track = this.trackTarget;\n const thumb = this.thumbTarget;\n // Resolve the direction once for the whole gesture: reading it per move\n // would query computed style on every frame, and a drag that flipped\n // mid-gesture would be incoherent anyway.\n const mirrored = this.#mirrored;\n const value = this.#valueFromClientX(event.clientX, mirrored, track);\n if (value === null) return;\n event.preventDefault();\n this.#commit(value);\n thumb.focus();\n\n const drag: SliderDrag = { pointer: null, track, thumb };\n drag.pointer = new OwnedPointerSession(event, track, {\n move: (move) => {\n if (!track.isConnected) {\n this.#endDrag();\n return;\n }\n const moved = this.#valueFromClientX(move.clientX, mirrored, track);\n if (moved !== null) this.#commit(moved);\n },\n end: () => {\n if (this.#drag === drag) this.#drag = null;\n },\n });\n this.#drag = drag;\n }\n\n /** Maps a pointer X coordinate to a raw value using a stable track snapshot. */\n #valueFromClientX(clientX: number, mirrored: boolean, track: HTMLElement): number | null {\n const rect = track.getBoundingClientRect();\n if (rect.width === 0) return null;\n const offset = (clientX - rect.left) / rect.width;\n const fraction = mirrored ? 1 - offset : offset;\n return this.minValue + fraction * (this.maxValue - this.minValue);\n }\n\n /**\n * Stores the normalized value the user moved to, renders it synchronously for\n * responsive input, and reports it as `change` when it differs from the value\n * last published. The comparison is with the value last published, not with\n * the value the move started from, so a page write no repaint has published\n * yet is reported once, as this change, and a move that ends where the value\n * was last published reports nothing. The baseline moves before either report\n * goes out, so the repaint the Value write schedules — and any move a\n * subscriber makes while the report is dispatched — is measured from this\n * value.\n */\n #commit(raw: number): void {\n const value = snapSteppedValue(raw, this.#steppedRange);\n const reported = this.#settled;\n this.#settled = value;\n if (!Object.is(this.valueValue, value)) this.valueValue = value;\n this.#renderValue(value);\n this.#mirrorField(value, true);\n if (value !== reported) this.dispatch(\"change\", { detail: { value } });\n }\n\n /** Mirrors `value` into the optional form field, reporting only a user's move. */\n #mirrorField(value: number, notify: boolean): void {\n if (!this.hasFieldTarget) return;\n if (writeField(this.fieldTarget, String(value)) && notify) commitField(this.fieldTarget);\n }\n\n /**\n * Reflects the normalized current Value without writing it back. A published\n * value that moved from the last one is reported once as `reconcile`; the\n * field follows without a native `change`.\n *\n * @stimeoRenderRoot\n */\n #render(): void {\n const value = this.#currentValue();\n this.#renderValue(value);\n this.#mirrorField(value, false);\n if (value === this.#settled) return;\n this.#settled = value;\n this.dispatch(\"reconcile\", { detail: { value } });\n }\n\n /** Reflects one normalized value on the current target and CSS output. */\n #renderValue(value: number): void {\n if (this.hasThumbTarget) {\n this.#renderThumb(this.thumbTarget, value);\n }\n this.#renderFraction(value);\n }\n\n /** Writes only ARIA values that differ, including on a replacement target. */\n #renderThumb(thumb: HTMLElement, value: number): void {\n const attributes = {\n \"aria-valuemin\": String(this.minValue),\n \"aria-valuemax\": String(this.maxValue),\n \"aria-valuenow\": String(value),\n };\n for (const [name, next] of Object.entries(attributes)) {\n if (thumb.getAttribute(name) !== next) thumb.setAttribute(name, next);\n }\n }\n\n /** Writes the behavior-only positioning hook only when its value changed. */\n #renderFraction(value: number): void {\n const fraction = rangeFraction(value, this.minValue, this.maxValue);\n const next = String(fraction);\n if (this.element.style.getPropertyValue(FRACTION_PROPERTY) !== next) {\n this.element.style.setProperty(FRACTION_PROPERTY, next);\n }\n }\n\n /** Current normalized value derived from the live declarative inputs. */\n #currentValue(): number {\n return snapSteppedValue(this.valueValue, this.#steppedRange);\n }\n\n /** Shared range configuration; finite endpoints remain allowed off the grid. */\n get #steppedRange() {\n return { min: this.minValue, max: this.maxValue, step: this.stepValue };\n }\n\n /** Ends the current pointer session without dispatching another change. */\n #endDrag(): void {\n const drag = this.#drag;\n this.#drag = null;\n drag?.pointer?.end();\n }\n}\n\n/** Stable DOM and gesture state owned for the duration of one pointer drag. */\ninterface SliderDrag {\n pointer: OwnedPointerSession | null;\n readonly track: HTMLElement;\n thumb: HTMLElement | null;\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/logical_scroll.ts","../../src/utils/arrow_step.ts","../../src/utils/field_mirror.ts","../../src/utils/listener_set.ts","../../src/utils/microtask_coalescer.ts","../../src/utils/morph_render_watcher.ts","../../src/utils/move_counter.ts","../../src/utils/number_bounds.ts","../../src/utils/coerce.ts","../../src/utils/number_value.ts","../../src/utils/owned_pointer_session.ts","../../src/utils/range.ts","../../src/utils/stepped_value.ts","../../src/controllers/slider_controller.ts"],"names":["position"],"mappings":"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","file":"slider_controller.js","sourcesContent":["/** Normalized scroll position and maximum distance on one logical axis. */\nexport interface LogicalScrollMetrics {\n position: number;\n max: number;\n}\n\n/**\n * Whether horizontal scrolling on `element` follows right-to-left inline flow.\n *\n * Resolved from the **computed** `direction`, so the authoring contract is the\n * usual `dir=\"rtl\"` (or a stylesheet) on the element or any ancestor.\n *\n * Scope: horizontal writing modes. A vertical writing mode (`writing-mode:\n * vertical-rl`) also inverts the horizontal axis, which this check does not\n * model — vertical writing modes are out of scope for the scroll utilities\n * (their consumers describe axes as horizontal/vertical, not inline/block).\n */\nexport function isRtl(element: Element): boolean {\n return window.getComputedStyle(element).direction === \"rtl\";\n}\n\n/**\n * Returns scroll distance from the logical start edge.\n *\n * CSSOM View exposes standards-mode RTL horizontal offsets as `0` at the inline\n * start (right) and increasingly negative values toward the inline end (left).\n * The normalized position is always clamped to `[0, max]`, which also absorbs\n * Safari's elastic overscroll values.\n */\nexport function logicalScrollMetrics(\n element: HTMLElement,\n horizontal: boolean,\n): LogicalScrollMetrics {\n const max = Math.max(\n 0,\n horizontal\n ? element.scrollWidth - element.clientWidth\n : element.scrollHeight - element.clientHeight,\n );\n const raw = horizontal ? element.scrollLeft : element.scrollTop;\n const position = horizontal && isRtl(element) ? -raw : raw;\n return { position: Math.min(max, Math.max(0, position)), max };\n}\n\n/**\n * Converts a logical start/end delta to the physical value accepted by\n * `Element.scrollBy`.\n */\nexport function physicalScrollDelta(\n element: HTMLElement,\n horizontal: boolean,\n logicalDelta: number,\n): number {\n return horizontal && isRtl(element) ? -logicalDelta : logicalDelta;\n}\n","import { isRtl } from \"./logical_scroll\";\n\n/**\n * Turns an arrow key into a **logical** step: `+1` for \"next\", `-1` for\n * \"previous\", `0` when the key names neither.\n *\n * APG defines the horizontal pair as *next / previous* and says a vertical\n * arrangement swaps in Down/Up for the same meaning — so the pair is one axis's\n * spelling of an order, and the order reverses with the writing direction. Only\n * the horizontal pair reverses. Down/Up name an axis the writing direction does\n * not mirror, and returning them unchanged is the point: many controllers fold\n * both pairs into one branch, where swapping the branches under RTL would flip\n * the vertical axis too — a bug that reads as \"the arrows work\" until someone\n * presses Down.\n *\n * **Direction is read from the element the caller passes, which should be the\n * container that lays the items out** — not the focused child. A child may carry\n * its own `dir` (an LTR input inside an RTL form is ordinary authoring), and\n * probing per handler makes two handlers disagree at the boundary between them.\n *\n * This decides direction only. Whether the axis is even active (an\n * `orientation=\"horizontal\"` widget ignoring Down/Up), how far the step lands,\n * and what wrapping does all stay with the caller.\n *\n * **It encodes the list-order convention: `ArrowDown` is *next*.** Widgets that\n * pair the arrows by *value* instead — `ArrowUp` meaning \"more\", as a rating or a\n * slider does — must not use this, or their vertical axis inverts. Reverse the\n * horizontal pair on its own there.\n *\n * @example\n * ```ts\n * const step = logicalArrowStep(event.key, this.element);\n * if (step === 0) return;\n * this.#roving.setActive(rovingMove(current, length, step, \"wrap\"), { focus: true });\n * ```\n */\nexport function logicalArrowStep(key: string, element: Element): 1 | -1 | 0 {\n if (key === \"ArrowDown\") return 1;\n if (key === \"ArrowUp\") return -1;\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\") return 0;\n const forward = isRtl(element) ? \"ArrowLeft\" : \"ArrowRight\";\n return key === forward ? 1 : -1;\n}\n\n/**\n * Rewrites `key` so an existing LTR-shaped branch keeps working under RTL:\n * `ArrowRight` and `ArrowLeft` trade places, everything else passes through.\n *\n * The alternative — negating a delta — silently breaks handlers whose two\n * horizontal branches are **not mirror images**. A grid that clamps one edge but\n * not the other, or a segmented field guarding `index > 0` on one side and\n * `index < length - 1` on the other, ends up applying the wrong guard to the\n * wrong direction. Swapping the key leaves each branch, guards and all, exactly\n * where its author put it.\n *\n * Same rule as {@link logicalArrowStep} about which element to read: pass the\n * container that lays the items out, not the focused child.\n *\n * @example\n * ```ts\n * switch (logicalArrowKey(event.key, this.element)) {\n * case \"ArrowLeft\": // \"previous\" — whatever direction that is on screen\n * ```\n */\nexport function logicalArrowKey(key: string, element: Element): string {\n if (key !== \"ArrowRight\" && key !== \"ArrowLeft\") return key;\n if (!isRtl(element)) return key;\n return key === \"ArrowRight\" ? \"ArrowLeft\" : \"ArrowRight\";\n}\n\n/** Modifiers a widget may claim on an arrow key, named for the `allow` list. */\nexport type ArrowModifier = \"alt\" | \"ctrl\" | \"meta\" | \"shift\";\n\n/**\n * True when an arrow key arrived carrying a modifier the widget must leave to\n * the browser: return without calling `preventDefault()` and without moving any\n * state.\n *\n * A bare arrow belongs to the widget; a chorded one usually does not.\n * `Alt`/`Meta` plus a horizontal arrow is history back/forward on every desktop\n * browser, and a widget that swallows it makes the shortcut work or not\n * depending on where focus happens to sit — a coin-flip the user cannot see.\n *\n * `allow` is for the combinations APG assigns to a pattern **and the widget\n * actually implements** — today only Combobox's optional `Alt+Down`/`Alt+Up`.\n * Listing one the widget does not implement defeats the point: the chord then\n * runs the plain-arrow branch, which is exactly what this guard exists to stop.\n * Non-arrow keys return `false`, so chorded letters and\n * `Control+Home`/`Control+End` are untouched.\n *\n * @example\n * ```ts\n * if (isReservedArrowChord(event)) return;\n * ```\n */\nexport function isReservedArrowChord(\n event: KeyboardEvent,\n allow: readonly ArrowModifier[] = [],\n): boolean {\n if (!event.key.startsWith(\"Arrow\")) return false;\n return (\n (event.altKey && !allow.includes(\"alt\")) ||\n (event.ctrlKey && !allow.includes(\"ctrl\")) ||\n (event.metaKey && !allow.includes(\"meta\")) ||\n (event.shiftKey && !allow.includes(\"shift\"))\n );\n}\n\n/**\n * True when a press arrived carrying any modifier, for the keys the browser and\n * the OS own outright: return without calling `preventDefault()` and without\n * moving any state.\n *\n * `Control+Home` and `Control+End` jump the document to its ends, and a widget\n * that swallows them makes the shortcut work or not depending on where focus\n * happens to sit. {@link isReservedArrowChord} answers the same question for the\n * arrows, but returns `false` for every other key so that this one can decide.\n *\n * There is no `allow` list here on purpose. APG assigns no modifier chord to\n * `Home`/`End`, so a widget that wanted one would be claiming a combination the\n * pattern never gave it.\n *\n * @example\n * ```ts\n * case \"Home\":\n * case \"End\":\n * if (hasModifierChord(event)) return;\n * ```\n */\nexport function hasModifierChord(event: KeyboardEvent): boolean {\n return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n}\n","/**\n * The hidden form fields a widget keeps in step with the state it owns.\n *\n * A widget whose value lives in ARIA attributes submits nothing on its own, so\n * it mirrors that value into `<input type=\"hidden\">` — one field for a single\n * value, a container of generated fields for a set. The mirror is one-way: the\n * widget's own state stays the source of truth and the field is what the form\n * reads.\n *\n * The write and the report are separate calls because they answer to different\n * rules. A mirror is refreshed on connect, after a morph, and whenever the\n * widget repairs itself — none of which a form should treat as an edit. Only\n * the user's own commit reports one, which is why {@link commitField} is never\n * folded into the writes.\n */\n\n/** How a widget's generated fields identify themselves to the form. */\nexport interface GeneratedFieldOptions {\n /** The `name` every generated input submits under. */\n readonly name: string;\n /** The `form` id, for a widget that sits outside the form it submits to. */\n readonly form?: string;\n}\n\n/**\n * Mirrors one value into a hidden field.\n *\n * @returns Whether the field's value moved.\n *\n * @example\n * ```ts\n * if (writeField(this.fieldTarget, String(value)) && userDriven) {\n * commitField(this.fieldTarget);\n * }\n * ```\n */\nexport function writeField(field: HTMLInputElement, value: string): boolean {\n if (field.value === value) return false;\n field.value = value;\n return true;\n}\n\n/**\n * Mirrors a set of values into `container` as generated hidden fields, in the\n * order given.\n *\n * A container that already submits exactly this set is left untouched, children\n * and all — the mirror is refreshed far more often than it moves (every connect,\n * morph and repair), and a rebuild that changes nothing is still a DOM mutation\n * a consumer's observer and a `:empty` rule can see.\n *\n * @returns Whether the submitted set moved — its values, their order, the\n * `name`, or the `form`.\n */\nexport function writeFields(\n container: HTMLElement,\n values: readonly string[],\n { name, form = \"\" }: GeneratedFieldOptions,\n): boolean {\n const current = [...container.children];\n const submits =\n current.length === values.length &&\n current.every(\n (child, index) =>\n child instanceof HTMLInputElement &&\n child.type === \"hidden\" &&\n child.value === values[index] &&\n child.name === name &&\n (child.getAttribute(\"form\") ?? \"\") === form,\n );\n if (submits) return false;\n\n container.replaceChildren(\n ...values.map((value) => {\n const input = document.createElement(\"input\");\n input.type = \"hidden\";\n input.name = name;\n input.value = value;\n if (form !== \"\") input.setAttribute(\"form\", form);\n return input;\n }),\n );\n return true;\n}\n\n/**\n * Reports a committed value from `target` the way a native form control does:\n * one bubbling, non-cancelable `change`.\n *\n * Call it only for a move the user made. Form-level behaviors listen for this —\n * validation re-checks, auto-submit — and a mirror refreshed by a morph or a\n * repair is not something the user submitted.\n *\n * `target` is the element that carries the value: the hidden field for a single\n * mirrored value, the container for a generated set (whose own inputs are\n * replaced on every write), or a widget's own native control where that is what\n * the form reads.\n */\nexport function commitField(target: HTMLElement): void {\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n","/**\n * Owns every listener a controller attaches for one connected lifetime and\n * releases them together, so an event name is spelled once and the release\n * cannot drift from the registration.\n *\n * Detaching by hand repeats three things at the release site — the type, the\n * handler reference and the capture flag — and any one of them drifting leaves\n * a listener alive on an element the controller no longer drives. Aborting the\n * signal a registration was created with releases it whatever it was made of,\n * so the release site names nothing.\n *\n * One set per lifetime, held as a field and never rebuilt. {@link\n * ListenerSet.dispose} is the only thing that closes a generation, and it opens\n * the next one in the same step, so the lifecycle hooks can call `add` and\n * `dispose` in any order any number of times, and no `add` ever meets an\n * already aborted signal — a DOM that registers a listener on such a signal\n * would keep it forever. Rebuilding the set instead would leak:\n * `addEventListener` matches an existing registration on target, type, callback\n * and capture alone, so re-adding the same handler while the first registration\n * is live is discarded, and that live registration keeps the signal it was\n * attached with — a set built by a second `connect()` can never release what it\n * appears to own.\n *\n * Scope is the registration only. Timers, observers, leases and the order they\n * are unwound in stay with the controller, which places `dispose()` in its\n * cleanup sequence. A receiver that changes at runtime (a\n * swapped target) is rebound by calling `dispose()` and then `add()` again from\n * the rebind, not by a second set.\n *\n * The set must own every registration of a tuple it holds: a listener the same\n * target already carries for the same type, callback and capture flag keeps the\n * right to remove it, and this set's `add` for that tuple is discarded. A\n * subscription shared between instances behind a participant count, or one that\n * lives for less than the connection, keeps its own pair of calls.\n *\n * @example\n * ```ts\n * readonly #listeners = new ListenerSet();\n *\n * connect(): void {\n * this.#listeners.add(this.element, \"submit\", this.#onNativeSubmit, { capture: true });\n * this.#listeners.add(this.element, \"turbo:submit-start\", this.#onSubmitStart);\n * this.#listeners.add(this.element, \"turbo:submit-end\", this.#onSubmitEnd);\n * }\n *\n * disconnect(): void {\n * this.#listeners.dispose();\n * }\n * ```\n */\nexport class ListenerSet {\n /** The generation every `add` joins until the next `dispose()`. */\n #abort = new AbortController();\n\n /**\n * Attaches `handler` to the open generation, exactly as the caller spelled it.\n *\n * The set supplies the signal, so `options` carries everything else the DOM\n * accepts — `capture` included, which has to match at release time and no\n * longer has a second place to drift from.\n */\n add(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: Omit<AddEventListenerOptions, \"signal\">,\n ): void {\n target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });\n }\n\n /**\n * Releases every listener of the open generation, synchronously, and opens the\n * next one. Idempotent, and safe before anything has been added.\n */\n dispose(): void {\n this.#abort.abort();\n this.#abort = new AbortController();\n }\n}\n","/**\n * Collapses many Stimulus lifecycle callbacks from one DOM mutation into a\n * single pass.\n *\n * Stimulus fires `<name>TargetConnected` / `Disconnected` once per element and\n * `<name>ValueChanged` once per changed attribute. Replacing a list of N options\n * or morphing several render Values therefore delivers N callbacks — but the\n * useful unit of work is \"reconcile against the resulting declarative input\",\n * once, after the batch has settled. Every controller with reconcilable targets\n * or render Values needs the same shape: a `queued` flag plus `queueMicrotask`.\n *\n * **A microtask is the right horizon, and the reason is specific.** Stimulus\n * drives these callbacks from a `MutationObserver`, whose own callback already\n * runs as a microtask with the whole batch in hand; scheduling one more lands\n * after the last sibling callback of that batch and still before paint or any\n * event handler. A timer would be later than it needs to be, and reconciling\n * synchronously would run once per element against a half-applied DOM.\n *\n * **The two guards are not the same guard.** Scheduling is refused before the\n * controller connects, and running is refused after it disconnects:\n *\n * - **Before `connect()`** — Stimulus delivers initial target and Value callbacks\n * ahead of `connect()`. Reconciling there would compute output against a\n * controller whose own state has not been initialised, and `connect()` is\n * about to do a full pass anyway.\n * - **After `disconnect()`** — Stimulus fires a callback for **every** target\n * during teardown, and a microtask queued just before it would otherwise run\n * against a detached tree. {@link MicrotaskCoalescer.cancel} exists for the\n * teardown path to drop the pending pass outright.\n *\n * Both guards are part of one contract here rather than something each consumer\n * has to remember separately.\n *\n * Scope is the scheduling only. *What* to reconcile — keep the surviving active\n * option, fall back to the next / previous / first visible one, rebuild derived\n * chips or hidden fields — stays in the controller, because no two consumers\n * answer it the same way.\n *\n * @example\n * ```ts\n * readonly #reconcile = new MicrotaskCoalescer(() => this.#reconcileOptions());\n *\n * connect() { this.#reconcile.activate(); }\n * disconnect() { this.#reconcile.cancel(); }\n *\n * optionTargetConnected() { this.#reconcile.schedule(); }\n * optionTargetDisconnected() { this.#reconcile.schedule(); }\n * ```\n */\nexport class MicrotaskCoalescer {\n readonly #run: () => void;\n #queued = false;\n #active = false;\n #generation = 0;\n\n /** @param run - the single reconciliation pass, invoked at most once per batch. */\n constructor(run: () => void) {\n this.#run = run;\n }\n\n /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */\n activate(): void {\n this.#active = true;\n }\n\n /** Closes the window and drops any pending pass; call from `disconnect()`. */\n cancel(): void {\n this.#active = false;\n this.#queued = false;\n this.#generation += 1;\n }\n\n /** Requests one pass after the batch settles. Idempotent; inert outside the window. */\n schedule(): void {\n if (!this.#active || this.#queued) return;\n this.#queued = true;\n const generation = this.#generation;\n queueMicrotask(() => {\n // A cancelled callback must not consume a pass queued after reconnect.\n if (generation !== this.#generation || !this.#queued || !this.#active) return;\n this.#queued = false;\n this.#run();\n });\n }\n}\n","import { ListenerSet } from \"./listener_set\";\nimport { MicrotaskCoalescer } from \"./microtask_coalescer\";\n\n/**\n * Coalesces retained-element morphs and explicit lifecycle requests into one pass.\n *\n * Observe the controller's element after its initial state is settled. Morphs on\n * that element and bubbling morphs on its descendants share the same microtask\n * as {@link schedule}. The callback repairs derived output; the controller owns\n * any logical transition reporting. {@link disconnect} releases the listener and\n * cancels pending work, including work from an earlier connected lifetime.\n */\nexport class MorphRenderWatcher {\n readonly #listeners = new ListenerSet();\n readonly #pass: MicrotaskCoalescer;\n #element: Element | null = null;\n readonly #onMorph = (): void => this.#pass.schedule();\n\n /** @param run - the single pass that repairs the settled controller's output. */\n constructor(run: () => void) {\n this.#pass = new MicrotaskCoalescer(run);\n }\n\n /** Opens observation; observing the same element again preserves queued work. */\n observe(element: Element): void {\n if (this.#element === element) return;\n this.disconnect();\n this.#element = element;\n this.#pass.activate();\n this.#listeners.add(element, \"turbo:morph-element\", this.#onMorph);\n }\n\n /** Requests one pass; requests outside an observed lifetime are ignored. */\n schedule(): void {\n this.#pass.schedule();\n }\n\n /** Releases observation and pending work synchronously; safe to repeat. */\n disconnect(): void {\n this.#listeners.dispose();\n this.#pass.cancel();\n this.#element = null;\n }\n}\n","/**\n * Identifies the latest reported state transition of one owner.\n *\n * Record a transition after its state is written and before invoking external\n * code. Check the returned token before each later report: a synchronous\n * transition made by a listener supersedes reports that have not been sent.\n * Reading state or committing an unchanged state must not advance the counter.\n * Reports stay in the caller so their ordering remains explicit.\n */\nexport class MoveCounter {\n #sequence = 0;\n\n /** Records a state transition and returns its report token. */\n record(): number {\n this.#sequence += 1;\n return this.#sequence;\n }\n\n /** Whether no later state transition has superseded this report token. */\n isLatest(token: number): boolean {\n return token === this.#sequence;\n }\n}\n","import { MAX_TIMER_DELAY_MS } from \"./timer_bounds\";\n\n/** Semantic constraints on an already decoded number, independent of the DOM. */\nexport interface NumberBounds {\n /** Finite numbers are required, including when this field is omitted. */\n readonly finite?: true;\n /** Inclusive lower endpoint. */\n readonly min?: number;\n /** Inclusive upper endpoint. */\n readonly max?: number;\n /** Exclusive lower endpoint. */\n readonly exclusiveMin?: number;\n /** Require a number without a fractional part. */\n readonly integer?: boolean;\n /** Exact decoded numbers accepted by a discrete contract. */\n readonly allowedValues?: readonly number[];\n /** JSON-safe exceptions to finite-number checking for unbounded endpoints. */\n readonly allowInfinity?: \"negative\" | \"positive\" | \"both\";\n}\n\n/** One constraint for each Number Value, including shorthand declarations. */\nexport type NumberValueConstraints<Values> = {\n readonly [Key in keyof Values as Values[Key] extends\n | NumberConstructor\n | { type: NumberConstructor }\n ? Key\n : never]: NumberBounds;\n};\n\n/** Reusable semantic domains; fractional inputs remain fractional unless excluded. */\nexport const NUMBER_BOUNDS = {\n finite: { finite: true },\n nonNegative: { finite: true, min: 0 },\n positive: { finite: true, exclusiveMin: 0 },\n nonNegativeInteger: { finite: true, min: 0, integer: true },\n positiveInteger: { finite: true, exclusiveMin: 0, integer: true },\n lowerBound: { finite: true, allowInfinity: \"negative\" },\n upperBound: { finite: true, allowInfinity: \"positive\" },\n timer: { finite: true, min: 0, max: MAX_TIMER_DELAY_MS },\n positiveTimer: { finite: true, exclusiveMin: 0, max: MAX_TIMER_DELAY_MS },\n} as const satisfies Record<string, NumberBounds>;\n\n/**\n * Checks all declared bounds without rounding, clamping, or coercing the input.\n * Infinity exceptions relax only finite checking; every other bound still applies.\n */\nexport function matchesNumberBounds(value: number, bounds: NumberBounds): boolean {\n if (!Number.isFinite(value)) {\n const direction = value === Infinity ? \"positive\" : value === -Infinity ? \"negative\" : null;\n if (direction === null) return false;\n if (bounds.allowInfinity !== \"both\" && bounds.allowInfinity !== direction) return false;\n }\n if (bounds.min !== undefined && value < bounds.min) return false;\n if (bounds.max !== undefined && value > bounds.max) return false;\n if (bounds.exclusiveMin !== undefined && value <= bounds.exclusiveMin) return false;\n if (bounds.integer && !Number.isInteger(value)) return false;\n if (bounds.allowedValues !== undefined && !bounds.allowedValues.includes(value)) return false;\n return true;\n}\n\n/** Decodes a Number Value literal; action params use their own JSON decoder. */\nexport function decodeNumberValue(raw: string): number {\n return Number(raw.replace(/_/g, \"\"));\n}\n","/**\n * Numeric coercion for controllers that accept a number through a Value, an action\n * param, or an event detail.\n *\n * Stimulus decodes action params as JSON when possible and leaves other text\n * untouched. CustomEvent detail can also supply a number or numeric string.\n * The reader accepts those two types while rejecting blank and non-finite input.\n */\n\nimport { matchesNumberBounds, type NumberBounds } from \"./number_bounds\";\n\n/**\n * Reads a finite number or nonblank numeric string; other input returns `null`.\n * Blank strings cannot silently reset a value to zero.\n */\nexport function toFiniteNumber(raw: unknown): number | null {\n if (typeof raw !== \"number\" && typeof raw !== \"string\") return null;\n if (typeof raw === \"string\" && raw.trim().length === 0) return null;\n const value = Number(raw);\n return Number.isFinite(value) ? value : null;\n}\n\n/**\n * Returns an accepted decoded Number Value or the caller's fallback unchanged.\n * The caller owns the fallback contract; this reader does not parse or write a Value.\n */\nexport function readNumber(raw: number, fallback: number, bounds: NumberBounds): number {\n return matchesNumberBounds(raw, bounds) ? raw : fallback;\n}\n","import { readNumber } from \"./coerce\";\nimport { matchesNumberBounds, type NumberBounds } from \"./number_bounds\";\n\n/** The instance identity carried by a Number Value read. */\nexport interface NumberValueOwner {\n readonly identifier: string;\n readonly element: Element;\n}\n\n/** Reads current declarations at the point of use without rewriting their attributes. */\nexport class NumberValueReader {\n /** The last rejected literal per Value; no history grows for an unchanged instance. */\n readonly #lastRejected = new Map<string, string>();\n\n /** Resolves the declared number using its own fallback and shared class contract. */\n read(\n owner: NumberValueOwner,\n name: string,\n raw: number,\n fallback: number,\n bounds: NumberBounds,\n ): number {\n const resolved = readNumber(raw, fallback, bounds);\n if (matchesNumberBounds(raw, bounds)) {\n this.#lastRejected.delete(name);\n return resolved;\n }\n const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;\n const literal = owner.element.getAttribute(attribute);\n if (literal === null) {\n this.#lastRejected.delete(name);\n return resolved;\n }\n if (this.#lastRejected.get(name) !== literal) {\n this.#lastRejected.set(name, literal);\n console.warn(\n `Stimeo UI: \"${owner.identifier}\" has an invalid number Value \"${name}\" declaration ${JSON.stringify(literal)}; using ${fallback}.`,\n );\n }\n return resolved;\n }\n}\n","/** What ended an owned pointer session. */\nexport type OwnedPointerSessionEnd = \"up\" | \"cancel\" | \"teardown\";\n\n/** Callbacks driven by one owned pointer until it ends or is cancelled. */\nexport interface OwnedPointerSessionHandlers {\n /** Receives movement from the initiating pointer only. */\n readonly move: (event: PointerEvent) => void;\n /**\n * Runs once after every listener and pointer capture have been released,\n * naming what ended the session.\n */\n readonly end?: (kind: OwnedPointerSessionEnd) => void;\n}\n\n/**\n * Owns one pointer across document-level movement and termination events.\n *\n * A controller may have at most one instance at a time. The session filters\n * every event by the initiating `pointerId` and binds all document listeners to\n * one abort signal, so exactly one callback runs when the session ends.\n *\n * **Pointer capture is delivery, not lifetime.** It is taken when the DOM\n * implementation supports it, and losing it — a consumer re-inserting the owner\n * mid-gesture, another element claiming the pointer — never ends the session:\n * the document listeners receive the pointer either way, because a captured\n * event still bubbles to the document and an uncaptured one fires there anyway.\n * An owner that actually left the tree is the owner's own business; every\n * consumer already answers that question with its own detach probe, and a\n * second answer here would cut gestures the consumer means to keep.\n */\nexport class OwnedPointerSession {\n readonly #pointerId: number;\n readonly #owner: HTMLElement;\n readonly #handlers: OwnedPointerSessionHandlers;\n readonly #abort = new AbortController();\n #active = true;\n\n constructor(start: PointerEvent, owner: HTMLElement, handlers: OwnedPointerSessionHandlers) {\n this.#pointerId = start.pointerId;\n this.#owner = owner;\n this.#handlers = handlers;\n\n const { signal } = this.#abort;\n owner.ownerDocument.addEventListener(\"pointermove\", this.#onMove, { signal });\n owner.ownerDocument.addEventListener(\"pointerup\", this.#onEndEvent, { signal });\n owner.ownerDocument.addEventListener(\"pointercancel\", this.#onEndEvent, { signal });\n\n // Pointer capture is progressive here: happy-dom and older DOM shims may not\n // implement it, while the document listeners still preserve ownership.\n try {\n owner.setPointerCapture?.(this.#pointerId);\n } catch {\n // A synthetic or already-ended pointer cannot be captured; filtering and\n // AbortController teardown remain sufficient for that environment.\n }\n }\n\n /** Releases capture and listeners, then reports the end exactly once. */\n end(): void {\n this.#finish(\"teardown\");\n }\n\n #finish(kind: OwnedPointerSessionEnd): void {\n if (!this.#active) return;\n this.#active = false;\n this.#abort.abort();\n try {\n this.#owner.releasePointerCapture?.(this.#pointerId);\n } catch {\n // Losing capture because the owner detached is already an ended session.\n }\n this.#handlers.end?.(kind);\n }\n\n #owns(event: PointerEvent): boolean {\n return this.#active && event.pointerId === this.#pointerId;\n }\n\n readonly #onMove = (event: PointerEvent): void => {\n if (this.#owns(event)) this.#handlers.move(event);\n };\n\n readonly #onEndEvent = (event: PointerEvent): void => {\n if (this.#owns(event)) this.#finish(event.type === \"pointerup\" ? \"up\" : \"cancel\");\n };\n}\n","/**\n * Range normalization shared by the value-bearing controllers (progress, meter,\n * slider, range-slider).\n *\n * Each of them publishes \"where the value sits inside `[min, max]`\" as a CSS\n * custom property the consumer multiplies a track by, and each has to answer the\n * same degenerate cases: empty and inverted ranges cannot express progress, and\n * malformed Number Values can produce `NaN`. Keeping the rule in one place is\n * what makes those answers identical across the four.\n */\n\n/**\n * Fraction of `[min, max]` that `value` occupies, always within `[0, 1]`.\n *\n * `value` is clamped into the range first, so a value outside it reports a full\n * or empty track rather than pushing the fraction past the ends.\n *\n * An empty, inverted, or non-numeric range yields `0`. That is a deliberate\n * floor rather than a computed result: `min === max` would produce `NaN`, and\n * `min > max` would report a full track for a value that is really out of range.\n * Non-finite results are floored for the same reason. These results reach\n * assistive tech, because the same fraction drives the percentage substituted\n * into `aria-valuetext`.\n */\nexport function rangeFraction(value: number, min: number, max: number): number {\n const span = max - min;\n if (!(span > 0)) return 0;\n\n const clamped = Math.min(max, Math.max(min, value));\n let fraction: number;\n if (Number.isFinite(span)) {\n fraction = (clamped - min) / span;\n } else {\n // Scaling preserves the ratio when two finite endpoints straddle zero so\n // widely that their subtraction overflows to Infinity.\n const scale = Math.max(Math.abs(min), Math.abs(max));\n fraction = (clamped / scale - min / scale) / (max / scale - min / scale);\n }\n\n if (!Number.isFinite(fraction)) return 0;\n return Math.min(1, Math.max(0, fraction));\n}\n","/** Configuration for a value constrained to a stepped numeric range. */\nexport interface SteppedRange {\n /** Inclusive lower endpoint. May be infinite for an unbounded control. */\n readonly min: number;\n /** Inclusive upper endpoint. May be infinite for an unbounded control. */\n readonly max: number;\n /** Requested step. Non-finite and non-positive values fall back to `1`. */\n readonly step: number;\n /** Step-grid origin. Defaults to a finite `min`, otherwise `0`. */\n readonly base?: number;\n}\n\n/** The positive finite step used at runtime and by keyboard stepping. */\nexport function effectiveStep(step: number): number {\n return Number.isFinite(step) && step > 0 ? step : 1;\n}\n\n/**\n * Clamps a raw value and selects its nearest allowed value.\n *\n * The allowed set is the step grid plus each finite range endpoint. Keeping the\n * endpoints in that set makes an authored `aria-valuemin`/`aria-valuemax`\n * truthful even when the upper endpoint is not aligned to the grid. A value\n * exactly between two allowed values resolves upward.\n */\nexport function snapSteppedValue(raw: number, range: SteppedRange): number {\n if (!(range.min <= range.max)) return finiteFallback(range.min, range.max);\n\n const input = Number.isNaN(raw) ? finiteFallback(range.min, range.max) : raw;\n const clamped = Math.min(range.max, Math.max(range.min, input));\n const step = effectiveStep(range.step);\n const base = stepBase(range);\n const candidates: number[] = [];\n\n if (Number.isFinite(range.min)) candidates.push(range.min);\n if (Number.isFinite(range.max)) candidates.push(range.max);\n\n const gridPosition = (clamped - base) / step;\n if (Number.isFinite(gridPosition)) {\n addGridCandidate(candidates, Math.floor(gridPosition), range, base, step);\n addGridCandidate(candidates, Math.ceil(gridPosition), range, base, step);\n }\n\n if (candidates.length === 0) return clamped;\n let nearest = candidates[0] as number;\n let nearestDistance = Math.abs(clamped - nearest);\n for (const candidate of candidates.slice(1)) {\n const distance = Math.abs(clamped - candidate);\n if (\n distance < nearestDistance ||\n (nearlyEqual(distance, nearestDistance) && candidate > nearest)\n ) {\n nearest = candidate;\n nearestDistance = distance;\n }\n }\n return nearest;\n}\n\n/**\n * Moves through the ordered allowed-value set by an integer number of steps.\n *\n * This differs from adding `step * count` and snapping afterward at an\n * off-grid endpoint: with `max=94, step=10`, one decrement from `94` must land\n * on `90`, and one increment from `90` must reach the advertised maximum `94`.\n */\nexport function stepSteppedValue(current: number, count: number, range: SteppedRange): number {\n const value = snapSteppedValue(current, range);\n const distance = Math.abs(Math.trunc(count));\n if (!Number.isFinite(distance) || distance === 0) return value;\n const direction = Math.sign(count);\n const adjacent = adjacentSteppedValue(value, direction, range);\n\n // The first move accounts for a possibly off-grid endpoint. From there a\n // direct grid jump is equivalent to repeated adjacency, and avoids work that\n // grows with Page-step magnitudes or programmatic counts.\n const raw = adjacent + direction * (distance - 1) * effectiveStep(range.step);\n return snapSteppedValue(raw, range);\n}\n\n/** Returns the next member of the ordered endpoint-plus-grid set. */\nfunction adjacentSteppedValue(current: number, direction: number, range: SteppedRange): number {\n const step = effectiveStep(range.step);\n const base = stepBase(range);\n const candidates: number[] = [];\n\n if (direction > 0) {\n const position = (current - base) / step;\n if (Number.isFinite(position)) {\n let gridIndex = Math.floor(position) + 1;\n let candidate = cleanGridValue(base + gridIndex * step, base, step);\n if (candidate < current || nearlyEqual(candidate, current)) {\n gridIndex += 1;\n candidate = cleanGridValue(base + gridIndex * step, base, step);\n }\n if (\n candidate > current &&\n !nearlyEqual(candidate, current) &&\n within(candidate, range.min, range.max)\n ) {\n candidates.push(clamp(candidate, range));\n }\n }\n return clamp(Math.min(...candidates), range);\n }\n\n const position = (current - base) / step;\n if (Number.isFinite(position)) {\n let gridIndex = Math.ceil(position) - 1;\n let candidate = cleanGridValue(base + gridIndex * step, base, step);\n if (candidate > current || nearlyEqual(candidate, current)) {\n gridIndex -= 1;\n candidate = cleanGridValue(base + gridIndex * step, base, step);\n }\n if (\n candidate < current &&\n !nearlyEqual(candidate, current) &&\n within(candidate, range.min, range.max)\n ) {\n candidates.push(clamp(candidate, range));\n }\n }\n return clamp(Math.max(...candidates), range);\n}\n\n/** Adds one grid value when it falls inside the inclusive range. */\nfunction addGridCandidate(\n candidates: number[],\n index: number,\n range: SteppedRange,\n base: number,\n step: number,\n): void {\n const candidate = cleanGridValue(base + index * step, base, step);\n if (within(candidate, range.min, range.max)) candidates.push(clamp(candidate, range));\n}\n\n/** A finite authored base wins; otherwise the finite lower bound or zero does. */\nfunction stepBase(range: SteppedRange): number {\n if (range.base !== undefined && Number.isFinite(range.base)) return range.base;\n return Number.isFinite(range.min) ? range.min : 0;\n}\n\n/** Removes binary noise without discarding significant integer-place digits. */\nfunction cleanGridValue(value: number, base: number, step: number): number {\n const precision = Math.max(decimalPlaces(base), decimalPlaces(step));\n // `toFixed` accepts at most 100 fractional digits. Below that limit it rounds\n // according to the authored grid precision rather than an arbitrary total\n // significant-digit count, which keeps unit steps distinct at large bases.\n return precision <= 100 ? Number(value.toFixed(precision)) : value;\n}\n\n/** Number of fractional decimal places represented by a finite JS number. */\nfunction decimalPlaces(value: number): number {\n const [coefficient = \"\", exponentText] = Math.abs(value).toString().toLowerCase().split(\"e\");\n const fractionLength = coefficient.split(\".\")[1]?.length ?? 0;\n const exponent = exponentText === undefined ? 0 : Number(exponentText);\n return Math.max(0, fractionLength - exponent);\n}\n\n/** Inclusive range check tolerant only of arithmetic noise at an endpoint. */\nfunction within(value: number, min: number, max: number): boolean {\n return (value > min || nearlyEqual(value, min)) && (value < max || nearlyEqual(value, max));\n}\n\n/** Clamps a candidate whose only overshoot may be floating-point noise. */\nfunction clamp(value: number, range: SteppedRange): number {\n return Math.min(range.max, Math.max(range.min, value));\n}\n\n/** Relative comparison used only to collapse arithmetic noise, not real steps. */\nfunction nearlyEqual(left: number, right: number): boolean {\n const scale = Math.max(Math.abs(left), Math.abs(right));\n return (\n Number.isFinite(left) &&\n Number.isFinite(right) &&\n Math.abs(left - right) <= Number.EPSILON * scale\n );\n}\n\n/** Stable fallback for malformed ranges or `NaN` input. */\nfunction finiteFallback(min: number, max: number): number {\n if (Number.isFinite(min)) return min;\n if (Number.isFinite(max)) return max;\n return 0;\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { isReservedArrowChord, logicalArrowKey } from \"../utils/arrow_step\";\nimport { commitField, writeField } from \"../utils/field_mirror\";\nimport { isRtl } from \"../utils/logical_scroll\";\nimport { MorphRenderWatcher } from \"../utils/morph_render_watcher\";\nimport { MoveCounter } from \"../utils/move_counter\";\nimport { NUMBER_BOUNDS, type NumberValueConstraints } from \"../utils/number_bounds\";\nimport { NumberValueReader } from \"../utils/number_value\";\nimport { OwnedPointerSession } from \"../utils/owned_pointer_session\";\nimport { rangeFraction } from \"../utils/range\";\nimport { snapSteppedValue, stepSteppedValue } from \"../utils/stepped_value\";\n\n/** Name of the CSS custom property exposing the thumb position (0..1). */\nconst FRACTION_PROPERTY = \"--stimeo--slider-fraction\";\n\n/**\n * Headless, accessible slider (single-thumb range) behavior.\n *\n * Markup contract (identifier: `stimeo--slider`):\n * <div data-controller=\"stimeo--slider\"\n * data-stimeo--slider-min-value=\"0\"\n * data-stimeo--slider-max-value=\"100\"\n * data-stimeo--slider-step-value=\"1\"\n * data-stimeo--slider-value-value=\"40\">\n * <input type=\"hidden\" name=\"volume\" data-stimeo--slider-target=\"field\" />\n * <div data-stimeo--slider-target=\"track\"\n * data-action=\"pointerdown->stimeo--slider#onPointerDown\">\n * <div data-stimeo--slider-target=\"thumb\" role=\"slider\" tabindex=\"0\" aria-label=\"Volume\"\n * aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"40\"\n * data-action=\"keydown->stimeo--slider#onKeydown\"></div>\n * </div>\n * </div>\n *\n * Implements the WAI-ARIA APG **Slider** pattern. The current value is exposed\n * to assistive tech via `aria-valuenow`/`aria-valuemin`/`aria-valuemax` on the\n * thumb, and to the consumer's CSS via the `--stimeo--slider-fraction` custom\n * property (a number in `[0, 1]`) set on the controller element — the library\n * positions nothing itself.\n *\n * `change` dispatches `{ value: number }`; `reconcile` dispatches `{ value: number }`.\n *\n * The Values are inputs. A declared `value` outside `[min, max]` or off the step\n * grid stays in its attribute as the page wrote it; the thumb's ARIA, the\n * fraction and the field publish the normalized value instead, and only a move\n * the user makes writes `value`. `change` reports a move the user made that left\n * the value somewhere other than the value last published. When a Value the page\n * changes at runtime — a Turbo morph or application code — moves the published\n * value, `reconcile` reports it once per batch with the same detail, so a\n * consumer can tell its user's move from the page's. Connecting reports\n * neither. A move handled before a page write is repainted reads the written\n * value, so its `change` covers the write as well, and a move that ends on the\n * value last published reports nothing. An event dispatched from script runs\n * every listener with no microtask between them, so a write made just before\n * it, or by a listener that runs ahead of the slider, is handled that way. An\n * event the browser dispatches runs microtasks between the listeners it calls\n * separately, so a write made by one called ahead of the slider's — a capture\n * listener on an ancestor or on `document`, a `:capture` action, or a listener\n * added to the thumb or the track before the slider's action was bound — is\n * repainted, and reported as `reconcile`, before the move is measured from it.\n * Stimulus calls the actions an element declares for one event and one set of\n * listener options from a single listener, in declaration order, so a write\n * made by an action declared before the slider's own on the thumb or the track\n * is handled like a write within an event dispatched from script.\n *\n * The optional `field` target mirrors the normalized value so the slider can be\n * submitted and read server-side. A value the user moved emits a native\n * bubbling `change` from that field, the way a form control does, so\n * `stimeo--auto-submit` and form-level validation hear it. The mirror is\n * refreshed silently on connect, on a replacement field, and whenever a morph\n * or application code writes a Value.\n *\n * All published state is settled before its reports. A synchronous listener\n * that confirms another value leaves that newer confirmation to report itself;\n * reports still pending for the replaced value are not sent. A read-only listener\n * or a confirmation that moves no published value leaves pending reports intact.\n * An event already being dispatched still reaches its remaining listeners.\n *\n * @remarks\n * Behavior only. The consumer owns all layout (e.g. positioning the thumb from\n * the fraction). Only the horizontal orientation is handled.\n *\n * Behavior provided:\n * - `ArrowRight`/`ArrowUp` increase and `ArrowLeft`/`ArrowDown` decrease by one\n * step; `Home`/`End` jump to the min/max; `PageUp`/`PageDown` move by ten steps.\n * - Pointer press/drag on the track sets the value from the pointer position.\n * - `step` must be finite and positive; invalid runtime input falls back to `1`.\n * Finite endpoints remain allowed even when they do not align to the step grid.\n *\n * The fraction is a value ratio, not a position, so only the consumer knows\n * whether their track mirrors under RTL. Set `logicalTrack` to declare that it\n * does: the pointer mapping and the horizontal arrow pair then follow the\n * writing direction. Left unset, nothing here reads `direction`.\n */\nexport class SliderController extends Controller<HTMLElement> {\n /** Numeric read boundaries share one reader for this controller instance. */\n readonly #numbers = new NumberValueReader();\n\n readonly #moves = new MoveCounter();\n #move = 0;\n\n static override targets = [\"track\", \"thumb\", \"field\"];\n static override values = {\n min: { type: Number, default: 0 },\n max: { type: Number, default: 100 },\n step: { type: Number, default: 1 },\n value: { type: Number, default: 0 },\n logicalTrack: { type: Boolean, default: false },\n };\n\n static valueConstraints = {\n min: NUMBER_BOUNDS.finite,\n max: NUMBER_BOUNDS.finite,\n step: NUMBER_BOUNDS.positive,\n value: NUMBER_BOUNDS.finite,\n } satisfies NumberValueConstraints<typeof SliderController.values>;\n static actions = [\"onKeydown\", \"onPointerDown\"] as const;\n static events = [\"change\", \"reconcile\"] as const;\n\n declare readonly trackTarget: HTMLElement;\n declare readonly thumbTarget: HTMLElement;\n declare readonly fieldTarget: HTMLInputElement;\n declare readonly hasTrackTarget: boolean;\n declare readonly hasThumbTarget: boolean;\n declare readonly hasFieldTarget: boolean;\n declare minValue: number;\n declare maxValue: number;\n declare stepValue: number;\n declare valueValue: number;\n declare logicalTrackValue: boolean;\n\n /** One initiating pointer owns each live drag and its stable target snapshot. */\n #drag: SliderDrag | null = null;\n\n /**\n * The value last published: taken on connect, then moved by each user commit\n * and by each repaint that reports a page-driven move.\n */\n #settled = 0;\n\n /** Collapses a morph that swaps several render Values into one repaint. */\n readonly #repaint = new MorphRenderWatcher(() => this.#render());\n\n /** Whether the consumer declared a mirroring track and the direction mirrors it. */\n get #mirrored(): boolean {\n return this.logicalTrackValue && isRtl(this.element);\n }\n\n /**\n * Renders the normalized value as the starting position without writing it\n * back, and takes it as the baseline, so connecting reports nothing.\n */\n override connect(): void {\n this.#repaint.observe(this.element);\n this.#settled = this.#currentValue();\n this.#render();\n }\n\n /** Cancels any active pointer drag so document listeners never leak. */\n override disconnect(): void {\n this.#repaint.disconnect();\n this.#endDrag();\n }\n\n /** Repaints a minimum changed by application code or a Turbo morph. */\n minValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Repaints a maximum changed by application code or a Turbo morph. */\n maxValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Repaints a step changed by application code or a Turbo morph. */\n stepValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Repaints a value changed by application code or a Turbo morph. */\n valueValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Hydrates a thumb inserted or replaced at runtime with the current ARIA state. */\n thumbTargetConnected(thumb: HTMLElement): void {\n const value = this.#currentValue();\n this.#renderThumb(thumb, value);\n if (this.#drag && this.#drag.thumb === null) {\n this.#drag.thumb = thumb;\n thumb.focus();\n }\n this.#repaint.schedule();\n }\n\n /** Fills a form field inserted or replaced at runtime on the next repaint. */\n fieldTargetConnected(): void {\n this.#repaint.schedule();\n }\n\n /** Brings the field that stays to the current value when an earlier one leaves. */\n fieldTargetDisconnected(): void {\n this.#repaint.schedule();\n }\n\n /**\n * Drops the stale focus owner while allowing a live track gesture to continue,\n * and brings the thumb that stays to the current value.\n */\n thumbTargetDisconnected(thumb: HTMLElement): void {\n if (this.#drag?.thumb === thumb) this.#drag.thumb = null;\n this.#repaint.schedule();\n }\n\n /** Ends a gesture whose geometry target disappeared or ceased being a target. */\n trackTargetDisconnected(track: HTMLElement): void {\n if (this.#drag?.track === track) this.#endDrag();\n }\n\n /** Handles keyboard stepping per the APG slider model. */\n onKeydown(event: KeyboardEvent): void {\n if (isReservedArrowChord(event)) return;\n let next: number | null = null;\n // Stepping snaps the declaration onto the value it publishes before moving.\n const declared = this.#safeValue;\n const range = this.#steppedRange;\n // On a mirrored track the greater value sits at the visual left, so the\n // horizontal pair trades places; the vertical pair passes through.\n switch (this.#mirrored ? logicalArrowKey(event.key, this.element) : event.key) {\n case \"ArrowRight\":\n case \"ArrowUp\":\n next = stepSteppedValue(declared, 1, range);\n break;\n case \"ArrowLeft\":\n case \"ArrowDown\":\n next = stepSteppedValue(declared, -1, range);\n break;\n case \"PageUp\":\n next = stepSteppedValue(declared, 10, range);\n break;\n case \"PageDown\":\n next = stepSteppedValue(declared, -10, range);\n break;\n case \"Home\":\n next = this.#safeMin;\n break;\n case \"End\":\n next = this.#safeMax;\n break;\n default:\n return;\n }\n event.preventDefault();\n this.#commit(next);\n }\n\n /** Begins a pointer drag: sets the value and tracks subsequent movement. */\n onPointerDown(event: PointerEvent): void {\n if (event.button !== 0 || this.#drag || !this.hasTrackTarget || !this.hasThumbTarget) return;\n const track = this.trackTarget;\n const thumb = this.thumbTarget;\n // Resolve the direction once for the whole gesture: reading it per move\n // would query computed style on every frame, and a drag that flipped\n // mid-gesture would be incoherent anyway.\n const mirrored = this.#mirrored;\n const value = this.#valueFromClientX(event.clientX, mirrored, track);\n if (value === null) return;\n event.preventDefault();\n this.#commit(value);\n thumb.focus();\n\n const drag: SliderDrag = { pointer: null, track, thumb };\n drag.pointer = new OwnedPointerSession(event, track, {\n move: (move) => {\n if (!track.isConnected) {\n this.#endDrag();\n return;\n }\n const moved = this.#valueFromClientX(move.clientX, mirrored, track);\n if (moved !== null) this.#commit(moved);\n },\n end: () => {\n if (this.#drag === drag) this.#drag = null;\n },\n });\n this.#drag = drag;\n }\n\n /** Maps a pointer X coordinate to a raw value using a stable track snapshot. */\n #valueFromClientX(clientX: number, mirrored: boolean, track: HTMLElement): number | null {\n const rect = track.getBoundingClientRect();\n if (rect.width === 0) return null;\n const offset = (clientX - rect.left) / rect.width;\n const fraction = mirrored ? 1 - offset : offset;\n return this.#safeMin + fraction * (this.#safeMax - this.#safeMin);\n }\n\n /**\n * Stores the normalized value the user moved to, renders it synchronously for\n * responsive input, and reports it as `change` when it differs from the value\n * last published. The comparison is with the value last published, not with\n * the value the move started from, so a page write no repaint has published\n * yet is reported once, as this change, and a move that ends where the value\n * was last published reports nothing. The baseline moves before either report\n * goes out, so the repaint the Value write schedules — and any move a\n * subscriber makes while the report is dispatched — is measured from this\n * value.\n */\n #commit(raw: number): void {\n const value = snapSteppedValue(raw, this.#steppedRange);\n const reported = this.#settled;\n this.#settled = value;\n if (value !== reported) this.#move = this.#moves.record();\n const move = this.#move;\n if (!Object.is(this.valueValue, value)) this.valueValue = value;\n this.#renderValue(value);\n this.#mirrorField(value, true);\n if (!this.#moves.isLatest(move)) return;\n if (value !== reported) this.dispatch(\"change\", { detail: { value } });\n }\n\n /** Mirrors `value` into the optional form field, reporting only a user's move. */\n #mirrorField(value: number, notify: boolean): void {\n if (!this.hasFieldTarget) return;\n if (writeField(this.fieldTarget, String(value)) && notify) commitField(this.fieldTarget);\n }\n\n /**\n * Reflects the normalized current Value without writing it back. A published\n * value that moved from the last one is reported once as `reconcile`; the\n * field follows without a native `change`.\n *\n * @stimeoRenderRoot\n */\n #render(): void {\n const value = this.#currentValue();\n this.#renderValue(value);\n this.#mirrorField(value, false);\n if (value === this.#settled) return;\n this.#settled = value;\n this.#move = this.#moves.record();\n this.dispatch(\"reconcile\", { detail: { value } });\n }\n\n /** Reflects one normalized value on the current target and CSS output. */\n #renderValue(value: number): void {\n if (this.hasThumbTarget) {\n this.#renderThumb(this.thumbTarget, value);\n }\n this.#renderFraction(value);\n }\n\n /** Writes only ARIA values that differ, including on a replacement target. */\n #renderThumb(thumb: HTMLElement, value: number): void {\n const attributes = {\n \"aria-valuemin\": String(this.#safeMin),\n \"aria-valuemax\": String(this.#safeMax),\n \"aria-valuenow\": String(value),\n };\n for (const [name, next] of Object.entries(attributes)) {\n if (thumb.getAttribute(name) !== next) thumb.setAttribute(name, next);\n }\n }\n\n /** Writes the behavior-only positioning hook only when its value changed. */\n #renderFraction(value: number): void {\n const fraction = rangeFraction(value, this.#safeMin, this.#safeMax);\n const next = String(fraction);\n if (this.element.style.getPropertyValue(FRACTION_PROPERTY) !== next) {\n this.element.style.setProperty(FRACTION_PROPERTY, next);\n }\n }\n\n /** Current normalized value derived from the live declarative inputs. */\n #currentValue(): number {\n return snapSteppedValue(this.#safeValue, this.#steppedRange);\n }\n\n /** Shared range configuration; finite endpoints remain allowed off the grid. */\n get #steppedRange() {\n return { min: this.#safeMin, max: this.#safeMax, step: this.#safeStep };\n }\n\n /** Ends the current pointer session without dispatching another change. */\n #endDrag(): void {\n const drag = this.#drag;\n this.#drag = null;\n drag?.pointer?.end();\n }\n /** Current `min` declaration resolved against its numeric contract. */\n get #safeMin(): number {\n return this.#numbers.read(\n this,\n \"min\",\n this.minValue,\n SliderController.values.min.default,\n SliderController.valueConstraints.min,\n );\n }\n\n /** Current `max` declaration resolved against its numeric contract. */\n get #safeMax(): number {\n return this.#numbers.read(\n this,\n \"max\",\n this.maxValue,\n SliderController.values.max.default,\n SliderController.valueConstraints.max,\n );\n }\n\n /** Current `step` declaration resolved against its numeric contract. */\n get #safeStep(): number {\n return this.#numbers.read(\n this,\n \"step\",\n this.stepValue,\n SliderController.values.step.default,\n SliderController.valueConstraints.step,\n );\n }\n\n /** Current `value` declaration resolved against its numeric contract. */\n get #safeValue(): number {\n return this.#numbers.read(\n this,\n \"value\",\n this.valueValue,\n this.#safeMin,\n SliderController.valueConstraints.value,\n );\n }\n}\n\n/** Stable DOM and gesture state owned for the duration of one pointer drag. */\ninterface SliderDrag {\n pointer: OwnedPointerSession | null;\n readonly track: HTMLElement;\n thumb: HTMLElement | null;\n}\n"]}
@@ -34,7 +34,13 @@ import { Controller } from '@hotwired/stimulus';
34
34
  * should disable the transition, not the behavior). Scroll work is
35
35
  * rAF-throttled; listeners and any pending frame are released on
36
36
  * `disconnect()`, and `connect()` resets the transient hook (a Turbo cache
37
- * snapshot must not restore a hidden header at scroll top).
37
+ * snapshot must not restore a hidden header at scroll top). The scroll source
38
+ * follows a runtime change: a `containerSelector` that names another container,
39
+ * or a morph that reaches the header after replacing the container its selector
40
+ * names, moves the listener to the container resolved now, and the position
41
+ * found there is a baseline rather than a scroll in either direction.
42
+ * `containerSelector` and `offset` changed in one batch are applied in a single
43
+ * pass after it.
38
44
  */
39
45
  declare class SmartStickyHeaderController extends Controller<HTMLElement> {
40
46
  #private;
@@ -52,13 +58,25 @@ declare class SmartStickyHeaderController extends Controller<HTMLElement> {
52
58
  default: number;
53
59
  };
54
60
  };
61
+ static valueConstraints: {
62
+ offset: {
63
+ readonly finite: true;
64
+ };
65
+ tolerance: {
66
+ readonly finite: true;
67
+ readonly min: 0;
68
+ };
69
+ };
55
70
  static events: readonly ["change"];
56
71
  containerSelectorValue: string;
57
72
  offsetValue: number;
58
73
  toleranceValue: number;
59
- /** Validates `containerSelector` once so connect never parses a selector that throws. */
74
+ /**
75
+ * Validates `containerSelector` once, so no resolve parses a selector that
76
+ * throws, then asks for a pass that follows the container it names.
77
+ */
60
78
  containerSelectorValueChanged(): void;
61
- /** Re-decides when application code (or a Turbo morph) changes `offset` at runtime. */
79
+ /** Asks for a pass when application code (or a Turbo morph) changes `offset`. */
62
80
  offsetValueChanged(): void;
63
81
  connect(): void;
64
82
  disconnect(): void;