stimeo-ui 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/README.md +128 -1
  3. package/dist/cable/index.d.ts +79 -23
  4. package/dist/cable/index.js +392 -417
  5. package/dist/cable/index.js.map +1 -1
  6. package/dist/controllers/accordion_controller.d.ts +34 -5
  7. package/dist/controllers/accordion_controller.js +228 -28
  8. package/dist/controllers/accordion_controller.js.map +1 -1
  9. package/dist/controllers/alert_dialog_controller.d.ts +20 -9
  10. package/dist/controllers/alert_dialog_controller.js +862 -221
  11. package/dist/controllers/alert_dialog_controller.js.map +1 -1
  12. package/dist/controllers/announcer_controller.d.ts +38 -7
  13. package/dist/controllers/announcer_controller.js +135 -191
  14. package/dist/controllers/announcer_controller.js.map +1 -1
  15. package/dist/controllers/aspect_ratio_controller.js +0 -10
  16. package/dist/controllers/aspect_ratio_controller.js.map +1 -1
  17. package/dist/controllers/auto_submit_controller.d.ts +30 -6
  18. package/dist/controllers/auto_submit_controller.js +295 -110
  19. package/dist/controllers/auto_submit_controller.js.map +1 -1
  20. package/dist/controllers/avatar_controller.js +172 -106
  21. package/dist/controllers/avatar_controller.js.map +1 -1
  22. package/dist/controllers/breadcrumb_controller.d.ts +10 -7
  23. package/dist/controllers/breadcrumb_controller.js +0 -129
  24. package/dist/controllers/breadcrumb_controller.js.map +1 -1
  25. package/dist/controllers/bulk_select_controller.d.ts +22 -4
  26. package/dist/controllers/bulk_select_controller.js +264 -53
  27. package/dist/controllers/bulk_select_controller.js.map +1 -1
  28. package/dist/controllers/calendar_controller.d.ts +109 -28
  29. package/dist/controllers/calendar_controller.js +346 -180
  30. package/dist/controllers/calendar_controller.js.map +1 -1
  31. package/dist/controllers/carousel_controller.d.ts +99 -27
  32. package/dist/controllers/carousel_controller.js +587 -300
  33. package/dist/controllers/carousel_controller.js.map +1 -1
  34. package/dist/controllers/character_counter_controller.d.ts +18 -2
  35. package/dist/controllers/character_counter_controller.js +271 -143
  36. package/dist/controllers/character_counter_controller.js.map +1 -1
  37. package/dist/controllers/checkbox_controller.d.ts +7 -2
  38. package/dist/controllers/checkbox_controller.js +77 -75
  39. package/dist/controllers/checkbox_controller.js.map +1 -1
  40. package/dist/controllers/clipboard_controller.d.ts +44 -7
  41. package/dist/controllers/clipboard_controller.js +187 -108
  42. package/dist/controllers/clipboard_controller.js.map +1 -1
  43. package/dist/controllers/collapsible_controller.d.ts +41 -5
  44. package/dist/controllers/collapsible_controller.js +374 -108
  45. package/dist/controllers/collapsible_controller.js.map +1 -1
  46. package/dist/controllers/color_picker_controller.d.ts +47 -14
  47. package/dist/controllers/color_picker_controller.js +183 -127
  48. package/dist/controllers/color_picker_controller.js.map +1 -1
  49. package/dist/controllers/combobox_controller.d.ts +33 -6
  50. package/dist/controllers/combobox_controller.js +426 -109
  51. package/dist/controllers/combobox_controller.js.map +1 -1
  52. package/dist/controllers/command_palette_controller.d.ts +45 -14
  53. package/dist/controllers/command_palette_controller.js +994 -350
  54. package/dist/controllers/command_palette_controller.js.map +1 -1
  55. package/dist/controllers/conditional_fields_controller.d.ts +15 -2
  56. package/dist/controllers/conditional_fields_controller.js +212 -125
  57. package/dist/controllers/conditional_fields_controller.js.map +1 -1
  58. package/dist/controllers/confirm_controller.d.ts +49 -12
  59. package/dist/controllers/confirm_controller.js +939 -245
  60. package/dist/controllers/confirm_controller.js.map +1 -1
  61. package/dist/controllers/context_menu_controller.d.ts +36 -3
  62. package/dist/controllers/context_menu_controller.js +275 -127
  63. package/dist/controllers/context_menu_controller.js.map +1 -1
  64. package/dist/controllers/count_up_controller.d.ts +13 -1
  65. package/dist/controllers/count_up_controller.js +73 -21
  66. package/dist/controllers/count_up_controller.js.map +1 -1
  67. package/dist/controllers/countdown_controller.d.ts +75 -2
  68. package/dist/controllers/countdown_controller.js +235 -97
  69. package/dist/controllers/countdown_controller.js.map +1 -1
  70. package/dist/controllers/currency_input_controller.d.ts +93 -15
  71. package/dist/controllers/currency_input_controller.js +241 -118
  72. package/dist/controllers/currency_input_controller.js.map +1 -1
  73. package/dist/controllers/data_grid_controller.d.ts +78 -22
  74. package/dist/controllers/data_grid_controller.js +229 -135
  75. package/dist/controllers/data_grid_controller.js.map +1 -1
  76. package/dist/controllers/date_range_picker_controller.d.ts +64 -11
  77. package/dist/controllers/date_range_picker_controller.js +359 -165
  78. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  79. package/dist/controllers/dialog_controller.d.ts +22 -3
  80. package/dist/controllers/dialog_controller.js +887 -225
  81. package/dist/controllers/dialog_controller.js.map +1 -1
  82. package/dist/controllers/direct_upload_controller.d.ts +24 -7
  83. package/dist/controllers/direct_upload_controller.js +80 -142
  84. package/dist/controllers/direct_upload_controller.js.map +1 -1
  85. package/dist/controllers/dirty_form_controller.d.ts +2 -2
  86. package/dist/controllers/dirty_form_controller.js +26 -47
  87. package/dist/controllers/dirty_form_controller.js.map +1 -1
  88. package/dist/controllers/dismissible_controller.d.ts +19 -0
  89. package/dist/controllers/dismissible_controller.js +175 -20
  90. package/dist/controllers/dismissible_controller.js.map +1 -1
  91. package/dist/controllers/drawer_controller.d.ts +52 -16
  92. package/dist/controllers/drawer_controller.js +963 -336
  93. package/dist/controllers/drawer_controller.js.map +1 -1
  94. package/dist/controllers/dropdown_controller.d.ts +39 -3
  95. package/dist/controllers/dropdown_controller.js +342 -85
  96. package/dist/controllers/dropdown_controller.js.map +1 -1
  97. package/dist/controllers/editable_controller.d.ts +12 -1
  98. package/dist/controllers/editable_controller.js +182 -58
  99. package/dist/controllers/editable_controller.js.map +1 -1
  100. package/dist/controllers/empty_state_controller.js +67 -53
  101. package/dist/controllers/empty_state_controller.js.map +1 -1
  102. package/dist/controllers/file_dropzone_controller.d.ts +60 -18
  103. package/dist/controllers/file_dropzone_controller.js +426 -229
  104. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  105. package/dist/controllers/filter_controller.d.ts +10 -4
  106. package/dist/controllers/filter_controller.js +78 -36
  107. package/dist/controllers/filter_controller.js.map +1 -1
  108. package/dist/controllers/flash_controller.d.ts +57 -14
  109. package/dist/controllers/flash_controller.js +328 -211
  110. package/dist/controllers/flash_controller.js.map +1 -1
  111. package/dist/controllers/focus_controller.d.ts +12 -3
  112. package/dist/controllers/focus_controller.js +654 -239
  113. package/dist/controllers/focus_controller.js.map +1 -1
  114. package/dist/controllers/form_field_controller.js +153 -136
  115. package/dist/controllers/form_field_controller.js.map +1 -1
  116. package/dist/controllers/form_validation_controller.js +29 -96
  117. package/dist/controllers/form_validation_controller.js.map +1 -1
  118. package/dist/controllers/frame_loading_controller.d.ts +41 -9
  119. package/dist/controllers/frame_loading_controller.js +263 -198
  120. package/dist/controllers/frame_loading_controller.js.map +1 -1
  121. package/dist/controllers/highlight_controller.d.ts +22 -2
  122. package/dist/controllers/highlight_controller.js +119 -70
  123. package/dist/controllers/highlight_controller.js.map +1 -1
  124. package/dist/controllers/hover_card_controller.d.ts +65 -4
  125. package/dist/controllers/hover_card_controller.js +335 -118
  126. package/dist/controllers/hover_card_controller.js.map +1 -1
  127. package/dist/controllers/idle_controller.d.ts +58 -4
  128. package/dist/controllers/idle_controller.js +316 -65
  129. package/dist/controllers/idle_controller.js.map +1 -1
  130. package/dist/controllers/input_mask_controller.d.ts +5 -2
  131. package/dist/controllers/input_mask_controller.js +116 -61
  132. package/dist/controllers/input_mask_controller.js.map +1 -1
  133. package/dist/controllers/intersection_controller.d.ts +32 -13
  134. package/dist/controllers/intersection_controller.js +147 -103
  135. package/dist/controllers/intersection_controller.js.map +1 -1
  136. package/dist/controllers/lazy_frame_controller.d.ts +16 -0
  137. package/dist/controllers/lazy_frame_controller.js +9 -56
  138. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  139. package/dist/controllers/listbox_controller.d.ts +84 -10
  140. package/dist/controllers/listbox_controller.js +413 -153
  141. package/dist/controllers/listbox_controller.js.map +1 -1
  142. package/dist/controllers/local_time_controller.d.ts +1 -1
  143. package/dist/controllers/local_time_controller.js +54 -64
  144. package/dist/controllers/local_time_controller.js.map +1 -1
  145. package/dist/controllers/masonry_controller.d.ts +11 -3
  146. package/dist/controllers/masonry_controller.js +70 -95
  147. package/dist/controllers/masonry_controller.js.map +1 -1
  148. package/dist/controllers/menu_controller.d.ts +40 -9
  149. package/dist/controllers/menu_controller.js +254 -167
  150. package/dist/controllers/menu_controller.js.map +1 -1
  151. package/dist/controllers/menubar_controller.d.ts +15 -4
  152. package/dist/controllers/menubar_controller.js +206 -331
  153. package/dist/controllers/menubar_controller.js.map +1 -1
  154. package/dist/controllers/meter_controller.d.ts +20 -0
  155. package/dist/controllers/meter_controller.js +159 -71
  156. package/dist/controllers/meter_controller.js.map +1 -1
  157. package/dist/controllers/multi_select_controller.d.ts +50 -7
  158. package/dist/controllers/multi_select_controller.js +797 -388
  159. package/dist/controllers/multi_select_controller.js.map +1 -1
  160. package/dist/controllers/navigation_menu_controller.d.ts +19 -1
  161. package/dist/controllers/navigation_menu_controller.js +156 -231
  162. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  163. package/dist/controllers/nested_form_controller.d.ts +10 -0
  164. package/dist/controllers/nested_form_controller.js +373 -174
  165. package/dist/controllers/nested_form_controller.js.map +1 -1
  166. package/dist/controllers/network_status_controller.d.ts +23 -0
  167. package/dist/controllers/network_status_controller.js +241 -45
  168. package/dist/controllers/network_status_controller.js.map +1 -1
  169. package/dist/controllers/number_input_controller.d.ts +62 -10
  170. package/dist/controllers/number_input_controller.js +387 -227
  171. package/dist/controllers/number_input_controller.js.map +1 -1
  172. package/dist/controllers/optimistic_controller.js +28 -75
  173. package/dist/controllers/optimistic_controller.js.map +1 -1
  174. package/dist/controllers/otp_controller.d.ts +38 -7
  175. package/dist/controllers/otp_controller.js +344 -196
  176. package/dist/controllers/otp_controller.js.map +1 -1
  177. package/dist/controllers/overflow_indicator_controller.d.ts +13 -12
  178. package/dist/controllers/overflow_indicator_controller.js +167 -93
  179. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  180. package/dist/controllers/overflow_menu_controller.d.ts +66 -9
  181. package/dist/controllers/overflow_menu_controller.js +408 -277
  182. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  183. package/dist/controllers/pagination_controller.d.ts +52 -15
  184. package/dist/controllers/pagination_controller.js +342 -120
  185. package/dist/controllers/pagination_controller.js.map +1 -1
  186. package/dist/controllers/password_reveal_controller.d.ts +60 -9
  187. package/dist/controllers/password_reveal_controller.js +424 -99
  188. package/dist/controllers/password_reveal_controller.js.map +1 -1
  189. package/dist/controllers/password_strength_controller.d.ts +14 -5
  190. package/dist/controllers/password_strength_controller.js +99 -153
  191. package/dist/controllers/password_strength_controller.js.map +1 -1
  192. package/dist/controllers/persist_controller.d.ts +11 -4
  193. package/dist/controllers/persist_controller.js +252 -96
  194. package/dist/controllers/persist_controller.js.map +1 -1
  195. package/dist/controllers/pointer_drag_controller.d.ts +19 -7
  196. package/dist/controllers/pointer_drag_controller.js +263 -164
  197. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  198. package/dist/controllers/popover_controller.d.ts +46 -4
  199. package/dist/controllers/popover_controller.js +267 -94
  200. package/dist/controllers/popover_controller.js.map +1 -1
  201. package/dist/controllers/portal_controller.d.ts +44 -4
  202. package/dist/controllers/portal_controller.js +209 -72
  203. package/dist/controllers/portal_controller.js.map +1 -1
  204. package/dist/controllers/preview_guard_controller.d.ts +10 -4
  205. package/dist/controllers/preview_guard_controller.js +243 -112
  206. package/dist/controllers/preview_guard_controller.js.map +1 -1
  207. package/dist/controllers/progress_controller.d.ts +11 -0
  208. package/dist/controllers/progress_controller.js +132 -59
  209. package/dist/controllers/progress_controller.js.map +1 -1
  210. package/dist/controllers/radio_group_controller.d.ts +19 -8
  211. package/dist/controllers/radio_group_controller.js +138 -133
  212. package/dist/controllers/radio_group_controller.js.map +1 -1
  213. package/dist/controllers/range_slider_controller.d.ts +92 -4
  214. package/dist/controllers/range_slider_controller.js +245 -112
  215. package/dist/controllers/range_slider_controller.js.map +1 -1
  216. package/dist/controllers/rating_controller.d.ts +33 -6
  217. package/dist/controllers/rating_controller.js +429 -194
  218. package/dist/controllers/rating_controller.js.map +1 -1
  219. package/dist/controllers/read_more_controller.d.ts +26 -2
  220. package/dist/controllers/read_more_controller.js +185 -47
  221. package/dist/controllers/read_more_controller.js.map +1 -1
  222. package/dist/controllers/reading_progress_controller.d.ts +1 -1
  223. package/dist/controllers/reading_progress_controller.js +147 -135
  224. package/dist/controllers/reading_progress_controller.js.map +1 -1
  225. package/dist/controllers/relative_time_controller.d.ts +18 -4
  226. package/dist/controllers/relative_time_controller.js +145 -110
  227. package/dist/controllers/relative_time_controller.js.map +1 -1
  228. package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
  229. package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +97 -38
  230. package/dist/controllers/reset_on_restore_controller.js.map +1 -0
  231. package/dist/controllers/resizable_controller.d.ts +44 -4
  232. package/dist/controllers/resizable_controller.js +294 -118
  233. package/dist/controllers/resizable_controller.js.map +1 -1
  234. package/dist/controllers/roving_controller.js +39 -84
  235. package/dist/controllers/roving_controller.js.map +1 -1
  236. package/dist/controllers/scroll_area_controller.d.ts +7 -3
  237. package/dist/controllers/scroll_area_controller.js +428 -221
  238. package/dist/controllers/scroll_area_controller.js.map +1 -1
  239. package/dist/controllers/scroll_restore_controller.js +0 -53
  240. package/dist/controllers/scroll_restore_controller.js.map +1 -1
  241. package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
  242. package/dist/controllers/scroll_visibility_controller.js +395 -146
  243. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  244. package/dist/controllers/scrollspy_controller.d.ts +9 -3
  245. package/dist/controllers/scrollspy_controller.js +181 -236
  246. package/dist/controllers/scrollspy_controller.js.map +1 -1
  247. package/dist/controllers/separator_controller.d.ts +59 -17
  248. package/dist/controllers/separator_controller.js +288 -132
  249. package/dist/controllers/separator_controller.js.map +1 -1
  250. package/dist/controllers/sidebar_controller.d.ts +81 -7
  251. package/dist/controllers/sidebar_controller.js +1071 -375
  252. package/dist/controllers/sidebar_controller.js.map +1 -1
  253. package/dist/controllers/skeleton_controller.d.ts +23 -0
  254. package/dist/controllers/skeleton_controller.js +248 -92
  255. package/dist/controllers/skeleton_controller.js.map +1 -1
  256. package/dist/controllers/slider_controller.d.ts +72 -8
  257. package/dist/controllers/slider_controller.js +211 -96
  258. package/dist/controllers/slider_controller.js.map +1 -1
  259. package/dist/controllers/smart_sticky_header_controller.d.ts +21 -3
  260. package/dist/controllers/smart_sticky_header_controller.js +163 -54
  261. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  262. package/dist/controllers/sortable_controller.js +13 -110
  263. package/dist/controllers/sortable_controller.js.map +1 -1
  264. package/dist/controllers/spinner_controller.d.ts +39 -4
  265. package/dist/controllers/spinner_controller.js +277 -161
  266. package/dist/controllers/spinner_controller.js.map +1 -1
  267. package/dist/controllers/step_indicator_controller.d.ts +24 -17
  268. package/dist/controllers/step_indicator_controller.js +107 -53
  269. package/dist/controllers/step_indicator_controller.js.map +1 -1
  270. package/dist/controllers/stepper_controller.d.ts +43 -9
  271. package/dist/controllers/stepper_controller.js +171 -48
  272. package/dist/controllers/stepper_controller.js.map +1 -1
  273. package/dist/controllers/stick_to_bottom_controller.d.ts +25 -0
  274. package/dist/controllers/stick_to_bottom_controller.js +310 -116
  275. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  276. package/dist/controllers/sticky_observer_controller.d.ts +11 -0
  277. package/dist/controllers/sticky_observer_controller.js +214 -49
  278. package/dist/controllers/sticky_observer_controller.js.map +1 -1
  279. package/dist/controllers/submit_once_controller.d.ts +22 -6
  280. package/dist/controllers/submit_once_controller.js +294 -192
  281. package/dist/controllers/submit_once_controller.js.map +1 -1
  282. package/dist/controllers/switch_controller.d.ts +40 -7
  283. package/dist/controllers/switch_controller.js +107 -43
  284. package/dist/controllers/switch_controller.js.map +1 -1
  285. package/dist/controllers/tabs_controller.d.ts +13 -1
  286. package/dist/controllers/tabs_controller.js +50 -25
  287. package/dist/controllers/tabs_controller.js.map +1 -1
  288. package/dist/controllers/tags_input_controller.d.ts +27 -3
  289. package/dist/controllers/tags_input_controller.js +290 -149
  290. package/dist/controllers/tags_input_controller.js.map +1 -1
  291. package/dist/controllers/textarea_autosize_controller.d.ts +10 -0
  292. package/dist/controllers/textarea_autosize_controller.js +71 -58
  293. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  294. package/dist/controllers/theme_controller.d.ts +37 -8
  295. package/dist/controllers/theme_controller.js +148 -80
  296. package/dist/controllers/theme_controller.js.map +1 -1
  297. package/dist/controllers/time_picker_controller.d.ts +18 -1
  298. package/dist/controllers/time_picker_controller.js +162 -81
  299. package/dist/controllers/time_picker_controller.js.map +1 -1
  300. package/dist/controllers/toast_controller.d.ts +85 -23
  301. package/dist/controllers/toast_controller.js +365 -193
  302. package/dist/controllers/toast_controller.js.map +1 -1
  303. package/dist/controllers/toggle_group_controller.d.ts +60 -9
  304. package/dist/controllers/toggle_group_controller.js +194 -99
  305. package/dist/controllers/toggle_group_controller.js.map +1 -1
  306. package/dist/controllers/toolbar_controller.js +92 -90
  307. package/dist/controllers/toolbar_controller.js.map +1 -1
  308. package/dist/controllers/tooltip_controller.d.ts +52 -2
  309. package/dist/controllers/tooltip_controller.js +185 -125
  310. package/dist/controllers/tooltip_controller.js.map +1 -1
  311. package/dist/controllers/transition_controller.d.ts +22 -4
  312. package/dist/controllers/transition_controller.js +123 -115
  313. package/dist/controllers/transition_controller.js.map +1 -1
  314. package/dist/controllers/tree_view_controller.d.ts +59 -18
  315. package/dist/controllers/tree_view_controller.js +248 -290
  316. package/dist/controllers/tree_view_controller.js.map +1 -1
  317. package/dist/index.d.ts +33 -3
  318. package/dist/index.js +8649 -8572
  319. package/dist/index.js.map +1 -1
  320. package/dist/inspector/cli.d.ts +95 -9
  321. package/dist/inspector/cli.js +343 -77
  322. package/dist/inspector/cli.js.map +1 -1
  323. package/dist/inspector/cli_bin.js +390 -96
  324. package/dist/inspector/cli_bin.js.map +1 -1
  325. package/dist/inspector/examples.json +45 -45
  326. package/dist/inspector/manifest.json +1308 -155
  327. package/dist/positioning/index.d.ts +8 -0
  328. package/dist/positioning/index.js +148 -45
  329. package/dist/positioning/index.js.map +1 -1
  330. package/package.json +7 -7
  331. package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
  332. package/dist/controllers/reset_before_cache_controller.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,212 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
  While the version is `0.x`, the public API (the `stimeo--*` data attributes) may
8
8
  change between releases.
9
9
 
10
+ ## [Unreleased]
11
+
12
+ ## [0.17.0] - 2026-10-04
13
+
14
+ ### Changed
15
+
16
+ - **Breaking** Replace `reset-before-cache` with `reset-on-restore` (class, export,
17
+ and subpath).
18
+ Reset runs on restoration; remove `dispatchReset` and `:request` bindings.
19
+ Restored drawers and command palettes start closed.
20
+ - **Breaking** Rename calendar, combobox, and command-palette `selectByClick`, and
21
+ tree-view `onClick`, to `select`; replace calendar `selectDayElement` with
22
+ `select(element)`.
23
+ Accordion `toggle`, theme `set`, and scrollspy `scrollTo` require owned targets.
24
+ - **Breaking** State events are silent for unchanged state and superseded pending
25
+ reports.
26
+ For child edits within partial checkbox groups, use the children's native `change`.
27
+ Number Values and action params enforce finite values and their declared domains.
28
+ Update Inspector integrations to schema v15 and run `stimeo check` before deploying.
29
+ - Target actions accept owned elements; user state reports include `detail.reason`.
30
+ Toast duration, persist debounce, and count-up duration changes apply to the next
31
+ operation. Portal destination changes update mounts; Cable params cannot replace
32
+ the declared channel.
33
+
34
+ ### Fixed
35
+
36
+ - Preserve live state across Turbo caching, repair derived state after retained
37
+ morphs, and restore focus reliably across nested layers and Shadow DOM.
38
+
39
+ ## [0.16.0] - 2026-09-26
40
+
41
+ Minor release with no new components. Widgets now report their own state
42
+ changes — `open` / `close`, and `reconcile` when the page rather than the user
43
+ moves committed state — mirror their value into hidden form fields that fire a
44
+ native `change`, and no longer write normalized values back to their Values.
45
+ Several event, detail, action, and Value names were unified, so read Changed and
46
+ Removed before upgrading. The Inspector manifest moves to schema v14, and
47
+ **`stimeo check` can report errors on views that passed under 0.15.0** (row
48
+ templates, action params, event names, submit-once's `idle` / `busy` pairs), so
49
+ run it before deploying.
50
+
51
+ ### Added
52
+
53
+ - accordion, collapsible, context-menu, dialog, drawer, dropdown, hover-card,
54
+ menu, menubar, navigation-menu, popover, read-more, sidebar, and tooltip:
55
+ `open` / `close` events whose `detail.reason` says why the state moved, typed
56
+ by the new `StateReason` type export. accordion also carries
57
+ `{ index, trigger, panel }`, menubar `{ index, menu }`, navigation-menu
58
+ `{ index, panel }`, and sidebar `{ mode }`.
59
+ - tabs: a `change` event with `{ index, total, previous }`.
60
+ - A `reconcile` event, once per batch and never on connect, when the page — code
61
+ writing a Value or an attribute, or a morph — rather than the user moves
62
+ committed state: calendar `{ date }`, currency-input `{ value, formatted }`,
63
+ data-grid `{ rows }`, date-range-picker `{ start, end }`, listbox
64
+ `{ value, option }`, pagination `{ page, total, previous }`, range-slider
65
+ `{ start, end }`, resizable `{ value, fraction }`, separator and slider
66
+ `{ value }`, stepper `{ index, previous, total, step }`, switch `{ checked }`,
67
+ theme `{ mode, resolved }`, toggle-group `{ values }`, and tree-view
68
+ `{ item }`. sidebar reports `reconcile` `{ mode, open }` when crossing its
69
+ breakpoint switches the mode.
70
+ - Hidden form fields that fire a native `change` on a user commit and stay
71
+ silent on connect, morphs, and Value writes: calendar `field` / `monthField`,
72
+ range-slider `startField` / `endField`, and a `field` on slider, switch
73
+ (`"true"` / `"false"`), and tree-view (the selected item's `data-value`).
74
+ toggle-group and data-grid mirror into a `fields` container with `name`
75
+ (`values[]` / `rows[]`) and `form` Values, data-grid from the selected rows'
76
+ `data-value`. tags-input gains the `form` Value multi-select already has.
77
+ - Label pairs the controller swaps with the state: `expandedLabel` /
78
+ `collapsedLabel` on accordion, collapsible, and read-more, and `onLabel` /
79
+ `offLabel` on carousel's play toggle and password-reveal. Regions it shows
80
+ only in their state: `empty` on combobox and multi-select, `hasNew` on
81
+ stick-to-bottom, and `prompt` / `idle` on idle, which also sets `data-prompt`
82
+ while the warning stands.
83
+ - listbox: a `placeholder` Value the trigger shows while nothing is selected.
84
+ - clipboard: `copy` carries `message`, the `copiedLabel` or `errorLabel` for the
85
+ outcome, so `stimeo--clipboard:copy->stimeo--toast#show` needs no script.
86
+ - stepper: `change` also carries `total`, so it wires straight into
87
+ step-indicator's `setIndex`.
88
+ - Inspector: `unknown-action-event`, `invalid-template-root`, and action-param
89
+ checks (`missing-action-param`, `invalid-action-param`, and the warning
90
+ `confusable-action-param`) for overflow-indicator's `direction`, stepper's
91
+ `index`, toast's `type`, and announcer's `assertive`.
92
+
93
+ ### Changed
94
+
95
+ - **Breaking** switch: the event is `change` (was `changed`).
96
+ - **Breaking** step-indicator: the `current` Value is `index`, `setCurrent` is
97
+ `setIndex` and reads `detail.index`, and `change` carries
98
+ `{ index, previous, total }`.
99
+ - **Breaking** toast: `body` → `message` (param, detail, and
100
+ `data-toast-slot`).
101
+ - **Breaking** toast, tags-input, multi-select, and file-dropzone: the row
102
+ `<template>` must hold exactly one element, and that element carries the
103
+ `item` / `tag` target itself. A wrapped row or a second element adds nothing;
104
+ tags-input, multi-select, and file-dropzone say so on the console once per
105
+ connection, and `stimeo check` reports `invalid-template-root`.
106
+ - **Breaking** detail keys: filter `visible` → `visibleCount`, overflow-menu
107
+ `{ visible, hidden }` → `{ overflowCount, total }`, portal `mount`
108
+ `target` → `destination`.
109
+ - **Breaking** slider, range-slider, separator, resizable, rating, color-picker,
110
+ stepper, pagination, bulk-select, carousel (`autoplay`), and calendar (`month`)
111
+ no longer write a normalized value back to their Values: the attribute keeps
112
+ what the page wrote, only a user move writes it, and a declared value takes
113
+ effect again once the bounds allow it. Read the published state
114
+ from ARIA, the hidden field, or the events. theme still writes a stored choice
115
+ back to `mode`.
116
+ - **Breaking** a page-driven move reports `reconcile`, not `change`:
117
+ currency-input on a `locale`, `currency`, or `precision` change, a swapped-in
118
+ display, or a reconnect that re-rounds; otp on a native form reset or a
119
+ `pattern` change that drops entered characters, with no `complete` either.
120
+ rating's `reconcile` reports every move of the shown rating the page causes, an
121
+ in-range `value` write included, and nothing for a clamp that leaves it where
122
+ it was.
123
+ - **Breaking** color-picker, date-range-picker, multi-select, rating, and
124
+ tags-input fire a native `change` on a user commit — from the hidden `field`,
125
+ or from the `fields` container on multi-select and tags-input — so a form with
126
+ `stimeo--auto-submit` or a `change` listener now reacts to it.
127
+ - **Breaking** number-input: a step from the buttons, the arrow and Page keys,
128
+ Home and End, or press-and-hold fires the native `input` and `change` a typed
129
+ value does, ahead of `stimeo--number-input:change`, so a form with
130
+ `stimeo--auto-submit` or a `change` listener now reacts to each step.
131
+ - **Breaking** calendar: without a `month`, the grid opens on the selected day's
132
+ month instead of today's and leaves `month` empty (read the shown month from
133
+ `monthField`). A `selected` day outside `min` / `max` is withheld — no
134
+ `aria-selected`, an empty `field` — and published again once the bounds allow
135
+ it; the `selected` Value is never rewritten. Focus inside the grid follows a
136
+ `month` change that moves the painted month to the new month's tab stop.
137
+ - **Breaking** date-range-picker: a confirmed range whose ends `min`, `max`, or
138
+ `disabledDates` exclude narrows to the nearest selectable days, or clears when
139
+ none remain, and reports `reconcile`; `connect()` narrows a range read from its
140
+ fields the same way, silently.
141
+ - **Breaking** flash and toast never evict a hovered or focused notification for
142
+ `max`: the stack stays over the cap until that hold ends, then the oldest
143
+ unheld ones go. toast evicts with reason `limit` (was `timeout`), and a `max`
144
+ of `0` or less, or not a finite number, means no limit (toast used to remove
145
+ every toast).
146
+ - **Breaking** carousel: the `autoplay` Value is no longer switched off at the
147
+ end of a non-looping set or under reduced motion. The declared rotation
148
+ resumes once a slide lies ahead again; reduced motion holds it until the user
149
+ presses play or the page changes `autoplay`.
150
+ - **Breaking** resizable and filter dispatch `change` only when the outcome
151
+ moved: resizable's position, filter's `{ active, visibleCount, total }`.
152
+ - **Breaking** slider, range-slider, and separator decide a user move's
153
+ `change` against the last published value; toggle-group, calendar, and
154
+ date-range-picker skip a `change` or `select` that a listener superseded.
155
+ - Components follow more runtime changes: calendar repaints on `min`, `max`, and
156
+ `weekStart`, and a consumer's `aria-disabled` moves with its date to the cell
157
+ that shows it; countdown follows `completeLabel`; clipboard rewrites a shown
158
+ result on `copiedLabel` / `errorLabel`; flash applies a changed `max` at once;
159
+ theme applies a `mode` declaration, reported as `reconcile`, while a stored
160
+ choice still wins; overflow-menu relabels its More trigger on `moreLabel`;
161
+ stepper re-derives every step when steps are added or removed.
162
+ - countdown: the completion text it wrote, marked
163
+ `data-stimeo--countdown-owns-status`, is taken back when the timer leaves
164
+ `complete`, and a `deadline` moved forward returns it to `paused`.
165
+ overflow-menu marks the More label it wrote the same way
166
+ (`data-stimeo--overflow-menu-owns-label`) and leaves alone a trigger the
167
+ consumer put elements or a name into.
168
+ - listbox: with nothing selected the trigger shows `placeholder`, else the text
169
+ it held before the first selection, instead of keeping the last selected
170
+ option's text.
171
+ - number-input: a text-type spinbutton reads full-width digits and signs
172
+ (`34`, `-5`) as numbers.
173
+ - color-picker: a repaint that does not move the color no longer overwrites text
174
+ being typed into the hex input.
175
+ - carousel: an in-page move keeps a running rotation without a new `play`, and a
176
+ real detach while the element stays in the document emits `pause`.
177
+ - Target attributes are read as a token list: calendar, date-range-picker,
178
+ flash, nested-form, and toast find a target that also carries other names, and
179
+ `stimeo check` resolves them the same way.
180
+ - currency-input, input-mask, number-input, and otp hold a page write that
181
+ arrives during IME composition until the composition ends.
182
+ - Inspector: submit-once's `idle` / `busy` pair is checked per submit control,
183
+ so a button holding one half is reported (`missing-conditional-target`) even
184
+ when another button holds both.
185
+
186
+ ### Removed
187
+
188
+ - **Breaking** overflow-indicator: the `update` action. The controller listens
189
+ to its viewport's `scroll` itself, and `stimeo check` reports a leftover
190
+ `scroll->stimeo--overflow-indicator#update` as `unknown-action-method`.
191
+ - **Breaking** calendar: the public `render()` method; the grid repaints itself
192
+ when `min`, `max`, or `weekStart` change.
193
+
194
+ ### Fixed
195
+
196
+ - A user-clicked form reset re-derives checkbox, conditional-fields, and otp
197
+ state.
198
+ - pointer-drag: a `setPointerCapture()` that throws no longer locks the handle
199
+ out of both pointer and keyboard dragging. slider, range-slider, and
200
+ color-picker: another element taking the pointer capture mid-drag no longer
201
+ ends the drag.
202
+ - otp: an edit that reaches a field right after an IME confirmation without a
203
+ keystroke — dictation, autofill, a drop — is taken instead of dropped.
204
+ - otp: the authored `aria-invalid`, `aria-errormessage`, and `aria-describedby`
205
+ come back even when a page cached while an error showed is restored under
206
+ another connection; while the error shows, each field carries a
207
+ `data-otp-*-lease` marker holding them.
208
+ - tags-input, multi-select, and file-dropzone: a row whose root is itself the
209
+ `remove` button or the `label` can be removed, focused, and relabelled.
210
+ - stepper: `goto` stays put on an `index` param that is empty or that Stimulus
211
+ reads as a boolean, `null`, or an array (`"true"`, `"null"`, `"[1]"`), instead
212
+ of jumping to a step; `stimeo check` already reports these params.
213
+ - The type declarations link `open`, `close`, `confirm`, and `scrollTo` to the
214
+ component's own method instead of the DOM global of the same name.
215
+
10
216
  ## [0.15.0] - 2026-09-20
11
217
 
12
218
  Minor release with no new components. Shared internals were consolidated across
@@ -1101,6 +1307,9 @@ Initial public alpha: 101 behavior-only, accessible Stimulus controllers driven
1101
1307
  by `data-*` attributes, shipping no CSS. Published to npm (with provenance) and
1102
1308
  RubyGems.
1103
1309
 
1310
+ [Unreleased]: https://github.com/taiyaky/stimeo-ui/compare/v0.17.0...HEAD
1311
+ [0.17.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.17.0
1312
+ [0.16.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.16.0
1104
1313
  [0.15.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.15.0
1105
1314
  [0.14.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.14.0
1106
1315
  [0.13.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.13.0
package/README.md CHANGED
@@ -62,7 +62,14 @@ registerStimeo(application); // registers every stimeo--* controller
62
62
  ```
63
63
 
64
64
  Need only a few controllers? Import them individually from
65
- `stimeo-ui/controllers/*` and register them under your own identifiers.
65
+ `stimeo-ui/controllers/*` and register them under your own identifiers. Each
66
+ file loads on its own, yet the coordination between components — which layer
67
+ Escape closes, a focus trap's `Tab` and background, the value two components
68
+ lend the same attribute — is kept once per page, whichever files the
69
+ controllers came from, `stimeo-ui` itself included.
70
+ Copies of the same controller also share dirty-form confirmations, highlight
71
+ deadlines and portal origins. Opt-in Cable copies share the consumer, subscriptions
72
+ and peer departure decisions; generated ARIA ids stay distinct across copies too.
66
73
 
67
74
  - **Peer dependencies:** `@hotwired/stimulus` (always), `@floating-ui/dom` (only
68
75
  if you use the opt-in `stimeo-ui/positioning` module — tooltips, popovers, etc.
@@ -114,6 +121,126 @@ The `eslint-plugin-jsx-a11y` equivalents are
114
121
  `no-noninteractive-tabindex`. These components' real accessibility is exercised
115
122
  with axe-core and real screen readers in this project's own test suite.
116
123
 
124
+ ## Composing components
125
+
126
+ Parts dispatch `stimeo--<identifier>:<event>` with a `detail`, and Stimulus can bind
127
+ one part's event straight to another part's action. Wiring two parts is a
128
+ `data-action`, not a `<script>`.
129
+
130
+ ```html
131
+ <!-- Copy a link and say so, with nothing in between. -->
132
+ <div data-controller="stimeo--toast"
133
+ data-action="stimeo--clipboard:copy->stimeo--toast#show">
134
+ <div data-controller="stimeo--clipboard"
135
+ data-stimeo--clipboard-text-value="https://example.com/share"
136
+ data-stimeo--clipboard-copied-label-value="Copied"
137
+ data-stimeo--clipboard-error-label-value="Copy failed">
138
+ <button type="button" data-stimeo--clipboard-target="button"
139
+ data-action="click->stimeo--clipboard#copy">Copy</button>
140
+ </div>
141
+ <ol data-stimeo--toast-target="list"></ol>
142
+ <template data-stimeo--toast-target="template">
143
+ <li data-stimeo--toast-target="item"><span data-toast-slot="message"></span></li>
144
+ </template>
145
+ </div>
146
+ ```
147
+
148
+ ```html
149
+ <!-- A wizard moves a read-only progress indicator. -->
150
+ <div data-controller="stimeo--stepper">
151
+ <ol data-controller="stimeo--step-indicator"
152
+ data-action="stimeo--stepper:change@window->stimeo--step-indicator#setIndex">
153
+ <li data-stimeo--step-indicator-target="step">Cart</li>
154
+ <li data-stimeo--step-indicator-target="step">Shipping</li>
155
+ </ol>
156
+ <!-- the stepper's own step targets and buttons -->
157
+ </div>
158
+ ```
159
+
160
+ ```html
161
+ <!-- A value a widget stepped submits the form, through the events a browser
162
+ would have fired for its own control. -->
163
+ <form data-controller="stimeo--auto-submit"
164
+ data-action="change->stimeo--auto-submit#submit">
165
+ <div data-controller="stimeo--number-input">
166
+ <input type="number" name="quantity" value="1" aria-label="Quantity"
167
+ data-stimeo--number-input-target="input"
168
+ data-action="change->stimeo--number-input#onInput
169
+ keydown->stimeo--number-input#onKeydown" />
170
+ <button type="button" aria-label="Increase" tabindex="-1"
171
+ data-stimeo--number-input-target="increment"
172
+ data-action="click->stimeo--number-input#increment">+</button>
173
+ </div>
174
+ </form>
175
+ ```
176
+
177
+ Two things to know:
178
+
179
+ - **Events bubble from the part that dispatched them.** The receiver has to be an
180
+ ancestor. Anywhere else — a sibling, or a receiver nested *inside* the part that
181
+ dispatches — needs `@window`, because bubbling only ever goes up:
182
+ `stimeo--clipboard:copy@window->stimeo--toast#show`.
183
+ - **Do not say the same thing twice.** A toast's message slot is a `role="status"`
184
+ live region. Wiring the same result to the shared announcer as well
185
+ (`announce-copied-text`, …) reads it out twice. Pick one.
186
+
187
+ `stimeo check` verifies both halves of a wire: the controller and action on the
188
+ receiving side, and the event name on the emitting side.
189
+
190
+ ## Styling notes
191
+
192
+ ### `hidden` under a utility CSS layer
193
+
194
+ Controllers show and hide their own declared regions with the `hidden` attribute —
195
+ a listbox option filtered out, an "empty" row, the half of a label that does not
196
+ belong to the current state. `hidden` only carries `display: none` from the user-agent
197
+ stylesheet, so any rule that sets `display` wins over it.
198
+
199
+ Utility-first frameworks make that collision likely. Tailwind v4 declares
200
+ `@layer theme, base, components, utilities`, and DaisyUI puts component classes such
201
+ as `.menu li`, `.tabs`, and `.steps` in the **last** layer. A hidden element inside one
202
+ of them stays visible, and a `display: none` you add in `@layer components` still loses.
203
+
204
+ Put the override **outside every layer** — unlayered rules beat layered ones, so no
205
+ `!important` is needed:
206
+
207
+ ```css
208
+ /* not inside @layer */
209
+ .menu li[hidden],
210
+ .menu [role="option"][hidden] {
211
+ display: none;
212
+ }
213
+ ```
214
+
215
+ Most visible with `combobox`, `listbox`, `multi-select`, `empty-state`, `filter`, and
216
+ `command-palette`, whose options and empty rows are the ones being hidden.
217
+
218
+ ### State-dependent text belongs in markup
219
+
220
+ It is tempting to put the words that change with a state into CSS:
221
+
222
+ ```css
223
+ /* don't */
224
+ .play::after { content: "Auto-advance: off"; }
225
+ .play[aria-pressed="true"]::after { content: "Auto-advance: on"; }
226
+ ```
227
+
228
+ Text in `content` never reaches a translation catalogue, and the usual "find untranslated
229
+ strings" scan reads HTML, so it does not turn up there either. `content: attr(aria-valuetext)`
230
+ has the same problem from the other side: the attribute is composed at runtime in one
231
+ language. Keep the words in markup and let the controller show the half that applies:
232
+
233
+ ```html
234
+ <button data-stimeo--read-more-target="trigger" aria-expanded="false">
235
+ <span data-stimeo--read-more-target="collapsedLabel">Read more</span>
236
+ <span data-stimeo--read-more-target="expandedLabel" hidden>Show less</span>
237
+ </button>
238
+ ```
239
+
240
+ Controllers that read out a composed value take the wording as an attribute instead —
241
+ `color-picker` accepts `data-value-text`, and the announcing controllers accept
242
+ `announce-*-text`.
243
+
117
244
  ## Inspector CLI & MCP server
118
245
 
119
246
  Stimeo UI bundles a zero-dependency static checker for its own markup contract
@@ -62,9 +62,10 @@ import { Controller, Application } from '@hotwired/stimulus';
62
62
  * (local-only) counters never disable their triggers. `announceText` is opt-in
63
63
  * and empty by default; when set, reconciled counts reach the page's shared
64
64
  * announcer, debounced so a burst is one message. The subscription follows the
65
- * declaration — a `channel` or `params` change moves it — and is released on
66
- * `disconnect()` (Turbo navigation included) along with any pending
67
- * announcement.
65
+ * declaration — a `channel` or `params` change moves it, once per batch of
66
+ * changes and only when the identifier they name differs from the one it was
67
+ * opened for — and is released on `disconnect()` (Turbo navigation included)
68
+ * along with any pending announcement.
68
69
  */
69
70
  declare class LiveCounterController extends Controller<HTMLElement> {
70
71
  #private;
@@ -96,13 +97,7 @@ declare class LiveCounterController extends Controller<HTMLElement> {
96
97
  paramsValue: string;
97
98
  idValue: string;
98
99
  announceTextValue: string;
99
- /**
100
- * Re-parses the identifier parameters and moves the subscription to the
101
- * identifier they now name.
102
- *
103
- * A malformed declaration falls back to no parameters, so the identifier keeps
104
- * naming the channel instead of the subscription never being created at all.
105
- */
100
+ /** Moves the subscription to the identifier the parameters now name. */
106
101
  paramsValueChanged(): void;
107
102
  /** Moves the subscription when the declaration names a different channel. */
108
103
  channelValueChanged(): void;
@@ -197,6 +192,22 @@ declare class LiveCounterController extends Controller<HTMLElement> {
197
192
  * Stream or a morph arrives empty and is drawn from the roster as it connects; the subscription, heartbeat interval,
198
193
  * per-peer expiry timers, and the `pagehide` listener are all released on
199
194
  * `disconnect()` (Turbo navigation included).
195
+ *
196
+ * The live resources follow the declaration; Values changed together move them
197
+ * once, after the batch, and nothing moves before `connect()` or after
198
+ * `disconnect()`. A `channel` or `params` change moves the subscription: the room
199
+ * being left gets the leaving notice under the same rules as `disconnect()`
200
+ * (confirmed, an own `id`, the last voice for it), and its roster, expiry timers,
201
+ * pending beacon and announcement, throttle window and rejected hook are dropped
202
+ * without an event, as a fresh connection would, since none of them is a fact of
203
+ * the new room. An `id` change keeps the subscription and its roster: the old id's
204
+ * voice is released once (the last voice leaves), the new id beacons at once —
205
+ * which also stands in for a convergence answer still queued — and a peer already
206
+ * listed under the new id is this client now, so it stops being counted without a
207
+ * `leave`: it went nowhere. A `heartbeat` change re-arms the running interval,
208
+ * counted from the change. `timeout` arms each peer's expiry when its beacon
209
+ * arrives, so a change applies from that peer's next beacon and never moves a
210
+ * deadline already set.
200
211
  */
201
212
  declare class PresenceController extends Controller<HTMLElement> {
202
213
  #private;
@@ -235,6 +246,18 @@ declare class PresenceController extends Controller<HTMLElement> {
235
246
  default: string;
236
247
  };
237
248
  };
249
+ static valueConstraints: {
250
+ heartbeat: {
251
+ readonly finite: true;
252
+ readonly exclusiveMin: 0;
253
+ readonly max: 2147483647;
254
+ };
255
+ timeout: {
256
+ readonly finite: true;
257
+ readonly exclusiveMin: 0;
258
+ readonly max: 2147483647;
259
+ };
260
+ };
238
261
  static events: readonly ["join", "leave", "change"];
239
262
  readonly hasCountTarget: boolean;
240
263
  readonly countTarget: HTMLElement;
@@ -250,13 +273,14 @@ declare class PresenceController extends Controller<HTMLElement> {
250
273
  timeoutValue: number;
251
274
  announceJoinTextValue: string;
252
275
  announceLeaveTextValue: string;
253
- /**
254
- * Re-parses the identifier parameters when the declaration changes.
255
- *
256
- * A malformed declaration falls back to no parameters, so the identifier keeps
257
- * naming the channel instead of the subscription never being created at all.
258
- */
276
+ /** Moves the subscription to the declared channel. */
277
+ channelValueChanged(): void;
278
+ /** Moves the subscription to the identifier the parameters name. */
259
279
  paramsValueChanged(): void;
280
+ /** Moves this element's voice to the declared id. */
281
+ idValueChanged(): void;
282
+ /** Re-arms a running heartbeat on the declared period. */
283
+ heartbeatValueChanged(): void;
260
284
  /**
261
285
  * Draws the roster into a list target, which arrives empty from a Turbo Stream
262
286
  * replacement or a morph. Stimulus runs this before `connect()` on the first mount
@@ -264,8 +288,12 @@ declare class PresenceController extends Controller<HTMLElement> {
264
288
  * preserved is what `connect()` goes on to do anyway.
265
289
  */
266
290
  listTargetConnected(): void;
291
+ /** Draws the roster into the list target that stays when an earlier one leaves. */
292
+ listTargetDisconnected(): void;
267
293
  /** Paints the roster size into a count target that arrives blank, for the same reason. */
268
294
  countTargetConnected(): void;
295
+ /** Paints the roster size into the count target that stays when an earlier one leaves. */
296
+ countTargetDisconnected(): void;
269
297
  connect(): void;
270
298
  disconnect(): void;
271
299
  }
@@ -324,6 +352,22 @@ declare class PresenceController extends Controller<HTMLElement> {
324
352
  * from the stream. The subscription, the per-typer timers, and the delegated
325
353
  * `input` listener are all released on `disconnect()` (Turbo navigation
326
354
  * included).
355
+ *
356
+ * The declared `channel` names the subscription: `params` *adds* identifier
357
+ * parameters except `channel`, which is ignored. Without a declared channel
358
+ * nothing is subscribed whatever `params` holds.
359
+ *
360
+ * The subscription follows the declaration: a `channel` or `params` change moves
361
+ * it — once, after the batch, however many of the two changed together, and never
362
+ * before `connect()` or after `disconnect()` — and drops the typers, their expiry
363
+ * timers, a pending announcement, the throttle window and the rejected hook
364
+ * without an event, as a fresh connection would, since none of them is a fact of
365
+ * the new room. A `name` change keeps the subscription and the typers, except one
366
+ * shown under the new name: that is this client now, so it is dropped with its
367
+ * expiry and the display redrawn, without a `change` — it did not stop typing.
368
+ * The own echo is still filtered by the current `name`. `timeout` arms each
369
+ * typer's expiry when its signal arrives, so a change applies from that typer's
370
+ * next signal and never moves a deadline already set.
327
371
  */
328
372
  declare class TypingIndicatorController extends Controller<HTMLElement> {
329
373
  #private;
@@ -358,6 +402,17 @@ declare class TypingIndicatorController extends Controller<HTMLElement> {
358
402
  default: string;
359
403
  };
360
404
  };
405
+ static valueConstraints: {
406
+ timeout: {
407
+ readonly finite: true;
408
+ readonly min: 0;
409
+ readonly max: 2147483647;
410
+ };
411
+ throttle: {
412
+ readonly finite: true;
413
+ readonly min: 0;
414
+ };
415
+ };
361
416
  static events: readonly ["change"];
362
417
  readonly hasStatusTarget: boolean;
363
418
  readonly statusTarget: HTMLElement;
@@ -368,22 +423,23 @@ declare class TypingIndicatorController extends Controller<HTMLElement> {
368
423
  throttleValue: number;
369
424
  announceOneTextValue: string;
370
425
  announceManyTextValue: string;
371
- /**
372
- * Re-parses the identifier parameters when the declaration changes.
373
- *
374
- * A malformed declaration falls back to no parameters, so the identifier keeps
375
- * naming the channel instead of the subscription never being created at all.
376
- */
426
+ /** Moves the subscription to the declared channel. */
427
+ channelValueChanged(): void;
428
+ /** Moves the subscription to the identifier the parameters name. */
377
429
  paramsValueChanged(): void;
430
+ /** Stops showing a typer under the name this client now declares. */
431
+ nameValueChanged(): void;
378
432
  /**
379
433
  * Paints the current copy into a `status` target that arrived at runtime.
380
434
  *
381
435
  * No event: the set of typers did not change, only the element that displays it.
382
436
  * Without this a region swapped in mid-conversation stays empty while `data-typing`
383
437
  * still says someone is typing, leaving the state in the visual hook alone. An empty
384
- * set needs no paint — a fresh region already shows it.
438
+ * set paints the empty copy, so a region that arrives with an old one is cleared.
385
439
  */
386
440
  statusTargetConnected(): void;
441
+ /** Paints the current copy, empty when nobody types, into the `status` target that stays. */
442
+ statusTargetDisconnected(): void;
387
443
  connect(): void;
388
444
  disconnect(): void;
389
445
  }