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/before_cache_reset.ts","../../src/utils/event_owner.ts","../../src/utils/focus_candidate.ts","../../src/utils/layout_observer.ts","../../src/utils/safe_timeout.ts","../../src/utils/tabindex_loan.ts","../../src/controllers/overflow_menu_controller.ts"],"names":[],"mappings":"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","file":"overflow_menu_controller.js","sourcesContent":["/**\n * Runs a controller's \"return to the initial state\" pass just before Turbo\n * caches the page.\n *\n * **`disconnect()` cannot do this job, for two independent reasons.** Turbo\n * queues the clone from this event rather than taking it here, and the body swap\n * that runs the controller's `disconnect()` is queued separately — so which of\n * the two lands first is not something a controller can rely on, and a rewind\n * written in `disconnect()` may reach only the DOM being thrown away. In the\n * other direction, `disconnect()` also fires on an in-page move (Stimulus tears\n * down and reconnects the same element), where rewinding would wipe a\n * legitimately in-progress interaction — a spinner mid-load would vanish. One\n * timing is unreliable, the other is too eager; `turbo:before-cache` is the only\n * point that is exactly \"the page is about to be frozen\".\n *\n * Scope is the subscription only: registering on `activate()`, unregistering on\n * `deactivate()`, and one shared document listener no matter how many instances\n * are live. *What* to return to its initial state — which `data-state`, which\n * `hidden`, which `aria-busy` — stays in the controller, because no two\n * consumers answer it the same way.\n *\n * **Rewind state, not appearance.** The pass writes attributes the controller\n * itself owns; the visual result of those attributes is the consumer's CSS, and\n * a library that reached for style or class names would be guessing at markup\n * it does not own.\n *\n * Both entry points are idempotent, so the lifecycle hooks can call them\n * unconditionally: a second `activate()` does not double-subscribe and does not\n * make the callback run twice, and `deactivate()` on an instance that never\n * subscribed is a no-op.\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 #beforeCache = new BeforeCacheReset(() => this.#rewind());\n *\n * connect() { this.#beforeCache.activate(); }\n * disconnect() { this.#beforeCache.deactivate(); }\n * ```\n */\nexport class BeforeCacheReset {\n /** Every subscribed instance, iterated by the one shared document listener. */\n static readonly #subscribers = new Set<BeforeCacheReset>();\n\n /** The shared listener; installed while at least one instance is subscribed. */\n static readonly #onBeforeCache = (): void => {\n for (const subscriber of BeforeCacheReset.#subscribers) subscriber.#rewind();\n };\n\n readonly #rewind: () => void;\n\n /** @param rewind - the pass that returns this controller's state to its initial form. */\n constructor(rewind: () => void) {\n this.#rewind = rewind;\n }\n\n /** Subscribes to `turbo:before-cache`; call from `connect()`. Idempotent. */\n activate(): void {\n const first = BeforeCacheReset.#subscribers.size === 0;\n BeforeCacheReset.#subscribers.add(this);\n if (first) {\n document.addEventListener(\"turbo:before-cache\", BeforeCacheReset.#onBeforeCache);\n }\n }\n\n /** Unsubscribes; call from `disconnect()`. Safe when never subscribed. */\n deactivate(): void {\n BeforeCacheReset.#subscribers.delete(this);\n if (BeforeCacheReset.#subscribers.size > 0) return;\n document.removeEventListener(\"turbo:before-cache\", BeforeCacheReset.#onBeforeCache);\n }\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 * Whether a disabled `<fieldset>` ancestor actually reaches `control`.\n *\n * HTML exempts the contents of a fieldset's **first direct-child `<legend>`**, and\n * the exemption is per fieldset — a control legal in one legend can still be\n * disabled by a second, outer fieldset, so the walk continues upward.\n *\n * Exported on its own for callers that need the disabled-inheritance rule without\n * the rest of {@link canTakeFocus} — a control's availability check, or a `hidden`\n * walk bounded at a widget root, which is a different rule to compose with.\n */\nexport function inheritsFieldsetDisabled(control: HTMLElement): boolean {\n let fieldset: Element | null = control.closest(\"fieldset[disabled]\");\n while (fieldset) {\n const legend = Array.from(fieldset.children).find((child) => child.tagName === \"LEGEND\");\n if (!legend?.contains(control)) return true;\n fieldset = fieldset.parentElement?.closest(\"fieldset[disabled]\") ?? null;\n }\n return false;\n}\n\n/**\n * Whether an element can actually take focus, checked **before** `focus()` runs.\n *\n * A controller that must move focus off a control it is about to disable or hide\n * picks a destination and calls `focus()` on it. If that destination cannot take\n * focus, the call **fails silently**: `hidden` and natively `disabled` elements\n * swallow it, so the caret stays in the subtree that is disappearing and lands on\n * `<body>` a frame later — the exact outcome the rescue exists to prevent, minus\n * any signal that it happened.\n *\n * Testing after the fact is the obvious alternative and is deliberately not the\n * rule. Reading `document.activeElement` back only works in a real browser, and\n * looping over candidates that way performs a real focus move per failure —\n * observable to assistive technology. Checking first costs nothing and catches\n * the cases that actually occur.\n *\n * **`aria-disabled` is not disqualifying.** It is the attribute an author uses\n * for a control that must stay *discoverable*, and the roving contract keeps\n * such items reachable. Only the four conditions that make the platform refuse\n * focus are checked: `hidden` / `inert` (an ancestor's counts),\n * `input[type=\"hidden\"]`, the native `disabled` property, and `disabled`\n * inherited from an ancestor `fieldset`. CSS-only invisibility is handled by\n * {@link isRenderedForFocus} when a consumer needs sequential-focus semantics.\n *\n * Reading `:disabled` instead of walking the fieldset chain would be shorter, but\n * that pseudo-class is not evaluated consistently outside real browsers and this\n * has to be right headlessly too. happy-dom in particular focuses a `<button>`\n * inside a disabled fieldset where a real engine refuses, so the inheritance is\n * spelled out rather than delegated.\n *\n * What a consumer does when nothing survives is its own call: some fall back to\n * their landmark, while a widget whose caret already sits somewhere legitimate\n * refuses the move outright rather than relocating it.\n *\n * @example\n * ```ts\n * const target = candidates.find(canTakeFocus);\n * if (target) target.focus();\n * else {\n * this.#tabindex.lend(this.element); // nothing left: fall back to the landmark\n * this.element.focus();\n * }\n * ```\n *\n * @param element - the candidate destination\n */\nexport function canTakeFocus(element: HTMLElement): boolean {\n if (element.closest(\"[hidden], [inert]\")) return false;\n if (element instanceof HTMLInputElement && element.type === \"hidden\") return false;\n if (!(\"disabled\" in element)) return true;\n if ((element as HTMLElement & { disabled: boolean }).disabled) return false;\n return !inheritsFieldsetDisabled(element);\n}\n\n/** Elements whose semantics or authored attributes can place them in sequential focus order. */\nexport const TAB_STOP_CANDIDATE_SELECTOR = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"input\",\n \"select\",\n \"textarea\",\n \"summary\",\n \"iframe\",\n \"audio[controls]\",\n \"video[controls]\",\n \"[tabindex]\",\n \"[contenteditable]\",\n].join(\",\");\n\n/** Optional browser visibility API used to exclude CSS-hidden candidates. */\ninterface VisibilityCheckable {\n checkVisibility?: (options?: { visibilityProperty?: boolean }) => boolean;\n}\n\n/** Whether CSS visibility allows an otherwise eligible element to participate in focus order. */\nexport function isRenderedForFocus(element: HTMLElement): boolean {\n const check = (element as HTMLElement & VisibilityCheckable).checkVisibility;\n return typeof check === \"function\" ? check.call(element, { visibilityProperty: true }) : true;\n}\n\n/** Parses an authored `tabindex`; invalid syntax has no explicit focus-order meaning. */\nfunction authoredTabindex(element: HTMLElement): number | null {\n const value = element.getAttribute(\"tabindex\");\n if (value === null || !/^[+-]?\\d+$/.test(value.trim())) return null;\n return Number(value);\n}\n\n/** Whether the element's native semantics place it in sequential focus order. */\nfunction hasNativeTabStop(element: HTMLElement): boolean {\n if (element instanceof HTMLAnchorElement || element instanceof HTMLAreaElement) {\n return element.hasAttribute(\"href\");\n }\n if (\n element instanceof HTMLButtonElement ||\n element instanceof HTMLSelectElement ||\n element instanceof HTMLTextAreaElement\n ) {\n return true;\n }\n if (element instanceof HTMLInputElement) return element.type !== \"hidden\";\n if (element instanceof HTMLIFrameElement) return true;\n if (element.tagName === \"AUDIO\" || element.tagName === \"VIDEO\") {\n return element.hasAttribute(\"controls\");\n }\n if (element instanceof HTMLElement && element.tagName === \"SUMMARY\") {\n const details = element.parentElement;\n return (\n details instanceof HTMLDetailsElement &&\n Array.from(details.children).find((child) => child.tagName === \"SUMMARY\") === element\n );\n }\n return false;\n}\n\n/** Whether an explicit `contenteditable` value creates an editable tab stop. */\nfunction hasEditableTabStop(element: HTMLElement): boolean {\n const value = element.getAttribute(\"contenteditable\")?.toLowerCase();\n return value === \"\" || value === \"true\" || value === \"plaintext-only\";\n}\n\n/**\n * Whether an element is a usable sequential Tab stop right now.\n *\n * Native semantics, authored `tabindex`, editable hosts, inherited disabled state,\n * HTML `hidden`/`inert`, and CSS visibility are evaluated together. `aria-disabled`\n * remains focusable because it communicates unavailability without removing the\n * control from discovery order.\n */\nexport function isTabStop(element: HTMLElement): boolean {\n if (!canTakeFocus(element) || !isRenderedForFocus(element)) return false;\n\n const tabindex = authoredTabindex(element);\n if (tabindex !== null) return tabindex >= 0;\n return hasNativeTabStop(element) || hasEditableTabStop(element);\n}\n\n/** Returns every usable sequential Tab stop below `root` in document order. */\nexport function tabStopsWithin(root: ParentNode): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(TAB_STOP_CANDIDATE_SELECTOR)).filter(\n isTabStop,\n );\n}\n\n/** Returns the first usable sequential Tab stop below `root`, if one exists. */\nexport function firstTabStop(root: ParentNode): HTMLElement | null {\n for (const candidate of root.querySelectorAll<HTMLElement>(TAB_STOP_CANDIDATE_SELECTOR)) {\n if (isTabStop(candidate)) return candidate;\n }\n return null;\n}\n\n/** Whether `root` contains at least one usable sequential Tab stop. */\nexport function hasTabStop(root: ParentNode): boolean {\n return firstTabStop(root) !== null;\n}\n","/**\n * Unified layout observation for Stimeo controllers.\n *\n * Widgets whose output is measured — an overflow boundary, a masonry column count,\n * an autosized textarea — have three sources that move the layout under them: their\n * *own* box changing — via {@link ResizeObserver} — the *viewport* changing — via the\n * `window` `resize` event — and a descendant *resource settling*, because an image or\n * a frame reports a height of zero until it has loaded. Wiring those three by hand in\n * every controller risks leaked listeners on `disconnect()`. {@link LayoutObserver}\n * owns all three behind one callback and one\n * {@link LayoutObserver.disconnect | disconnect()} that releases everything.\n *\n * Behavior only: the helper reports *that* layout changed; it never reads or\n * writes styles. Consumers decide what to recompute.\n */\n\n/** Invoked whenever an observed element or the viewport changes size. */\nexport type LayoutCallback = () => void;\n\n/** Constructs a {@link ResizeObserver}; injectable so tests stay deterministic. */\nexport type ResizeObserverFactory = (callback: ResizeObserverCallback) => ResizeObserver;\n\n/** Options for {@link LayoutObserver}. */\nexport interface LayoutObserverOptions {\n /**\n * Factory for the {@link ResizeObserver} used by {@link LayoutObserver.observe}.\n * Defaults to the global constructor; override it in tests, or to no-op in\n * environments where `ResizeObserver` is unavailable.\n */\n resizeObserverFactory?: ResizeObserverFactory;\n}\n\n/**\n * Observes element resizes and/or viewport resizes through a single callback,\n * with guaranteed teardown.\n *\n * @example\n * ```ts\n * #layout = new LayoutObserver(() => this.#reposition());\n *\n * connect() {\n * this.#layout.observe(this.panelTarget);\n * this.#layout.observeViewport();\n * this.#layout.observeDescendantLoads(this.panelTarget);\n * }\n *\n * disconnect() {\n * this.#layout.disconnect();\n * }\n * ```\n */\nexport class LayoutObserver {\n readonly #callback: LayoutCallback;\n readonly #resizeObserverFactory: ResizeObserverFactory | null;\n #resizeObserver: ResizeObserver | null = null;\n #observingViewport = false;\n #loadContainer: Element | null = null;\n\n /** Stable bound handler so add/removeEventListener target the same reference. */\n readonly #handleViewportResize = (): void => {\n this.#callback();\n };\n\n /** Stable bound handler for the capture-phase `load`; see {@link observeDescendantLoads}. */\n readonly #handleDescendantLoad = (): void => {\n this.#callback();\n };\n\n constructor(callback: LayoutCallback, options: LayoutObserverOptions = {}) {\n this.#callback = callback;\n this.#resizeObserverFactory =\n options.resizeObserverFactory ??\n (typeof ResizeObserver === \"undefined\" ? null : (cb) => new ResizeObserver(cb));\n }\n\n /**\n * Starts observing an element's size. Repeated calls observe additional\n * elements through the same shared observer. No-ops when no\n * `ResizeObserver` implementation is available.\n */\n observe(element: Element): void {\n if (!this.#resizeObserverFactory) return;\n if (!this.#resizeObserver) {\n this.#resizeObserver = this.#resizeObserverFactory(() => {\n this.#callback();\n });\n }\n this.#resizeObserver.observe(element);\n }\n\n /** Stops observing a single element while leaving any others in place. */\n unobserve(element: Element): void {\n this.#resizeObserver?.unobserve(element);\n }\n\n /** Starts observing viewport resizes. Idempotent: the listener is added once. */\n observeViewport(): void {\n if (this.#observingViewport) return;\n this.#observingViewport = true;\n window.addEventListener(\"resize\", this.#handleViewportResize);\n }\n\n /** Stops observing viewport resizes without affecting element observation. */\n unobserveViewport(): void {\n if (!this.#observingViewport) return;\n this.#observingViewport = false;\n window.removeEventListener(\"resize\", this.#handleViewportResize);\n }\n\n /**\n * Starts reporting a `load` from anywhere inside `container` — an image or a\n * frame settling changes the box it sits in, and it measures as zero high until\n * then. `load` does not bubble, so the subscription is a capture-phase listener\n * on the container itself and nothing the caller spells.\n *\n * **One container at a time.** A further call moves the observation, so a widget\n * whose content element is swapped at runtime releases the element it let go by\n * naming the new one — there is no second place for the release to drift from.\n */\n observeDescendantLoads(container: Element): void {\n this.unobserveDescendantLoads();\n this.#loadContainer = container;\n container.addEventListener(\"load\", this.#handleDescendantLoad, true);\n }\n\n /** Stops reporting descendant loads without affecting element or viewport observation. */\n unobserveDescendantLoads(): void {\n this.#loadContainer?.removeEventListener(\"load\", this.#handleDescendantLoad, true);\n this.#loadContainer = null;\n }\n\n /**\n * Releases every observation: disconnects the {@link ResizeObserver} and removes\n * the viewport and descendant-load listeners. Safe to call multiple times. Call\n * this from a controller's `disconnect()`.\n */\n disconnect(): void {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n this.unobserveViewport();\n this.unobserveDescendantLoads();\n }\n}\n","/**\n * Self-cleaning timer registries shared by Stimeo controllers.\n *\n * Stimulus controllers frequently schedule `setTimeout` / `setInterval` work\n * (auto-dismiss, debouncing, polling). When the element leaves the DOM — a\n * Turbo Drive navigation, a Turbo Stream replacement, or any `disconnect()` —\n * orphaned timers keep firing against a detached controller, leaking memory and\n * mutating stale state. {@link SafeTimeout} and {@link SafeInterval} track every\n * timer they create so a single {@link TimerRegistry.clearAll | clearAll()} call\n * in `disconnect()` tears them all down.\n *\n * These are intentionally low-level primitives: they own *registration and\n * cleanup only*. Higher-level policy (pause/resume, remaining-time accounting)\n * stays in the individual controllers so per-widget semantics are not flattened\n * into a lowest-common-denominator helper.\n */\n\n/**\n * Largest delay a timer can hold: the platform stores it in a 32-bit signed\n * integer, and anything larger overflows to `1`, so a delay meant to be far in\n * the future fires almost immediately. A declared delay above this bound names\n * no delay at all, and a controller reading one falls back to its default.\n */\nexport const MAX_TIMER_DELAY_MS = 2_147_483_647;\n\n/**\n * Shared registry bookkeeping for the timeout/interval variants.\n *\n * Subclasses provide the scheduling primitive ({@link schedule}) and its matching\n * canceller ({@link cancel}); this base owns the set of live ids plus the\n * per-id and bulk teardown shared by both.\n */\nabstract class TimerRegistry {\n /** Live timer ids that have not yet been cleared (or, for timeouts, fired). */\n protected readonly ids = new Set<number>();\n\n /** Schedules the underlying platform timer and returns its id. */\n protected abstract schedule(callback: () => void, delay: number): number;\n\n /** Cancels the underlying platform timer for `id`. */\n protected abstract cancel(id: number): void;\n\n /**\n * Cancels a single tracked timer.\n *\n * No-ops if the id is unknown (already cleared, fired, or never owned by this\n * registry), so callers can clear defensively without guarding.\n */\n clear(id: number): void {\n if (this.ids.delete(id)) {\n this.cancel(id);\n }\n }\n\n /**\n * Cancels every tracked timer. Call this from a controller's `disconnect()`\n * to guarantee no timer outlives the element.\n */\n clearAll(): void {\n for (const id of this.ids) {\n this.cancel(id);\n }\n this.ids.clear();\n }\n\n /** Number of timers currently tracked (pending). */\n get size(): number {\n return this.ids.size;\n }\n}\n\n/**\n * `setTimeout` wrapper that auto-forgets each timer once it fires and supports\n * bulk teardown on disconnect.\n *\n * @example\n * ```ts\n * #timers = new SafeTimeout();\n *\n * connect() {\n * this.#timers.set(() => this.dismiss(), 5000);\n * }\n *\n * disconnect() {\n * this.#timers.clearAll();\n * }\n * ```\n */\nexport class SafeTimeout extends TimerRegistry {\n /**\n * Schedules `callback` after `delay` ms and returns the timer id.\n *\n * The id is removed from the registry automatically when the timeout fires,\n * so {@link TimerRegistry.size | size} reflects only still-pending timers.\n */\n set(callback: () => void, delay: number): number {\n const id = this.schedule(() => {\n this.ids.delete(id);\n callback();\n }, delay);\n this.ids.add(id);\n return id;\n }\n\n protected schedule(callback: () => void, delay: number): number {\n return window.setTimeout(callback, delay);\n }\n\n protected cancel(id: number): void {\n window.clearTimeout(id);\n }\n}\n\n/**\n * `setInterval` wrapper that tracks every interval for bulk teardown on\n * disconnect. Unlike {@link SafeTimeout}, intervals are retained until they are\n * explicitly cleared because they fire repeatedly.\n *\n * @example\n * ```ts\n * #intervals = new SafeInterval();\n *\n * connect() {\n * this.#intervals.set(() => this.tick(), 1000);\n * }\n *\n * disconnect() {\n * this.#intervals.clearAll();\n * }\n * ```\n */\nexport class SafeInterval extends TimerRegistry {\n /** Schedules a repeating `callback` every `delay` ms and returns the timer id. */\n set(callback: () => void, delay: number): number {\n const id = this.schedule(callback, delay);\n this.ids.add(id);\n return id;\n }\n\n protected schedule(callback: () => void, delay: number): number {\n return window.setInterval(callback, delay);\n }\n\n protected cancel(id: number): void {\n window.clearInterval(id);\n }\n}\n","import { BeforeCacheReset } from \"./before_cache_reset\";\n\n/**\n * Shared bookkeeping for a `tabindex` a controller lends an element temporarily.\n *\n * A controller that must move focus somewhere the author never made focusable\n * (a landmark root, a scroll destination) reaches for the same trick: add a\n * `tabindex` just-in-time and hand it back once it is no longer needed. The\n * borrow is the easy half; the return is what the two conditions below are for.\n *\n * **Returning needs two conditions, not one.** Owning the borrow is not enough:\n * the attribute must also still hold the value this instance wrote. A consumer\n * that changed it afterwards — `tabindex=\"0\"` to make the root its own Tab stop\n * — owns it now, and removing it there silently discards authored markup. The\n * bookkeeping is dropped either way, since the loan is over regardless of who\n * ends up owning the value.\n *\n * **Never borrow over an existing value.** An element that already carries a\n * `tabindex` is the author's to control, so there is nothing to lend and nothing\n * to return.\n *\n * Every live loan also owns a shared `turbo:before-cache` subscription. The loan\n * is returned before Turbo can copy it into a snapshot, so consumers get cache\n * safety without duplicating a lifecycle hook; `returnAll()` removes the\n * subscription again as soon as no loan remains.\n *\n * The registry is keyed by element, so a controller borrowing on a single\n * element (`this.element`) and one borrowing across a changing set of targets\n * use the same API — the single-element case is a set of one. It holds no\n * opinion about *when* to borrow or where focus goes next; that stays in the\n * controller.\n *\n * **The API is deliberately two methods.** This file's own doc block is dropped\n * from `dist`, but every member comment is inlined into **each** consumer entry\n * (`tsup` builds with `splitting: false`), so rationale belongs here, only the\n * contract belongs on the members, and every method no consumer calls is still\n * paid for once per consumer entry.\n *\n * @example\n * ```ts\n * readonly #tabindex = new TabindexLoan();\n *\n * #rescueFocus() {\n * this.#tabindex.lend(this.element);\n * this.element.focus();\n * }\n *\n * disconnect() {\n * this.#tabindex.returnAll();\n * }\n * ```\n */\nexport class TabindexLoan<T extends HTMLElement = HTMLElement> {\n readonly #value: string;\n readonly #lent = new Set<T>();\n /** Returns live loans before Turbo can copy them into its page snapshot. */\n readonly #beforeCache = new BeforeCacheReset(() => this.returnAll());\n\n /**\n * @param value - the `tabindex` to lend. `\"-1\"` (the default) is\n * programmatically focusable but not a Tab stop; `\"0\"` is a real Tab stop,\n * which a scroll region with no focusable content of its own needs.\n */\n constructor(value: string = \"-1\") {\n this.#value = value;\n }\n\n /** Lends `element` the value; no-ops when it already carries a `tabindex`. */\n lend(element: T): void {\n if (element.hasAttribute(\"tabindex\")) return;\n element.setAttribute(\"tabindex\", this.#value);\n this.#lent.add(element);\n // Subscribe only while a real loan exists. Keeping this guarantee here means\n // every consumer is Turbo-safe without another lifecycle hook to remember.\n this.#beforeCache.activate();\n }\n\n /** Takes back every loan whose value is still the one that was lent. */\n returnAll(): void {\n for (const element of this.#lent) {\n if (element.getAttribute(\"tabindex\") === this.#value) element.removeAttribute(\"tabindex\");\n }\n this.#lent.clear();\n this.#beforeCache.deactivate();\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { BeforeCacheReset } from \"../utils/before_cache_reset\";\nimport { ownerOf } from \"../utils/event_owner\";\nimport { canTakeFocus } from \"../utils/focus_candidate\";\nimport { LayoutObserver } from \"../utils/layout_observer\";\nimport { SafeTimeout } from \"../utils/safe_timeout\";\nimport { TabindexLoan } from \"../utils/tabindex_loan\";\nimport type { MenuController } from \"./menu_controller\";\n\n/** Suffix of the marker on an item living in the More menu (survives a DOM snapshot). */\nconst BANKED = \"banked\";\n/**\n * Suffix of the canonical index persisted while anything is banked, so a fresh\n * instance can re-adopt.\n */\nconst INDEX = \"index\";\n/**\n * Suffix of the marker on the inert split point retained only while every managed\n * item is banked.\n */\nconst BOUNDARY = \"boundary\";\n/**\n * Suffixes of the attributes saving an item's authored values while it wears menu\n * semantics (\"\" = attribute was absent).\n */\nconst SAVED_ROLE = \"role\";\nconst SAVED_TABINDEX = \"tabindex\";\nconst SAVED_MENU_TARGET = \"saved-menu\";\n/** Menu's target attribute — set to `item` while banked so Menu drives the item. */\nconst MENU_TARGET = \"data-stimeo--menu-target\";\n/** Everything this controller writes on an item; all removed on the way back to the bar. */\nconst BOOKKEEPING = [BANKED, INDEX, SAVED_ROLE, SAVED_TABINDEX, SAVED_MENU_TARGET] as const;\n/**\n * Suffix of the marker on the More label this controller wrote into the trigger;\n * the marker holds that label as its value. The trigger is this controller's only\n * while it holds that label and nothing else: text the consumer rewrites there, or\n * an element child, an `aria-label` or an `aria-labelledby` they add, makes it\n * theirs.\n */\nconst OWNED_LABEL = \"owns-label\";\n\n/** `ParentNode.moveBefore` (Chromium 133+): relocates a node without removing it first. */\ninterface MovableParent {\n moveBefore?: (node: Node, child: Node | null) => void;\n}\n\n/**\n * Headless **overflow / priority menu**: items that no longer fit their container are\n * moved into a \"More\" dropdown (lowest `data-priority` first) and moved back as space\n * returns, watched with a {@link ResizeObserver} (no dedicated APG pattern — a\n * composition; the menu's a11y is delegated to Menu, so it is not re-implemented).\n *\n * Markup contract (identifier: `stimeo--overflow-menu`):\n * <nav data-controller=\"stimeo--overflow-menu\" aria-label=\"Actions\">\n * <div data-stimeo--overflow-menu-target=\"items\">\n * <button data-priority=\"1\">Save</button>\n * <button>Delete</button>\n * </div>\n * <div data-controller=\"stimeo--menu\" data-stimeo--overflow-menu-target=\"more\" hidden>\n * <button id=\"more-trigger\" data-stimeo--menu-target=\"trigger\"\n * aria-haspopup=\"menu\" aria-expanded=\"false\"\n * data-action=\"click->stimeo--menu#toggle\n * keydown->stimeo--menu#onTriggerKeydown\">More</button>\n * <div role=\"menu\" aria-labelledby=\"more-trigger\"\n * data-stimeo--menu-target=\"menu\" hidden></div>\n * </div>\n * </nav>\n *\n * This controller does not own the root's role. It ships none: a navigation bar is\n * a named `<nav>` whose items stay in the normal Tab order. A consumer may add\n * `role=\"toolbar\"`, but that alone is not an APG Toolbar — the single-tab-stop\n * roving is {@link ToolbarController}'s behavior, not this one's — and a named\n * role still needs `aria-label` / `aria-labelledby`.\n *\n * Two parts of that contract are load-bearing and easy to drop. The banked-items\n * container is a permissive single `role=\"menu\"` element this controller appends to\n * directly; use a `<div>`, since a `<ul>` cannot directly own the moved controls. And the\n * trigger's `data-action` is **required, not decoration**: without it the More button\n * never opens, and `keydown->stimeo--menu#onTriggerKeydown` is what makes it reachable\n * by keyboard at all (`Enter` / `Space` / `ArrowDown`). It is spelled out above rather\n * than referenced, because the keyboard half of this contract lives *only* in the\n * consumer's markup — nothing in this controller's source would reveal its absence.\n * Items need no bindings of their own — Menu delegates their handling from its own\n * element, so a control that only becomes a menu item at runtime is operable the\n * moment it lands.\n *\n * A bare More trigger — no text, no element child, no `aria-label` or\n * `aria-labelledby` — gets `moreLabel` as its text on every pass, before the pass\n * measures it, marked with `data-<identifier>-owns-label` whose value is that\n * label. The trigger stays this controller's only while it holds that label and\n * nothing else — the text still matches the marker, and it has no element child,\n * `aria-label` or `aria-labelledby` — and only then does a `moreLabel` swapped at\n * runtime rewrite it, or an empty one hand it back bare. Any other trigger content\n * is the author's and is never written: a trigger the consumer has rewritten, or\n * added an element child or a name to, is neither rewritten nor emptied, and its\n * marker stays where it is. Once it holds the label alone again, it is this\n * controller's again.\n *\n * On connect (and every debounced resize) it measures the items against the container's\n * content width and, when they overflow, banks the lowest-priority ones into the More\n * menu — giving each `role=\"menuitem\"` / `tabindex=\"-1\"` and the menu's `item` target so\n * Menu drives it — until the rest fit beside the More button. When nothing overflows the\n * More wrapper (button *and* menu) is `hidden`. The controller element carries\n * `data-overflowing` / `data-overflow-count`, and a `change` event fires on connect and\n * on every later transition.\n *\n * `change` dispatches `{ overflowCount, total }`.\n *\n * @remarks\n * **Measuring.** The container's width must not be derived from its content (give the bar\n * an explicit width, `flex: 1`, or plain block layout): the More button is revealed before\n * measuring, so a shrink-to-fit container always reports \"items + gap + More\" and nothing\n * ever overflows. The budget is the container's *content box* (`clientWidth` minus its\n * horizontal padding); the gap between items comes from the items container, the gap\n * reserved for the More button from the bar itself. Item widths are cached (a natural\n * width is location-independent) so a pass reads only the items in the bar — one reflow,\n * not two. The trade-off: an item whose content changes *while banked* (a locale switch, a\n * badge update) keeps its stale width until it is back in the bar, so it may return one\n * pass late; re-measuring it in place would cost a second reflow every pass. An item the\n * author marked `hidden` is out of the budget, out of the drop order, and never banked; it\n * holds its canonical slot and rejoins as soon as the attribute goes away. Toggling\n * `hidden` is an attribute change, not a resize, so call `update` after it.\n *\n * **Moving.** Items are moved (never cloned), and only the nodes that are actually out of\n * place — a pass that changes nothing touches no node, because re-inserting a node removes\n * it first and the browser then drops focus to `<body>`. Where `moveBefore` is supported\n * the move preserves focus and transient element state outright.\n *\n * **Focus.** When the focused item (or a descendant of it) *starts* retreating into a\n * collapsed menu it would be hidden and lose focus, so focus is redirected to the More\n * trigger (falling back to the More wrapper when the markup has no trigger — give it one,\n * or focus is left to the browser). While the menu is expanded the item stays visible, so\n * focus is left alone — unless the focused item is the one returning to the bar, which\n * takes focus out of the wrapper and leaves the expanded menu with nothing that owns it;\n * the menu is then closed and focus stays on the returned item. When the last banked item\n * returns, the wrapper is about to be hidden: the menu is closed and focus is moved out of\n * it to the last item that can actually hold it (`hidden` and disabled ones cannot), or to\n * the root when none can.\n *\n * **Priority.** Lower `data-priority` is kept longer; a value that is absent, empty, or\n * not a number ranks lowest and drops first.\n *\n * **Turbo.** The managed set and the canonical order are rebuilt *from the DOM* every\n * pass, so a fresh `connect()` onto markup that already holds banked items (cache restore,\n * a morph, a clone, server-rendered overflow) re-adopts them instead of orphaning them\n * inside a wrapper it would then hide. Symmetrically, `disconnect()` and\n * `turbo:before-cache` return every item to the bar, collapse the composed menu (so it\n * releases its dismissal-stack membership rather than being snapshotted mid-gesture),\n * take back the More label the trigger still holds alone, and strip the items'\n * bookkeeping attributes, so a cached snapshot is the authored DOM. A trigger the\n * consumer added to after the label was written keeps the label and its marker:\n * taking either off would write to content that belongs to the consumer. The\n * `ResizeObserver` and debounce timer are released on `disconnect()` too.\n *\n * Behavior only — no styling.\n */\nexport class OverflowMenuController extends Controller<HTMLElement> {\n /** One bookkeeping attribute, in the namespace this controller is registered under. */\n #attr(name: string): string {\n return `data-${this.identifier}-${name}`;\n }\n\n static override targets = [\"items\", \"more\"];\n static override values = {\n moreLabel: { type: String, default: \"More\" },\n debounce: { type: Number, default: 100 },\n };\n static actions = [\"update\"] as const;\n static events = [\"change\"] as const;\n\n declare readonly itemsTarget: HTMLElement;\n declare readonly moreTarget: HTMLElement;\n declare readonly hasItemsTarget: boolean;\n declare readonly hasMoreTarget: boolean;\n\n declare moreLabelValue: string;\n declare debounceValue: number;\n\n readonly #layout = new LayoutObserver(() => this.#scheduleUpdate());\n readonly #timers = new SafeTimeout();\n /** The managed items in canonical (authored) order, rebuilt from the DOM each pass. */\n #items: HTMLElement[] = [];\n #index = new WeakMap<HTMLElement, number>();\n /** Cached bar-context width per item; see the class remarks for the staleness caveat. */\n #widths = new WeakMap<HTMLElement, number>();\n /** Last reported overflow count, so `change` fires only on transitions. */\n #lastHidden: number | null = null;\n /** The `tabindex` this instance lends the root for the focus fallback. */\n readonly #tabindex = new TabindexLoan();\n\n /** Hands Turbo a snapshot of the bar with every item back in place. */\n readonly #beforeCache = new BeforeCacheReset(() => this.#restoreAll());\n /**\n * Whether `connect()` has run for this connection. Stimulus delivers Value\n * callbacks ahead of it, and the first pass writes the label anyway.\n */\n #connected = false;\n\n override connect(): void {\n this.#connected = true;\n if (!this.hasItemsTarget || !this.hasMoreTarget) return;\n\n this.#beforeCache.activate();\n this.#layout.observe(this.element);\n this.#layout.observeViewport();\n this.update();\n }\n\n override disconnect(): void {\n this.#connected = false;\n this.#layout.disconnect();\n this.#timers.clearAll();\n this.#beforeCache.deactivate();\n this.#restoreAll();\n this.#lastHidden = null;\n }\n\n /**\n * Follows a More label swapped in place by a morph, on a trigger that still holds\n * the label this controller wrote and nothing else. Render only: nothing is\n * measured and `change` is not dispatched here; the next pass measures the bar.\n */\n moreLabelValueChanged(): void {\n if (!this.#connected || !this.hasItemsTarget || !this.hasMoreTarget) return;\n this.#syncLabel();\n }\n\n /** Re-measures and rebalances items between the bar and the More menu. */\n update(): void {\n if (!this.hasItemsTarget || !this.hasMoreTarget) return;\n // The label is part of the More button's width, so it is in place before the\n // button is measured below.\n this.#syncLabel();\n this.#syncItems();\n\n // Reveal More so its trigger is measurable, then refresh the widths of the items\n // currently in the bar (menu items keep their location-independent last value).\n this.moreTarget.hidden = false;\n // Server-rendered overflow arrives with items already in the menu, which is\n // hidden, so they measure zero and the budget would read as \"everything fits\".\n // Bring the set back to the bar once, unbanked, so the first balance works from\n // real widths taken in the context the items are actually laid out in — a\n // banked item can carry consumer styling of its own.\n if (\n this.#items.some((item) => item.parentElement !== this.itemsTarget && !this.#widths.has(item))\n ) {\n this.#removeBoundary();\n for (const item of this.#items) this.#unbank(item);\n this.#reorder(this.itemsTarget, this.#items);\n }\n for (const item of this.#items) {\n if (item.parentElement === this.itemsTarget) this.#widths.set(item, item.offsetWidth);\n }\n const moreWidth = (this.#trigger() ?? this.moreTarget).offsetWidth;\n const itemGap = this.#gap(this.itemsTarget); // between the items themselves\n const barGap = this.#gap(this.element); // between the items row and the More button\n\n const widthOf = (el: HTMLElement): number => this.#widths.get(el) ?? el.offsetWidth;\n const containerWidth = this.element.clientWidth - this.#paddingX(this.element);\n // An authored `hidden` item occupies no width, but a naive count would still\n // charge a gap for it and could bank a sibling that in fact fits — or raise a\n // More button whose menu has nothing operable in it. It keeps its canonical\n // slot; it just does not take part in the budget or in the drop order.\n const rendered = this.#items.filter((item) => this.#rendered(item));\n const itemsWidth = rendered.reduce((sum, el) => sum + widthOf(el), 0);\n let visibleWidth = itemsWidth + Math.max(0, rendered.length - 1) * itemGap;\n\n const hidden = new Set<HTMLElement>();\n if (visibleWidth > containerWidth) {\n const budget = containerWidth - moreWidth - barGap; // reserve the More button + its gap\n // Drop lowest-retention first: no usable `data-priority` (rank ∞), then highest\n // number; ties broken right-to-left so leading items survive.\n const dropOrder = [...rendered].sort(\n (a, b) => this.#rank(b) - this.#rank(a) || this.#indexOf(b) - this.#indexOf(a),\n );\n for (const item of dropOrder) {\n if (visibleWidth <= budget) break;\n hidden.add(item);\n visibleWidth -= widthOf(item) + itemGap; // dropping an item frees its width and a gap\n }\n }\n\n // Decided before any node moves, so it cannot race the browser's blur.\n const active = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n const focused = active === null ? null : this.#ownerOf(active);\n const retreating =\n focused !== null &&\n hidden.has(focused) &&\n focused.parentElement === this.itemsTarget && // i.e. *starting* to retreat\n !this.#menuExpanded();\n // The mirror image: the item holding focus is on its way *out* of an expanded\n // menu. Focus rides along with the node, but once it sits outside the More\n // wrapper the menu owns nothing that reaches it — the shared dismissal\n // resolver stops claiming for this layer, and the item's own menu bindings\n // fall out of Stimulus scope. Leaving the menu open would strand it with no\n // owner, so it is collapsed after the move (see below).\n const returning =\n focused !== null &&\n !hidden.has(focused) &&\n focused.parentElement !== this.itemsTarget && // i.e. *leaving* the menu\n this.#menuExpanded();\n\n // A fully-banked snapshot retains an inert split point so a fresh controller can\n // tell prepend from append. Once a real item remains in the bar, its saved index is\n // the stronger anchor and the boundary must not participate in DOM reordering.\n if (hidden.size === 0 || hidden.size !== this.#items.length) this.#removeBoundary();\n\n // The menu pass runs first, so retreating items leave the bar before it is reordered\n // (otherwise every trailing item would be shuffled needlessly).\n for (const item of this.#items) {\n if (hidden.has(item)) this.#bank(item);\n else this.#unbank(item);\n }\n this.#reorder(\n this.#menuList(),\n this.#items.filter((item) => hidden.has(item)),\n );\n this.#reorder(\n this.itemsTarget,\n this.#items.filter((item) => !hidden.has(item)),\n );\n\n if (retreating) (this.#trigger() ?? this.moreTarget).focus();\n else if (active !== null && this.#lostFocus(active)) active.focus();\n\n const count = hidden.size;\n // Keep the canonical positions on both sides while overflow exists. If the bar is\n // emptied, also retain an inert split point: a later prepend lands before it and an\n // append after it, preserving intent when a fresh controller adopts the snapshot.\n for (const item of this.#items) {\n if (count > 0) item.setAttribute(this.#attr(INDEX), String(this.#indexOf(item)));\n else item.removeAttribute(this.#attr(INDEX));\n }\n if (count > 0 && count === this.#items.length) this.#ensureBoundary();\n else this.#removeBoundary();\n const inMore =\n document.activeElement instanceof HTMLElement &&\n this.moreTarget.contains(document.activeElement);\n if (count === 0 || returning) {\n // Either the wrapper is about to be hidden — collapse the menu so it cannot\n // reappear expanded without a gesture, and move focus out before it\n // disappears — or the item that held focus just carried it out of the menu.\n // `close()` rather than the dismissal path, so the trigger does not take\n // back focus the user is now holding on the returned item; `inMore` is false\n // in that case, so the rescue below stays out of the way. Items still banked\n // remain reachable by reopening from the trigger.\n this.#closeMenu();\n if (inMore) this.#rescueFocus();\n }\n this.moreTarget.hidden = count === 0;\n if (count > 0) this.element.setAttribute(\"data-overflowing\", \"true\");\n else this.element.removeAttribute(\"data-overflowing\");\n this.element.setAttribute(\"data-overflow-count\", String(count));\n\n if (this.#lastHidden !== count) {\n this.#lastHidden = count;\n this.dispatch(\"change\", { detail: { overflowCount: count, total: this.#items.length } });\n }\n }\n\n /** The flex `column-gap` on `el` in px (0 when none / unsupported). */\n #gap(el: HTMLElement): number {\n const style = this.#styleOf(el);\n return style === null ? 0 : this.#px(style.columnGap || style.gap);\n }\n\n /** Horizontal padding on `el` in px — `clientWidth` counts it, the content box cannot. */\n #paddingX(el: HTMLElement): number {\n const style = this.#styleOf(el);\n return style === null ? 0 : this.#px(style.paddingLeft) + this.#px(style.paddingRight);\n }\n\n #styleOf(el: HTMLElement): CSSStyleDeclaration | null {\n return typeof window.getComputedStyle === \"function\" ? window.getComputedStyle(el) : null;\n }\n\n #px(value: string | undefined): number {\n const parsed = Number.parseFloat(value ?? \"\");\n return Number.isNaN(parsed) ? 0 : parsed;\n }\n\n /**\n * Rebuilds the managed set and the canonical order from the DOM. The bar's children\n * give the order of everything inline (so a leading insert is not silently appended)\n * and {@link #merge} weaves the banked items back among them.\n */\n #syncItems(): void {\n const previous = this.#items;\n const bar: HTMLElement[] = [];\n let boundaryAt: number | undefined;\n for (const el of this.itemsTarget.children) {\n if (el instanceof HTMLTemplateElement && el.hasAttribute(this.#attr(BOUNDARY))) {\n boundaryAt ??= bar.length;\n continue;\n }\n if (el instanceof HTMLElement) bar.push(el);\n }\n\n const banked: HTMLElement[] = [];\n for (const el of this.#menuList().children) {\n if (el instanceof HTMLElement && el.hasAttribute(this.#attr(BANKED))) banked.push(el);\n }\n banked.sort((a, b) => this.#bankedIndex(a) - this.#bankedIndex(b));\n\n const items = this.#merge(bar, banked, boundaryAt);\n\n // An item re-homed elsewhere is no longer ours, but it would keep the menu\n // semantics we gave it — strip them before dropping it from the set.\n for (const el of previous) {\n if (!items.includes(el)) {\n this.#unbank(el);\n el.removeAttribute(this.#attr(INDEX));\n }\n }\n\n this.#items = items;\n this.#index = new WeakMap();\n items.forEach((el, i) => {\n this.#index.set(el, i);\n });\n }\n\n /**\n * Interleaves the banked items back among the bar's children.\n *\n * A saved index is a position in the *canonical* order, so it can only be compared\n * against another canonical position — never used as an offset into the current bar,\n * which is a shorter and differently-indexed list. (Doing so survives an untouched\n * round trip and silently scrambles the order as soon as the consumer inserts into a\n * bar that is already short, and `#bank()` then burns the scrambled index back into\n * the attribute, so widening never heals it.) Each bar child the controller already\n * knows carries its canonical index from the previous pass; a banked item goes in\n * front of the first known child whose index is higher.\n *\n * Children never seen before — inserted by the consumer since the last pass — have no\n * canonical position yet, so they keep their DOM neighbours. The exception is a\n * *trailing* run of them: appending to the bar means appending to the toolbar, so\n * everything banked is emitted before it.\n *\n * With no known child at all (a fresh instance connecting to markup that already\n * holds banked items), a fully-banked snapshot's inert boundary preserves whether an\n * unindexed run was prepended or appended before connect. Markup that holds banked items but no boundary —\n * server-rendered or hand-authored — uses the saved index as the\n * offset, the inverse of the move that banked it.\n */\n #merge(\n bar: readonly HTMLElement[],\n banked: readonly HTMLElement[],\n boundaryAt?: number,\n ): HTMLElement[] {\n const canonical = bar.map((el) => this.#index.get(el) ?? this.#savedIndex(el));\n let lastKnown = -1;\n canonical.forEach((index, i) => {\n if (index !== undefined) lastKnown = i;\n });\n\n if (lastKnown === -1) {\n if (boundaryAt !== undefined) {\n return [...bar.slice(0, boundaryAt), ...banked, ...bar.slice(boundaryAt)];\n }\n const restored = [...bar];\n for (const item of banked) {\n restored.splice(Math.min(this.#bankedIndex(item), restored.length), 0, item);\n }\n return restored;\n }\n\n const items: HTMLElement[] = [];\n let next = 0;\n const drainWhile = (accept: (saved: number) => boolean): void => {\n while (next < banked.length) {\n const item = banked[next];\n if (item === undefined || !accept(this.#bankedIndex(item))) break;\n items.push(item);\n next++;\n }\n };\n\n bar.forEach((el, i) => {\n const index = canonical[i];\n if (index !== undefined) drainWhile((saved) => saved < index);\n else if (i > lastKnown) drainWhile(() => true);\n items.push(el);\n });\n drainWhile(() => true);\n return items;\n }\n\n /** The canonical index a banked item saved, or ∞ (append) when it carries none. */\n #bankedIndex(item: HTMLElement): number {\n return this.#savedIndex(item) ?? Number.POSITIVE_INFINITY;\n }\n\n /** A finite canonical index stored on either side of the overflow split. */\n #savedIndex(item: HTMLElement): number | undefined {\n const raw = item.getAttribute(this.#attr(INDEX));\n if (raw === null) return undefined;\n const value = Number(raw);\n return Number.isFinite(value) ? value : undefined;\n }\n\n /** The inert split point written only when every managed item lives in More. */\n #boundary(): HTMLTemplateElement | null {\n for (const el of this.itemsTarget.children) {\n if (el instanceof HTMLTemplateElement && el.hasAttribute(this.#attr(BOUNDARY))) return el;\n }\n return null;\n }\n\n #ensureBoundary(): void {\n if (this.#boundary() !== null) return;\n const boundary = document.createElement(\"template\");\n boundary.setAttribute(this.#attr(BOUNDARY), \"\");\n this.itemsTarget.appendChild(boundary);\n }\n\n #removeBoundary(): void {\n this.#boundary()?.remove();\n }\n\n /** Debounced re-measure for resize-driven churn. */\n #scheduleUpdate(): void {\n this.#timers.clearAll();\n this.#timers.set(() => this.update(), this.debounceValue);\n }\n\n /** Returns the menu list the items are banked into (falls back to the More wrapper). */\n #menuList(): HTMLElement {\n return (\n this.moreTarget.querySelector<HTMLElement>('[data-stimeo--menu-target=\"menu\"]') ??\n this.moreTarget\n );\n }\n\n #trigger(): HTMLElement | null {\n return this.moreTarget.querySelector<HTMLElement>('[data-stimeo--menu-target=\"trigger\"]');\n }\n\n /**\n * Keeps the More trigger's text on `moreLabel` wherever that text is this\n * controller's to write: a bare trigger, or one still holding the label this\n * controller wrote and nothing else. An empty `moreLabel` hands such a trigger\n * back bare. A pass that finds the label already in place writes nothing, and a\n * trigger that is neither is not written at all.\n *\n * @stimeoRenderRoot\n */\n #syncLabel(): void {\n const trigger = this.#trigger();\n if (trigger === null) return;\n const owned = this.#ownsLabel(trigger);\n if (!owned && !this.#isBareTrigger(trigger)) return;\n const label = this.moreLabelValue;\n if (label === \"\") {\n this.#releaseLabel(trigger);\n return;\n }\n if (owned && trigger.textContent === label) return;\n trigger.textContent = label;\n trigger.setAttribute(this.#attr(OWNED_LABEL), label);\n }\n\n /**\n * Whether the trigger holds the label this controller wrote there and nothing\n * else: the text still matches the marker, and the trigger carries nothing but\n * text. Ownership is read afresh on every call, so a trigger the consumer adds to\n * is theirs for as long as the addition is there.\n */\n #ownsLabel(trigger: HTMLElement): boolean {\n return (\n trigger.getAttribute(this.#attr(OWNED_LABEL)) === trigger.textContent &&\n this.#carriesOnlyText(trigger)\n );\n }\n\n /**\n * Takes the label this controller wrote back out of the trigger, leaving it bare.\n * A trigger that is not this controller's is left exactly as it is, marker\n * included: taking the marker off would itself write to it.\n */\n #releaseLabel(trigger: HTMLElement): void {\n if (!this.#ownsLabel(trigger)) return;\n trigger.textContent = \"\";\n trigger.removeAttribute(this.#attr(OWNED_LABEL));\n }\n\n /**\n * Whether the More trigger is bare, so the label is safe to write: no text, no\n * element child, no `aria-label` and no `aria-labelledby`. A trigger with neither\n * text, nor children, nor a name has nothing to lose and gets the fallback; one\n * that is empty *and* unnamed is the only case the label rescues.\n */\n #isBareTrigger(trigger: HTMLElement): boolean {\n return (trigger.textContent ?? \"\").trim() === \"\" && this.#carriesOnlyText(trigger);\n }\n\n /**\n * Whether the trigger carries nothing but text: no element child, no\n * `aria-label` and no `aria-labelledby`. Assigning `textContent` replaces\n * *every* child node, so a trigger holding an icon would silently lose it — and\n * the loss is permanent, since only the label this controller wrote is ever\n * taken back. A trigger that carries an accessible name is left alone too:\n * visible text written under a different `aria-label` would make the label and\n * the name disagree. Only a trigger that carries nothing but text is ever\n * written or emptied.\n */\n #carriesOnlyText(trigger: HTMLElement): boolean {\n return (\n trigger.firstElementChild === null &&\n !trigger.hasAttribute(\"aria-label\") &&\n !trigger.hasAttribute(\"aria-labelledby\")\n );\n }\n\n /**\n * Whether the More menu is expanded. Menu owns that state and reflects it on the\n * trigger's `aria-expanded`, so read the contract rather than guess from `hidden`\n * (which is absent until Menu connects).\n */\n #menuExpanded(): boolean {\n return this.#trigger()?.getAttribute(\"aria-expanded\") === \"true\";\n }\n\n /**\n * Collapses the More menu before its wrapper is hidden. Menu owns the state (and the\n * Escape-stack membership that goes with it), so ask it; the DOM fallback covers markup\n * that reached an expanded state with no Menu mounted.\n */\n #closeMenu(): void {\n if (!this.#menuExpanded()) return;\n const menu = this.application.getControllerForElementAndIdentifier(\n this.moreTarget,\n \"stimeo--menu\",\n ) as MenuController | null;\n if (menu) {\n menu.close();\n return;\n }\n this.#trigger()?.setAttribute(\"aria-expanded\", \"false\");\n const list = this.#menuList();\n if (list !== this.moreTarget) list.hidden = true;\n }\n\n /** The managed item that is, or contains, `el` — focus rescue works on either. */\n #ownerOf(el: HTMLElement): HTMLElement | null {\n return ownerOf(this.#items, el);\n }\n\n /** Whether the item takes up room in the bar; an authored `hidden` one does not. */\n #rendered(item: HTMLElement): boolean {\n return !item.hasAttribute(\"hidden\");\n }\n\n /**\n * Moves focus out of the More wrapper just before it is hidden, to the last\n * item in canonical order that can hold it. When every item refuses, the root\n * takes focus instead of letting the browser drop it to `<body>`, borrowing a\n * `tabindex=\"-1\"` just-in-time — not a Tab stop, and handed back on restore\n * when this controller was the one that added it.\n */\n #rescueFocus(): void {\n for (let i = this.#items.length - 1; i >= 0; i--) {\n const item = this.#items[i];\n // The shared pre-check, not `#rendered`: that one answers \"does this item\n // take up room in the bar\", which reads only the item's own `hidden`. Focus\n // eligibility has to see an ancestor's too — the same rule `#lostFocus`\n // applies below.\n if (item !== undefined && canTakeFocus(item)) {\n item.focus();\n return;\n }\n }\n this.#tabindex.lend(this.element);\n this.element.focus();\n }\n\n /**\n * Whether `el` held focus, is still in a visible part of this controller, and lost it —\n * what a re-insert does in a real browser. An item that retreated into a collapsed menu\n * is excluded: it sits in a `hidden` subtree and must not be focused back.\n */\n #lostFocus(el: HTMLElement): boolean {\n return (\n el.isConnected &&\n document.activeElement !== el &&\n this.element.contains(el) &&\n el.closest(\"[hidden]\") === null\n );\n }\n\n /** Returns every item to the bar and removes all traces of this controller. */\n #restoreAll(): void {\n if (!this.hasItemsTarget || !this.hasMoreTarget) return;\n this.#syncItems();\n this.#removeBoundary();\n this.#reorder(this.itemsTarget, this.#items);\n for (const item of this.#items) {\n this.#unbank(item);\n item.removeAttribute(this.#attr(INDEX));\n }\n // The wrapper is being hidden for good, so the composed menu must not stay\n // expanded behind it: an unclosed menu keeps its dismissal-stack membership\n // and would be written into a Turbo snapshot mid-gesture. Focus is left\n // exactly where it is — this path runs at teardown, where moving it would be\n // the surprise.\n this.#closeMenu();\n const trigger = this.#trigger();\n if (trigger !== null) this.#releaseLabel(trigger);\n this.moreTarget.hidden = true;\n this.element.removeAttribute(\"data-overflowing\");\n this.element.removeAttribute(\"data-overflow-count\");\n this.#tabindex.returnAll();\n }\n\n /**\n * Makes `parent`'s managed children match `sequence`, moving only what is out of place.\n * Walking backwards lets each item be compared against the element that should follow\n * it, so an unchanged run costs zero DOM mutations — the point of the exercise, since\n * every re-insert blurs the focused node.\n */\n #reorder(parent: HTMLElement, sequence: readonly HTMLElement[]): void {\n let next: HTMLElement | null = null;\n for (let i = sequence.length - 1; i >= 0; i--) {\n const item = sequence[i];\n if (item === undefined) continue;\n if (item.parentElement !== parent || item.nextElementSibling !== next) {\n this.#insert(parent, item, next);\n }\n next = item;\n }\n }\n\n /** Relocates `item`, preferring `moveBefore` (keeps focus and element state). */\n #insert(parent: HTMLElement, item: HTMLElement, before: HTMLElement | null): void {\n const move = (parent as HTMLElement & MovableParent).moveBefore;\n if (typeof move === \"function\") {\n try {\n move.call(parent, item, before);\n return;\n } catch {\n // Not movable in place (e.g. a disconnected node) — fall through.\n }\n }\n parent.insertBefore(item, before);\n }\n\n /**\n * Gives an item menuitem semantics for Menu to drive and records its canonical index,\n * saving every authored value it overwrites (\"\" means the attribute was absent).\n */\n #bank(item: HTMLElement): void {\n if (!item.hasAttribute(this.#attr(BANKED))) {\n item.setAttribute(this.#attr(BANKED), \"true\");\n item.setAttribute(this.#attr(SAVED_ROLE), item.getAttribute(\"role\") ?? \"\");\n item.setAttribute(this.#attr(SAVED_TABINDEX), item.getAttribute(\"tabindex\") ?? \"\");\n item.setAttribute(this.#attr(SAVED_MENU_TARGET), item.getAttribute(MENU_TARGET) ?? \"\");\n item.setAttribute(\"role\", \"menuitem\");\n item.setAttribute(\"tabindex\", \"-1\");\n item.setAttribute(MENU_TARGET, \"item\");\n }\n item.setAttribute(this.#attr(INDEX), String(this.#indexOf(item)));\n }\n\n /** Undoes the banking: restores every authored value and drops the bookkeeping. */\n #unbank(item: HTMLElement): void {\n if (!item.hasAttribute(this.#attr(BANKED))) return;\n this.#restoreAttr(item, \"role\", item.getAttribute(this.#attr(SAVED_ROLE)));\n this.#restoreAttr(item, \"tabindex\", item.getAttribute(this.#attr(SAVED_TABINDEX)));\n this.#restoreAttr(item, MENU_TARGET, item.getAttribute(this.#attr(SAVED_MENU_TARGET)));\n for (const name of BOOKKEEPING) item.removeAttribute(this.#attr(name));\n }\n\n /** Re-applies a saved attribute value, or removes the attribute when it was absent. */\n #restoreAttr(item: HTMLElement, name: string, original: string | null): void {\n if (original === null || original === \"\") item.removeAttribute(name);\n else item.setAttribute(name, original);\n }\n\n #indexOf(item: HTMLElement): number {\n return this.#index.get(item) ?? 0;\n }\n\n /**\n * Retention rank: lower keeps longer. An absent, empty, or non-numeric `data-priority`\n * ranks lowest (drops first) — empty is the common ERB accident\n * (`data-priority=\"<%= maybe_nil %>\"`), and `Number(\"\")` is 0, which would otherwise\n * read as the *highest* retention.\n */\n #rank(item: HTMLElement): number {\n const raw = item.getAttribute(\"data-priority\");\n if (raw === null || raw.trim() === \"\") return Number.POSITIVE_INFINITY;\n const value = Number(raw);\n return Number.isNaN(value) ? Number.POSITIVE_INFINITY : value;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/event_owner.ts","../../src/utils/focus_candidate.ts","../../src/utils/layout_observer.ts","../../src/utils/listener_set.ts","../../src/utils/microtask_coalescer.ts","../../src/utils/morph_render_watcher.ts","../../src/utils/timer_bounds.ts","../../src/utils/number_bounds.ts","../../src/utils/coerce.ts","../../src/utils/number_value.ts","../../src/utils/safe_timeout.ts","../../src/utils/query_open_descendants.ts","../../src/utils/shared_registry.ts","../../src/utils/tabindex_loan.ts","../../src/controllers/overflow_menu_controller.ts"],"names":["above"],"mappings":"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","file":"overflow_menu_controller.js","sourcesContent":["/**\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 * Whether a disabled `<fieldset>` ancestor actually reaches `control`.\n *\n * HTML exempts the contents of a fieldset's **first direct-child `<legend>`**, and\n * the exemption is per fieldset — a control legal in one legend can still be\n * disabled by a second, outer fieldset, so the walk continues upward.\n *\n * Exported on its own for callers that need the disabled-inheritance rule without\n * the rest of {@link canTakeFocus} — a control's availability check, or a `hidden`\n * walk bounded at a widget root, which is a different rule to compose with.\n */\nexport function inheritsFieldsetDisabled(control: HTMLElement): boolean {\n let fieldset: Element | null = control.closest(\"fieldset[disabled]\");\n while (fieldset) {\n const legend = Array.from(fieldset.children).find((child) => child.tagName === \"LEGEND\");\n if (!legend?.contains(control)) return true;\n fieldset = fieldset.parentElement?.closest(\"fieldset[disabled]\") ?? null;\n }\n return false;\n}\n\n/**\n * Whether the engine reports `element` assigned to no slot of the open shadow root its parent\n * hosts: such an element is not in the flat tree, so it and what it holds are rendered nowhere\n * and cannot take focus.\n */\nfunction unslotted(element: Element): boolean {\n return element.assignedSlot === null && element.parentElement?.shadowRoot != null;\n}\n\n/**\n * The parent of `element` in the flat tree: the slot it is assigned to, its parent element,\n * or the host of the shadow root it is a child of; `null` at the top of the document or of a\n * detached tree, and for an element the engine assigns to no slot of the open shadow root its\n * parent hosts, which is outside the flat tree. A closed shadow root does not report its slots,\n * so an element assigned to one climbs to the host.\n */\nexport function flatTreeParent(element: Element): Element | null {\n if (unslotted(element)) return null;\n const parent = element.assignedSlot ?? element.parentNode;\n if (parent instanceof ShadowRoot) return parent.host;\n return parent instanceof Element ? parent : null;\n}\n\n/** Whether `element` is `ancestor` or one of its descendants in the flat tree. */\nexport function flatTreeContains(ancestor: Element, element: Element | null): boolean {\n for (let node = element; node; node = flatTreeParent(node)) {\n if (node === ancestor) return true;\n }\n return false;\n}\n\n/** The nearest of `element` and its flat-tree ancestors that matches `selector`, or `null`. */\nexport function closestInFlatTree(element: Element, selector: string): Element | null {\n for (let node: Element | null = element; node; node = flatTreeParent(node)) {\n if (node.matches(selector)) return node;\n }\n return null;\n}\n\n/**\n * The children of `element` in the flat tree: its open shadow root's children, a slot's\n * assigned elements (its own children when nothing is assigned to it), or its children.\n */\nexport function flatTreeChildren(element: Element): Element[] {\n return ownedScope(element) ?? Array.from(element.children);\n}\n\n/**\n * Whether an element can actually take focus, checked **before** `focus()` runs.\n *\n * A controller that must move focus off a control it is about to disable or hide\n * picks a destination and calls `focus()` on it. If that destination cannot take\n * focus, the call **fails silently**: `hidden` and natively `disabled` elements\n * swallow it, so the caret stays in the subtree that is disappearing and lands on\n * `<body>` a frame later — the exact outcome the rescue exists to prevent, minus\n * any signal that it happened.\n *\n * Testing after the fact is the obvious alternative and is deliberately not the\n * rule. Reading `document.activeElement` back only works in a real browser, and\n * looping over candidates that way performs a real focus move per failure —\n * observable to assistive technology. Checking first costs nothing and catches\n * the cases that actually occur.\n *\n * **`aria-disabled` is not disqualifying.** It is the attribute an author uses\n * for a control that must stay *discoverable*, and the roving contract keeps\n * such items reachable. Only the conditions that make the platform refuse\n * focus are checked: `hidden` / `inert` on the element or a flat-tree ancestor\n * (the host of an open shadow root it sits in, the slot it is assigned to), the\n * element or an ancestor left out of the flat tree (one the engine assigns to no\n * slot of the open shadow root its parent hosts), `input[type=\"hidden\"]`, the\n * native `disabled` property, and `disabled` inherited from an ancestor\n * `fieldset`. CSS-only invisibility is handled by {@link isRenderedForFocus}\n * when a consumer needs sequential-focus semantics.\n *\n * Reading `:disabled` instead of walking the fieldset chain would be shorter, but\n * that pseudo-class is not evaluated consistently outside real browsers and this\n * has to be right headlessly too. happy-dom in particular focuses a `<button>`\n * inside a disabled fieldset where a real engine refuses, so the inheritance is\n * spelled out rather than delegated.\n *\n * What a consumer does when nothing survives is its own call: some fall back to\n * their landmark, while a widget whose caret already sits somewhere legitimate\n * refuses the move outright rather than relocating it.\n *\n * @example\n * ```ts\n * const target = candidates.find(canTakeFocus);\n * if (target) target.focus();\n * else {\n * this.#tabindex.lend(this.element); // nothing left: fall back to the landmark\n * this.element.focus();\n * }\n * ```\n *\n * @param element - the candidate destination\n */\nexport function canTakeFocus(element: HTMLElement): boolean {\n for (let node: Element | null = element; node; node = flatTreeParent(node)) {\n if (unslotted(node) || node.matches(\"[hidden], [inert]\")) return false;\n }\n if (element instanceof HTMLInputElement && element.type === \"hidden\") return false;\n if (!(\"disabled\" in element)) return true;\n if ((element as HTMLElement & { disabled: boolean }).disabled) return false;\n return !inheritsFieldsetDisabled(element);\n}\n\n/** Elements whose semantics or authored attributes can place them in sequential focus order. */\nexport const TAB_STOP_CANDIDATE_SELECTOR = [\n \"a[href]\",\n \"area[href]\",\n \"button\",\n \"input\",\n \"select\",\n \"textarea\",\n \"summary\",\n \"iframe\",\n \"audio[controls]\",\n \"video[controls]\",\n \"[tabindex]\",\n \"[contenteditable]\",\n].join(\",\");\n\n/** Optional browser visibility API used to exclude CSS-hidden candidates. */\ninterface VisibilityCheckable {\n checkVisibility?: (options?: { visibilityProperty?: boolean }) => boolean;\n}\n\n/** Whether CSS visibility allows an otherwise eligible element to participate in focus order. */\nexport function isRenderedForFocus(element: HTMLElement): boolean {\n const check = (element as HTMLElement & VisibilityCheckable).checkVisibility;\n return typeof check === \"function\" ? check.call(element, { visibilityProperty: true }) : true;\n}\n\n/** Parses an authored `tabindex`; invalid syntax has no explicit focus-order meaning. */\nfunction authoredTabindex(element: Element): number | null {\n const value = element.getAttribute(\"tabindex\");\n if (value === null || !/^[+-]?\\d+$/.test(value.trim())) return null;\n return Number(value);\n}\n\n/** Whether the element's native semantics place it in sequential focus order. */\nfunction hasNativeTabStop(element: HTMLElement): boolean {\n if (element instanceof HTMLAnchorElement || element instanceof HTMLAreaElement) {\n return element.hasAttribute(\"href\");\n }\n if (\n element instanceof HTMLButtonElement ||\n element instanceof HTMLSelectElement ||\n element instanceof HTMLTextAreaElement\n ) {\n return true;\n }\n if (element instanceof HTMLInputElement) return element.type !== \"hidden\";\n if (element instanceof HTMLIFrameElement) return true;\n if (element.tagName === \"AUDIO\" || element.tagName === \"VIDEO\") {\n return element.hasAttribute(\"controls\");\n }\n if (element instanceof HTMLElement && element.tagName === \"SUMMARY\") {\n const details = element.parentElement;\n return (\n details instanceof HTMLDetailsElement &&\n Array.from(details.children).find((child) => child.tagName === \"SUMMARY\") === element\n );\n }\n return false;\n}\n\n/** Whether an explicit `contenteditable` value creates an editable tab stop. */\nfunction hasEditableTabStop(element: HTMLElement): boolean {\n const value = element.getAttribute(\"contenteditable\")?.toLowerCase();\n return value === \"\" || value === \"true\" || value === \"plaintext-only\";\n}\n\n/**\n * Whether an element is a usable sequential Tab stop right now.\n *\n * Native semantics, authored `tabindex`, editable hosts, inherited disabled state,\n * HTML `hidden`/`inert`, and CSS visibility are evaluated together. `aria-disabled`\n * remains focusable because it communicates unavailability without removing the\n * control from discovery order.\n */\nexport function isTabStop(element: HTMLElement): boolean {\n if (!canTakeFocus(element) || !isRenderedForFocus(element)) return false;\n\n const tabindex = authoredTabindex(element);\n if (tabindex !== null) return tabindex >= 0;\n return hasNativeTabStop(element) || hasEditableTabStop(element);\n}\n\n/** Returns every usable sequential Tab stop below `root` in document order. */\nexport function tabStopsWithin(root: ParentNode): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(TAB_STOP_CANDIDATE_SELECTOR)).filter(\n isTabStop,\n );\n}\n\n/** Returns the first usable sequential Tab stop below `root`, if one exists. */\nexport function firstTabStop(root: ParentNode): HTMLElement | null {\n for (const candidate of root.querySelectorAll<HTMLElement>(TAB_STOP_CANDIDATE_SELECTOR)) {\n if (isTabStop(candidate)) return candidate;\n }\n return null;\n}\n\n/** Whether `root` contains at least one usable sequential Tab stop. */\nexport function hasTabStop(root: ParentNode): boolean {\n return firstTabStop(root) !== null;\n}\n\n/** An element sequential focus navigation can stop on. */\nexport type TabStopElement = HTMLElement | SVGElement;\n\n/** Whether the element is a radio button. */\nfunction isRadio(element: Element | null): element is HTMLInputElement {\n return element instanceof HTMLInputElement && element.type === \"radio\";\n}\n\n/**\n * Whether two radios form one group: the same non-empty `name`, the same form owner and\n * the same tree. A radio without a name is a group of its own.\n */\nfunction sameRadioGroup(a: HTMLInputElement, b: HTMLInputElement): boolean {\n return (\n a.name !== \"\" && a.name === b.name && a.form === b.form && a.getRootNode() === b.getRootNode()\n );\n}\n\n/**\n * Whether the element is part of editable content: the nearest ancestor that sets a valid\n * `contenteditable` decides. `false` ends the editable region (a non-editable island\n * inside an editor); an invalid value inherits from further up.\n */\nfunction isInEditableContent(element: Element): boolean {\n for (let node = element.parentElement; node; node = node.parentElement) {\n if (node.getAttribute(\"contenteditable\")?.toLowerCase() === \"false\") return false;\n if (hasEditableTabStop(node)) return true;\n }\n return false;\n}\n\n/** The XLink namespace, where an SVG link may carry its `href`. */\nconst XLINK_NAMESPACE = \"http://www.w3.org/1999/xlink\";\n\n/** Whether the element is an SVG link: an SVG `a` with `href` or `xlink:href`. */\nfunction isSvgLink(element: Element): boolean {\n return (\n element instanceof SVGElement &&\n element.localName === \"a\" &&\n (element.hasAttribute(\"href\") || element.hasAttributeNS(XLINK_NAMESPACE, \"href\"))\n );\n}\n\n/**\n * Whether an image-map area has a rendered image: an `img` in the area's tree whose\n * `usemap` names the area's map (by `name`, or by `id` without one) and that is rendered.\n * The area has no box of its own for {@link isRenderedForFocus} to check.\n */\nfunction hasRenderedImage(area: HTMLAreaElement): boolean {\n const map = area.closest(\"map\");\n const key = map?.name || map?.id;\n if (!map || !key) return false;\n const root = map.getRootNode() as Document | ShadowRoot;\n return Array.from(root.querySelectorAll<HTMLElement>(\"img[usemap]\")).some(\n (image) => image.getAttribute(\"usemap\") === `#${key}` && isRenderedForFocus(image),\n );\n}\n\n/** Whether the element can take focus and has no negative `tabindex`. */\nfunction isFocusableInOrder(element: TabStopElement): boolean {\n const tabindex = authoredTabindex(element);\n return (tabindex === null || tabindex >= 0) && canTakeFocus(element as HTMLElement);\n}\n\n/**\n * The engine's verdict for the stops {@link isTabStop} does not judge the way sequential\n * navigation does, or `null` for every other element: an image-map area with an `href` or\n * its own `tabindex` stops while an image that uses its map is rendered; an object stops\n * while it holds a nested document, as an iframe does; an SVG link stops while it is\n * rendered. Each also needs to take focus and not be taken out of the order with a\n * negative `tabindex`.\n */\nfunction extraStop(element: TabStopElement): boolean | null {\n if (element instanceof HTMLAreaElement) {\n const focusable = element.hasAttribute(\"href\") || authoredTabindex(element) !== null;\n return focusable && isFocusableInOrder(element) && hasRenderedImage(element);\n }\n if (element instanceof HTMLObjectElement) {\n return (\n isFocusableInOrder(element) && isRenderedForFocus(element) && element.contentWindow !== null\n );\n }\n if (isSvgLink(element))\n return isFocusableInOrder(element) && isRenderedForFocus(element as HTMLElement);\n return null;\n}\n\n/**\n * Whether sequential navigation stops on the element: a usable Tab stop\n * ({@link isTabStop}), or one of the stops `extraStop` judges, except a link inside\n * editable content without a `tabindex` of its own, which the engine leaves to editing.\n * Other controls inside an editing host, and the host itself, stay stops.\n */\nfunction isSequentialStop(element: TabStopElement): boolean {\n const stop =\n extraStop(element) ??\n (element.matches(TAB_STOP_CANDIDATE_SELECTOR) && isTabStop(element as HTMLElement));\n if (!stop) return false;\n const link =\n element instanceof HTMLAnchorElement ||\n element instanceof HTMLAreaElement ||\n isSvgLink(element);\n return !(link && authoredTabindex(element) === null && isInEditableContent(element));\n}\n\n/**\n * The elements of the focus navigation scope `element` owns: its open shadow root's\n * children, or a slot's assigned elements (its fallback content when nothing is\n * assigned). `null` when it owns no scope. A closed shadow root cannot be read, so its\n * host owns none.\n */\nfunction ownedScope(element: Element): Element[] | null {\n if (element.shadowRoot) return Array.from(element.shadowRoot.children);\n if (element instanceof HTMLSlotElement) {\n const assigned = element.assignedElements();\n return assigned.length > 0 ? assigned : Array.from(element.children);\n }\n return null;\n}\n\n/** One member of a focus navigation scope: its tabindex and the stops it contributes. */\ninterface ScopeEntry {\n readonly tabindex: number;\n readonly stops: TabStopElement[];\n}\n\n/** What a walk of the order records besides the order itself. */\ninterface OrderWalk {\n /** The element a move starts from. */\n readonly from: Element | null;\n /** Every stop, in flat-tree order. */\n readonly tree: TabStopElement[];\n /** How many entries of {@link OrderWalk.tree} come before `from`; `-1` until the walk meets it. */\n fromAt: number;\n}\n\n/**\n * Orders one focus navigation scope the way HTML's sequential navigation does: members\n * with a positive `tabindex` first, ascending, ties in tree order, then the rest in tree\n * order. A member that owns a scope (a shadow host, a slot) is followed by that scope's\n * own order; one taken out of the order with a negative `tabindex` takes its scope with it.\n */\nfunction orderScope(elements: Element[], walk: OrderWalk): TabStopElement[] {\n const entries: ScopeEntry[] = [];\n const visit = (element: Element): void => {\n if (element === walk.from) walk.fromAt = walk.tree.length;\n const tabindex = authoredTabindex(element) ?? 0;\n const stop =\n (element instanceof HTMLElement || element instanceof SVGElement) && isSequentialStop(element)\n ? element\n : null;\n if (stop) walk.tree.push(stop);\n const owned = ownedScope(element);\n if (owned) {\n if (tabindex >= 0) {\n entries.push({ tabindex, stops: [...(stop ? [stop] : []), ...orderScope(owned, walk)] });\n }\n return;\n }\n if (stop) entries.push({ tabindex, stops: [stop] });\n for (const child of Array.from(element.children)) visit(child);\n };\n for (const element of elements) visit(element);\n const positive = entries.filter((entry) => entry.tabindex > 0);\n positive.sort((a, b) => a.tabindex - b.tabindex);\n const rest = entries.filter((entry) => entry.tabindex === 0);\n return [...positive, ...rest].flatMap((entry) => entry.stops);\n}\n\n/**\n * Whether a candidate passes the radio-group rule the engine applies: a checked radio\n * among the stops always does; an unchecked one only as the first radio of a group with\n * no checked stop, and not while focus is on a radio of that group. `tree` is the walk's\n * stops in flat-tree order, so a group is counted within the walked root only.\n */\nfunction passesRadioRule(\n element: TabStopElement,\n tree: TabStopElement[],\n focusedRadio: HTMLInputElement | null,\n): boolean {\n if (!isRadio(element) || element.checked) return true;\n const group = tree.filter(\n (stop): stop is HTMLInputElement =>\n stop === element || (isRadio(stop) && sameRadioGroup(stop, element)),\n );\n if (group.some((radio) => radio.checked)) return false;\n if (group[0] !== element) return false;\n return focusedRadio === null || !sameRadioGroup(focusedRadio, element);\n}\n\n/**\n * The index in `order` a move from the walk's `from` visits first. A start the walk did\n * not meet is outside: the move enters at the first stop, or the last going backward. A\n * start that is a stop moves one place along the order. Any other start (the root, an\n * element with a negative `tabindex`) moves to the nearest stop after it in tree order,\n * or before it going backward, and wraps when there is none.\n */\nfunction startIndex(\n order: TabStopElement[],\n walk: OrderWalk,\n backward: boolean,\n isStop: (element: TabStopElement) => boolean,\n): number {\n if (walk.fromAt < 0) return backward ? order.length - 1 : 0;\n const at = order.indexOf(walk.from as TabStopElement);\n if (at >= 0) return backward ? at - 1 : at + 1;\n const neighbour = backward\n ? walk.tree.slice(0, walk.fromAt).reverse().find(isStop)\n : walk.tree.slice(walk.fromAt).find(isStop);\n if (neighbour) return order.indexOf(neighbour);\n return backward ? order.length - 1 : 0;\n}\n\n/**\n * The stops below `root` in the order a sequential move from `from` visits them: the\n * next stop first (the previous one when `backward`), wrapping at the ends, with `from`\n * itself left out. Without a `from` — or with one outside `root` — the list starts at the\n * first stop, or at the last one when `backward`.\n *\n * The order is HTML's sequential navigation order within `root`: positive `tabindex`\n * first, ascending, then `tabindex=\"0\"` and native stops in tree order. Open shadow roots\n * are walked in flat-tree order, slots expanded, each scope ordered on its own; a closed\n * shadow root is not read. A radio group, counted within `root`, stops once: on its\n * checked radio when that radio can take focus, even with focus elsewhere in the group,\n * and otherwise on its first radio that can, unless focus is already in the group.\n * A link inside editable content without its own `tabindex` is not a stop. Every stop\n * also passes its applicable focusability and rendering checks.\n *\n * @param root - The element whose descendants are ordered; it is not a stop itself.\n * @param from - Where the move starts, usually {@link deepActiveElement}.\n * @param backward - Whether the move goes backward (`Shift+Tab`).\n */\nexport function sequentialTabStops(\n root: Element,\n from: Element | null = null,\n backward = false,\n): TabStopElement[] {\n const walk: OrderWalk = { from, tree: [], fromAt: from === root ? 0 : -1 };\n const order = orderScope(ownedScope(root) ?? Array.from(root.children), walk);\n const focusedRadio = walk.fromAt >= 0 && isRadio(from) ? from : null;\n const isStop = (element: TabStopElement): boolean =>\n passesRadioRule(element, walk.tree, focusedRadio);\n const start = startIndex(order, walk, backward, isStop);\n const visited = backward\n ? [...order.slice(0, start + 1).reverse(), ...order.slice(start + 1).reverse()]\n : [...order.slice(start), ...order.slice(0, start)];\n return visited.filter((element) => element !== from && isStop(element));\n}\n\n/**\n * The element that holds focus in `ownerDocument`, looking through open shadow roots:\n * `document.activeElement` stops at a shadow host. A closed shadow root cannot be read,\n * so focus inside one reads as its host.\n */\nexport function deepActiveElement(ownerDocument: Document): Element | null {\n let active = ownerDocument.activeElement;\n while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;\n return active;\n}\n","/**\n * Unified layout observation for Stimeo controllers.\n *\n * Widgets whose output is measured — an overflow boundary, a masonry column count,\n * an autosized textarea — have three sources that move the layout under them: their\n * *own* box changing — via {@link ResizeObserver} — the *viewport* changing — via the\n * `window` `resize` event — and a descendant *resource settling*, because an image or\n * a frame reports a height of zero until it has loaded. Wiring those three by hand in\n * every controller risks leaked listeners on `disconnect()`. {@link LayoutObserver}\n * owns all three behind one callback and one\n * {@link LayoutObserver.disconnect | disconnect()} that releases everything.\n *\n * Behavior only: the helper reports *that* layout changed; it never reads or\n * writes styles. Consumers decide what to recompute.\n */\n\n/** Invoked whenever an observed element or the viewport changes size. */\nexport type LayoutCallback = () => void;\n\n/** Constructs a {@link ResizeObserver}; injectable so tests stay deterministic. */\nexport type ResizeObserverFactory = (callback: ResizeObserverCallback) => ResizeObserver;\n\n/** Options for {@link LayoutObserver}. */\nexport interface LayoutObserverOptions {\n /**\n * Factory for the {@link ResizeObserver} used by {@link LayoutObserver.observe}.\n * Defaults to the global constructor; override it in tests, or to no-op in\n * environments where `ResizeObserver` is unavailable.\n */\n resizeObserverFactory?: ResizeObserverFactory;\n}\n\n/**\n * Observes element resizes and/or viewport resizes through a single callback,\n * with guaranteed teardown.\n *\n * @example\n * ```ts\n * #layout = new LayoutObserver(() => this.#reposition());\n *\n * connect() {\n * this.#layout.observe(this.panelTarget);\n * this.#layout.observeViewport();\n * this.#layout.observeDescendantLoads(this.panelTarget);\n * }\n *\n * disconnect() {\n * this.#layout.disconnect();\n * }\n * ```\n */\nexport class LayoutObserver {\n readonly #callback: LayoutCallback;\n readonly #resizeObserverFactory: ResizeObserverFactory | null;\n #resizeObserver: ResizeObserver | null = null;\n #observingViewport = false;\n #loadContainer: Element | null = null;\n\n /** Stable bound handler so add/removeEventListener target the same reference. */\n readonly #handleViewportResize = (): void => {\n this.#callback();\n };\n\n /** Stable bound handler for the capture-phase `load`; see {@link observeDescendantLoads}. */\n readonly #handleDescendantLoad = (): void => {\n this.#callback();\n };\n\n constructor(callback: LayoutCallback, options: LayoutObserverOptions = {}) {\n this.#callback = callback;\n this.#resizeObserverFactory =\n options.resizeObserverFactory ??\n (typeof ResizeObserver === \"undefined\" ? null : (cb) => new ResizeObserver(cb));\n }\n\n /**\n * Starts observing an element's size. Repeated calls observe additional\n * elements through the same shared observer. No-ops when no\n * `ResizeObserver` implementation is available.\n */\n observe(element: Element): void {\n if (!this.#resizeObserverFactory) return;\n if (!this.#resizeObserver) {\n this.#resizeObserver = this.#resizeObserverFactory(() => {\n this.#callback();\n });\n }\n this.#resizeObserver.observe(element);\n }\n\n /** Stops observing a single element while leaving any others in place. */\n unobserve(element: Element): void {\n this.#resizeObserver?.unobserve(element);\n }\n\n /** Starts observing viewport resizes. Idempotent: the listener is added once. */\n observeViewport(): void {\n if (this.#observingViewport) return;\n this.#observingViewport = true;\n window.addEventListener(\"resize\", this.#handleViewportResize);\n }\n\n /** Stops observing viewport resizes without affecting element observation. */\n unobserveViewport(): void {\n if (!this.#observingViewport) return;\n this.#observingViewport = false;\n window.removeEventListener(\"resize\", this.#handleViewportResize);\n }\n\n /**\n * Starts reporting a `load` from anywhere inside `container` — an image or a\n * frame settling changes the box it sits in, and it measures as zero high until\n * then. `load` does not bubble, so the subscription is a capture-phase listener\n * on the container itself and nothing the caller spells.\n *\n * **One container at a time.** A further call moves the observation, so a widget\n * whose content element is swapped at runtime releases the element it let go by\n * naming the new one — there is no second place for the release to drift from.\n */\n observeDescendantLoads(container: Element): void {\n this.unobserveDescendantLoads();\n this.#loadContainer = container;\n container.addEventListener(\"load\", this.#handleDescendantLoad, true);\n }\n\n /** Stops reporting descendant loads without affecting element or viewport observation. */\n unobserveDescendantLoads(): void {\n this.#loadContainer?.removeEventListener(\"load\", this.#handleDescendantLoad, true);\n this.#loadContainer = null;\n }\n\n /**\n * Releases every observation: disconnects the {@link ResizeObserver} and removes\n * the viewport and descendant-load listeners. Safe to call multiple times. Call\n * this from a controller's `disconnect()`.\n */\n disconnect(): void {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n this.unobserveViewport();\n this.unobserveDescendantLoads();\n }\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 * Largest delay a timer can hold: the platform stores it in a 32-bit signed\n * integer, and anything larger overflows to `1`, so a delay meant to be far in\n * the future fires almost immediately. A declared delay above this bound names\n * no delay at all, and a controller reading one falls back to its default.\n */\nexport const MAX_TIMER_DELAY_MS = 2_147_483_647;\n","import { MAX_TIMER_DELAY_MS } from \"./timer_bounds\";\n\n/** Semantic constraints on an already decoded number, independent of the DOM. */\nexport interface NumberBounds {\n /** Finite numbers are required, including when this field is omitted. */\n readonly finite?: true;\n /** Inclusive lower endpoint. */\n readonly min?: number;\n /** Inclusive upper endpoint. */\n readonly max?: number;\n /** Exclusive lower endpoint. */\n readonly exclusiveMin?: number;\n /** Require a number without a fractional part. */\n readonly integer?: boolean;\n /** Exact decoded numbers accepted by a discrete contract. */\n readonly allowedValues?: readonly number[];\n /** JSON-safe exceptions to finite-number checking for unbounded endpoints. */\n readonly allowInfinity?: \"negative\" | \"positive\" | \"both\";\n}\n\n/** One constraint for each Number Value, including shorthand declarations. */\nexport type NumberValueConstraints<Values> = {\n readonly [Key in keyof Values as Values[Key] extends\n | NumberConstructor\n | { type: NumberConstructor }\n ? Key\n : never]: NumberBounds;\n};\n\n/** Reusable semantic domains; fractional inputs remain fractional unless excluded. */\nexport const NUMBER_BOUNDS = {\n finite: { finite: true },\n nonNegative: { finite: true, min: 0 },\n positive: { finite: true, exclusiveMin: 0 },\n nonNegativeInteger: { finite: true, min: 0, integer: true },\n positiveInteger: { finite: true, exclusiveMin: 0, integer: true },\n lowerBound: { finite: true, allowInfinity: \"negative\" },\n upperBound: { finite: true, allowInfinity: \"positive\" },\n timer: { finite: true, min: 0, max: MAX_TIMER_DELAY_MS },\n positiveTimer: { finite: true, exclusiveMin: 0, max: MAX_TIMER_DELAY_MS },\n} as const satisfies Record<string, NumberBounds>;\n\n/**\n * Checks all declared bounds without rounding, clamping, or coercing the input.\n * Infinity exceptions relax only finite checking; every other bound still applies.\n */\nexport function matchesNumberBounds(value: number, bounds: NumberBounds): boolean {\n if (!Number.isFinite(value)) {\n const direction = value === Infinity ? \"positive\" : value === -Infinity ? \"negative\" : null;\n if (direction === null) return false;\n if (bounds.allowInfinity !== \"both\" && bounds.allowInfinity !== direction) return false;\n }\n if (bounds.min !== undefined && value < bounds.min) return false;\n if (bounds.max !== undefined && value > bounds.max) return false;\n if (bounds.exclusiveMin !== undefined && value <= bounds.exclusiveMin) return false;\n if (bounds.integer && !Number.isInteger(value)) return false;\n if (bounds.allowedValues !== undefined && !bounds.allowedValues.includes(value)) return false;\n return true;\n}\n\n/** Decodes a Number Value literal; action params use their own JSON decoder. */\nexport function decodeNumberValue(raw: string): number {\n return Number(raw.replace(/_/g, \"\"));\n}\n","/**\n * Numeric coercion for controllers that accept a number through a Value, an action\n * param, or an event detail.\n *\n * Stimulus decodes action params as JSON when possible and leaves other text\n * untouched. CustomEvent detail can also supply a number or numeric string.\n * The reader accepts those two types while rejecting blank and non-finite input.\n */\n\nimport { matchesNumberBounds, type NumberBounds } from \"./number_bounds\";\n\n/**\n * Reads a finite number or nonblank numeric string; other input returns `null`.\n * Blank strings cannot silently reset a value to zero.\n */\nexport function toFiniteNumber(raw: unknown): number | null {\n if (typeof raw !== \"number\" && typeof raw !== \"string\") return null;\n if (typeof raw === \"string\" && raw.trim().length === 0) return null;\n const value = Number(raw);\n return Number.isFinite(value) ? value : null;\n}\n\n/**\n * Returns an accepted decoded Number Value or the caller's fallback unchanged.\n * The caller owns the fallback contract; this reader does not parse or write a Value.\n */\nexport function readNumber(raw: number, fallback: number, bounds: NumberBounds): number {\n return matchesNumberBounds(raw, bounds) ? raw : fallback;\n}\n","import { readNumber } from \"./coerce\";\nimport { matchesNumberBounds, type NumberBounds } from \"./number_bounds\";\n\n/** The instance identity carried by a Number Value read. */\nexport interface NumberValueOwner {\n readonly identifier: string;\n readonly element: Element;\n}\n\n/** Reads current declarations at the point of use without rewriting their attributes. */\nexport class NumberValueReader {\n /** The last rejected literal per Value; no history grows for an unchanged instance. */\n readonly #lastRejected = new Map<string, string>();\n\n /** Resolves the declared number using its own fallback and shared class contract. */\n read(\n owner: NumberValueOwner,\n name: string,\n raw: number,\n fallback: number,\n bounds: NumberBounds,\n ): number {\n const resolved = readNumber(raw, fallback, bounds);\n if (matchesNumberBounds(raw, bounds)) {\n this.#lastRejected.delete(name);\n return resolved;\n }\n const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;\n const literal = owner.element.getAttribute(attribute);\n if (literal === null) {\n this.#lastRejected.delete(name);\n return resolved;\n }\n if (this.#lastRejected.get(name) !== literal) {\n this.#lastRejected.set(name, literal);\n console.warn(\n `Stimeo UI: \"${owner.identifier}\" has an invalid number Value \"${name}\" declaration ${JSON.stringify(literal)}; using ${fallback}.`,\n );\n }\n return resolved;\n }\n}\n","/**\n * Self-cleaning timer registries shared by Stimeo controllers.\n *\n * Stimulus controllers frequently schedule `setTimeout` / `setInterval` work\n * (auto-dismiss, debouncing, polling). When the element leaves the DOM — a\n * Turbo Drive navigation, a Turbo Stream replacement, or any `disconnect()` —\n * orphaned timers keep firing against a detached controller, leaking memory and\n * mutating stale state. {@link SafeTimeout} and {@link SafeInterval} track every\n * timer they create so a single {@link TimerRegistry.clearAll | clearAll()} call\n * in `disconnect()` tears them all down.\n *\n * These are intentionally low-level primitives: they own *registration and\n * cleanup only*. Higher-level policy (pause/resume, remaining-time accounting)\n * stays in the individual controllers so per-widget semantics are not flattened\n * into a lowest-common-denominator helper.\n */\n\nexport { MAX_TIMER_DELAY_MS } from \"./timer_bounds\";\n\n/**\n * Shared registry bookkeeping for the timeout/interval variants.\n *\n * Subclasses provide the scheduling primitive ({@link schedule}) and its matching\n * canceller ({@link cancel}); this base owns the set of live ids plus the\n * per-id and bulk teardown shared by both.\n */\nabstract class TimerRegistry {\n /** Live timer ids that have not yet been cleared (or, for timeouts, fired). */\n protected readonly ids = new Set<number>();\n\n /** Schedules the underlying platform timer and returns its id. */\n protected abstract schedule(callback: () => void, delay: number): number;\n\n /** Cancels the underlying platform timer for `id`. */\n protected abstract cancel(id: number): void;\n\n /**\n * Cancels a single tracked timer.\n *\n * No-ops if the id is unknown (already cleared, fired, or never owned by this\n * registry), so callers can clear defensively without guarding.\n */\n clear(id: number): void {\n if (this.ids.delete(id)) {\n this.cancel(id);\n }\n }\n\n /**\n * Cancels every tracked timer. Call this from a controller's `disconnect()`\n * to guarantee no timer outlives the element.\n */\n clearAll(): void {\n for (const id of this.ids) {\n this.cancel(id);\n }\n this.ids.clear();\n }\n\n /** Number of timers currently tracked (pending). */\n get size(): number {\n return this.ids.size;\n }\n}\n\n/**\n * `setTimeout` wrapper that auto-forgets each timer once it fires and supports\n * bulk teardown on disconnect.\n *\n * @example\n * ```ts\n * #timers = new SafeTimeout();\n *\n * connect() {\n * this.#timers.set(() => this.dismiss(), 5000);\n * }\n *\n * disconnect() {\n * this.#timers.clearAll();\n * }\n * ```\n */\nexport class SafeTimeout extends TimerRegistry {\n /**\n * Schedules `callback` after `delay` ms and returns the timer id.\n *\n * The id is removed from the registry automatically when the timeout fires,\n * so {@link TimerRegistry.size | size} reflects only still-pending timers.\n */\n set(callback: () => void, delay: number): number {\n const id = this.schedule(() => {\n this.ids.delete(id);\n callback();\n }, delay);\n this.ids.add(id);\n return id;\n }\n\n protected schedule(callback: () => void, delay: number): number {\n return window.setTimeout(callback, delay);\n }\n\n protected cancel(id: number): void {\n window.clearTimeout(id);\n }\n}\n\n/**\n * `setInterval` wrapper that tracks every interval for bulk teardown on\n * disconnect. Unlike {@link SafeTimeout}, intervals are retained until they are\n * explicitly cleared because they fire repeatedly.\n *\n * @example\n * ```ts\n * #intervals = new SafeInterval();\n *\n * connect() {\n * this.#intervals.set(() => this.tick(), 1000);\n * }\n *\n * disconnect() {\n * this.#intervals.clearAll();\n * }\n * ```\n */\nexport class SafeInterval extends TimerRegistry {\n /** Schedules a repeating `callback` every `delay` ms and returns the timer id. */\n set(callback: () => void, delay: number): number {\n const id = this.schedule(callback, delay);\n this.ids.add(id);\n return id;\n }\n\n protected schedule(callback: () => void, delay: number): number {\n return window.setInterval(callback, delay);\n }\n\n protected cancel(id: number): void {\n window.clearInterval(id);\n }\n}\n","/** Queries physical descendants and nested open shadow trees, including `root`'s own. */\nexport function queryOpenDescendants<T extends Element = Element>(\n root: ParentNode,\n selector: string,\n): T[] {\n const matches: T[] = [];\n const roots: ParentNode[] = [root];\n for (const scope of roots) {\n matches.push(...scope.querySelectorAll<T>(selector));\n if (scope.nodeType === Node.ELEMENT_NODE) {\n const shadow = (scope as Element).shadowRoot;\n if (shadow) roots.push(shadow);\n }\n for (const element of scope.querySelectorAll(\"*\")) {\n if (element.shadowRoot) roots.push(element.shadowRoot);\n }\n }\n return matches;\n}\n","/**\n * One registry per page for every copy of the library.\n *\n * Each `stimeo-ui/controllers/*` file, and each opt-in entry, is built on its own and carries\n * its own copy of every utility it uses, so a page that imports controllers one by one, or one\n * of them next to the barrel, evaluates a utility several times. A registry that coordinates\n * instances of different controllers — the stacks of leased values, the loans of a\n * `tabindex`, the Escape layers, the focus traps — must not be split by that: a dialog inside\n * a drawer, or a character counter and a form field on one input, coordinate whichever files\n * they came from. So such a registry lives once on `globalThis`, under a `Symbol.for` key the\n * copies agree on, and the first copy to ask for it creates it.\n *\n * The key names the registry and the version of its shape\n * (`stimeo-ui.<utility>.registry.v<n>`). Copies whose registries have the same shape share\n * one; a release that changes the shape changes the version, so a copy of another release\n * keeps a registry of its own instead of reading entries it does not understand — the two\n * then coordinate within each release only. An entry another copy put in a registry is read\n * through its fields alone, never through `#private` members, which belong to the class of\n * the copy that created it.\n */\n\n/**\n * The registry stored under `key`, created by `create` on first use.\n *\n * @param key - `stimeo-ui.<utility>.registry.v<n>`: the version is that of the shape `create`\n * returns.\n * @param create - Builds the empty registry.\n */\nexport function sharedRegistry<T extends object>(key: string, create: () => T): T {\n const symbol = Symbol.for(key);\n const scope = globalThis as unknown as Record<symbol, T | undefined>;\n const existing = scope[symbol];\n if (existing !== undefined) return existing;\n const registry = create();\n Object.defineProperty(globalThis, symbol, { value: registry });\n return registry;\n}\n","import { queryOpenDescendants } from \"./query_open_descendants\";\nimport { sharedRegistry } from \"./shared_registry\";\n\n/** One loan's hold on one element's `tabindex`, in the stack every loan of it shares. */\ninterface LoanHold {\n /** The loan holding it; `null` for a loan read from a copy's record until a loan takes it. */\n loan: object | null;\n readonly record: string;\n readonly value: string;\n /** Whether it hands back the value of the hold beneath it; otherwise no `tabindex`. */\n linked: boolean;\n}\n\n/** The loans on each element, bottom first, and every loan's record name. */\ninterface TabindexLoanRegistry {\n readonly stacks: WeakMap<HTMLElement, LoanHold[]>;\n readonly names: Set<string>;\n}\n\n/**\n * Shared bookkeeping for a `tabindex` a controller lends an element temporarily.\n *\n * A controller that must move focus somewhere the author never made focusable\n * (a landmark root, a scroll destination) reaches for the same trick: add a\n * `tabindex` just-in-time and hand it back once it is no longer needed. The\n * borrow is the easy half; the return is what the two conditions below are for.\n *\n * **Returning needs two conditions, not one.** Owning the borrow is not enough:\n * the attribute must also still hold the value this instance wrote. A consumer\n * that changed it afterwards — `tabindex=\"0\"` to make the root its own Tab stop\n * — owns it now, and removing it there silently discards authored markup. The\n * bookkeeping is dropped either way, since the loan is over regardless of who\n * ends up owning the value.\n *\n * **Never borrow over a value no loan holds.** An element whose `tabindex` no loan\n * holds — the author's, or one the page wrote over the loans — is the author's to\n * control, so there is nothing to lend and nothing to return.\n *\n * **Every loan of an element shares one stack of loans**, whatever its owner and\n * whichever file of the package constructed it (the stacks are one per page). A loan\n * lends over the loans that hold the element while its `tabindex` is theirs — sharing\n * their value, or covering it with its own — and lends again where the page removed\n * the `tabindex`. The `tabindex` is the highest loan's that lends its value: returning\n * that loan gives the element the value of the loan beneath it, or no `tabindex`, and\n * any other return only leaves the stack. So two loans of one value — every focus trap\n * lends its container under one owner — keep it until the last of them returns, and a\n * loan lent after the page removed an earlier one's `tabindex` keeps it when the\n * earlier one returns.\n *\n * **A loan is recorded on the element.** Lending writes\n * `data-<owner>-tabindex-loan` holding the value the owner's topmost loan lends next\n * to the `tabindex`, and the owner's last loan to end removes it. A copy of the\n * element — a page Turbo restores from its cache is one — so tells its owners' loans\n * from an authored `tabindex`: `lend()` takes over a loan its owner recorded, and\n * `reclaim()` gives back one no loan has taken over; the `tabindex` goes with the last\n * of them. A copy keeps no order of its loans beyond putting those of the value it\n * carries on top. Without a record a `tabindex` is the author's. Nothing returns a\n * live loan before Turbo caches the page: `turbo:before-cache` also fires on pages\n * that stay, and the loan is still in use there.\n *\n * The registry is keyed by element, so a controller borrowing on a single\n * element (`this.element`) and one borrowing across a changing set of targets\n * use the same API — the single-element case is a set of one. It holds no\n * opinion about *when* to borrow or where focus goes next; that stays in the\n * controller.\n *\n * **The API is deliberately small.** Each consumer entry includes its own copy\n * of the class, so unused methods still increase its runtime output.\n *\n * @example\n * ```ts\n * readonly #tabindex = new TabindexLoan(\"-1\", this.identifier);\n *\n * connect() {\n * this.#tabindex.reclaim(this.element);\n * }\n *\n * #rescueFocus() {\n * this.#tabindex.lend(this.element);\n * this.element.focus();\n * }\n *\n * disconnect() {\n * this.#tabindex.returnAll();\n * }\n * ```\n */\nexport class TabindexLoan<T extends HTMLElement = HTMLElement> {\n /** The loans on each element and the record names, one per page. */\n static readonly #registry = sharedRegistry(\n \"stimeo-ui.tabindex-loan.registry.v1\",\n (): TabindexLoanRegistry => ({ stacks: new WeakMap(), names: new Set() }),\n );\n readonly #value: string;\n readonly #record: string;\n readonly #lent = new Set<T>();\n\n /**\n * @param value - the `tabindex` to lend. `\"-1\"` is programmatically focusable but\n * not a Tab stop; `\"0\"` is a real Tab stop, which a scroll region with no\n * focusable content of its own needs.\n * @param owner - Names the record on the element; the controller's identifier.\n */\n constructor(value: string, owner: string) {\n this.#value = value;\n this.#record = `data-${owner}-tabindex-loan`;\n TabindexLoan.#registry.names.add(this.#record);\n }\n\n /**\n * Lends `element` the value over the loans holding its `tabindex`, or where the page removed\n * it; a `tabindex` no loan holds is left alone, and a loan recorded on a copy taken over.\n */\n lend(element: T): void {\n const stack = this.#stack(element);\n const current = element.getAttribute(\"tabindex\");\n const held =\n stack.find((hold) => hold.loan === this) ??\n stack.find(\n (hold) => hold.loan === null && hold.record === this.#record && hold.value === this.#value,\n );\n const linked = stack.at(-1)?.value === current;\n if (!held && current !== null && !linked) return;\n this.#lent.add(element);\n if (held) held.loan = this;\n else stack.push({ loan: this, record: this.#record, value: this.#value, linked });\n this.#mark(element, stack);\n if (current === null || (!held && current !== this.#value)) {\n element.setAttribute(\"tabindex\", this.#value);\n }\n }\n\n /** Takes back every loan; one whose value the element shows hands it to the loan beneath. */\n returnAll(): void {\n for (const element of this.#lent) {\n const stack = this.#stack(element);\n const hold = stack.find((held) => held.loan === this);\n if (hold) this.#release(element, stack, hold);\n }\n this.#lent.clear();\n }\n\n /**\n * Gives back a loan its owner recorded on a restored copy that no loan has taken over, unless\n * the record holds another value or the element holds focus.\n */\n reclaim(element: HTMLElement): void {\n if (element.getAttribute(this.#record) !== this.#value) return;\n const stack = this.#stack(element);\n const hold = stack.find((held) => held.loan === null && held.record === this.#record);\n if (hold && !element.matches(\":focus\")) this.#release(element, stack, hold);\n }\n\n /** Gives back, as {@link reclaim} does, every loan of its owner recorded inside `root`. */\n reclaimWithin(root: ParentNode): void {\n for (const element of queryOpenDescendants<HTMLElement>(root, `[${this.#record}]`)) {\n this.reclaim(element);\n }\n }\n\n /** The element's loans, read from its records the first time. */\n #stack(element: HTMLElement): LoanHold[] {\n const stacks = TabindexLoan.#registry.stacks;\n const stack = stacks.get(element) ?? this.#seed(element);\n stacks.set(element, stack);\n return stack;\n }\n\n /** The loans a copy's records describe, those of the value it carries on top. */\n #seed(element: HTMLElement): LoanHold[] {\n const current = element.getAttribute(\"tabindex\");\n const holds: LoanHold[] = [];\n for (const record of TabindexLoan.#registry.names) {\n const value = element.getAttribute(record);\n if (value !== null) holds.push({ loan: null, record, value, linked: true });\n }\n holds.sort((one, other) => Number(one.value === current) - Number(other.value === current));\n for (const [index, hold] of holds.entries()) hold.linked = index > 0;\n return holds;\n }\n\n /** Takes `hold` off, handing the value it shows to the loan beneath. */\n #release(element: HTMLElement, stack: LoanHold[], hold: LoanHold): void {\n const current = element.getAttribute(\"tabindex\");\n const index = stack.indexOf(hold);\n const owns =\n current === hold.value && !stack.slice(index + 1).some((above) => above.value === current);\n stack.splice(index, 1);\n const above = stack[index];\n if (above) above.linked &&= hold.linked;\n this.#mark(element, stack);\n if (!owns) return;\n const below = hold.linked ? stack[index - 1] : undefined;\n if (!below) element.removeAttribute(\"tabindex\");\n else if (below.value !== current) element.setAttribute(\"tabindex\", below.value);\n }\n\n /** Leaves each owner's record of the value its topmost loan lends. */\n #mark(element: HTMLElement, stack: readonly LoanHold[]): void {\n const records = new Map<string, string | null>([[this.#record, null]]);\n for (const hold of stack) records.set(hold.record, hold.value);\n for (const [name, recorded] of records) {\n if (element.getAttribute(name) === recorded) continue;\n if (recorded === null) element.removeAttribute(name);\n else element.setAttribute(name, recorded);\n }\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { ownerOf } from \"../utils/event_owner\";\nimport { canTakeFocus } from \"../utils/focus_candidate\";\nimport { LayoutObserver } from \"../utils/layout_observer\";\nimport { MorphRenderWatcher } from \"../utils/morph_render_watcher\";\nimport { NUMBER_BOUNDS, type NumberValueConstraints } from \"../utils/number_bounds\";\nimport { NumberValueReader } from \"../utils/number_value\";\nimport { SafeTimeout } from \"../utils/safe_timeout\";\nimport { TabindexLoan } from \"../utils/tabindex_loan\";\nimport type { MenuController } from \"./menu_controller\";\n\n/** Suffix of the marker on an item living in the More menu (survives a DOM snapshot). */\nconst BANKED = \"banked\";\n/**\n * Suffix of the canonical index persisted while anything is banked, so a fresh\n * instance can re-adopt.\n */\nconst INDEX = \"index\";\n/**\n * Suffix of the marker on the inert split point retained only while every managed\n * item is banked.\n */\nconst BOUNDARY = \"boundary\";\n/**\n * Suffixes of the attributes saving an item's authored values while it wears menu\n * semantics (\"\" = attribute was absent).\n */\nconst SAVED_ROLE = \"role\";\nconst SAVED_TABINDEX = \"tabindex\";\nconst SAVED_MENU_TARGET = \"saved-menu\";\n/** Menu's target attribute — set to `item` while banked so Menu drives the item. */\nconst MENU_TARGET = \"data-stimeo--menu-target\";\n/** Everything this controller writes on an item; all removed on the way back to the bar. */\nconst BOOKKEEPING = [BANKED, INDEX, SAVED_ROLE, SAVED_TABINDEX, SAVED_MENU_TARGET] as const;\n/**\n * Suffix of the marker on the More label this controller wrote into the trigger;\n * the marker holds that label as its value. The trigger is this controller's only\n * while it holds that label and nothing else: text the consumer rewrites there, or\n * an element child, an `aria-label` or an `aria-labelledby` they add, makes it\n * theirs.\n */\nconst OWNED_LABEL = \"owns-label\";\n\n/** `ParentNode.moveBefore` (Chromium 133+): relocates a node without removing it first. */\ninterface MovableParent {\n moveBefore?: (node: Node, child: Node | null) => void;\n}\n\n/**\n * Headless **overflow / priority menu**: items that no longer fit their container are\n * moved into a \"More\" dropdown (lowest `data-priority` first) and moved back as space\n * returns, watched with a {@link ResizeObserver} (no dedicated APG pattern — a\n * composition; the menu's a11y is delegated to Menu, so it is not re-implemented).\n *\n * Markup contract (identifier: `stimeo--overflow-menu`):\n * <nav data-controller=\"stimeo--overflow-menu\" aria-label=\"Actions\">\n * <div data-stimeo--overflow-menu-target=\"items\">\n * <button data-priority=\"1\">Save</button>\n * <button>Delete</button>\n * </div>\n * <div data-controller=\"stimeo--menu\" data-stimeo--overflow-menu-target=\"more\" hidden>\n * <button id=\"more-trigger\" data-stimeo--menu-target=\"trigger\"\n * aria-haspopup=\"menu\" aria-expanded=\"false\"\n * data-action=\"click->stimeo--menu#toggle\n * keydown->stimeo--menu#onTriggerKeydown\">More</button>\n * <div role=\"menu\" aria-labelledby=\"more-trigger\"\n * data-stimeo--menu-target=\"menu\" hidden></div>\n * </div>\n * </nav>\n *\n * This controller does not own the root's role. It ships none: a navigation bar is\n * a named `<nav>` whose items stay in the normal Tab order. A consumer may add\n * `role=\"toolbar\"`, but that alone is not an APG Toolbar — the single-tab-stop\n * roving is {@link ToolbarController}'s behavior, not this one's — and a named\n * role still needs `aria-label` / `aria-labelledby`.\n *\n * Two parts of that contract are load-bearing and easy to drop. The banked-items\n * container is a permissive single `role=\"menu\"` element this controller appends to\n * directly; use a `<div>`, since a `<ul>` cannot directly own the moved controls. And the\n * trigger's `data-action` is **required, not decoration**: without it the More button\n * never opens, and `keydown->stimeo--menu#onTriggerKeydown` is what makes it reachable\n * by keyboard at all (`Enter` / `Space` / `ArrowDown`). It is spelled out above rather\n * than referenced, because the keyboard half of this contract lives *only* in the\n * consumer's markup — nothing in this controller's source would reveal its absence.\n * Items need no bindings of their own — Menu delegates their handling from its own\n * element, so a control that only becomes a menu item at runtime is operable the\n * moment it lands.\n *\n * A bare More trigger — no text, no element child, no `aria-label` or\n * `aria-labelledby` — gets `moreLabel` as its text on every pass, before the pass\n * measures it, marked with `data-<identifier>-owns-label` whose value is that\n * label. The trigger stays this controller's only while it holds that label and\n * nothing else — the text still matches the marker, and it has no element child,\n * `aria-label` or `aria-labelledby` — and only then does a `moreLabel` swapped at\n * runtime rewrite it, or an empty one hand it back bare. Any other trigger content\n * is the author's and is never written: a trigger the consumer has rewritten, or\n * added an element child or a name to, is neither rewritten nor emptied, and its\n * marker stays where it is. Once it holds the label alone again, it is this\n * controller's again.\n *\n * On connect (and every debounced resize) it measures the items against the container's\n * content width and, when they overflow, banks the lowest-priority ones into the More\n * menu — giving each `role=\"menuitem\"` / `tabindex=\"-1\"` and the menu's `item` target so\n * Menu drives it — until the rest fit beside the More button. When nothing overflows the\n * More wrapper (button *and* menu) is `hidden`. The controller element carries\n * `data-overflowing` / `data-overflow-count`, and a `change` event fires on connect and\n * on later update or resize transitions; retained-element morphs report `reconcile`.\n *\n * `change` and `reconcile` dispatch `{ overflowCount, total }`.\n *\n * @remarks\n * **Measuring.** The container's width must not be derived from its content (give the bar\n * an explicit width, `flex: 1`, or plain block layout): the More button is revealed before\n * measuring, so a shrink-to-fit container always reports \"items + gap + More\" and nothing\n * ever overflows. The budget is the container's *content box* (`clientWidth` minus its\n * horizontal padding); the gap between items comes from the items container, the gap\n * reserved for the More button from the bar itself. Item widths are cached (a natural\n * width is location-independent) so a pass reads only the items in the bar — one reflow,\n * not two. The trade-off: an item whose content changes *while banked* (a locale switch, a\n * badge update) keeps its stale width until it is back in the bar, so it may return one\n * pass late; re-measuring it in place would cost a second reflow every pass. An item the\n * author marked `hidden` is out of the budget, out of the drop order, and never banked; it\n * holds its canonical slot and rejoins as soon as the attribute goes away. Toggling\n * `hidden` is an attribute change, not a resize, so call `update` after it.\n *\n * **Moving.** Items are moved (never cloned), and only the nodes that are actually out of\n * place — a pass that changes nothing touches no node, because re-inserting a node removes\n * it first and the browser then drops focus to `<body>`. Where `moveBefore` is supported\n * the move preserves focus and transient element state outright.\n *\n * **Focus.** When the focused item (or a descendant of it) *starts* retreating into a\n * collapsed menu it would be hidden and lose focus, so focus is redirected to the More\n * trigger (falling back to the More wrapper when the markup has no trigger — give it one,\n * or focus is left to the browser). While the menu is expanded the item stays visible, so\n * focus is left alone — unless the focused item is the one returning to the bar, which\n * takes focus out of the wrapper and leaves the expanded menu with nothing that owns it;\n * the menu is then closed and focus stays on the returned item. When the last banked item\n * returns, the wrapper is about to be hidden: the menu is closed and focus is moved out of\n * it to the last item that can actually hold it (`hidden` and disabled ones cannot), or to\n * the root when none can.\n *\n * **Priority.** Lower `data-priority` is kept longer; a value that is absent, empty, or\n * not a number ranks lowest and drops first.\n *\n * **Turbo.** The managed set and the canonical order are rebuilt *from the DOM* every\n * pass, so a fresh `connect()` onto markup that already holds banked items (cache restore,\n * a morph, a clone, server-rendered overflow) re-adopts them instead of orphaning them\n * inside a wrapper it would then hide. Symmetrically, `disconnect()` returns every item\n * to the bar, collapses the composed menu (so it releases its dismissal-stack\n * membership), takes back the More label the trigger still holds alone, and strips the\n * items' bookkeeping attributes. `turbo:before-cache` changes nothing: Turbo also\n * dispatches it on pages that stay (a promoted frame navigation, a `popstate` without\n * Turbo state, a refresh of a cached URL), where the bar stays balanced and an open\n * More menu stays open, and a page restored from its cache is re-adopted and balanced\n * by the connection that adopts it. A trigger the consumer added to after the label\n * was written keeps the label and its marker: taking either off would write to content\n * that belongs to the consumer. The `ResizeObserver` and debounce timer are released on\n * `disconnect()` too.\n *\n * **Swapped targets.** An items row or a More wrapper that takes over — in one task,\n * in front of the current one, or after an earlier one leaves in a later task — is\n * balanced by a pass of its own, which reports `reconcile` only when the overflow count\n * moved. The row and the wrapper balanced before are handed back first, so a banked item\n * is neither lost nor counted twice. A row or a wrapper\n * that stops resolving as the target is handed back the way `disconnect()` hands\n * back the bar: the items banked from a row return to it, and a wrapper is hidden\n * with its menu collapsed and its label taken back — after `disconnect()` too, since\n * dropping the identifier leaves both on the page.\n *\n * Behavior only — no styling.\n */\nexport class OverflowMenuController extends Controller<HTMLElement> {\n /** Numeric read boundaries share one reader for this controller instance. */\n readonly #numbers = new NumberValueReader();\n\n /** One bookkeeping attribute, in the namespace this controller is registered under. */\n #attr(name: string): string {\n return `data-${this.identifier}-${name}`;\n }\n\n static override targets = [\"items\", \"more\"];\n static override values = {\n moreLabel: { type: String, default: \"More\" },\n debounce: { type: Number, default: 100 },\n };\n\n static valueConstraints = {\n debounce: NUMBER_BOUNDS.timer,\n } satisfies NumberValueConstraints<typeof OverflowMenuController.values>;\n static actions = [\"update\"] as const;\n static events = [\"change\", \"reconcile\"] as const;\n\n declare readonly itemsTarget: HTMLElement;\n declare readonly itemsTargets: HTMLElement[];\n declare readonly moreTarget: HTMLElement;\n declare readonly moreTargets: HTMLElement[];\n declare readonly hasItemsTarget: boolean;\n declare readonly hasMoreTarget: boolean;\n\n declare moreLabelValue: string;\n declare debounceValue: number;\n\n readonly #layout = new LayoutObserver(() => this.#scheduleUpdate());\n readonly #timers = new SafeTimeout();\n /** The managed items in canonical (authored) order, rebuilt from the DOM each pass. */\n #items: HTMLElement[] = [];\n #index = new WeakMap<HTMLElement, number>();\n /** Cached bar-context width per item; see the class remarks for the staleness caveat. */\n #widths = new WeakMap<HTMLElement, number>();\n /** Last reported overflow count, so `change` fires only on transitions. */\n #lastHidden: number | null = null;\n /**\n * Counts the passes and restores begun on this instance. Moving focus and closing\n * the composed Menu run page code, which can start a pass or a restore of its own;\n * that one writes the whole state, so a pass that finds this count moved on after\n * such a call writes and reports nothing more.\n */\n #pass = 0;\n /**\n * Whether every item is being returned to the bar. Closing the composed Menu there\n * runs page code, and a pass it starts would bank items again behind the More\n * wrapper that the restore then hides, so no pass runs until the restore ends —\n * the outermost one, when that page code starts another restore inside it.\n */\n #restoring = false;\n /** The `tabindex` this instance lends the root for the focus fallback. */\n readonly #tabindex = new TabindexLoan(\"-1\", this.identifier);\n /** The items row the last pass balanced, until it or the wrapper is handed back. */\n #bar: HTMLElement | null = null;\n /** The More wrapper the last pass balanced, until it or the row is handed back. */\n #wrapper: HTMLElement | null = null;\n\n /**\n * Whether `connect()` has run for this connection. Stimulus delivers Value\n * callbacks ahead of it, and the first pass writes the label anyway.\n */\n #connected = false;\n\n readonly #morphRender = new MorphRenderWatcher(() => this.#reconcile());\n\n override connect(): void {\n this.#tabindex.reclaim(this.element);\n this.#morphRender.observe(this.element);\n this.#connected = true;\n if (!this.hasItemsTarget || !this.hasMoreTarget) return;\n\n this.#layout.observe(this.element);\n this.#layout.observeViewport();\n this.update();\n }\n\n override disconnect(): void {\n this.#morphRender.disconnect();\n this.#connected = false;\n this.#layout.disconnect();\n this.#timers.clearAll();\n this.#restoreAll();\n this.#lastHidden = null;\n }\n\n /** Balances an items row that arrives after connect in front of the others. */\n itemsTargetConnected(): void {\n this.#followTargets();\n }\n\n /**\n * Hands the items back to a row that no longer resolves as the target — after\n * `disconnect()` too, since dropping the identifier leaves the element on the page — then\n * balances the row that stays.\n */\n itemsTargetDisconnected(bar: HTMLElement): void {\n if (bar === this.#bar && !this.itemsTargets.includes(bar)) this.#release();\n this.#followTargets();\n }\n\n /** Balances a More wrapper that arrives after connect in front of the others. */\n moreTargetConnected(): void {\n this.#followTargets();\n }\n\n /**\n * Hands the items banked in a More wrapper that no longer resolves as the target back to\n * the row, and hides it — after `disconnect()` too — then balances the wrapper that stays.\n */\n moreTargetDisconnected(more: HTMLElement): void {\n if (more === this.#wrapper && !this.moreTargets.includes(more)) this.#release();\n this.#followTargets();\n }\n\n /**\n * Follows a More label swapped in place by a morph, on a trigger that still holds\n * the label this controller wrote and nothing else. Render only: nothing is\n * measured and `change` is not dispatched here; the next pass measures the bar.\n */\n moreLabelValueChanged(): void {\n if (!this.#connected || !this.hasItemsTarget || !this.hasMoreTarget) return;\n this.#syncLabel();\n }\n\n /** Re-measures and rebalances items between the bar and the More menu. */\n update(): void {\n const detail = this.#render();\n if (detail) this.dispatch(\"change\", { detail });\n }\n\n /** Reports a published overflow count changed by a retained-element morph. */\n #reconcile(): void {\n const detail = this.#render();\n if (detail) this.dispatch(\"reconcile\", { detail });\n }\n\n /** Rebalances the current item set and returns a changed published count. */\n #render(): { overflowCount: number; total: number } | null {\n if (this.#restoring || !this.hasItemsTarget || !this.hasMoreTarget) return null;\n const pass = ++this.#pass;\n this.#bar = this.itemsTarget;\n this.#wrapper = this.moreTarget;\n // The label is part of the More button's width, so it is in place before the\n // button is measured below.\n this.#syncLabel();\n this.#syncItems(this.itemsTarget, this.moreTarget);\n\n // Reveal More so its trigger is measurable, then refresh the widths of the items\n // currently in the bar (menu items keep their location-independent last value).\n this.moreTarget.hidden = false;\n // Server-rendered overflow arrives with items already in the menu, which is\n // hidden, so they measure zero and the budget would read as \"everything fits\".\n // Bring the set back to the bar once, unbanked, so the first balance works from\n // real widths taken in the context the items are actually laid out in — a\n // banked item can carry consumer styling of its own.\n if (\n this.#items.some((item) => item.parentElement !== this.itemsTarget && !this.#widths.has(item))\n ) {\n this.#removeBoundary(this.itemsTarget);\n for (const item of this.#items) this.#unbank(item);\n this.#reorder(this.itemsTarget, this.#items);\n }\n for (const item of this.#items) {\n if (item.parentElement === this.itemsTarget) this.#widths.set(item, item.offsetWidth);\n }\n const moreWidth = (this.#trigger(this.moreTarget) ?? this.moreTarget).offsetWidth;\n const itemGap = this.#gap(this.itemsTarget); // between the items themselves\n const barGap = this.#gap(this.element); // between the items row and the More button\n\n const widthOf = (el: HTMLElement): number => this.#widths.get(el) ?? el.offsetWidth;\n const containerWidth = this.element.clientWidth - this.#paddingX(this.element);\n // An authored `hidden` item occupies no width, but a naive count would still\n // charge a gap for it and could bank a sibling that in fact fits — or raise a\n // More button whose menu has nothing operable in it. It keeps its canonical\n // slot; it just does not take part in the budget or in the drop order.\n const rendered = this.#items.filter((item) => this.#rendered(item));\n const itemsWidth = rendered.reduce((sum, el) => sum + widthOf(el), 0);\n let visibleWidth = itemsWidth + Math.max(0, rendered.length - 1) * itemGap;\n\n const hidden = new Set<HTMLElement>();\n if (visibleWidth > containerWidth) {\n const budget = containerWidth - moreWidth - barGap; // reserve the More button + its gap\n // Drop lowest-retention first: no usable `data-priority` (rank ∞), then highest\n // number; ties broken right-to-left so leading items survive.\n const dropOrder = [...rendered].sort(\n (a, b) => this.#rank(b) - this.#rank(a) || this.#indexOf(b) - this.#indexOf(a),\n );\n for (const item of dropOrder) {\n if (visibleWidth <= budget) break;\n hidden.add(item);\n visibleWidth -= widthOf(item) + itemGap; // dropping an item frees its width and a gap\n }\n }\n\n // Decided before any node moves, so it cannot race the browser's blur.\n const active = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n const focused = active === null ? null : this.#ownerOf(active);\n const retreating =\n focused !== null &&\n hidden.has(focused) &&\n focused.parentElement === this.itemsTarget && // i.e. *starting* to retreat\n !this.#menuExpanded(this.moreTarget);\n // The mirror image: the item holding focus is on its way *out* of an expanded\n // menu. Focus rides along with the node, but once it sits outside the More\n // wrapper the menu owns nothing that reaches it — the shared dismissal\n // resolver stops claiming for this layer, and the item's own menu bindings\n // fall out of Stimulus scope. Leaving the menu open would strand it with no\n // owner, so it is collapsed after the move (see below).\n const returning =\n focused !== null &&\n !hidden.has(focused) &&\n focused.parentElement !== this.itemsTarget && // i.e. *leaving* the menu\n this.#menuExpanded(this.moreTarget);\n\n // A fully-banked snapshot retains an inert split point so a fresh controller can\n // tell prepend from append. Once a real item remains in the bar, its saved index is\n // the stronger anchor and the boundary must not participate in DOM reordering.\n if (hidden.size === 0 || hidden.size !== this.#items.length) {\n this.#removeBoundary(this.itemsTarget);\n }\n\n // The menu pass runs first, so retreating items leave the bar before it is reordered\n // (otherwise every trailing item would be shuffled needlessly).\n for (const item of this.#items) {\n if (hidden.has(item)) this.#bank(item);\n else this.#unbank(item);\n }\n this.#reorder(\n this.#menuList(this.moreTarget),\n this.#items.filter((item) => hidden.has(item)),\n );\n this.#reorder(\n this.itemsTarget,\n this.#items.filter((item) => !hidden.has(item)),\n );\n\n if (retreating) (this.#trigger(this.moreTarget) ?? this.moreTarget).focus();\n else if (active !== null && this.#lostFocus(active)) active.focus();\n if (pass !== this.#pass) return null;\n\n const count = hidden.size;\n // Keep the canonical positions on both sides while overflow exists. If the bar is\n // emptied, also retain an inert split point: a later prepend lands before it and an\n // append after it, preserving intent when a fresh controller adopts the snapshot.\n for (const item of this.#items) {\n if (count > 0) item.setAttribute(this.#attr(INDEX), String(this.#indexOf(item)));\n else item.removeAttribute(this.#attr(INDEX));\n }\n if (count > 0 && count === this.#items.length) this.#ensureBoundary();\n const inMore =\n document.activeElement instanceof HTMLElement &&\n this.moreTarget.contains(document.activeElement);\n if (count === 0 || returning) {\n // Either the wrapper is about to be hidden — collapse the menu so it cannot\n // reappear expanded without a gesture, and move focus out before it\n // disappears — or the item that held focus just carried it out of the menu.\n // `close()` rather than the dismissal path, so the trigger does not take\n // back focus the user is now holding on the returned item; `inMore` is false\n // in that case, so the rescue below stays out of the way. Items still banked\n // remain reachable by reopening from the trigger.\n this.#closeMenu(this.moreTarget);\n if (inMore && pass === this.#pass) this.#rescueFocus();\n if (pass !== this.#pass) return null;\n }\n this.moreTarget.hidden = count === 0;\n if (count > 0) this.element.setAttribute(\"data-overflowing\", \"true\");\n else this.element.removeAttribute(\"data-overflowing\");\n this.element.setAttribute(\"data-overflow-count\", String(count));\n\n if (this.#lastHidden !== count) {\n this.#lastHidden = count;\n return { overflowCount: count, total: this.#items.length };\n }\n return null;\n }\n\n /** The flex `column-gap` on `el` in px (0 when none / unsupported). */\n #gap(el: HTMLElement): number {\n const style = this.#styleOf(el);\n return style === null ? 0 : this.#px(style.columnGap || style.gap);\n }\n\n /** Horizontal padding on `el` in px — `clientWidth` counts it, the content box cannot. */\n #paddingX(el: HTMLElement): number {\n const style = this.#styleOf(el);\n return style === null ? 0 : this.#px(style.paddingLeft) + this.#px(style.paddingRight);\n }\n\n #styleOf(el: HTMLElement): CSSStyleDeclaration | null {\n return typeof window.getComputedStyle === \"function\" ? window.getComputedStyle(el) : null;\n }\n\n #px(value: string | undefined): number {\n const parsed = Number.parseFloat(value ?? \"\");\n return Number.isNaN(parsed) ? 0 : parsed;\n }\n\n /**\n * Rebuilds the managed set and the canonical order from the DOM of the items row `row`\n * and the More wrapper `more`. The row's children give the order of everything inline (so\n * a leading insert is not silently appended) and {@link #merge} weaves the banked items\n * back among them.\n */\n #syncItems(row: HTMLElement, more: HTMLElement): void {\n const previous = this.#items;\n const bar: HTMLElement[] = [];\n let boundaryAt: number | undefined;\n for (const el of row.children) {\n if (el instanceof HTMLTemplateElement && el.hasAttribute(this.#attr(BOUNDARY))) {\n boundaryAt ??= bar.length;\n continue;\n }\n if (el instanceof HTMLElement) bar.push(el);\n }\n\n const banked: HTMLElement[] = [];\n for (const el of this.#menuList(more).children) {\n if (el instanceof HTMLElement && el.hasAttribute(this.#attr(BANKED))) banked.push(el);\n }\n banked.sort((a, b) => this.#bankedIndex(a) - this.#bankedIndex(b));\n\n const items = this.#merge(bar, banked, boundaryAt);\n\n // An item re-homed elsewhere is no longer ours, but it would keep the menu\n // semantics we gave it — strip them before dropping it from the set.\n for (const el of previous) {\n if (!items.includes(el)) {\n this.#unbank(el);\n el.removeAttribute(this.#attr(INDEX));\n }\n }\n\n this.#items = items;\n this.#index = new WeakMap();\n items.forEach((el, i) => {\n this.#index.set(el, i);\n });\n }\n\n /**\n * Interleaves the banked items back among the bar's children.\n *\n * A saved index is a position in the *canonical* order, so it can only be compared\n * against another canonical position — never used as an offset into the current bar,\n * which is a shorter and differently-indexed list. (Doing so survives an untouched\n * round trip and silently scrambles the order as soon as the consumer inserts into a\n * bar that is already short, and `#bank()` then burns the scrambled index back into\n * the attribute, so widening never heals it.) Each bar child the controller already\n * knows carries its canonical index from the previous pass; a banked item goes in\n * front of the first known child whose index is higher.\n *\n * Children never seen before — inserted by the consumer since the last pass — have no\n * canonical position yet, so they keep their DOM neighbours. The exception is a\n * *trailing* run of them: appending to the bar means appending to the toolbar, so\n * everything banked is emitted before it.\n *\n * With no known child at all (a fresh instance connecting to markup that already\n * holds banked items), a fully-banked snapshot's inert boundary preserves whether an\n * unindexed run was prepended or appended before connect. Markup that holds banked items but no boundary —\n * server-rendered or hand-authored — uses the saved index as the\n * offset, the inverse of the move that banked it.\n */\n #merge(\n bar: readonly HTMLElement[],\n banked: readonly HTMLElement[],\n boundaryAt?: number,\n ): HTMLElement[] {\n const canonical = bar.map((el) => this.#index.get(el) ?? this.#savedIndex(el));\n let lastKnown = -1;\n canonical.forEach((index, i) => {\n if (index !== undefined) lastKnown = i;\n });\n\n if (lastKnown === -1) {\n if (boundaryAt !== undefined) {\n return [...bar.slice(0, boundaryAt), ...banked, ...bar.slice(boundaryAt)];\n }\n const restored = [...bar];\n for (const item of banked) {\n restored.splice(Math.min(this.#bankedIndex(item), restored.length), 0, item);\n }\n return restored;\n }\n\n const items: HTMLElement[] = [];\n let next = 0;\n const drainWhile = (accept: (saved: number) => boolean): void => {\n while (next < banked.length) {\n const item = banked[next];\n if (item === undefined || !accept(this.#bankedIndex(item))) break;\n items.push(item);\n next++;\n }\n };\n\n bar.forEach((el, i) => {\n const index = canonical[i];\n if (index !== undefined) drainWhile((saved) => saved < index);\n else if (i > lastKnown) drainWhile(() => true);\n items.push(el);\n });\n drainWhile(() => true);\n return items;\n }\n\n /** The canonical index a banked item saved, or ∞ (append) when it carries none. */\n #bankedIndex(item: HTMLElement): number {\n return this.#savedIndex(item) ?? Number.POSITIVE_INFINITY;\n }\n\n /** A finite canonical index stored on either side of the overflow split. */\n #savedIndex(item: HTMLElement): number | undefined {\n const raw = item.getAttribute(this.#attr(INDEX));\n if (raw === null) return undefined;\n const value = Number(raw);\n return Number.isFinite(value) ? value : undefined;\n }\n\n /** The inert split point in `bar`, written only when every managed item lives in More. */\n #boundary(bar: HTMLElement): HTMLTemplateElement | null {\n for (const el of bar.children) {\n if (el instanceof HTMLTemplateElement && el.hasAttribute(this.#attr(BOUNDARY))) return el;\n }\n return null;\n }\n\n #ensureBoundary(): void {\n if (this.#boundary(this.itemsTarget) !== null) return;\n const boundary = document.createElement(\"template\");\n boundary.setAttribute(this.#attr(BOUNDARY), \"\");\n this.itemsTarget.appendChild(boundary);\n }\n\n #removeBoundary(bar: HTMLElement): void {\n this.#boundary(bar)?.remove();\n }\n\n /** Debounced re-measure for resize-driven churn. */\n #scheduleUpdate(): void {\n this.#timers.clearAll();\n this.#timers.set(() => this.update(), this.#safeDebounce);\n }\n\n /**\n * Hands back the row and the wrapper the last pass balanced and schedules a pass when the\n * items row or the More wrapper that is first is not that one, so the pass gathers every\n * item from the row and the wrapper that are first then. Only a bar that has published a\n * count follows its targets — one missing a target since connect stays as inert as\n * `connect()` left it — and none does during a restore, whose page code must not bank\n * items again behind it.\n */\n #followTargets(): void {\n if (this.#restoring || this.#lastHidden === null) return;\n const bar = this.hasItemsTarget ? this.itemsTarget : null;\n const more = this.hasMoreTarget ? this.moreTarget : null;\n if (bar === this.#bar && more === this.#wrapper) return;\n this.#release();\n this.#morphRender.schedule();\n }\n\n /** Returns the menu list `more` banks the items into (falls back to the wrapper itself). */\n #menuList(more: HTMLElement): HTMLElement {\n return more.querySelector<HTMLElement>('[data-stimeo--menu-target=\"menu\"]') ?? more;\n }\n\n #trigger(more: HTMLElement): HTMLElement | null {\n return more.querySelector<HTMLElement>('[data-stimeo--menu-target=\"trigger\"]');\n }\n\n /**\n * Keeps the More trigger's text on `moreLabel` wherever that text is this\n * controller's to write: a bare trigger, or one still holding the label this\n * controller wrote and nothing else. An empty `moreLabel` hands such a trigger\n * back bare. A pass that finds the label already in place writes nothing, and a\n * trigger that is neither is not written at all.\n *\n * @stimeoRenderRoot\n */\n #syncLabel(): void {\n const trigger = this.#trigger(this.moreTarget);\n if (trigger === null) return;\n const owned = this.#ownsLabel(trigger);\n if (!owned && !this.#isBareTrigger(trigger)) return;\n const label = this.moreLabelValue;\n if (label === \"\") {\n this.#releaseLabel(trigger);\n return;\n }\n if (owned && trigger.textContent === label) return;\n trigger.textContent = label;\n trigger.setAttribute(this.#attr(OWNED_LABEL), label);\n }\n\n /**\n * Whether the trigger holds the label this controller wrote there and nothing\n * else: the text still matches the marker, and the trigger carries nothing but\n * text. Ownership is read afresh on every call, so a trigger the consumer adds to\n * is theirs for as long as the addition is there.\n */\n #ownsLabel(trigger: HTMLElement): boolean {\n return (\n trigger.getAttribute(this.#attr(OWNED_LABEL)) === trigger.textContent &&\n this.#carriesOnlyText(trigger)\n );\n }\n\n /**\n * Takes the label this controller wrote back out of the trigger, leaving it bare.\n * A trigger that is not this controller's is left exactly as it is, marker\n * included: taking the marker off would itself write to it.\n */\n #releaseLabel(trigger: HTMLElement): void {\n if (!this.#ownsLabel(trigger)) return;\n trigger.textContent = \"\";\n trigger.removeAttribute(this.#attr(OWNED_LABEL));\n }\n\n /**\n * Whether the More trigger is bare, so the label is safe to write: no text, no\n * element child, no `aria-label` and no `aria-labelledby`. A trigger with neither\n * text, nor children, nor a name has nothing to lose and gets the fallback; one\n * that is empty *and* unnamed is the only case the label rescues.\n */\n #isBareTrigger(trigger: HTMLElement): boolean {\n return (trigger.textContent ?? \"\").trim() === \"\" && this.#carriesOnlyText(trigger);\n }\n\n /**\n * Whether the trigger carries nothing but text: no element child, no\n * `aria-label` and no `aria-labelledby`. Assigning `textContent` replaces\n * *every* child node, so a trigger holding an icon would silently lose it — and\n * the loss is permanent, since only the label this controller wrote is ever\n * taken back. A trigger that carries an accessible name is left alone too:\n * visible text written under a different `aria-label` would make the label and\n * the name disagree. Only a trigger that carries nothing but text is ever\n * written or emptied.\n */\n #carriesOnlyText(trigger: HTMLElement): boolean {\n return (\n trigger.firstElementChild === null &&\n !trigger.hasAttribute(\"aria-label\") &&\n !trigger.hasAttribute(\"aria-labelledby\")\n );\n }\n\n /**\n * Whether the menu `more` composes is expanded. Menu owns that state and reflects it on\n * the trigger's `aria-expanded`, so read the contract rather than guess from `hidden`\n * (which is absent until Menu connects).\n */\n #menuExpanded(more: HTMLElement): boolean {\n return this.#trigger(more)?.getAttribute(\"aria-expanded\") === \"true\";\n }\n\n /**\n * Collapses the menu `more` composes before the wrapper is hidden. Menu owns the state\n * (and the Escape-stack membership that goes with it), so ask it; the DOM fallback covers\n * markup that reached an expanded state with no Menu mounted.\n */\n #closeMenu(more: HTMLElement): void {\n if (!this.#menuExpanded(more)) return;\n const menu = this.application.getControllerForElementAndIdentifier(\n more,\n \"stimeo--menu\",\n ) as MenuController | null;\n if (menu) {\n menu.close();\n return;\n }\n this.#trigger(more)?.setAttribute(\"aria-expanded\", \"false\");\n const list = this.#menuList(more);\n if (list !== more) list.hidden = true;\n }\n\n /** The managed item that is, or contains, `el` — focus rescue works on either. */\n #ownerOf(el: HTMLElement): HTMLElement | null {\n return ownerOf(this.#items, el);\n }\n\n /** Whether the item takes up room in the bar; an authored `hidden` one does not. */\n #rendered(item: HTMLElement): boolean {\n return !item.hasAttribute(\"hidden\");\n }\n\n /**\n * Moves focus out of the More wrapper just before it is hidden, to the last\n * item in canonical order that can hold it. When every item refuses, the root\n * takes focus instead of letting the browser drop it to `<body>`, borrowing a\n * `tabindex=\"-1\"` just-in-time — not a Tab stop, and handed back on restore\n * when this controller was the one that added it.\n */\n #rescueFocus(): void {\n for (let i = this.#items.length - 1; i >= 0; i--) {\n const item = this.#items[i];\n // The shared pre-check, not `#rendered`: that one answers \"does this item\n // take up room in the bar\", which reads only the item's own `hidden`. Focus\n // eligibility has to see an ancestor's too — the same rule `#lostFocus`\n // applies below.\n if (item !== undefined && canTakeFocus(item)) {\n item.focus();\n return;\n }\n }\n this.#tabindex.lend(this.element);\n this.element.focus();\n }\n\n /**\n * Whether `el` held focus, is still in a visible part of this controller, and lost it —\n * what a re-insert does in a real browser. An item that retreated into a collapsed menu\n * is excluded: it sits in a `hidden` subtree and must not be focused back.\n */\n #lostFocus(el: HTMLElement): boolean {\n return (\n el.isConnected &&\n document.activeElement !== el &&\n this.element.contains(el) &&\n el.closest(\"[hidden]\") === null\n );\n }\n\n /** Returns every item to the bar and removes all traces of this controller. */\n #restoreAll(): void {\n if (!this.hasItemsTarget || !this.hasMoreTarget) return;\n this.#giveBack(this.itemsTarget, this.moreTarget);\n }\n\n /** Hands back the row and the wrapper the last pass balanced, when one did. */\n #release(): void {\n if (this.#bar && this.#wrapper) this.#giveBack(this.#bar, this.#wrapper);\n }\n\n /**\n * Returns every item to `bar` and removes all traces of this controller from it, from\n * `more` and from the root. Nothing counts as balanced afterwards, so the next pass\n * balances whatever row and wrapper are first then.\n */\n #giveBack(bar: HTMLElement, more: HTMLElement): void {\n this.#bar = null;\n this.#wrapper = null;\n const restoring = this.#restoring;\n this.#restoring = true;\n this.#pass++;\n this.#syncItems(bar, more);\n this.#removeBoundary(bar);\n this.#reorder(bar, this.#items);\n for (const item of this.#items) {\n this.#unbank(item);\n item.removeAttribute(this.#attr(INDEX));\n }\n // The wrapper is being hidden for good, so the composed menu must not stay\n // expanded behind it: an unclosed menu keeps its dismissal-stack membership.\n // Focus is left exactly where it is — this path runs at teardown, where moving\n // it would be the surprise.\n this.#closeMenu(more);\n const trigger = this.#trigger(more);\n if (trigger !== null) this.#releaseLabel(trigger);\n more.hidden = true;\n this.element.removeAttribute(\"data-overflowing\");\n this.element.removeAttribute(\"data-overflow-count\");\n this.#tabindex.returnAll();\n this.#restoring = restoring;\n }\n\n /**\n * Makes `parent`'s managed children match `sequence`, moving only what is out of place.\n * Walking backwards lets each item be compared against the element that should follow\n * it, so an unchanged run costs zero DOM mutations — the point of the exercise, since\n * every re-insert blurs the focused node.\n */\n #reorder(parent: HTMLElement, sequence: readonly HTMLElement[]): void {\n let next: HTMLElement | null = null;\n for (let i = sequence.length - 1; i >= 0; i--) {\n const item = sequence[i];\n if (item === undefined) continue;\n if (item.parentElement !== parent || item.nextElementSibling !== next) {\n this.#insert(parent, item, next);\n }\n next = item;\n }\n }\n\n /** Relocates `item`, preferring `moveBefore` (keeps focus and element state). */\n #insert(parent: HTMLElement, item: HTMLElement, before: HTMLElement | null): void {\n const move = (parent as HTMLElement & MovableParent).moveBefore;\n if (typeof move === \"function\") {\n try {\n move.call(parent, item, before);\n return;\n } catch {\n // Not movable in place (e.g. a disconnected node) — fall through.\n }\n }\n parent.insertBefore(item, before);\n }\n\n /**\n * Gives an item menuitem semantics for Menu to drive and records its canonical index,\n * saving every authored value it overwrites (\"\" means the attribute was absent).\n */\n #bank(item: HTMLElement): void {\n if (!item.hasAttribute(this.#attr(BANKED))) {\n item.setAttribute(this.#attr(BANKED), \"true\");\n item.setAttribute(this.#attr(SAVED_ROLE), item.getAttribute(\"role\") ?? \"\");\n item.setAttribute(this.#attr(SAVED_TABINDEX), item.getAttribute(\"tabindex\") ?? \"\");\n item.setAttribute(this.#attr(SAVED_MENU_TARGET), item.getAttribute(MENU_TARGET) ?? \"\");\n item.setAttribute(\"role\", \"menuitem\");\n item.setAttribute(\"tabindex\", \"-1\");\n item.setAttribute(MENU_TARGET, \"item\");\n }\n item.setAttribute(this.#attr(INDEX), String(this.#indexOf(item)));\n }\n\n /** Undoes the banking: restores every authored value and drops the bookkeeping. */\n #unbank(item: HTMLElement): void {\n if (!item.hasAttribute(this.#attr(BANKED))) return;\n this.#restoreAttr(item, \"role\", item.getAttribute(this.#attr(SAVED_ROLE)));\n this.#restoreAttr(item, \"tabindex\", item.getAttribute(this.#attr(SAVED_TABINDEX)));\n this.#restoreAttr(item, MENU_TARGET, item.getAttribute(this.#attr(SAVED_MENU_TARGET)));\n for (const name of BOOKKEEPING) item.removeAttribute(this.#attr(name));\n }\n\n /** Re-applies a saved attribute value, or removes the attribute when it was absent. */\n #restoreAttr(item: HTMLElement, name: string, original: string | null): void {\n if (original === null || original === \"\") item.removeAttribute(name);\n else item.setAttribute(name, original);\n }\n\n #indexOf(item: HTMLElement): number {\n return this.#index.get(item) ?? 0;\n }\n\n /**\n * Retention rank: lower keeps longer. An absent, empty, or non-numeric `data-priority`\n * ranks lowest (drops first) — empty is the common ERB accident\n * (`data-priority=\"<%= maybe_nil %>\"`), and `Number(\"\")` is 0, which would otherwise\n * read as the *highest* retention.\n */\n #rank(item: HTMLElement): number {\n const raw = item.getAttribute(\"data-priority\");\n if (raw === null || raw.trim() === \"\") return Number.POSITIVE_INFINITY;\n const value = Number(raw);\n return Number.isNaN(value) ? Number.POSITIVE_INFINITY : value;\n }\n /** Current `debounce` declaration resolved against its numeric contract. */\n get #safeDebounce(): number {\n return this.#numbers.read(\n this,\n \"debounce\",\n this.debounceValue,\n OverflowMenuController.values.debounce.default,\n OverflowMenuController.valueConstraints.debounce,\n );\n }\n}\n"]}