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/coerce.ts","../../src/utils/field_mirror.ts","../../src/utils/microtask_coalescer.ts","../../src/utils/owned_pointer_session.ts","../../src/controllers/color_picker_controller.ts"],"names":[],"mappings":"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","file":"color_picker_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 * Numeric coercion for controllers that accept a number through a Value, an action\n * param, or an event detail.\n *\n * Stimulus already coerces numeric action params to numbers, but a value can also\n * arrive as a string — via a `*:set` CustomEvent `detail`, or an action param\n * whose attribute does not look numeric. Centralizing the parse keeps `setValue`\n * tolerant of either form while rejecting anything that is not a finite number.\n */\n\n/**\n * Coerces `raw` to a finite number, or returns `null` when it is absent, empty,\n * or not parseable. Empty strings are treated as \"no value\" rather than `0`, so a\n * stray blank param cannot silently reset the value.\n */\nexport function toFiniteNumber(raw: number | string | null | undefined): number | null {\n if (raw === null || raw === undefined || raw === \"\") return null;\n const value = typeof raw === \"number\" ? raw : Number(raw);\n return Number.isFinite(value) ? value : null;\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","import { Controller } from \"@hotwired/stimulus\";\nimport { isReservedArrowChord, logicalArrowKey } from \"../utils/arrow_step\";\nimport { toFiniteNumber } from \"../utils/coerce\";\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\";\n\n/** CSS custom property exposing the current color to consumer CSS. */\nconst COLOR_PROPERTY = \"--stimeo--color\";\n\n/** A slider's `aria-valuetext` template, where `{value}` is the channel value. */\nconst VALUE_TEXT_ATTRIBUTE = \"data-value-text\";\n\n/** A color channel slider, identified by its `data-channel` attribute. */\ntype Channel = \"hue\" | \"saturation\" | \"lightness\" | \"alpha\";\n\n/** Default `[min, max]` per channel when the slider omits aria-valuemin/max. */\nconst CHANNEL_RANGE: Record<Channel, [number, number]> = {\n hue: [0, 360],\n saturation: [0, 100],\n lightness: [0, 100],\n alpha: [0, 100],\n};\n\n/** Internal color model: HSL plus an alpha percentage (0–100). */\ninterface Hsla {\n hue: number;\n saturation: number;\n lightness: number;\n alpha: number;\n}\n\n/**\n * Headless, accessible **Color Picker** behavior.\n *\n * Markup contract (identifier: `stimeo--color-picker`):\n * <div data-controller=\"stimeo--color-picker\"\n * data-stimeo--color-picker-value-value=\"#3366cc\">\n * <div role=\"slider\" aria-label=\"Hue\" data-channel=\"hue\" tabindex=\"0\"\n * aria-valuemin=\"0\" aria-valuemax=\"360\" aria-valuenow=\"210\"\n * data-value-text=\"Hue {value} degrees\"\n * data-stimeo--color-picker-target=\"slider\"\n * data-action=\"keydown->stimeo--color-picker#onKeydown\n * pointerdown->stimeo--color-picker#onPointerDown\"></div>\n * <!-- saturation / lightness / alpha sliders share the same contract -->\n * <input type=\"text\" aria-label=\"Hex color\"\n * data-stimeo--color-picker-target=\"hex\"\n * data-action=\"change->stimeo--color-picker#onHexInput\" />\n * <div data-stimeo--color-picker-target=\"preview\" aria-hidden=\"true\"></div>\n * <input type=\"hidden\" data-stimeo--color-picker-target=\"field\" />\n * </div>\n *\n * Decomposes color selection into independent APG **Slider** channels (hue,\n * saturation, lightness, optional alpha) instead of a 2-D palette, so every\n * adjustment is keyboard- and screen-reader-operable. Each slider exposes\n * `aria-valuenow` and a human-readable `aria-valuetext` (e.g. \"Hue 210 degrees\");\n * the hex input stays two-way synced; the current color is published on the\n * preview and root as the `--stimeo--color` custom property and mirrored into a\n * hidden form field.\n *\n * Text typed into the hex input is the reader's until they commit it (`change`).\n * A repaint the page drives replaces it only when the color it shows moves, so\n * a slider arriving or a Value rewritten without moving the color leaves the\n * typing alone. The reader's own commit, and a hex input that arrives, are\n * written with the color in its canonical form.\n *\n * A color the user committed also emits a native bubbling `change` from every\n * hidden `field`, the way a form control does, so `stimeo--auto-submit` and\n * form-level validation hear it; a repaint driven by the `value` Value, by a\n * replacement field, or by the controller's own repair refreshes the mirrors\n * silently.\n *\n * `change` and `reconcile` dispatch\n * `{ value: string, rgba: { r: number, g: number, b: number, a: number } }`.\n *\n * @remarks\n * Behavior only — the swatch/gradient visuals are the consumer's CSS/canvas, fed\n * by `--stimeo--color`. Only the consumer knows whether a channel track mirrors\n * under RTL: set `logicalTrack` to declare that it does, and the pointer mapping\n * and horizontal arrow pair follow the writing direction. Left unset, nothing\n * here reads `direction`. A gradient has no logical `to` keyword, so mirroring\n * one means swapping `to right`/`to left` under a `:dir(rtl)` selector.\n *\n * A channel slider announces its bounds from its own `aria-valuemin`/`aria-valuemax`,\n * falling back per channel when they are absent or blank; the resolved pair is\n * written back, so assistive tech never hears the `slider` role's 0–100 default\n * over a hue that reaches 360. `aria-valuetext` is filled from the slider's\n * `data-value-text` template — `{value}` is the channel value — which\n * keeps the announced wording i18n-neutral; without a template the text is English.\n *\n * A drag belongs to the pointer that started it: only a primary button opens one,\n * and `OwnedPointerSession` filters movement and termination by that\n * `pointerId`, so a second finger neither steers nor cuts the gesture. Its\n * listeners are released on drag end, when the slider leaves, and on `disconnect()`\n * (Turbo navigation included).\n *\n * The `value` Value is the page's input, and it carries the user's color back: a\n * color the user commits is written into it before anything reports it, so a Turbo\n * cache restore carries the color the user picked. A repaint the page drives —\n * connecting, an `alpha` change, a `value` spelled another way or naming no color —\n * never rewrites it, so a declared translucency comes back once `alpha` is enabled\n * again. An outside write that names another color — application code or a\n * morph — re-seeds the model and reports `reconcile`. The ARIA attributes,\n * `--stimeo--color`, and the mirrored input values are this controller's own output\n * and stay in the DOM as written, which is what makes the restored snapshot show the\n * current color.\n *\n * The internal model is integer HSL(A), so a hex → HSL → hex round-trip is not\n * exactly bijective: a typed hex can normalize to a near (not identical) value\n * once the HSL sliders are touched. This keeps the model small and zero-dep; use a\n * dedicated color library on the consumer side if exact hex preservation matters.\n *\n * While `alpha` is disabled the model stays opaque and an alpha slider authored\n * anyway edits nothing, so the hex and `change`'s `rgba.a` never disagree.\n *\n * A color the user set through a slider or the hex input is reported as\n * `stimeo--color-picker:change`. Changing `alpha` or `value` at runtime can move the\n * committed color without a user edit, and that arrives as\n * `stimeo--color-picker:reconcile` with the same detail. Neither fires on connect.\n */\nexport class ColorPickerController extends Controller<HTMLElement> {\n static override targets = [\"slider\", \"hex\", \"preview\", \"field\"];\n static override values = {\n value: { type: String, default: \"#000000\" },\n alpha: { type: Boolean, default: false },\n logicalTrack: { type: Boolean, default: false },\n };\n static actions = [\"onHexInput\", \"onKeydown\", \"onPointerDown\"] as const;\n static events = [\"change\", \"reconcile\"] as const;\n\n declare readonly sliderTargets: HTMLElement[];\n declare readonly hexTarget: HTMLInputElement;\n declare readonly hasHexTarget: boolean;\n declare readonly previewTargets: HTMLElement[];\n declare readonly fieldTargets: HTMLInputElement[];\n declare valueValue: string;\n declare alphaValue: boolean;\n declare logicalTrackValue: boolean;\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 /** The current color in the editing model; its alpha is 100 while `alpha` is off. */\n #color: Hsla = { hue: 0, saturation: 0, lightness: 0, alpha: 100 };\n /** The pointer that owns the live drag, with the slider whose geometry maps it. */\n #drag: ColorDrag | null = null;\n /** Color the last repaint settled on, so a configuration-driven move is reported once. */\n #committedHex: string | null = null;\n\n /**\n * Whether the paint about to run was asked for by this picker's own controls.\n * The `value` Value is shared with the page — application code and a Turbo\n * morph write it too — so the form fields and the hex input take their \"did\n * the user commit this\" answer from the route, not from the Value.\n */\n #movedByUser = false;\n\n /**\n * The hex this picker last wrote into its hex input, or `null` before it wrote\n * one. A repaint the page drives compares with it rather than with the input's\n * text, so a color that did not move leaves what the reader is typing alone.\n */\n #writtenHex: string | null = null;\n\n /**\n * Collapses a morph that swaps render inputs into one repaint, and refuses the\n * pass Stimulus delivers before `connect()`.\n */\n readonly #repaint = new MicrotaskCoalescer(() => this.#reconcileColor());\n\n /** Seeds the model from the initial hex value and renders every surface. */\n override connect(): void {\n this.#repaint.activate();\n this.#adoptValue();\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 when application code (or a Turbo morph) changes `alpha` at runtime. */\n alphaValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Adopts a color application code (or a Turbo morph) put in `value` at runtime. */\n valueValueChanged(): void {\n // The write of a color the user committed lands here too, and it already\n // matches the DOM.\n if (this.valueValue === this.#committedHex) return;\n this.#repaint.schedule();\n }\n\n /**\n * Hydrates a channel slider inserted or replaced at runtime through the repaint\n * pass, which renders every slider after the batch and reports a committed\n * color that moved. A slider arriving moves no color, so that pass reports\n * nothing.\n */\n sliderTargetConnected(): void {\n this.#repaint.schedule();\n }\n\n /** Ends a gesture whose geometry target disappeared or ceased being a target. */\n sliderTargetDisconnected(slider: HTMLElement): void {\n if (this.#drag?.slider === slider) this.#endDrag();\n }\n\n /** Fills a hex input inserted or replaced at runtime with the current color. */\n hexTargetConnected(hex: HTMLInputElement): void {\n this.#writeHex(hex, this.#hexString());\n }\n\n /** Fills a form field inserted or replaced at runtime with the current color. */\n fieldTargetConnected(field: HTMLInputElement): void {\n this.#mirrorColor(field, this.#hexString());\n }\n\n /** Publishes the current color on a preview inserted or replaced at runtime. */\n previewTargetConnected(preview: HTMLElement): void {\n this.#publishColor(preview, this.#hexString());\n }\n\n /** Keyboard stepping on the focused channel slider (APG Slider model). */\n onKeydown(event: KeyboardEvent): void {\n if (isReservedArrowChord(event)) return;\n const slider = event.currentTarget as HTMLElement;\n const channel = this.#editableChannel(slider);\n if (!channel) return;\n\n const [min, max] = this.#rangeOf(slider, channel);\n const value = this.#color[channel];\n let next: number | null = null;\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 = value + 1;\n break;\n case \"ArrowLeft\":\n case \"ArrowDown\":\n next = value - 1;\n break;\n case \"PageUp\":\n next = value + 10;\n break;\n case \"PageDown\":\n next = value - 10;\n break;\n case \"Home\":\n next = min;\n break;\n case \"End\":\n next = max;\n break;\n default:\n return;\n }\n event.preventDefault();\n this.#setChannel(channel, next, min, max);\n }\n\n /** Begins a primary-button drag on a channel slider, owned by its own pointer. */\n onPointerDown(event: PointerEvent): void {\n // A secondary button opens the context menu instead, and a live drag keeps its\n // slider: another press must not silently take the gesture over.\n if (event.button !== 0 || this.#drag) return;\n const slider = event.currentTarget as HTMLElement;\n const channel = this.#editableChannel(slider);\n if (!channel) return;\n\n const [min, max] = this.#rangeOf(slider, channel);\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 update = (clientX: number): boolean => {\n const rect = slider.getBoundingClientRect();\n if (rect.width === 0) return false;\n const offset = Math.min(1, Math.max(0, (clientX - rect.left) / rect.width));\n const fraction = mirrored ? 1 - offset : offset;\n this.#setChannel(channel, min + fraction * (max - min), min, max);\n return true;\n };\n // A track with no width maps no coordinate, so the press is left to the page.\n if (!update(event.clientX)) return;\n event.preventDefault();\n slider.focus();\n\n const drag: ColorDrag = { pointer: null, slider };\n drag.pointer = new OwnedPointerSession(event, slider, {\n move: (move) => {\n // A slider detached mid-drag would map against a stale rectangle.\n if (slider.isConnected) update(move.clientX);\n else this.#endDrag();\n },\n end: () => {\n if (this.#drag === drag) this.#drag = null;\n },\n });\n this.#drag = drag;\n }\n\n /** Parses the hex input on confirm and syncs every channel + surface. */\n onHexInput(): void {\n if (!this.hasHexTarget) return;\n const parsed = hexToHsla(this.hexTarget.value);\n if (!parsed) {\n // Reject invalid input by restoring the last valid hex.\n this.#writeHex(this.hexTarget, this.#hexString());\n return;\n }\n this.#color = this.#opaqueUnlessEnabled(parsed);\n this.#commitColor();\n }\n\n /** Replaces the model with the color `value` names, leaving an unparsable one alone. */\n #adoptValue(): void {\n const parsed = hexToHsla(this.valueValue);\n if (parsed) this.#color = this.#opaqueUnlessEnabled(parsed);\n }\n\n /**\n * The model a parsed color implies: alpha only survives while its channel is\n * enabled, because `hexString()` would otherwise emit `#RRGGBB` while `change`\n * reported `rgba.a < 1`.\n */\n #opaqueUnlessEnabled(parsed: Hsla): Hsla {\n return this.alphaValue ? parsed : { ...parsed, alpha: 100 };\n }\n\n /** Clamps and snaps one channel to an integer, then re-renders + emits change. */\n #setChannel(channel: Channel, raw: number, min: number, max: number): void {\n this.#color[channel] = Math.round(Math.min(max, Math.max(min, raw)));\n this.#commitColor();\n }\n\n /**\n * Renders the model and reports a color the user actually moved. A key pressed\n * at a bound, a pointer that lands on the step already showing, and a re-confirmed\n * hex all leave the committed color where it was, so no `change` describes them.\n *\n * The color is written into `value` first — the one path that writes it — so a\n * Turbo snapshot and a morph read the color the user picked, and a listener of\n * the field's native `change` already finds it there.\n */\n #commitColor(): void {\n const previous = this.#committedHex;\n const hex = this.#hexString();\n if (this.valueValue !== hex) this.valueValue = hex;\n this.#movedByUser = true;\n this.#render();\n if (this.#committedHex !== previous) {\n this.dispatch(\"change\", { detail: this.#settledDetail() });\n }\n }\n\n /**\n * Reflects the model onto sliders, the hex input, preview, and form field. The\n * `value` Value is left as it is.\n *\n * The hex input is written for the reader's own commit, which shows the color\n * in its canonical form, and otherwise only when the hex it shows moved: a\n * repaint the page drives that leaves the color where it is keeps text the\n * reader has typed there and not committed.\n *\n * @stimeoRenderRoot\n */\n #render(): void {\n const byUser = this.#movedByUser;\n this.#movedByUser = false;\n for (const slider of this.sliderTargets) this.#renderSlider(slider);\n\n const hex = this.#hexString();\n this.#committedHex = hex;\n if (this.hasHexTarget && (byUser || hex !== this.#writtenHex)) {\n this.#writeHex(this.hexTarget, hex);\n }\n for (const field of this.fieldTargets) {\n if (this.#mirrorColor(field, hex) && byUser) commitField(field);\n }\n for (const preview of this.previewTargets) this.#publishColor(preview, hex);\n this.#publishColor(this.element, hex);\n }\n\n /** Writes one slider's announced range, value, and value text, skipping equal ones. */\n #renderSlider(slider: HTMLElement): void {\n const channel = this.#channelOf(slider);\n if (!channel) return;\n const [min, max] = this.#rangeOf(slider, channel);\n const value = this.#color[channel];\n const attributes = {\n \"aria-valuemin\": String(min),\n \"aria-valuemax\": String(max),\n \"aria-valuenow\": String(value),\n \"aria-valuetext\": this.#valueText(slider, channel, value),\n };\n for (const [name, next] of Object.entries(attributes)) {\n if (slider.getAttribute(name) !== next) slider.setAttribute(name, next);\n }\n }\n\n /** Writes `hex` into a hex input and keeps it as the hex last written there. */\n #writeHex(input: HTMLInputElement, hex: string): void {\n this.#writtenHex = hex;\n this.#mirrorColor(input, hex);\n }\n\n /**\n * Mirrors the color into an input, leaving an already-equal value untouched.\n *\n * @returns Whether the input's value moved.\n */\n #mirrorColor(input: HTMLInputElement, hex: string): boolean {\n return writeField(input, hex);\n }\n\n /** Publishes the color as the consumer's CSS hook, skipping an equal value. */\n #publishColor(element: HTMLElement, hex: string): void {\n if (element.style.getPropertyValue(COLOR_PROPERTY) !== hex) {\n element.style.setProperty(COLOR_PROPERTY, hex);\n }\n }\n\n /**\n * Repaints after a declarative input changed at runtime and reports a color this\n * controller settled on. Disabling alpha drops it from the model and an outside\n * `value` names another color, so the committed color can move without a user\n * edit; `change` stays reserved for the picker's own actions.\n */\n #reconcileColor(): void {\n // Compared against the last rendered color, not against the model: the Value\n // callback that scheduled this pass has already moved the Values, so\n // re-deriving the \"before\" state here would always match the \"after\" one.\n const previous = this.#committedHex;\n // A `value` that equals the rendered color is the user's own commit, and\n // re-seeding from it would round-trip the model through hex and drop the hue\n // and saturation a gray cannot carry. Any other `value` is the page's: the\n // model was seeded from it, or it is new, so adopting it is safe.\n if (previous !== null && this.valueValue !== previous) this.#adoptValue();\n if (!this.alphaValue) this.#color.alpha = 100;\n this.#render();\n if (previous !== null && this.#committedHex !== previous) {\n this.dispatch(\"reconcile\", { detail: this.#settledDetail() });\n }\n }\n\n /** The settled color as event detail, shared by both report paths. */\n #settledDetail(): { value: string; rgba: { r: number; g: number; b: number; a: number } } {\n const rgb = hslToRgb(this.#color.hue, this.#color.saturation, this.#color.lightness);\n return { value: this.#hexString(), rgba: { ...rgb, a: this.#color.alpha / 100 } };\n }\n\n /** The current color as `#RRGGBB`, or `#RRGGBBAA` when alpha is enabled. */\n #hexString(): string {\n const rgb = hslToRgb(this.#color.hue, this.#color.saturation, this.#color.lightness);\n const base = `#${hex2(rgb.r)}${hex2(rgb.g)}${hex2(rgb.b)}`;\n if (!this.alphaValue) return base;\n return `${base}${hex2(Math.round((this.#color.alpha / 100) * 255))}`;\n }\n\n /** Reads a slider's `data-channel`, if it is a known channel. */\n #channelOf(slider: HTMLElement): Channel | null {\n const channel = slider.getAttribute(\"data-channel\");\n // Own keys only: an inherited name such as `toString` would otherwise index the\n // model with a function and be announced as one.\n return channel && Object.hasOwn(CHANNEL_RANGE, channel) ? (channel as Channel) : null;\n }\n\n /**\n * The channel a slider edits, or null when this picker edits none through it. An\n * alpha slider authored while `alpha` is off edits nothing: moving it would leave\n * the model translucent behind an opaque `#RRGGBB`.\n */\n #editableChannel(slider: HTMLElement): Channel | null {\n const channel = this.#channelOf(slider);\n return channel === \"alpha\" && !this.alphaValue ? null : channel;\n }\n\n /** The channel's announced text: the slider's template, or the built-in English. */\n #valueText(slider: HTMLElement, channel: Channel, value: number): string {\n const template = slider.getAttribute(VALUE_TEXT_ATTRIBUTE);\n // A placeholder with no substitution stays as authored, so a typo is visible\n // instead of being read as a blank.\n return template\n ? template.replaceAll(\"{value}\", String(value))\n : defaultValueText(channel, value);\n }\n\n /** Ends the live drag so no further movement of that pointer reaches the model. */\n #endDrag(): void {\n const drag = this.#drag;\n this.#drag = null;\n drag?.pointer?.end();\n }\n\n /**\n * A slider's `[min, max]` from aria-valuemin/max, falling back per channel.\n * An absent or blank attribute means \"not authored\", not zero — coercing it to\n * a number would pin the channel at `0` and make the per-channel default\n * unreachable.\n */\n #rangeOf(slider: HTMLElement, channel: Channel): [number, number] {\n const [defMin, defMax] = CHANNEL_RANGE[channel];\n return [\n toFiniteNumber(slider.getAttribute(\"aria-valuemin\")) ?? defMin,\n toFiniteNumber(slider.getAttribute(\"aria-valuemax\")) ?? defMax,\n ];\n }\n}\n\n/** Stable gesture state owned for the duration of one pointer drag. */\ninterface ColorDrag {\n pointer: OwnedPointerSession | null;\n readonly slider: HTMLElement;\n}\n\n/** Capitalizes a channel name for `aria-valuetext` (e.g. \"Hue\"). */\nfunction defaultValueText(channel: Channel, value: number): string {\n const label = channel.charAt(0).toUpperCase() + channel.slice(1);\n const unit = channel === \"hue\" ? \"degrees\" : \"percent\";\n return `${label} ${value} ${unit}`;\n}\n\n/** Formats a 0–255 byte as a 2-digit lowercase hex pair. */\nfunction hex2(value: number): string {\n return Math.round(Math.min(255, Math.max(0, value)))\n .toString(16)\n .padStart(2, \"0\");\n}\n\n/** Converts HSL (h:0–360, s/l:0–100) to RGB bytes (0–255). */\nfunction hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n const sat = s / 100;\n const light = l / 100;\n const c = (1 - Math.abs(2 * light - 1)) * sat;\n const hp = (((h % 360) + 360) % 360) / 60;\n const x = c * (1 - Math.abs((hp % 2) - 1));\n let r = 0;\n let g = 0;\n let b = 0;\n if (hp >= 0 && hp < 1) [r, g, b] = [c, x, 0];\n else if (hp < 2) [r, g, b] = [x, c, 0];\n else if (hp < 3) [r, g, b] = [0, c, x];\n else if (hp < 4) [r, g, b] = [0, x, c];\n else if (hp < 5) [r, g, b] = [x, 0, c];\n else [r, g, b] = [c, 0, x];\n const m = light - c / 2;\n return {\n r: Math.round((r + m) * 255),\n g: Math.round((g + m) * 255),\n b: Math.round((b + m) * 255),\n };\n}\n\n/** Converts RGB bytes (0–255) to HSL (h:0–360, s/l:0–100). */\nfunction rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: number } {\n const rn = r / 255;\n const gn = g / 255;\n const bn = b / 255;\n const max = Math.max(rn, gn, bn);\n const min = Math.min(rn, gn, bn);\n const delta = max - min;\n const l = (max + min) / 2;\n\n let h = 0;\n if (delta !== 0) {\n if (max === rn) h = ((gn - bn) / delta) % 6;\n else if (max === gn) h = (bn - rn) / delta + 2;\n else h = (rn - gn) / delta + 4;\n h = (h * 60 + 360) % 360;\n }\n const s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));\n return { h: Math.round(h), s: Math.round(s * 100), l: Math.round(l * 100) };\n}\n\n/**\n * Parses `#RGB`, `#RGBA`, `#RRGGBB`, or `#RRGGBBAA` into the HSLA model, or\n * returns null when the string is not a valid hex color.\n */\nfunction hexToHsla(input: string): Hsla | null {\n const hex = input.trim().replace(/^#/, \"\");\n if (!/^(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(hex)) return null;\n\n // Expand shorthand (#RGB / #RGBA) so every channel is a full byte pair.\n const full =\n hex.length <= 4\n ? hex\n .split(\"\")\n .map((char) => char + char)\n .join(\"\")\n : hex;\n\n const r = Number.parseInt(full.slice(0, 2), 16);\n const g = Number.parseInt(full.slice(2, 4), 16);\n const b = Number.parseInt(full.slice(4, 6), 16);\n const a = full.length === 8 ? Number.parseInt(full.slice(6, 8), 16) : 255;\n\n const { h, s, l } = rgbToHsl(r, g, b);\n return { hue: h, saturation: s, lightness: l, alpha: Math.round((a / 255) * 100) };\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/logical_scroll.ts","../../src/utils/arrow_step.ts","../../src/utils/coerce.ts","../../src/utils/event_owner.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/owned_pointer_session.ts","../../src/controllers/color_picker_controller.ts"],"names":[],"mappings":"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","file":"color_picker_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 * 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","/**\n * Resolves which of a controller's elements owns a node.\n *\n * A delegated listener hears events from a whole subtree, so the handler's first\n * job is almost always the same question: which item, handle, or control does\n * this `event.target` belong to? The same question comes up for a\n * `MutationRecord.target`, for `document.activeElement`, and for a\n * `relatedTarget` on the way out of a hover region.\n *\n * The answer is `Node.contains()`, which is **inclusive** — an element contains\n * itself — so testing the candidate for identity as well would be redundant.\n *\n * **The guard is what makes this safe to call with a raw event target.**\n * `event.target` is typed `EventTarget | null`, and `contains()` takes a `Node?`:\n * browsers throw `TypeError` for anything else, and `window` — the everyday\n * `EventTarget` that is not a `Node` — is what an event dispatched at it carries.\n * Narrowing here means a caller never has to cast, and the rule cannot drift\n * between the places that ask the question.\n *\n * Scope stays with the caller. These helpers say *which candidate owns the node*,\n * not *whether the node belongs to this controller at all* — a component with\n * nested instances of itself decides that first (by comparing the closest\n * annotated ancestor) and passes the candidates it owns.\n */\n\n/**\n * Index in `candidates` of the first one that is, or contains, `node`.\n *\n * `-1` when none does, when `node` is absent, and when it is an `EventTarget`\n * that is not a `Node`. Candidates are tested in array order, so a nested pair\n * resolves to whichever the caller listed first.\n */\nexport function ownerIndex<T extends Element>(\n candidates: readonly T[],\n node: EventTarget | null | undefined,\n): number {\n if (!(node instanceof Node)) return -1;\n return candidates.findIndex((candidate) => candidate.contains(node));\n}\n\n/**\n * The first candidate that is, or contains, `node`; `null` when none does.\n *\n * A miss indexes the array at `-1`, which reads as `undefined` and lands on the\n * same `null` the absent cases produce.\n */\nexport function ownerOf<T extends Element>(\n candidates: readonly T[],\n node: EventTarget | null | undefined,\n): T | null {\n return candidates[ownerIndex(candidates, node)] ?? null;\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","/** 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","import { Controller } from \"@hotwired/stimulus\";\nimport { isReservedArrowChord, logicalArrowKey } from \"../utils/arrow_step\";\nimport { toFiniteNumber } from \"../utils/coerce\";\nimport { ownerOf } from \"../utils/event_owner\";\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 { OwnedPointerSession } from \"../utils/owned_pointer_session\";\n\n/** CSS custom property exposing the current color to consumer CSS. */\nconst COLOR_PROPERTY = \"--stimeo--color\";\n\n/** A slider's `aria-valuetext` template, where `{value}` is the channel value. */\nconst VALUE_TEXT_ATTRIBUTE = \"data-value-text\";\n\n/** A color channel slider, identified by its `data-channel` attribute. */\ntype Channel = \"hue\" | \"saturation\" | \"lightness\" | \"alpha\";\n\n/** Default `[min, max]` per channel when the slider omits aria-valuemin/max. */\nconst CHANNEL_RANGE: Record<Channel, [number, number]> = {\n hue: [0, 360],\n saturation: [0, 100],\n lightness: [0, 100],\n alpha: [0, 100],\n};\n\n/** Internal color model: HSL plus an alpha percentage (0–100). */\ninterface Hsla {\n hue: number;\n saturation: number;\n lightness: number;\n alpha: number;\n}\n\n/**\n * Headless, accessible **Color Picker** behavior.\n *\n * Markup contract (identifier: `stimeo--color-picker`):\n * <div data-controller=\"stimeo--color-picker\"\n * data-stimeo--color-picker-value-value=\"#3366cc\">\n * <div role=\"slider\" aria-label=\"Hue\" data-channel=\"hue\" tabindex=\"0\"\n * aria-valuemin=\"0\" aria-valuemax=\"360\" aria-valuenow=\"210\"\n * data-value-text=\"Hue {value} degrees\"\n * data-stimeo--color-picker-target=\"slider\"\n * data-action=\"keydown->stimeo--color-picker#onKeydown\n * pointerdown->stimeo--color-picker#onPointerDown\"></div>\n * <!-- saturation / lightness / alpha sliders share the same contract -->\n * <input type=\"text\" aria-label=\"Hex color\"\n * data-stimeo--color-picker-target=\"hex\"\n * data-action=\"change->stimeo--color-picker#onHexInput\" />\n * <div data-stimeo--color-picker-target=\"preview\" aria-hidden=\"true\"></div>\n * <input type=\"hidden\" data-stimeo--color-picker-target=\"field\" />\n * </div>\n *\n * Decomposes color selection into independent APG **Slider** channels (hue,\n * saturation, lightness, optional alpha) instead of a 2-D palette, so every\n * adjustment is keyboard- and screen-reader-operable. Each slider exposes\n * `aria-valuenow` and a human-readable `aria-valuetext` (e.g. \"Hue 210 degrees\");\n * the hex input stays two-way synced; the current color is published on the\n * preview and root as the `--stimeo--color` custom property and mirrored into a\n * hidden form field.\n *\n * Text typed into the hex input is the reader's until they commit it (`change`).\n * A repaint the page drives replaces it only when the color it shows moves, so\n * a slider arriving or a Value rewritten without moving the color leaves the\n * typing alone. The reader's own commit, and a hex input that arrives, are\n * written with the color in its canonical form.\n *\n * A color the user committed also emits a native bubbling `change` from every\n * hidden `field`, the way a form control does, so `stimeo--auto-submit` and\n * form-level validation hear it; a repaint driven by the `value` Value, by a\n * replacement field, or by the controller's own repair refreshes the mirrors\n * silently.\n *\n * `change` and `reconcile` dispatch\n * `{ value: string, rgba: { r: number, g: number, b: number, a: number } }`.\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 swatch/gradient visuals are the consumer's CSS/canvas, fed\n * by `--stimeo--color`. Only the consumer knows whether a channel track mirrors\n * under RTL: set `logicalTrack` to declare that it does, and the pointer mapping\n * and horizontal arrow pair follow the writing direction. Left unset, nothing\n * here reads `direction`. A gradient has no logical `to` keyword, so mirroring\n * one means swapping `to right`/`to left` under a `:dir(rtl)` selector.\n *\n * A channel slider announces its bounds from its own `aria-valuemin`/`aria-valuemax`,\n * falling back per channel when they are absent or blank; the resolved pair is\n * written back, so assistive tech never hears the `slider` role's 0–100 default\n * over a hue that reaches 360. `aria-valuetext` is filled from the slider's\n * `data-value-text` template — `{value}` is the channel value — which\n * keeps the announced wording i18n-neutral; without a template the text is English.\n *\n * A drag belongs to the pointer that started it: only a primary button opens one,\n * and `OwnedPointerSession` filters movement and termination by that\n * `pointerId`, so a second finger neither steers nor cuts the gesture. Its\n * listeners are released on drag end, when the slider leaves, and on `disconnect()`\n * (Turbo navigation included).\n *\n * The `value` Value is the page's input, and it carries the user's color back: a\n * color the user commits is written into it before anything reports it, so a Turbo\n * cache restore carries the color the user picked. A repaint the page drives —\n * connecting, an `alpha` change, a `value` spelled another way or naming no color —\n * never rewrites it, so a declared translucency comes back once `alpha` is enabled\n * again. An outside write that names another color — application code or a\n * morph — re-seeds the model and reports `reconcile`. The ARIA attributes,\n * `--stimeo--color`, and the mirrored input values are this controller's own output\n * and stay in the DOM as written, which is what makes the restored snapshot show the\n * current color.\n *\n * Parsed hex bytes are kept exactly until a channel of the integer HSL(A)\n * editing model moves. A boundary key that leaves that model unchanged keeps\n * those bytes, and event RGBA channels describe the bytes published as hex.\n *\n * While `alpha` is disabled the model stays opaque and an alpha slider authored\n * anyway edits nothing, so the hex and `change`'s `rgba.a` never disagree.\n *\n * A color the user set through a slider or the hex input is reported as\n * `stimeo--color-picker:change`. Changing `alpha` or `value` at runtime can move the\n * committed color without a user edit, and that arrives as\n * `stimeo--color-picker:reconcile` with the same detail. Neither fires on connect.\n */\nexport class ColorPickerController extends Controller<HTMLElement> {\n readonly #fieldWrites = new WeakMap<HTMLInputElement, number>();\n\n readonly #moves = new MoveCounter();\n #move = 0;\n #adoptedValue: string | null = null;\n #adoptedAlpha = false;\n /** Exact parsed bytes, kept until an editing channel actually moves. */\n #exactHex: string | null = null;\n\n static override targets = [\"slider\", \"hex\", \"preview\", \"field\"];\n static override values = {\n value: { type: String, default: \"#000000\" },\n alpha: { type: Boolean, default: false },\n logicalTrack: { type: Boolean, default: false },\n };\n static actions = [\"onHexInput\", \"onKeydown\", \"onPointerDown\"] as const;\n static events = [\"change\", \"reconcile\"] as const;\n\n declare readonly sliderTargets: HTMLElement[];\n declare readonly hexTarget: HTMLInputElement;\n declare readonly hexTargets: HTMLInputElement[];\n declare readonly hasHexTarget: boolean;\n declare readonly previewTargets: HTMLElement[];\n declare readonly fieldTargets: HTMLInputElement[];\n declare valueValue: string;\n declare alphaValue: boolean;\n declare logicalTrackValue: boolean;\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 /** The current color in the editing model; its alpha is 100 while `alpha` is off. */\n #color: Hsla = { hue: 0, saturation: 0, lightness: 0, alpha: 100 };\n /** The pointer that owns the live drag, with the slider whose geometry maps it. */\n #drag: ColorDrag | null = null;\n /** Color the last repaint settled on, so a configuration-driven move is reported once. */\n #committedHex: string | null = null;\n\n /**\n * The hex this picker last wrote into its hex input, or `null` before it wrote\n * one. A repaint the page drives compares with it rather than with the input's\n * text, so a color that did not move leaves what the reader is typing alone.\n */\n #writtenHex: string | null = null;\n\n /**\n * The hex input a repaint last wrote as the one in use, or `null` before one was.\n * A repaint writes the hex input it resolves whenever that is another element, so\n * an input that takes over from an earlier one shows the current color.\n */\n #writtenHexInput: HTMLInputElement | null = null;\n\n /**\n * Collapses a morph that swaps render inputs into one repaint, and refuses the\n * pass Stimulus delivers before `connect()`.\n */\n readonly #repaint = new MorphRenderWatcher(() => this.#reconcileColor());\n\n /** Seeds the model from the initial hex value and renders every surface. */\n override connect(): void {\n this.#repaint.observe(this.element);\n this.#adoptValue();\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 when application code (or a Turbo morph) changes `alpha` at runtime. */\n alphaValueChanged(): void {\n this.#repaint.schedule();\n }\n\n /** Adopts a color application code (or a Turbo morph) put in `value` at runtime. */\n valueValueChanged(): void {\n // The write of a color the user committed lands here too, and it already\n // matches the DOM.\n if (this.valueValue === this.#committedHex) return;\n this.#repaint.schedule();\n }\n\n /**\n * Hydrates a channel slider inserted or replaced at runtime through the repaint\n * pass, which renders every slider after the batch and reports a committed\n * color that moved. A slider arriving moves no color, so that pass reports\n * nothing.\n */\n sliderTargetConnected(): void {\n this.#repaint.schedule();\n }\n\n /** Ends a gesture whose geometry target disappeared or ceased being a target. */\n sliderTargetDisconnected(slider: HTMLElement): void {\n if (this.#drag?.slider === slider) this.#endDrag();\n }\n\n /** Fills a hex input inserted or replaced at runtime with the current color. */\n hexTargetConnected(hex: HTMLInputElement): void {\n this.#writeHex(hex, this.#hexString());\n // Only the input a repaint resolves is recorded, so one arriving behind it leaves\n // text typed into the input in use alone.\n if (hex === this.hexTarget) this.#writtenHexInput = hex;\n }\n\n /** Repaints so the hex input that stays when an earlier one leaves shows the current color. */\n hexTargetDisconnected(): void {\n this.#repaint.schedule();\n }\n\n /** Fills a form field inserted or replaced at runtime with the current color. */\n fieldTargetConnected(field: HTMLInputElement): void {\n this.#mirrorColor(field, this.#hexString());\n }\n\n /** Publishes the current color on a preview inserted or replaced at runtime. */\n previewTargetConnected(preview: HTMLElement): void {\n this.#publishColor(preview, this.#hexString());\n }\n\n /** Keyboard stepping on the focused channel slider (APG Slider model). */\n onKeydown(event: KeyboardEvent): void {\n if (isReservedArrowChord(event)) return;\n const slider = event.currentTarget as HTMLElement;\n const channel = this.#editableChannel(slider);\n if (!channel) return;\n\n this.#adoptPendingValue();\n const [min, max] = this.#rangeOf(slider, channel);\n const value = this.#color[channel];\n let next: number | null = null;\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 = value + 1;\n break;\n case \"ArrowLeft\":\n case \"ArrowDown\":\n next = value - 1;\n break;\n case \"PageUp\":\n next = value + 10;\n break;\n case \"PageDown\":\n next = value - 10;\n break;\n case \"Home\":\n next = min;\n break;\n case \"End\":\n next = max;\n break;\n default:\n return;\n }\n event.preventDefault();\n this.#setChannel(channel, next, min, max);\n }\n\n /** Begins a primary-button drag on a channel slider, owned by its own pointer. */\n onPointerDown(event: PointerEvent): void {\n // A secondary button opens the context menu instead, and a live drag keeps its\n // slider: another press must not silently take the gesture over.\n if (event.button !== 0 || this.#drag) return;\n const slider = event.currentTarget as HTMLElement;\n const channel = this.#editableChannel(slider);\n if (!channel) return;\n\n const [min, max] = this.#rangeOf(slider, channel);\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 update = (clientX: number): boolean => {\n const rect = slider.getBoundingClientRect();\n if (rect.width === 0) return false;\n const offset = Math.min(1, Math.max(0, (clientX - rect.left) / rect.width));\n const fraction = mirrored ? 1 - offset : offset;\n this.#setChannel(channel, min + fraction * (max - min), min, max);\n return true;\n };\n // A track with no width maps no coordinate, so the press is left to the page.\n if (!update(event.clientX)) return;\n event.preventDefault();\n slider.focus();\n\n const drag: ColorDrag = { pointer: null, slider };\n drag.pointer = new OwnedPointerSession(event, slider, {\n move: (move) => {\n // A slider detached mid-drag would map against a stale rectangle.\n if (slider.isConnected) update(move.clientX);\n else this.#endDrag();\n },\n end: () => {\n if (this.#drag === drag) this.#drag = null;\n },\n });\n this.#drag = drag;\n }\n\n /**\n * Parses the hex input the confirming event came from and syncs every channel +\n * surface. Called without an event, it reads the hex input in use; an event that\n * no hex input dispatched commits nothing.\n */\n onHexInput(event?: Event): void {\n const input = this.#confirmingHexInput(event);\n if (!input) return;\n const parsed = hexToHsla(input.value);\n if (!parsed) {\n // Reject invalid input by restoring the last valid hex.\n this.#writeHex(input, this.#hexString());\n return;\n }\n this.#color = this.#opaqueUnlessEnabled(parsed.color);\n this.#exactHex = parsed.hex;\n this.#commitColor(input);\n }\n\n /** The hex input a confirming event came from, or the one in use for a call with no event. */\n #confirmingHexInput(event?: Event): HTMLInputElement | null {\n if (event) return ownerOf(this.hexTargets, event.target);\n return this.hasHexTarget ? this.hexTarget : null;\n }\n\n /** Replaces the model with the color `value` names, leaving an unparsable one alone. */\n #adoptValue(): void {\n this.#adoptedValue = this.valueValue;\n this.#adoptedAlpha = this.alphaValue;\n const parsed = hexToHsla(this.valueValue);\n if (parsed) {\n this.#color = this.#opaqueUnlessEnabled(parsed.color);\n this.#exactHex = parsed.hex;\n }\n }\n\n /** Reads a page declaration that has not reached its repaint before an action. */\n #adoptPendingValue(): void {\n if (this.valueValue !== this.#adoptedValue || this.alphaValue !== this.#adoptedAlpha) {\n this.#adoptValue();\n }\n }\n\n /**\n * Keeps the alpha slider at full opacity while its channel is disabled.\n */\n #opaqueUnlessEnabled(parsed: Hsla): Hsla {\n return this.alphaValue ? parsed : { ...parsed, alpha: 100 };\n }\n\n /** Clamps and snaps one channel to an integer, then re-renders + emits change. */\n #setChannel(channel: Channel, raw: number, min: number, max: number): void {\n this.#adoptPendingValue();\n const next = Math.round(Math.min(max, Math.max(min, raw)));\n if (next !== this.#color[channel]) this.#exactHex = null;\n this.#color[channel] = next;\n this.#commitColor();\n }\n\n /**\n * Renders the model and reports a color the user actually moved. A key pressed\n * at a bound, a pointer that lands on the step already showing, and a re-confirmed\n * hex all leave the committed color where it was, so no `change` describes them.\n *\n * The color is written into `value` first — the one path that writes it — so a\n * Turbo snapshot and a morph read the color the user picked, and a listener of\n * the field's native `change` already finds it there.\n *\n * @param source - The hex input the reader committed in, which then shows the\n * color in its canonical form even while it waits behind the one in use.\n */\n #commitColor(source: HTMLInputElement | null = null): void {\n const previous = this.#committedHex;\n const hex = this.#hexString();\n const changed = hex !== previous;\n if (changed) {\n if (this.valueValue !== hex) this.valueValue = hex;\n this.#adoptedValue = hex;\n this.#adoptedAlpha = this.alphaValue;\n this.#move = this.#moves.record();\n }\n const move = this.#move;\n const fields = this.#render(true);\n if (source) this.#writeHex(source, hex);\n const detail = this.#settledDetail();\n for (const [field, write] of fields) {\n if (field.value === hex && this.#fieldWrites.get(field) === write) commitField(field);\n }\n if (!this.#moves.isLatest(move)) return;\n if (changed) this.dispatch(\"change\", { detail });\n }\n\n /**\n * Reflects the model onto sliders, the hex input, preview, and form field. The\n * `value` Value is left as it is.\n *\n * The hex input is written for the reader's own commit, which shows the color\n * in its canonical form, and otherwise only when the hex it shows moved or the\n * input it resolves is another element than the one it last wrote: a repaint the\n * page drives that leaves the color and the input where they are keeps text the\n * reader has typed there and not committed.\n *\n * @stimeoRenderRoot\n */\n #render(byUser = false): [HTMLInputElement, number][] {\n const fields: [HTMLInputElement, number][] = [];\n for (const slider of this.sliderTargets) this.#renderSlider(slider);\n\n const hex = this.#hexString();\n this.#committedHex = hex;\n if (this.hasHexTarget) {\n const input = this.hexTarget;\n if (byUser || hex !== this.#writtenHex || input !== this.#writtenHexInput) {\n this.#writtenHexInput = input;\n this.#writeHex(input, hex);\n }\n }\n for (const field of this.fieldTargets) {\n if (this.#mirrorColor(field, hex)) fields.push([field, this.#fieldWrites.get(field) ?? 0]);\n }\n for (const preview of this.previewTargets) this.#publishColor(preview, hex);\n this.#publishColor(this.element, hex);\n return fields;\n }\n\n /** Writes one slider's announced range, value, and value text, skipping equal ones. */\n #renderSlider(slider: HTMLElement): void {\n const channel = this.#channelOf(slider);\n if (!channel) return;\n const [min, max] = this.#rangeOf(slider, channel);\n const value = this.#color[channel];\n const attributes = {\n \"aria-valuemin\": String(min),\n \"aria-valuemax\": String(max),\n \"aria-valuenow\": String(value),\n \"aria-valuetext\": this.#valueText(slider, channel, value),\n };\n for (const [name, next] of Object.entries(attributes)) {\n if (slider.getAttribute(name) !== next) slider.setAttribute(name, next);\n }\n }\n\n /** Writes `hex` into a hex input and keeps it as the hex last written there. */\n #writeHex(input: HTMLInputElement, hex: string): void {\n this.#writtenHex = hex;\n this.#mirrorColor(input, hex);\n }\n\n /**\n * Mirrors the color into an input, leaving an already-equal value untouched.\n *\n * @returns Whether the input's value moved.\n */\n #mirrorColor(input: HTMLInputElement, hex: string): boolean {\n if (!writeField(input, hex)) return false;\n this.#fieldWrites.set(input, (this.#fieldWrites.get(input) ?? 0) + 1);\n return true;\n }\n\n /** Publishes the color as the consumer's CSS hook, skipping an equal value. */\n #publishColor(element: HTMLElement, hex: string): void {\n if (element.style.getPropertyValue(COLOR_PROPERTY) !== hex) {\n element.style.setProperty(COLOR_PROPERTY, hex);\n }\n }\n\n /**\n * Repaints after a declarative input changed at runtime and reports a color this\n * controller settled on. Disabling alpha drops it from the model and an outside\n * `value` names another color, so the committed color can move without a user\n * edit; `change` stays reserved for the picker's own actions. A drag on a slider\n * the picker no longer edits ends here.\n */\n #reconcileColor(): void {\n if (this.#drag && !this.#editableChannel(this.#drag.slider)) this.#endDrag();\n // Compared against the last rendered color, not against the model: the Value\n // callback that scheduled this pass has already moved the Values, so\n // re-deriving the \"before\" state here would always match the \"after\" one.\n const previous = this.#committedHex;\n /** A consumed declaration leaves hue and saturation retained in achromatic colors. */\n this.#adoptPendingValue();\n if (!this.alphaValue) this.#color.alpha = 100;\n this.#render();\n if (previous !== null && this.#committedHex !== previous) {\n this.#move = this.#moves.record();\n this.dispatch(\"reconcile\", { detail: this.#settledDetail() });\n }\n }\n\n /** The settled color as event detail, shared by both report paths. */\n #settledDetail(): { value: string; rgba: { r: number; g: number; b: number; a: number } } {\n const value = this.#hexString();\n return {\n value,\n rgba: {\n r: Number.parseInt(value.slice(1, 3), 16),\n g: Number.parseInt(value.slice(3, 5), 16),\n b: Number.parseInt(value.slice(5, 7), 16),\n a: this.alphaValue ? Number.parseInt(value.slice(7, 9), 16) / 255 : 1,\n },\n };\n }\n\n /** The current color as `#RRGGBB`, or `#RRGGBBAA` when alpha is enabled. */\n #hexString(): string {\n if (this.#exactHex !== null) {\n return this.alphaValue ? this.#exactHex : this.#exactHex.slice(0, 7);\n }\n const rgb = hslToRgb(this.#color.hue, this.#color.saturation, this.#color.lightness);\n const base = `#${hex2(rgb.r)}${hex2(rgb.g)}${hex2(rgb.b)}`;\n if (!this.alphaValue) return base;\n return `${base}${hex2(Math.round((this.#color.alpha / 100) * 255))}`;\n }\n\n /** Reads a slider's `data-channel`, if it is a known channel. */\n #channelOf(slider: HTMLElement): Channel | null {\n const channel = slider.getAttribute(\"data-channel\");\n // Own keys only: an inherited name such as `toString` would otherwise index the\n // model with a function and be announced as one.\n return channel && Object.hasOwn(CHANNEL_RANGE, channel) ? (channel as Channel) : null;\n }\n\n /**\n * The channel a slider edits, or null when this picker edits none through it. An\n * alpha slider authored while `alpha` is off edits nothing: moving it would leave\n * the model translucent behind an opaque `#RRGGBB`.\n */\n #editableChannel(slider: HTMLElement): Channel | null {\n const channel = this.#channelOf(slider);\n return channel === \"alpha\" && !this.alphaValue ? null : channel;\n }\n\n /** The channel's announced text: the slider's template, or the built-in English. */\n #valueText(slider: HTMLElement, channel: Channel, value: number): string {\n const template = slider.getAttribute(VALUE_TEXT_ATTRIBUTE);\n // A placeholder with no substitution stays as authored, so a typo is visible\n // instead of being read as a blank.\n return template\n ? template.replaceAll(\"{value}\", String(value))\n : defaultValueText(channel, value);\n }\n\n /** Ends the live drag so no further movement of that pointer reaches the model. */\n #endDrag(): void {\n const drag = this.#drag;\n this.#drag = null;\n drag?.pointer?.end();\n }\n\n /**\n * A slider's `[min, max]` from aria-valuemin/max, falling back per channel.\n * An absent or blank attribute means \"not authored\", not zero — coercing it to\n * a number would pin the channel at `0` and make the per-channel default\n * unreachable.\n */\n #rangeOf(slider: HTMLElement, channel: Channel): [number, number] {\n const [defMin, defMax] = CHANNEL_RANGE[channel];\n return [\n toFiniteNumber(slider.getAttribute(\"aria-valuemin\")) ?? defMin,\n toFiniteNumber(slider.getAttribute(\"aria-valuemax\")) ?? defMax,\n ];\n }\n}\n\n/** Stable gesture state owned for the duration of one pointer drag. */\ninterface ColorDrag {\n pointer: OwnedPointerSession | null;\n readonly slider: HTMLElement;\n}\n\n/** Capitalizes a channel name for `aria-valuetext` (e.g. \"Hue\"). */\nfunction defaultValueText(channel: Channel, value: number): string {\n const label = channel.charAt(0).toUpperCase() + channel.slice(1);\n const unit = channel === \"hue\" ? \"degrees\" : \"percent\";\n return `${label} ${value} ${unit}`;\n}\n\n/** Formats a 0–255 byte as a 2-digit lowercase hex pair. */\nfunction hex2(value: number): string {\n return Math.round(Math.min(255, Math.max(0, value)))\n .toString(16)\n .padStart(2, \"0\");\n}\n\n/** Converts HSL (h:0–360, s/l:0–100) to RGB bytes (0–255). */\nfunction hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n const sat = s / 100;\n const light = l / 100;\n const c = (1 - Math.abs(2 * light - 1)) * sat;\n const hp = (((h % 360) + 360) % 360) / 60;\n const x = c * (1 - Math.abs((hp % 2) - 1));\n let r = 0;\n let g = 0;\n let b = 0;\n if (hp >= 0 && hp < 1) [r, g, b] = [c, x, 0];\n else if (hp < 2) [r, g, b] = [x, c, 0];\n else if (hp < 3) [r, g, b] = [0, c, x];\n else if (hp < 4) [r, g, b] = [0, x, c];\n else if (hp < 5) [r, g, b] = [x, 0, c];\n else [r, g, b] = [c, 0, x];\n const m = light - c / 2;\n return {\n r: Math.round((r + m) * 255),\n g: Math.round((g + m) * 255),\n b: Math.round((b + m) * 255),\n };\n}\n\n/** Converts RGB bytes (0–255) to HSL (h:0–360, s/l:0–100). */\nfunction rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: number } {\n const rn = r / 255;\n const gn = g / 255;\n const bn = b / 255;\n const max = Math.max(rn, gn, bn);\n const min = Math.min(rn, gn, bn);\n const delta = max - min;\n const l = (max + min) / 2;\n\n let h = 0;\n if (delta !== 0) {\n if (max === rn) h = ((gn - bn) / delta) % 6;\n else if (max === gn) h = (bn - rn) / delta + 2;\n else h = (rn - gn) / delta + 4;\n h = (h * 60 + 360) % 360;\n }\n const s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));\n return { h: Math.round(h), s: Math.round(s * 100), l: Math.round(l * 100) };\n}\n\n/**\n * Parses `#RGB`, `#RGBA`, `#RRGGBB`, or `#RRGGBBAA` into the HSLA model, or\n * returns null when the string is not a valid hex color.\n */\nfunction hexToHsla(input: string): { color: Hsla; hex: string } | null {\n const hex = input.trim().replace(/^#/, \"\");\n if (!/^(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(hex)) return null;\n\n // Expand shorthand (#RGB / #RGBA) so every channel is a full byte pair.\n const full =\n hex.length <= 4\n ? hex\n .split(\"\")\n .map((char) => char + char)\n .join(\"\")\n : hex;\n\n const r = Number.parseInt(full.slice(0, 2), 16);\n const g = Number.parseInt(full.slice(2, 4), 16);\n const b = Number.parseInt(full.slice(4, 6), 16);\n const a = full.length === 8 ? Number.parseInt(full.slice(6, 8), 16) : 255;\n\n const { h, s, l } = rgbToHsl(r, g, b);\n return {\n color: { hue: h, saturation: s, lightness: l, alpha: Math.round((a / 255) * 100) },\n hex: `#${full.slice(0, 6).toLowerCase()}${hex2(a)}`,\n };\n}\n"]}
@@ -3,6 +3,9 @@ import { Controller } from '@hotwired/stimulus';
3
3
  /**
4
4
  * Headless, accessible combobox behavior (list autocomplete).
5
5
  *
6
+ * Selection reflects the input and popup before notifying listeners. A synchronous
7
+ * replacement selection suppresses the older confirmation that has not yet been sent.
8
+ *
6
9
  * Markup contract (identifier: `stimeo--combobox`):
7
10
  * <div data-controller="stimeo--combobox">
8
11
  * <input type="text" role="combobox" aria-expanded="false"
@@ -15,7 +18,7 @@ import { Controller } from '@hotwired/stimulus';
15
18
  * <ul id="listbox" role="listbox" data-stimeo--combobox-target="list" hidden>
16
19
  * <li role="option" id="opt-apple" data-value="apple"
17
20
  * data-stimeo--combobox-target="option"
18
- * data-action="click->stimeo--combobox#selectByClick">Apple</li>
21
+ * data-action="click->stimeo--combobox#select">Apple</li>
19
22
  * <!-- more options -->
20
23
  * </ul>
21
24
  * <p data-stimeo--combobox-target="empty" hidden>No fruit matches.</p>
@@ -54,11 +57,13 @@ import { Controller } from '@hotwired/stimulus';
54
57
  declare class ComboboxController extends Controller<HTMLElement> {
55
58
  #private;
56
59
  static targets: string[];
57
- static actions: readonly ["close", "filter", "onKeydown", "open", "selectByClick"];
60
+ static actions: readonly ["close", "filter", "onKeydown", "open", "select"];
58
61
  static events: readonly ["selected"];
59
62
  readonly emptyTargets: HTMLElement[];
60
63
  readonly inputTarget: HTMLInputElement;
64
+ readonly inputTargets: HTMLInputElement[];
61
65
  readonly listTarget: HTMLElement;
66
+ readonly listTargets: HTMLElement[];
62
67
  readonly optionTargets: HTMLElement[];
63
68
  readonly hasInputTarget: boolean;
64
69
  readonly hasListTarget: boolean;
@@ -68,8 +73,21 @@ declare class ComboboxController extends Controller<HTMLElement> {
68
73
  disconnect(): void;
69
74
  /** Tracks an input added initially or after connect. */
70
75
  inputTargetConnected(input: HTMLInputElement): void;
71
- /** Removes composition listeners when the active input is replaced or removed. */
76
+ /**
77
+ * Removes composition listeners, gives an input that no longer resolves as one back its
78
+ * `aria-expanded` and `aria-activedescendant` — after `disconnect()` too, since dropping
79
+ * the identifier leaves the element on the page — and reconciles the input that stays.
80
+ */
72
81
  inputTargetDisconnected(input: HTMLInputElement): void;
82
+ /** Applies the open state to a list that arrives after connect in front of the others. */
83
+ listTargetConnected(): void;
84
+ /**
85
+ * Applies the open state to the list left, then gives a list that no longer resolves as
86
+ * the target its own `hidden` back — after `disconnect()` too, since dropping the
87
+ * identifier leaves the element on the page. The open state is read off the departing
88
+ * list first, while it still carries it.
89
+ */
90
+ listTargetDisconnected(list: HTMLElement): void;
73
91
  /** Settles a connecting region on the side the empty state is on. */
74
92
  emptyTargetConnected(): void;
75
93
  /** Establishes the active-state baseline, then reconciles a runtime addition. */
@@ -97,8 +115,8 @@ declare class ComboboxController extends Controller<HTMLElement> {
97
115
  close(): void;
98
116
  /** Routes keyboard interaction per the APG combobox model. */
99
117
  onKeydown(event: KeyboardEvent): void;
100
- /** Selects the clicked option. Bound via `data-action` (click). */
101
- selectByClick(event: Event): void;
118
+ /** Selects an owned option or descendant; API calls preserve external focus. */
119
+ select(source: Event | HTMLElement): void;
102
120
  }
103
121
 
104
122
  export { ComboboxController };