stimeo-ui 0.16.0 → 0.18.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 (337) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/README.md +27 -11
  3. package/dist/cable/index.d.ts +88 -31
  4. package/dist/cable/index.js +384 -449
  5. package/dist/cable/index.js.map +1 -1
  6. package/dist/coerce-JtZVNG5h.d.ts +20 -0
  7. package/dist/controllers/accordion_controller.d.ts +4 -2
  8. package/dist/controllers/accordion_controller.js +174 -55
  9. package/dist/controllers/accordion_controller.js.map +1 -1
  10. package/dist/controllers/alert_dialog_controller.d.ts +12 -2
  11. package/dist/controllers/alert_dialog_controller.js +903 -235
  12. package/dist/controllers/alert_dialog_controller.js.map +1 -1
  13. package/dist/controllers/announcer_controller.d.ts +37 -5
  14. package/dist/controllers/announcer_controller.js +238 -205
  15. package/dist/controllers/announcer_controller.js.map +1 -1
  16. package/dist/controllers/aspect_ratio_controller.js +0 -10
  17. package/dist/controllers/aspect_ratio_controller.js.map +1 -1
  18. package/dist/controllers/auto_submit_controller.d.ts +30 -6
  19. package/dist/controllers/auto_submit_controller.js +414 -145
  20. package/dist/controllers/auto_submit_controller.js.map +1 -1
  21. package/dist/controllers/avatar_controller.js +185 -107
  22. package/dist/controllers/avatar_controller.js.map +1 -1
  23. package/dist/controllers/breadcrumb_controller.js +0 -130
  24. package/dist/controllers/breadcrumb_controller.js.map +1 -1
  25. package/dist/controllers/bulk_select_controller.d.ts +21 -3
  26. package/dist/controllers/bulk_select_controller.js +282 -58
  27. package/dist/controllers/bulk_select_controller.js.map +1 -1
  28. package/dist/controllers/calendar_controller.d.ts +38 -16
  29. package/dist/controllers/calendar_controller.js +228 -260
  30. package/dist/controllers/calendar_controller.js.map +1 -1
  31. package/dist/controllers/carousel_controller.d.ts +43 -12
  32. package/dist/controllers/carousel_controller.js +536 -436
  33. package/dist/controllers/carousel_controller.js.map +1 -1
  34. package/dist/controllers/character_counter_controller.d.ts +44 -7
  35. package/dist/controllers/character_counter_controller.js +493 -207
  36. package/dist/controllers/character_counter_controller.js.map +1 -1
  37. package/dist/controllers/checkbox_controller.d.ts +7 -2
  38. package/dist/controllers/checkbox_controller.js +38 -74
  39. package/dist/controllers/checkbox_controller.js.map +1 -1
  40. package/dist/controllers/clipboard_controller.d.ts +16 -5
  41. package/dist/controllers/clipboard_controller.js +261 -149
  42. package/dist/controllers/clipboard_controller.js.map +1 -1
  43. package/dist/controllers/collapsible_controller.d.ts +17 -5
  44. package/dist/controllers/collapsible_controller.js +304 -120
  45. package/dist/controllers/collapsible_controller.js.map +1 -1
  46. package/dist/controllers/color_picker_controller.d.ts +18 -6
  47. package/dist/controllers/color_picker_controller.js +178 -146
  48. package/dist/controllers/color_picker_controller.js.map +1 -1
  49. package/dist/controllers/combobox_controller.d.ts +24 -6
  50. package/dist/controllers/combobox_controller.js +522 -156
  51. package/dist/controllers/combobox_controller.js.map +1 -1
  52. package/dist/controllers/command_palette_controller.d.ts +51 -20
  53. package/dist/controllers/command_palette_controller.js +1156 -395
  54. package/dist/controllers/command_palette_controller.js.map +1 -1
  55. package/dist/controllers/conditional_fields_controller.d.ts +15 -2
  56. package/dist/controllers/conditional_fields_controller.js +300 -171
  57. package/dist/controllers/conditional_fields_controller.js.map +1 -1
  58. package/dist/controllers/confirm_controller.d.ts +49 -12
  59. package/dist/controllers/confirm_controller.js +980 -262
  60. package/dist/controllers/confirm_controller.js.map +1 -1
  61. package/dist/controllers/context_menu_controller.d.ts +80 -18
  62. package/dist/controllers/context_menu_controller.js +346 -153
  63. package/dist/controllers/context_menu_controller.js.map +1 -1
  64. package/dist/controllers/count_up_controller.d.ts +13 -1
  65. package/dist/controllers/count_up_controller.js +73 -21
  66. package/dist/controllers/count_up_controller.js.map +1 -1
  67. package/dist/controllers/countdown_controller.d.ts +47 -3
  68. package/dist/controllers/countdown_controller.js +281 -158
  69. package/dist/controllers/countdown_controller.js.map +1 -1
  70. package/dist/controllers/currency_input_controller.d.ts +93 -10
  71. package/dist/controllers/currency_input_controller.js +575 -225
  72. package/dist/controllers/currency_input_controller.js.map +1 -1
  73. package/dist/controllers/data_grid_controller.d.ts +25 -12
  74. package/dist/controllers/data_grid_controller.js +248 -214
  75. package/dist/controllers/data_grid_controller.js.map +1 -1
  76. package/dist/controllers/date_range_picker_controller.d.ts +42 -14
  77. package/dist/controllers/date_range_picker_controller.js +338 -235
  78. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  79. package/dist/controllers/dialog_controller.d.ts +17 -6
  80. package/dist/controllers/dialog_controller.js +899 -237
  81. package/dist/controllers/dialog_controller.js.map +1 -1
  82. package/dist/controllers/direct_upload_controller.d.ts +25 -8
  83. package/dist/controllers/direct_upload_controller.js +97 -167
  84. package/dist/controllers/direct_upload_controller.js.map +1 -1
  85. package/dist/controllers/dirty_form_controller.d.ts +6 -1
  86. package/dist/controllers/dirty_form_controller.js +72 -69
  87. package/dist/controllers/dirty_form_controller.js.map +1 -1
  88. package/dist/controllers/dismissible_controller.d.ts +19 -0
  89. package/dist/controllers/dismissible_controller.js +196 -24
  90. package/dist/controllers/dismissible_controller.js.map +1 -1
  91. package/dist/controllers/drawer_controller.d.ts +39 -11
  92. package/dist/controllers/drawer_controller.js +974 -355
  93. package/dist/controllers/drawer_controller.js.map +1 -1
  94. package/dist/controllers/dropdown_controller.d.ts +31 -1
  95. package/dist/controllers/dropdown_controller.js +339 -96
  96. package/dist/controllers/dropdown_controller.js.map +1 -1
  97. package/dist/controllers/editable_controller.d.ts +12 -1
  98. package/dist/controllers/editable_controller.js +315 -88
  99. package/dist/controllers/editable_controller.js.map +1 -1
  100. package/dist/controllers/empty_state_controller.js +79 -58
  101. package/dist/controllers/empty_state_controller.js.map +1 -1
  102. package/dist/controllers/file_dropzone_controller.d.ts +63 -18
  103. package/dist/controllers/file_dropzone_controller.js +322 -211
  104. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  105. package/dist/controllers/filter_controller.js +77 -42
  106. package/dist/controllers/filter_controller.js.map +1 -1
  107. package/dist/controllers/flash_controller.d.ts +35 -12
  108. package/dist/controllers/flash_controller.js +238 -347
  109. package/dist/controllers/flash_controller.js.map +1 -1
  110. package/dist/controllers/focus_controller.d.ts +15 -6
  111. package/dist/controllers/focus_controller.js +679 -240
  112. package/dist/controllers/focus_controller.js.map +1 -1
  113. package/dist/controllers/form_field_controller.js +156 -132
  114. package/dist/controllers/form_field_controller.js.map +1 -1
  115. package/dist/controllers/form_validation_controller.d.ts +3 -3
  116. package/dist/controllers/form_validation_controller.js +31 -97
  117. package/dist/controllers/form_validation_controller.js.map +1 -1
  118. package/dist/controllers/frame_loading_controller.d.ts +47 -14
  119. package/dist/controllers/frame_loading_controller.js +275 -217
  120. package/dist/controllers/frame_loading_controller.js.map +1 -1
  121. package/dist/controllers/highlight_controller.d.ts +27 -6
  122. package/dist/controllers/highlight_controller.js +107 -75
  123. package/dist/controllers/highlight_controller.js.map +1 -1
  124. package/dist/controllers/hover_card_controller.d.ts +60 -4
  125. package/dist/controllers/hover_card_controller.js +327 -130
  126. package/dist/controllers/hover_card_controller.js.map +1 -1
  127. package/dist/controllers/idle_controller.d.ts +48 -6
  128. package/dist/controllers/idle_controller.js +271 -101
  129. package/dist/controllers/idle_controller.js.map +1 -1
  130. package/dist/controllers/input_mask_controller.d.ts +30 -13
  131. package/dist/controllers/input_mask_controller.js +483 -97
  132. package/dist/controllers/input_mask_controller.js.map +1 -1
  133. package/dist/controllers/intersection_controller.d.ts +32 -13
  134. package/dist/controllers/intersection_controller.js +150 -106
  135. package/dist/controllers/intersection_controller.js.map +1 -1
  136. package/dist/controllers/lazy_frame_controller.d.ts +19 -2
  137. package/dist/controllers/lazy_frame_controller.js +24 -68
  138. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  139. package/dist/controllers/listbox_controller.d.ts +44 -9
  140. package/dist/controllers/listbox_controller.js +523 -240
  141. package/dist/controllers/listbox_controller.js.map +1 -1
  142. package/dist/controllers/local_time_controller.d.ts +9 -7
  143. package/dist/controllers/local_time_controller.js +102 -77
  144. package/dist/controllers/local_time_controller.js.map +1 -1
  145. package/dist/controllers/masonry_controller.d.ts +11 -3
  146. package/dist/controllers/masonry_controller.js +80 -96
  147. package/dist/controllers/masonry_controller.js.map +1 -1
  148. package/dist/controllers/menu_controller.d.ts +55 -11
  149. package/dist/controllers/menu_controller.js +302 -188
  150. package/dist/controllers/menu_controller.js.map +1 -1
  151. package/dist/controllers/menubar_controller.d.ts +51 -9
  152. package/dist/controllers/menubar_controller.js +232 -345
  153. package/dist/controllers/menubar_controller.js.map +1 -1
  154. package/dist/controllers/meter_controller.d.ts +33 -20
  155. package/dist/controllers/meter_controller.js +417 -87
  156. package/dist/controllers/meter_controller.js.map +1 -1
  157. package/dist/controllers/multi_select_controller.d.ts +48 -18
  158. package/dist/controllers/multi_select_controller.js +785 -393
  159. package/dist/controllers/multi_select_controller.js.map +1 -1
  160. package/dist/controllers/navigation_menu_controller.d.ts +27 -6
  161. package/dist/controllers/navigation_menu_controller.js +190 -250
  162. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  163. package/dist/controllers/nested_form_controller.d.ts +10 -0
  164. package/dist/controllers/nested_form_controller.js +396 -192
  165. package/dist/controllers/nested_form_controller.js.map +1 -1
  166. package/dist/controllers/network_status_controller.d.ts +23 -0
  167. package/dist/controllers/network_status_controller.js +268 -62
  168. package/dist/controllers/network_status_controller.js.map +1 -1
  169. package/dist/controllers/number_input_controller.d.ts +50 -8
  170. package/dist/controllers/number_input_controller.js +610 -303
  171. package/dist/controllers/number_input_controller.js.map +1 -1
  172. package/dist/controllers/optimistic_controller.d.ts +8 -5
  173. package/dist/controllers/optimistic_controller.js +45 -87
  174. package/dist/controllers/optimistic_controller.js.map +1 -1
  175. package/dist/controllers/otp_controller.d.ts +55 -8
  176. package/dist/controllers/otp_controller.js +658 -255
  177. package/dist/controllers/otp_controller.js.map +1 -1
  178. package/dist/controllers/overflow_indicator_controller.d.ts +5 -0
  179. package/dist/controllers/overflow_indicator_controller.js +122 -113
  180. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  181. package/dist/controllers/overflow_menu_controller.d.ts +58 -20
  182. package/dist/controllers/overflow_menu_controller.js +470 -295
  183. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  184. package/dist/controllers/pagination_controller.d.ts +37 -7
  185. package/dist/controllers/pagination_controller.js +332 -123
  186. package/dist/controllers/pagination_controller.js.map +1 -1
  187. package/dist/controllers/password_reveal_controller.d.ts +46 -8
  188. package/dist/controllers/password_reveal_controller.js +392 -121
  189. package/dist/controllers/password_reveal_controller.js.map +1 -1
  190. package/dist/controllers/password_strength_controller.d.ts +15 -6
  191. package/dist/controllers/password_strength_controller.js +111 -158
  192. package/dist/controllers/password_strength_controller.js.map +1 -1
  193. package/dist/controllers/persist_controller.d.ts +11 -4
  194. package/dist/controllers/persist_controller.js +165 -111
  195. package/dist/controllers/persist_controller.js.map +1 -1
  196. package/dist/controllers/pointer_drag_controller.d.ts +35 -12
  197. package/dist/controllers/pointer_drag_controller.js +434 -188
  198. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  199. package/dist/controllers/popover_controller.d.ts +41 -5
  200. package/dist/controllers/popover_controller.js +269 -113
  201. package/dist/controllers/popover_controller.js.map +1 -1
  202. package/dist/controllers/portal_controller.d.ts +44 -4
  203. package/dist/controllers/portal_controller.js +215 -76
  204. package/dist/controllers/portal_controller.js.map +1 -1
  205. package/dist/controllers/preview_guard_controller.d.ts +10 -4
  206. package/dist/controllers/preview_guard_controller.js +243 -116
  207. package/dist/controllers/preview_guard_controller.js.map +1 -1
  208. package/dist/controllers/progress_controller.d.ts +20 -19
  209. package/dist/controllers/progress_controller.js +391 -78
  210. package/dist/controllers/progress_controller.js.map +1 -1
  211. package/dist/controllers/radio_group_controller.d.ts +21 -9
  212. package/dist/controllers/radio_group_controller.js +278 -211
  213. package/dist/controllers/radio_group_controller.js.map +1 -1
  214. package/dist/controllers/range_slider_controller.d.ts +47 -6
  215. package/dist/controllers/range_slider_controller.js +220 -113
  216. package/dist/controllers/range_slider_controller.js.map +1 -1
  217. package/dist/controllers/rating_controller.d.ts +20 -4
  218. package/dist/controllers/rating_controller.js +458 -211
  219. package/dist/controllers/rating_controller.js.map +1 -1
  220. package/dist/controllers/read_more_controller.d.ts +2 -0
  221. package/dist/controllers/read_more_controller.js +138 -63
  222. package/dist/controllers/read_more_controller.js.map +1 -1
  223. package/dist/controllers/reading_progress_controller.d.ts +1 -1
  224. package/dist/controllers/reading_progress_controller.js +166 -137
  225. package/dist/controllers/reading_progress_controller.js.map +1 -1
  226. package/dist/controllers/relative_time_controller.d.ts +20 -6
  227. package/dist/controllers/relative_time_controller.js +211 -112
  228. package/dist/controllers/relative_time_controller.js.map +1 -1
  229. package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
  230. package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +103 -38
  231. package/dist/controllers/reset_on_restore_controller.js.map +1 -0
  232. package/dist/controllers/resizable_controller.d.ts +31 -2
  233. package/dist/controllers/resizable_controller.js +299 -150
  234. package/dist/controllers/resizable_controller.js.map +1 -1
  235. package/dist/controllers/roving_controller.d.ts +3 -3
  236. package/dist/controllers/roving_controller.js +49 -88
  237. package/dist/controllers/roving_controller.js.map +1 -1
  238. package/dist/controllers/scroll_area_controller.d.ts +7 -3
  239. package/dist/controllers/scroll_area_controller.js +490 -246
  240. package/dist/controllers/scroll_area_controller.js.map +1 -1
  241. package/dist/controllers/scroll_restore_controller.d.ts +3 -3
  242. package/dist/controllers/scroll_restore_controller.js +14 -55
  243. package/dist/controllers/scroll_restore_controller.js.map +1 -1
  244. package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
  245. package/dist/controllers/scroll_visibility_controller.js +432 -149
  246. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  247. package/dist/controllers/scrollspy_controller.d.ts +6 -1
  248. package/dist/controllers/scrollspy_controller.js +193 -248
  249. package/dist/controllers/scrollspy_controller.js.map +1 -1
  250. package/dist/controllers/separator_controller.d.ts +20 -5
  251. package/dist/controllers/separator_controller.js +285 -142
  252. package/dist/controllers/separator_controller.js.map +1 -1
  253. package/dist/controllers/sidebar_controller.d.ts +65 -8
  254. package/dist/controllers/sidebar_controller.js +1069 -404
  255. package/dist/controllers/sidebar_controller.js.map +1 -1
  256. package/dist/controllers/skeleton_controller.d.ts +23 -0
  257. package/dist/controllers/skeleton_controller.js +259 -101
  258. package/dist/controllers/skeleton_controller.js.map +1 -1
  259. package/dist/controllers/slider_controller.d.ts +29 -2
  260. package/dist/controllers/slider_controller.js +187 -86
  261. package/dist/controllers/slider_controller.js.map +1 -1
  262. package/dist/controllers/smart_sticky_header_controller.d.ts +22 -4
  263. package/dist/controllers/smart_sticky_header_controller.js +173 -66
  264. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  265. package/dist/controllers/sortable_controller.d.ts +4 -4
  266. package/dist/controllers/sortable_controller.js +26 -125
  267. package/dist/controllers/sortable_controller.js.map +1 -1
  268. package/dist/controllers/spinner_controller.d.ts +39 -4
  269. package/dist/controllers/spinner_controller.js +288 -173
  270. package/dist/controllers/spinner_controller.js.map +1 -1
  271. package/dist/controllers/step_indicator_controller.d.ts +9 -4
  272. package/dist/controllers/step_indicator_controller.js +105 -46
  273. package/dist/controllers/step_indicator_controller.js.map +1 -1
  274. package/dist/controllers/stepper_controller.d.ts +14 -6
  275. package/dist/controllers/stepper_controller.js +120 -73
  276. package/dist/controllers/stepper_controller.js.map +1 -1
  277. package/dist/controllers/stick_to_bottom_controller.d.ts +9 -1
  278. package/dist/controllers/stick_to_bottom_controller.js +275 -140
  279. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  280. package/dist/controllers/sticky_observer_controller.d.ts +11 -0
  281. package/dist/controllers/sticky_observer_controller.js +220 -49
  282. package/dist/controllers/sticky_observer_controller.js.map +1 -1
  283. package/dist/controllers/submit_once_controller.d.ts +24 -8
  284. package/dist/controllers/submit_once_controller.js +376 -227
  285. package/dist/controllers/submit_once_controller.js.map +1 -1
  286. package/dist/controllers/switch_controller.d.ts +18 -4
  287. package/dist/controllers/switch_controller.js +201 -84
  288. package/dist/controllers/switch_controller.js.map +1 -1
  289. package/dist/controllers/tabs_controller.d.ts +9 -6
  290. package/dist/controllers/tabs_controller.js +41 -30
  291. package/dist/controllers/tabs_controller.js.map +1 -1
  292. package/dist/controllers/tags_input_controller.d.ts +16 -3
  293. package/dist/controllers/tags_input_controller.js +293 -173
  294. package/dist/controllers/tags_input_controller.js.map +1 -1
  295. package/dist/controllers/textarea_autosize_controller.d.ts +11 -1
  296. package/dist/controllers/textarea_autosize_controller.js +108 -74
  297. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  298. package/dist/controllers/theme_controller.d.ts +24 -11
  299. package/dist/controllers/theme_controller.js +140 -116
  300. package/dist/controllers/theme_controller.js.map +1 -1
  301. package/dist/controllers/time_picker_controller.d.ts +55 -5
  302. package/dist/controllers/time_picker_controller.js +331 -127
  303. package/dist/controllers/time_picker_controller.js.map +1 -1
  304. package/dist/controllers/toast_controller.d.ts +40 -16
  305. package/dist/controllers/toast_controller.js +244 -324
  306. package/dist/controllers/toast_controller.js.map +1 -1
  307. package/dist/controllers/toggle_group_controller.d.ts +14 -6
  308. package/dist/controllers/toggle_group_controller.js +252 -191
  309. package/dist/controllers/toggle_group_controller.js.map +1 -1
  310. package/dist/controllers/toolbar_controller.d.ts +8 -6
  311. package/dist/controllers/toolbar_controller.js +219 -120
  312. package/dist/controllers/toolbar_controller.js.map +1 -1
  313. package/dist/controllers/tooltip_controller.d.ts +49 -4
  314. package/dist/controllers/tooltip_controller.js +158 -124
  315. package/dist/controllers/tooltip_controller.js.map +1 -1
  316. package/dist/controllers/transition_controller.d.ts +22 -4
  317. package/dist/controllers/transition_controller.js +123 -119
  318. package/dist/controllers/transition_controller.js.map +1 -1
  319. package/dist/controllers/tree_view_controller.d.ts +22 -12
  320. package/dist/controllers/tree_view_controller.js +283 -369
  321. package/dist/controllers/tree_view_controller.js.map +1 -1
  322. package/dist/index.d.ts +10 -5
  323. package/dist/index.js +8573 -10410
  324. package/dist/index.js.map +1 -1
  325. package/dist/inspector/cli.d.ts +38 -14
  326. package/dist/inspector/cli.js +108 -40
  327. package/dist/inspector/cli.js.map +1 -1
  328. package/dist/inspector/cli_bin.js +145 -64
  329. package/dist/inspector/cli_bin.js.map +1 -1
  330. package/dist/inspector/examples.json +20 -20
  331. package/dist/inspector/manifest.json +802 -101
  332. package/dist/positioning/index.d.ts +15 -7
  333. package/dist/positioning/index.js +154 -47
  334. package/dist/positioning/index.js.map +1 -1
  335. package/package.json +11 -10
  336. package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
  337. package/dist/controllers/reset_before_cache_controller.js.map +0 -1
@@ -1,73 +1,62 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/announcer_controller.ts
4
-
5
- // src/utils/before_cache_reset.ts
6
- var BeforeCacheReset = class _BeforeCacheReset {
7
- /** Every subscribed instance, iterated by the one shared document listener. */
8
- static #subscribers = /* @__PURE__ */ new Set();
9
- /** The shared listener; installed while at least one instance is subscribed. */
10
- static #onBeforeCache = () => {
11
- for (const subscriber of _BeforeCacheReset.#subscribers) subscriber.#rewind();
12
- };
13
- #rewind;
14
- /** @param rewind - the pass that returns this controller's state to its initial form. */
15
- constructor(rewind) {
16
- this.#rewind = rewind;
17
- }
18
- /** Subscribes to `turbo:before-cache`; call from `connect()`. Idempotent. */
19
- activate() {
20
- const first = _BeforeCacheReset.#subscribers.size === 0;
21
- _BeforeCacheReset.#subscribers.add(this);
22
- if (first) {
23
- document.addEventListener("turbo:before-cache", _BeforeCacheReset.#onBeforeCache);
3
+ var DetachGate = class _DetachGate {
4
+ #pending = false;
5
+ get pending() {
6
+ return this.#pending;
7
+ }
8
+ static isDetached(host) {
9
+ return !host.element.isConnected || !_DetachGate.#listed(host);
10
+ }
11
+ disconnected(host, teardown) {
12
+ const carried = _DetachGate.#carried(host);
13
+ if (!carried && _DetachGate.isDetached(host)) {
14
+ this.#pending = false;
15
+ teardown();
16
+ return;
24
17
  }
18
+ this.#pending = true;
19
+ const probe = () => {
20
+ if (!this.#pending) return;
21
+ this.#pending = false;
22
+ teardown();
23
+ };
24
+ if (carried) setTimeout(probe, 0);
25
+ else queueMicrotask(probe);
26
+ }
27
+ static #carried(host) {
28
+ const element = host.element;
29
+ return !element.isConnected && element.closest("[data-turbo-permanent]") !== null && _DetachGate.#listed(host);
30
+ }
31
+ static #listed(host) {
32
+ const tokens = (host.element.getAttribute("data-controller") ?? "").split(/\s+/);
33
+ return tokens.includes(host.identifier);
25
34
  }
26
- /** Unsubscribes; call from `disconnect()`. Safe when never subscribed. */
27
- deactivate() {
28
- _BeforeCacheReset.#subscribers.delete(this);
29
- if (_BeforeCacheReset.#subscribers.size > 0) return;
30
- document.removeEventListener("turbo:before-cache", _BeforeCacheReset.#onBeforeCache);
35
+ cancel() {
36
+ this.#pending = false;
31
37
  }
32
38
  };
33
39
 
34
- // src/utils/safe_timeout.ts
40
+ var MAX_TIMER_DELAY_MS = 2147483647;
41
+
35
42
  var TimerRegistry = class {
36
- /** Live timer ids that have not yet been cleared (or, for timeouts, fired). */
37
43
  ids = /* @__PURE__ */ new Set();
38
- /**
39
- * Cancels a single tracked timer.
40
- *
41
- * No-ops if the id is unknown (already cleared, fired, or never owned by this
42
- * registry), so callers can clear defensively without guarding.
43
- */
44
44
  clear(id) {
45
45
  if (this.ids.delete(id)) {
46
46
  this.cancel(id);
47
47
  }
48
48
  }
49
- /**
50
- * Cancels every tracked timer. Call this from a controller's `disconnect()`
51
- * to guarantee no timer outlives the element.
52
- */
53
49
  clearAll() {
54
50
  for (const id of this.ids) {
55
51
  this.cancel(id);
56
52
  }
57
53
  this.ids.clear();
58
54
  }
59
- /** Number of timers currently tracked (pending). */
60
55
  get size() {
61
56
  return this.ids.size;
62
57
  }
63
58
  };
64
59
  var SafeTimeout = class extends TimerRegistry {
65
- /**
66
- * Schedules `callback` after `delay` ms and returns the timer id.
67
- *
68
- * The id is removed from the registry automatically when the timeout fires,
69
- * so {@link TimerRegistry.size | size} reflects only still-pending timers.
70
- */
71
60
  set(callback, delay) {
72
61
  const id = this.schedule(() => {
73
62
  this.ids.delete(id);
@@ -84,16 +73,9 @@ var SafeTimeout = class extends TimerRegistry {
84
73
  }
85
74
  };
86
75
 
87
- // src/utils/keyed_timers.ts
88
76
  var KeyedTimers = class {
89
77
  #timers = new SafeTimeout();
90
- /** The pending timer of each key; an entry lives exactly as long as its timer. */
91
78
  #pending = /* @__PURE__ */ new Map();
92
- /**
93
- * Arms `callback` after `delay` ms for `key`, cancelling the timer `key` had
94
- * pending. The entry is dropped before the callback runs, so the callback sees
95
- * the key unarmed and may arm it again for the next round.
96
- */
97
79
  set(key, callback, delay) {
98
80
  this.clear(key);
99
81
  const id = this.#timers.set(() => {
@@ -102,52 +84,49 @@ var KeyedTimers = class {
102
84
  }, delay);
103
85
  this.#pending.set(key, id);
104
86
  }
105
- /**
106
- * Cancels `key`'s pending timer, if it has one.
107
- *
108
- * A timer id is a positive integer, so `-1` stands for "nothing pending" and
109
- * the registry ignores an id it does not own — the unarmed case needs no
110
- * branch of its own, and no other key's timer can be reached from here.
111
- */
112
87
  clear(key) {
113
88
  this.#timers.clear(this.#pending.get(key) ?? -1);
114
89
  this.#pending.delete(key);
115
90
  }
116
- /**
117
- * Cancels every pending timer and forgets every key. Call this from a
118
- * controller's `disconnect()` so no timer, and no entry, outlives the element.
119
- */
120
91
  clearAll() {
121
92
  this.#timers.clearAll();
122
93
  this.#pending.clear();
123
94
  }
124
- /** Whether `key` has a timer pending. */
125
95
  has(key) {
126
96
  return this.#pending.has(key);
127
97
  }
128
98
  };
129
99
 
130
- // src/utils/microtask_coalescer.ts
100
+ var ListenerSet = class {
101
+ #abort = new AbortController();
102
+ add(target, type, handler, options) {
103
+ target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
104
+ }
105
+ dispose() {
106
+ this.#abort.abort();
107
+ this.#abort = new AbortController();
108
+ }
109
+ };
110
+
131
111
  var MicrotaskCoalescer = class {
132
112
  #run;
133
113
  #queued = false;
134
114
  #active = false;
135
115
  #generation = 0;
136
- /** @param run - the single reconciliation pass, invoked at most once per batch. */
137
116
  constructor(run) {
138
117
  this.#run = run;
139
118
  }
140
- /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */
141
119
  activate() {
142
120
  this.#active = true;
143
121
  }
144
- /** Closes the window and drops any pending pass; call from `disconnect()`. */
145
122
  cancel() {
146
123
  this.#active = false;
147
124
  this.#queued = false;
148
125
  this.#generation += 1;
149
126
  }
150
- /** Requests one pass after the batch settles. Idempotent; inert outside the window. */
127
+ get pending() {
128
+ return this.#queued;
129
+ }
151
130
  schedule() {
152
131
  if (!this.#active || this.#queued) return;
153
132
  this.#queued = true;
@@ -160,49 +139,168 @@ var MicrotaskCoalescer = class {
160
139
  }
161
140
  };
162
141
 
163
- // src/controllers/announcer_controller.ts
142
+ var NUMBER_BOUNDS = {
143
+ timer: { finite: true, min: 0, max: MAX_TIMER_DELAY_MS }};
144
+ function matchesNumberBounds(value, bounds) {
145
+ if (!Number.isFinite(value)) {
146
+ const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
147
+ if (direction === null) return false;
148
+ if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
149
+ }
150
+ if (bounds.min !== void 0 && value < bounds.min) return false;
151
+ if (bounds.max !== void 0 && value > bounds.max) return false;
152
+ if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
153
+ if (bounds.integer && !Number.isInteger(value)) return false;
154
+ if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
155
+ return true;
156
+ }
157
+
158
+ function readNumber(raw, fallback, bounds) {
159
+ return matchesNumberBounds(raw, bounds) ? raw : fallback;
160
+ }
161
+
162
+ var NumberValueReader = class {
163
+ #lastRejected = /* @__PURE__ */ new Map();
164
+ read(owner, name, raw, fallback, bounds) {
165
+ const resolved = readNumber(raw, fallback, bounds);
166
+ if (matchesNumberBounds(raw, bounds)) {
167
+ this.#lastRejected.delete(name);
168
+ return resolved;
169
+ }
170
+ const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;
171
+ const literal = owner.element.getAttribute(attribute);
172
+ if (literal === null) {
173
+ this.#lastRejected.delete(name);
174
+ return resolved;
175
+ }
176
+ if (this.#lastRejected.get(name) !== literal) {
177
+ this.#lastRejected.set(name, literal);
178
+ console.warn(
179
+ `Stimeo UI: "${owner.identifier}" has an invalid number Value "${name}" declaration ${JSON.stringify(literal)}; using ${fallback}.`
180
+ );
181
+ }
182
+ return resolved;
183
+ }
184
+ };
185
+
186
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
187
+ if (element.getAttribute(name) === value) return false;
188
+ if (value === null) element.removeAttribute(name);
189
+ else element.setAttribute(name, value);
190
+ return true;
191
+ }
192
+
193
+ var OwnedText = class {
194
+ #attribute;
195
+ #channel;
196
+ #guard;
197
+ #writes = /* @__PURE__ */ new WeakMap();
198
+ constructor(attribute, channel = "text", guard = () => true) {
199
+ this.#attribute = attribute;
200
+ this.#channel = channel;
201
+ this.#guard = guard;
202
+ }
203
+ hasRecord(element) {
204
+ return element.hasAttribute(this.#attribute);
205
+ }
206
+ read(element, evidence = {}) {
207
+ if (evidence.source === "live") return this.#writes.get(element) ?? null;
208
+ const raw = element.getAttribute(this.#attribute);
209
+ if (raw === null) return null;
210
+ try {
211
+ const record = JSON.parse(raw);
212
+ if (!Array.isArray(record) || record.length !== 3 || record[0] !== this.#channel || typeof record[1] !== "string" || typeof record[2] !== "string")
213
+ return null;
214
+ return { original: record[1], written: record[2] };
215
+ } catch {
216
+ return null;
217
+ }
218
+ }
219
+ owns(element, evidence = {}) {
220
+ return this.#ownedRecord(element, evidence) !== null;
221
+ }
222
+ #ownedRecord(element, evidence) {
223
+ const record = this.read(element, evidence);
224
+ if (record === null || !this.#guard(element)) return null;
225
+ if (this.#channel === "text" && element.firstElementChild !== null) return null;
226
+ const current = this.#current(element);
227
+ return current === record.written || evidence.source === "live" && evidence.allowOriginal === true && current === record.original ? record : null;
228
+ }
229
+ write(element, written, original, force = false) {
230
+ const current = this.#current(element);
231
+ if (current === null) return;
232
+ const before = original ?? this.#writes.get(element)?.original ?? this.read(element)?.original ?? current;
233
+ if (force || current !== written) this.#put(element, written);
234
+ this.remember(element, written, before);
235
+ }
236
+ remember(element, written, original) {
237
+ const current = this.#current(element);
238
+ if (current === null) return;
239
+ const before = original ?? this.#writes.get(element)?.original ?? this.read(element)?.original ?? current;
240
+ this.#writes.set(element, { original: before, written });
241
+ setAttributeIfChanged(
242
+ element,
243
+ this.#attribute,
244
+ JSON.stringify([this.#channel, before, written])
245
+ );
246
+ }
247
+ clear(element, evidence = {}) {
248
+ if (!this.owns(element, evidence)) return false;
249
+ if (this.#current(element) !== "") this.#put(element, "");
250
+ this.forget(element);
251
+ return true;
252
+ }
253
+ restore(element, evidence = {}) {
254
+ const record = this.#ownedRecord(element, evidence);
255
+ if (record === null) return false;
256
+ if (this.#current(element) !== record.original) this.#put(element, record.original);
257
+ this.forget(element);
258
+ return true;
259
+ }
260
+ forget(element) {
261
+ setAttributeIfChanged(element, this.#attribute, null);
262
+ this.#writes.delete(element);
263
+ }
264
+ #current(element) {
265
+ if (this.#channel === "text") return element.textContent ?? "";
266
+ return element instanceof HTMLInputElement ? element.value : null;
267
+ }
268
+ #put(element, text) {
269
+ if (this.#channel === "text") element.textContent = text;
270
+ else if (element instanceof HTMLInputElement) element.value = text;
271
+ }
272
+ };
273
+
164
274
  var LEVELS = ["polite", "assertive"];
165
- var AnnouncerController = class extends Controller {
275
+ var STAND_IN = "stand-in";
276
+ var ANNOUNCED = "announced";
277
+ var AnnouncerController = class _AnnouncerController extends Controller {
278
+ #numbers = new NumberValueReader();
166
279
  static targets = ["polite", "assertive"];
167
280
  static values = {
168
281
  clearAfter: { type: Number, default: 1e3 },
169
282
  dedupeReannounce: { type: Boolean, default: true }
170
283
  };
284
+ static valueConstraints = {
285
+ clearAfter: NUMBER_BOUNDS.timer
286
+ };
171
287
  static actions = ["announce"];
172
- /** Drain timers, which belong to a politeness level rather than to a region. */
173
288
  #timers = new SafeTimeout();
174
- /**
175
- * The one timer a region may have outstanding — its dedupe re-set, then its
176
- * auto-clear. A region carries at most one, and the registry releases the
177
- * previous one whenever a newer message takes the region over.
178
- */
289
+ #gate = new DetachGate();
290
+ #listeners = new ListenerSet();
179
291
  #regionTimers = new KeyedTimers();
180
- /** Live regions generated to stand in for absent targets, for teardown. */
181
292
  #generated = /* @__PURE__ */ new Map();
182
- /** Messages waiting to be written, oldest first, one queue per politeness. */
293
+ get #standIn() {
294
+ return `data-${this.identifier}-${STAND_IN}`;
295
+ }
296
+ #messageText = new OwnedText(`data-${this.identifier}-${ANNOUNCED}`);
183
297
  #queues = /* @__PURE__ */ new Map();
184
- /** Politeness levels whose next drain is already armed. */
185
298
  #draining = /* @__PURE__ */ new Set();
186
- /** Collapses a batch of target callbacks (and morph removals) into one pass. */
187
299
  #reconcile = new MicrotaskCoalescer(() => this.#reconcileRegions());
188
- /**
189
- * Watches the host's own children for a generated region disappearing. A morph
190
- * drops it — the server's HTML never had it — and no target callback reports
191
- * that, because a generated region carries no target attribute. `subtree` stays
192
- * off so writing a message inside a region does not re-enter this pass.
193
- */
194
300
  #hostWatch = new MutationObserver(() => {
195
301
  this.#reconcile.schedule();
196
302
  });
197
- /** Rewinds to an announceable initial state for the snapshot; see the remarks. */
198
- #beforeCache = new BeforeCacheReset(() => this.#rewindForCache());
199
- /**
200
- * Guards against handling the same CustomEvent twice. An event dispatched on
201
- * the controller element with `bubbles: true` reaches both the element and the
202
- * `window` listener; this WeakSet ensures it announces only once.
203
- */
204
303
  #handled = /* @__PURE__ */ new WeakSet();
205
- /** Receives programmatic announcements at the element or bubbled to `window`. */
206
304
  #onAnnounceEvent = (event) => {
207
305
  if (this.#handled.has(event)) return;
208
306
  this.#handled.add(event);
@@ -212,58 +310,47 @@ var AnnouncerController = class extends Controller {
212
310
  this.#announce(message, this.#assertiveFromDetail(detail));
213
311
  };
214
312
  connect() {
313
+ const moved = this.#gate.pending;
314
+ this.#gate.cancel();
315
+ if (moved) return;
215
316
  this.#reconcile.activate();
216
- this.#beforeCache.activate();
317
+ this.#dropInheritedStandIns();
318
+ this.#emptyInheritedMessages();
217
319
  this.#reconcileRegions();
218
320
  this.#hostWatch.observe(this.element, { childList: true });
219
- this.element.addEventListener("stimeo--announcer:announce", this.#onAnnounceEvent);
220
- window.addEventListener("stimeo--announcer:announce", this.#onAnnounceEvent);
321
+ this.#listeners.add(this.element, "stimeo--announcer:announce", this.#onAnnounceEvent);
322
+ this.#listeners.add(window, "stimeo--announcer:announce", this.#onAnnounceEvent);
221
323
  }
222
324
  disconnect() {
325
+ this.#gate.disconnected(this, () => this.#teardown());
326
+ }
327
+ #teardown() {
223
328
  this.#reconcile.cancel();
224
329
  this.#hostWatch.disconnect();
225
- this.#beforeCache.deactivate();
226
- this.element.removeEventListener("stimeo--announcer:announce", this.#onAnnounceEvent);
227
- window.removeEventListener("stimeo--announcer:announce", this.#onAnnounceEvent);
330
+ this.#listeners.dispose();
228
331
  this.#timers.clearAll();
229
332
  this.#regionTimers.clearAll();
230
333
  this.#queues.clear();
231
334
  this.#draining.clear();
232
335
  this.#removeGenerated();
233
336
  }
234
- /** Retires the stand-in once the consumer supplies a polite region. */
235
337
  politeTargetConnected() {
236
338
  this.#reconcile.schedule();
237
339
  }
238
- /** Materialises a stand-in once the consumer's polite region goes away. */
239
340
  politeTargetDisconnected() {
240
341
  this.#reconcile.schedule();
241
342
  }
242
- /** Retires the stand-in once the consumer supplies an assertive region. */
243
343
  assertiveTargetConnected() {
244
344
  this.#reconcile.schedule();
245
345
  }
246
- /** Materialises a stand-in once the consumer's assertive region goes away. */
247
346
  assertiveTargetDisconnected() {
248
347
  this.#reconcile.schedule();
249
348
  }
250
- /**
251
- * Brings the region set back to exactly one region per politeness and reports
252
- * whether anything had to be created.
253
- *
254
- * A region created here is not written to in the same task: assistive tech
255
- * reports changes to regions it already knows about, so {@link drain} waits a
256
- * task whenever this says a region is new.
257
- */
258
349
  #reconcileRegions() {
259
350
  let created = false;
260
351
  for (const level of LEVELS) {
261
352
  if (this.#hasTargetFor(level)) {
262
- const generated = this.#generated.get(level);
263
- if (generated) {
264
- generated.remove();
265
- this.#generated.delete(level);
266
- }
353
+ this.#generated.get(level)?.remove();
267
354
  continue;
268
355
  }
269
356
  const existing = this.#generated.get(level);
@@ -273,38 +360,31 @@ var AnnouncerController = class extends Controller {
273
360
  }
274
361
  return created;
275
362
  }
276
- /** Whether the consumer supplied a target for `level`. */
277
363
  #hasTargetFor(level) {
278
364
  return level === "assertive" ? this.hasAssertiveTarget : this.hasPoliteTarget;
279
365
  }
280
- /** Builds a visually hidden live region for `level` and attaches it. */
281
366
  #createRegion(level) {
282
367
  const region = document.createElement("div");
283
368
  region.setAttribute("aria-live", level);
284
369
  region.setAttribute("aria-atomic", "true");
370
+ region.setAttribute(this.#standIn, "");
285
371
  visuallyHide(region);
286
372
  this.element.appendChild(region);
287
373
  return region;
288
374
  }
289
- /**
290
- * Removes and forgets every region this controller generated. Authored targets
291
- * belong to the consumer and are left untouched. Forgetting them is what keeps
292
- * the live page working after a snapshot rewind: the next announcement finds an
293
- * empty map and materialises a fresh region.
294
- */
295
- #removeGenerated() {
296
- for (const region of this.#generated.values()) {
297
- region.remove();
375
+ #dropInheritedStandIns() {
376
+ for (const child of Array.from(this.element.children)) {
377
+ if (child.hasAttribute(this.#standIn)) child.remove();
378
+ }
379
+ }
380
+ #emptyInheritedMessages() {
381
+ for (const region of [...this.politeTargets, ...this.assertiveTargets]) {
382
+ this.#messageText.clear(region);
298
383
  }
299
- this.#generated.clear();
300
- }
301
- /**
302
- * Announces a message. Reads the text from a Stimulus action param
303
- * (`message`, plus optional `assertive`) for attribute-only triggers, falling
304
- * back to a CustomEvent `detail` when the same handler is wired to an event.
305
- * An empty/non-string message is ignored so untrusted payloads cannot blank
306
- * the region.
307
- */
384
+ }
385
+ #removeGenerated() {
386
+ for (const region of this.#generated.values()) region.remove();
387
+ }
308
388
  announce(event) {
309
389
  const params = event.params;
310
390
  const fromParam = params?.message;
@@ -313,13 +393,6 @@ var AnnouncerController = class extends Controller {
313
393
  const assertive = params?.assertive === true || this.#assertiveFromDetail(event.detail);
314
394
  this.#announce(message, assertive);
315
395
  }
316
- /**
317
- * Queues `message` for its politeness and arms the drain.
318
- *
319
- * Queuing is what makes a burst audible: assistive tech announces the changes it
320
- * observes, so several messages written into one region within a single task are
321
- * one change and only the last is read.
322
- */
323
396
  #announce(message, assertive) {
324
397
  const level = assertive ? "assertive" : "polite";
325
398
  const queue = this.#queues.get(level);
@@ -330,7 +403,6 @@ var AnnouncerController = class extends Controller {
330
403
  }
331
404
  this.#scheduleDrain(level);
332
405
  }
333
- /** Arms one drain pass for `level`; further messages ride the pass already armed. */
334
406
  #scheduleDrain(level) {
335
407
  if (this.#draining.has(level)) return;
336
408
  this.#draining.add(level);
@@ -339,89 +411,43 @@ var AnnouncerController = class extends Controller {
339
411
  this.#drain(level);
340
412
  }, 0);
341
413
  }
342
- /**
343
- * Writes one queued message, then arms the next pass while the queue holds more.
344
- *
345
- * Two steps take a whole pass without consuming the message: materialising a
346
- * region (it has to be in the accessibility tree before the text arrives) and
347
- * emptying a region that already holds this exact text (an unchanged node is not
348
- * re-read, so `dedupeReannounce` clears first and writes on the following pass).
349
- *
350
- * @stimeoRuntimeOnly `dedupeReannounce` decides whether one queued message is spoken again; the
351
- * region's text is the message itself.
352
- */
353
414
  #drain(level) {
354
415
  const queue = this.#queues.get(level);
355
416
  const message = queue?.[0];
356
417
  if (queue === void 0 || message === void 0) return;
357
- if (this.#reconcileRegions()) {
418
+ const created = this.#reconcileRegions();
419
+ const region = this.#regionFor(level);
420
+ if (created || region === void 0) {
358
421
  this.#scheduleDrain(level);
359
422
  return;
360
423
  }
361
- const region = this.#regionFor(level);
362
424
  if (this.dedupeReannounceValue && region.textContent === message) {
363
- this.#regionTimers.clear(region);
364
425
  region.textContent = "";
426
+ this.#messageText.forget(region);
365
427
  this.#scheduleDrain(level);
366
428
  return;
367
429
  }
368
430
  queue.shift();
369
431
  this.#regionTimers.clear(region);
370
- region.textContent = message;
371
- this.#scheduleClear(region, message);
432
+ this.#messageText.write(region, message, void 0, true);
433
+ this.#scheduleClear(region);
372
434
  if (queue.length > 0) this.#scheduleDrain(level);
373
435
  }
374
- /**
375
- * Clears the region after `clearAfter` ms, unless a newer message replaced it.
376
- *
377
- * @stimeoRuntimeOnly `clearAfter` is the delay of the one clearing timer this call arms.
378
- */
379
- #scheduleClear(region, message) {
380
- if (this.clearAfterValue <= 0) return;
436
+ #scheduleClear(region) {
437
+ if (this.#safeClearAfter <= 0) return;
381
438
  this.#regionTimers.set(
382
439
  region,
383
440
  () => {
384
- if (region.textContent === message) region.textContent = "";
441
+ this.#messageText.clear(region);
385
442
  },
386
- this.clearAfterValue
443
+ this.#safeClearAfter
387
444
  );
388
445
  }
389
- /**
390
- * Resolves the live region for a politeness level.
391
- *
392
- * The remembered stand-in is used only while it is still in the document: a morph
393
- * can drop it, and writing into the detached node would announce nothing at all.
394
- */
395
446
  #regionFor(level) {
396
447
  if (level === "assertive" && this.hasAssertiveTarget) return this.assertiveTarget;
397
448
  if (level === "polite" && this.hasPoliteTarget) return this.politeTarget;
398
- const existing = this.#generated.get(level);
399
- if (existing?.isConnected) return existing;
400
- const region = this.#createRegion(level);
401
- this.#generated.set(level, region);
402
- return region;
403
- }
404
- /**
405
- * Restores the announceable initial state for the snapshot Turbo is about to
406
- * take: queued and displayed messages go, generated regions go, and the live
407
- * page — which keeps running when a visit is aborted — gets its regions back on
408
- * the next task, after the clone.
409
- */
410
- #rewindForCache() {
411
- this.#queues.clear();
412
- this.#draining.clear();
413
- this.#timers.clearAll();
414
- this.#regionTimers.clearAll();
415
- for (const level of LEVELS) {
416
- if (this.#hasTargetFor(level)) {
417
- const target = level === "assertive" ? this.assertiveTarget : this.politeTarget;
418
- target.textContent = "";
419
- }
420
- }
421
- this.#removeGenerated();
422
- this.#timers.set(() => this.#reconcileRegions(), 0);
449
+ return this.#generated.get(level);
423
450
  }
424
- /** Extracts a non-empty string `message` from a CustomEvent detail, else null. */
425
451
  #messageFromDetail(detail) {
426
452
  if (detail && typeof detail === "object" && "message" in detail) {
427
453
  const value = detail.message;
@@ -429,10 +455,18 @@ var AnnouncerController = class extends Controller {
429
455
  }
430
456
  return null;
431
457
  }
432
- /** Reads an `assertive === true` flag from a CustomEvent detail (default polite). */
433
458
  #assertiveFromDetail(detail) {
434
459
  return !!detail && typeof detail === "object" && detail.assertive === true;
435
460
  }
461
+ get #safeClearAfter() {
462
+ return this.#numbers.read(
463
+ this,
464
+ "clearAfter",
465
+ this.clearAfterValue,
466
+ _AnnouncerController.values.clearAfter.default,
467
+ _AnnouncerController.valueConstraints.clearAfter
468
+ );
469
+ }
436
470
  };
437
471
  function visuallyHide(node) {
438
472
  const { style } = node;
@@ -449,5 +483,4 @@ function visuallyHide(node) {
449
483
  }
450
484
 
451
485
  export { AnnouncerController, visuallyHide };
452
- //# sourceMappingURL=announcer_controller.js.map
453
486
  //# sourceMappingURL=announcer_controller.js.map