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,8 +1,5 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/clipboard_controller.ts
4
-
5
- // src/utils/announce.ts
6
3
  function announce(message, options = {}) {
7
4
  const text = message.trim();
8
5
  if (text.length === 0) return;
@@ -13,79 +10,234 @@ function announce(message, options = {}) {
13
10
  );
14
11
  }
15
12
 
16
- // src/utils/before_cache_reset.ts
17
- var BeforeCacheReset = class _BeforeCacheReset {
18
- /** Every subscribed instance, iterated by the one shared document listener. */
19
- static #subscribers = /* @__PURE__ */ new Set();
20
- /** The shared listener; installed while at least one instance is subscribed. */
21
- static #onBeforeCache = () => {
22
- for (const subscriber of _BeforeCacheReset.#subscribers) subscriber.#rewind();
23
- };
24
- #rewind;
25
- /** @param rewind - the pass that returns this controller's state to its initial form. */
26
- constructor(rewind) {
27
- this.#rewind = rewind;
13
+ function setDefaultAttribute(element, name, value) {
14
+ if (element.hasAttribute(name)) return false;
15
+ element.setAttribute(name, value);
16
+ return true;
17
+ }
18
+
19
+ var ListenerSet = class {
20
+ #abort = new AbortController();
21
+ add(target, type, handler, options) {
22
+ target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
23
+ }
24
+ dispose() {
25
+ this.#abort.abort();
26
+ this.#abort = new AbortController();
27
+ }
28
+ };
29
+
30
+ var MicrotaskCoalescer = class {
31
+ #run;
32
+ #queued = false;
33
+ #active = false;
34
+ #generation = 0;
35
+ constructor(run) {
36
+ this.#run = run;
28
37
  }
29
- /** Subscribes to `turbo:before-cache`; call from `connect()`. Idempotent. */
30
38
  activate() {
31
- const first = _BeforeCacheReset.#subscribers.size === 0;
32
- _BeforeCacheReset.#subscribers.add(this);
33
- if (first) {
34
- document.addEventListener("turbo:before-cache", _BeforeCacheReset.#onBeforeCache);
35
- }
39
+ this.#active = true;
36
40
  }
37
- /** Unsubscribes; call from `disconnect()`. Safe when never subscribed. */
38
- deactivate() {
39
- _BeforeCacheReset.#subscribers.delete(this);
40
- if (_BeforeCacheReset.#subscribers.size > 0) return;
41
- document.removeEventListener("turbo:before-cache", _BeforeCacheReset.#onBeforeCache);
41
+ cancel() {
42
+ this.#active = false;
43
+ this.#queued = false;
44
+ this.#generation += 1;
45
+ }
46
+ get pending() {
47
+ return this.#queued;
48
+ }
49
+ schedule() {
50
+ if (!this.#active || this.#queued) return;
51
+ this.#queued = true;
52
+ const generation = this.#generation;
53
+ queueMicrotask(() => {
54
+ if (generation !== this.#generation || !this.#queued || !this.#active) return;
55
+ this.#queued = false;
56
+ this.#run();
57
+ });
42
58
  }
43
59
  };
44
60
 
45
- // src/utils/default_attribute.ts
46
- function setDefaultAttribute(element, name, value) {
47
- if (element.hasAttribute(name)) return false;
48
- element.setAttribute(name, value);
61
+ var MorphRenderWatcher = class {
62
+ #listeners = new ListenerSet();
63
+ #pass;
64
+ #element = null;
65
+ #onMorph = () => this.#pass.schedule();
66
+ constructor(run) {
67
+ this.#pass = new MicrotaskCoalescer(run);
68
+ }
69
+ observe(element) {
70
+ if (this.#element === element) return;
71
+ this.disconnect();
72
+ this.#element = element;
73
+ this.#pass.activate();
74
+ this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
75
+ }
76
+ schedule() {
77
+ this.#pass.schedule();
78
+ }
79
+ get pending() {
80
+ return this.#pass.pending;
81
+ }
82
+ disconnect() {
83
+ this.#listeners.dispose();
84
+ this.#pass.cancel();
85
+ this.#element = null;
86
+ }
87
+ };
88
+
89
+ var MAX_TIMER_DELAY_MS = 2147483647;
90
+
91
+ var NUMBER_BOUNDS = {
92
+ timer: { finite: true, min: 0, max: MAX_TIMER_DELAY_MS }};
93
+ function matchesNumberBounds(value, bounds) {
94
+ if (!Number.isFinite(value)) {
95
+ const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
96
+ if (direction === null) return false;
97
+ if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
98
+ }
99
+ if (bounds.min !== void 0 && value < bounds.min) return false;
100
+ if (bounds.max !== void 0 && value > bounds.max) return false;
101
+ if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
102
+ if (bounds.integer && !Number.isInteger(value)) return false;
103
+ if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
104
+ return true;
105
+ }
106
+
107
+ function readNumber(raw, fallback, bounds) {
108
+ return matchesNumberBounds(raw, bounds) ? raw : fallback;
109
+ }
110
+
111
+ var NumberValueReader = class {
112
+ #lastRejected = /* @__PURE__ */ new Map();
113
+ read(owner, name, raw, fallback, bounds) {
114
+ const resolved = readNumber(raw, fallback, bounds);
115
+ if (matchesNumberBounds(raw, bounds)) {
116
+ this.#lastRejected.delete(name);
117
+ return resolved;
118
+ }
119
+ const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;
120
+ const literal = owner.element.getAttribute(attribute);
121
+ if (literal === null) {
122
+ this.#lastRejected.delete(name);
123
+ return resolved;
124
+ }
125
+ if (this.#lastRejected.get(name) !== literal) {
126
+ this.#lastRejected.set(name, literal);
127
+ console.warn(
128
+ `Stimeo UI: "${owner.identifier}" has an invalid number Value "${name}" declaration ${JSON.stringify(literal)}; using ${fallback}.`
129
+ );
130
+ }
131
+ return resolved;
132
+ }
133
+ };
134
+
135
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
136
+ if (element.getAttribute(name) === value) return false;
137
+ if (value === null) element.removeAttribute(name);
138
+ else element.setAttribute(name, value);
49
139
  return true;
50
140
  }
51
141
 
52
- // src/utils/safe_timeout.ts
142
+ var OwnedText = class {
143
+ #attribute;
144
+ #channel;
145
+ #guard;
146
+ #writes = /* @__PURE__ */ new WeakMap();
147
+ constructor(attribute, channel = "text", guard = () => true) {
148
+ this.#attribute = attribute;
149
+ this.#channel = channel;
150
+ this.#guard = guard;
151
+ }
152
+ hasRecord(element) {
153
+ return element.hasAttribute(this.#attribute);
154
+ }
155
+ read(element, evidence = {}) {
156
+ if (evidence.source === "live") return this.#writes.get(element) ?? null;
157
+ const raw = element.getAttribute(this.#attribute);
158
+ if (raw === null) return null;
159
+ try {
160
+ const record = JSON.parse(raw);
161
+ if (!Array.isArray(record) || record.length !== 3 || record[0] !== this.#channel || typeof record[1] !== "string" || typeof record[2] !== "string")
162
+ return null;
163
+ return { original: record[1], written: record[2] };
164
+ } catch {
165
+ return null;
166
+ }
167
+ }
168
+ owns(element, evidence = {}) {
169
+ return this.#ownedRecord(element, evidence) !== null;
170
+ }
171
+ #ownedRecord(element, evidence) {
172
+ const record = this.read(element, evidence);
173
+ if (record === null || !this.#guard(element)) return null;
174
+ if (this.#channel === "text" && element.firstElementChild !== null) return null;
175
+ const current = this.#current(element);
176
+ return current === record.written || evidence.source === "live" && evidence.allowOriginal === true && current === record.original ? record : null;
177
+ }
178
+ write(element, written, original, force = false) {
179
+ const current = this.#current(element);
180
+ if (current === null) return;
181
+ const before = original ?? this.#writes.get(element)?.original ?? this.read(element)?.original ?? current;
182
+ if (force || current !== written) this.#put(element, written);
183
+ this.remember(element, written, before);
184
+ }
185
+ remember(element, written, original) {
186
+ const current = this.#current(element);
187
+ if (current === null) return;
188
+ const before = original ?? this.#writes.get(element)?.original ?? this.read(element)?.original ?? current;
189
+ this.#writes.set(element, { original: before, written });
190
+ setAttributeIfChanged(
191
+ element,
192
+ this.#attribute,
193
+ JSON.stringify([this.#channel, before, written])
194
+ );
195
+ }
196
+ clear(element, evidence = {}) {
197
+ if (!this.owns(element, evidence)) return false;
198
+ if (this.#current(element) !== "") this.#put(element, "");
199
+ this.forget(element);
200
+ return true;
201
+ }
202
+ restore(element, evidence = {}) {
203
+ const record = this.#ownedRecord(element, evidence);
204
+ if (record === null) return false;
205
+ if (this.#current(element) !== record.original) this.#put(element, record.original);
206
+ this.forget(element);
207
+ return true;
208
+ }
209
+ forget(element) {
210
+ setAttributeIfChanged(element, this.#attribute, null);
211
+ this.#writes.delete(element);
212
+ }
213
+ #current(element) {
214
+ if (this.#channel === "text") return element.textContent ?? "";
215
+ return element instanceof HTMLInputElement ? element.value : null;
216
+ }
217
+ #put(element, text) {
218
+ if (this.#channel === "text") element.textContent = text;
219
+ else if (element instanceof HTMLInputElement) element.value = text;
220
+ }
221
+ };
222
+
53
223
  var TimerRegistry = class {
54
- /** Live timer ids that have not yet been cleared (or, for timeouts, fired). */
55
224
  ids = /* @__PURE__ */ new Set();
56
- /**
57
- * Cancels a single tracked timer.
58
- *
59
- * No-ops if the id is unknown (already cleared, fired, or never owned by this
60
- * registry), so callers can clear defensively without guarding.
61
- */
62
225
  clear(id) {
63
226
  if (this.ids.delete(id)) {
64
227
  this.cancel(id);
65
228
  }
66
229
  }
67
- /**
68
- * Cancels every tracked timer. Call this from a controller's `disconnect()`
69
- * to guarantee no timer outlives the element.
70
- */
71
230
  clearAll() {
72
231
  for (const id of this.ids) {
73
232
  this.cancel(id);
74
233
  }
75
234
  this.ids.clear();
76
235
  }
77
- /** Number of timers currently tracked (pending). */
78
236
  get size() {
79
237
  return this.ids.size;
80
238
  }
81
239
  };
82
240
  var SafeTimeout = class extends TimerRegistry {
83
- /**
84
- * Schedules `callback` after `delay` ms and returns the timer id.
85
- *
86
- * The id is removed from the registry automatically when the timeout fires,
87
- * so {@link TimerRegistry.size | size} reflects only still-pending timers.
88
- */
89
241
  set(callback, delay) {
90
242
  const id = this.schedule(() => {
91
243
  this.ids.delete(id);
@@ -102,9 +254,9 @@ var SafeTimeout = class extends TimerRegistry {
102
254
  }
103
255
  };
104
256
 
105
- // src/controllers/clipboard_controller.ts
106
257
  var TRANSIENT_STATES = /* @__PURE__ */ new Set(["copied", "error"]);
107
- var ClipboardController = class extends Controller {
258
+ var ClipboardController = class _ClipboardController extends Controller {
259
+ #numbers = new NumberValueReader();
108
260
  static targets = ["source", "button", "feedback"];
109
261
  static values = {
110
262
  text: { type: String, default: "" },
@@ -114,63 +266,36 @@ var ClipboardController = class extends Controller {
114
266
  announceCopiedText: { type: String, default: "" },
115
267
  announceErrorText: { type: String, default: "" }
116
268
  };
269
+ static valueConstraints = {
270
+ feedbackDuration: NUMBER_BOUNDS.timer
271
+ };
117
272
  static actions = ["copy"];
118
273
  static events = ["copy"];
119
- /**
120
- * The pending return to idle — the only timer this controller schedules, so
121
- * `clearAll()` is exactly "drop the auto-clear" and needs no id of its own.
122
- */
123
274
  #timers = new SafeTimeout();
124
- /** Returns the completion state to idle for the snapshot Turbo takes. */
125
- #beforeCache = new BeforeCacheReset(() => this.#rewind());
126
- /**
127
- * Whether this connection is still live. `copy()` suspends on the Clipboard API,
128
- * and a teardown that lands while it is suspended must win: the continuation
129
- * would otherwise write to an element nobody owns and arm a timer past the
130
- * `clearAll()` that was supposed to be the last word. Stimulus also runs the label
131
- * callbacks ahead of `connect()`, while this is still false: a result restored with
132
- * the markup is `connect()`'s to settle, not theirs.
133
- */
134
275
  #connected = false;
276
+ #result = null;
277
+ #feedback = null;
278
+ #feedbackText = new OwnedText(`data-${this.identifier}-feedback-text`);
279
+ #written = /* @__PURE__ */ new Set();
280
+ #morphRender = new MorphRenderWatcher(() => this.#renderResult());
135
281
  connect() {
136
282
  this.#connected = true;
137
283
  this.#adopt();
138
- this.#beforeCache.activate();
284
+ this.#result = null;
285
+ this.#feedback = this.hasFeedbackTarget ? { element: this.feedbackTarget, original: this.feedbackTarget.textContent ?? "" } : null;
286
+ this.#morphRender.observe(this.element);
139
287
  }
140
288
  disconnect() {
141
289
  this.#connected = false;
142
- this.#beforeCache.deactivate();
290
+ this.#morphRender.disconnect();
143
291
  this.#timers.clearAll();
144
292
  }
145
- /**
146
- * Follows a `copiedLabel` swapped in place while a successful copy is shown.
147
- *
148
- * Render only: nothing is announced or dispatched, and the return to idle keeps the
149
- * deadline the copy set. The slot changes only while `data-state` is `copied` and it
150
- * still reads the previous label — the one the copy wrote there — so text someone
151
- * else put in the slot stays. Stimulus also runs this ahead of `connect()`, which
152
- * settles a result restored with the markup itself, so nothing is written then.
153
- */
154
293
  copiedLabelValueChanged(label, previous) {
155
294
  this.#followLabel("copied", label, previous);
156
295
  }
157
- /**
158
- * Follows an `errorLabel` swapped in place while a failed copy is shown, on the same
159
- * terms as {@link ClipboardController.copiedLabelValueChanged}: only while
160
- * `data-state` is `error` and the slot still reads the previous label.
161
- */
162
296
  errorLabelValueChanged(label, previous) {
163
297
  this.#followLabel("error", label, previous);
164
298
  }
165
- /**
166
- * Copies the resolved text and reports the outcome. Bound via `data-action`
167
- * (click). Dispatches `stimeo--clipboard:copy` with `{ success, text, message }`
168
- * once per completed attempt — including on failure — so consumers can react
169
- * either way. `message` is the authored label for that outcome, so a part that
170
- * shows wording — `stimeo--clipboard:copy->stimeo--toast#show` — needs nothing
171
- * else; wiring both that and the announcer reads the same result twice.
172
- * An attempt whose connection ended while it was in flight reports nothing.
173
- */
174
299
  async copy() {
175
300
  const text = this.#resolveText();
176
301
  let success = false;
@@ -185,10 +310,6 @@ var ClipboardController = class extends Controller {
185
310
  const message = success ? this.copiedLabelValue : this.errorLabelValue;
186
311
  this.dispatch("copy", { detail: { success, text, message } });
187
312
  }
188
- /**
189
- * The text to copy: the explicit `text` value when set, otherwise the source
190
- * target's current value (inputs/textareas) or text content.
191
- */
192
313
  #resolveText() {
193
314
  if (this.textValue.length > 0) return this.textValue;
194
315
  if (!this.hasSourceTarget) return "";
@@ -198,92 +319,83 @@ var ClipboardController = class extends Controller {
198
319
  }
199
320
  return source.textContent ?? "";
200
321
  }
201
- /**
202
- * Reads the current state back from the DOM.
203
- *
204
- * A `copied` or `error` found at connect time is this controller's own output
205
- * from a connection that is gone, and so is the timer that would have cleared it
206
- * — nothing else would ever return the element to `idle`. Any other authored
207
- * value belongs to the consumer and only a missing attribute takes the default.
208
- */
209
322
  #adopt() {
210
323
  if (this.#inTransientState()) {
211
324
  this.#reset();
325
+ for (const element of this.feedbackTargets) this.#feedbackText.clear(element);
212
326
  return;
213
327
  }
214
328
  setDefaultAttribute(this.element, "data-state", "idle");
215
329
  }
216
- /** Whether `data-state` currently holds one of the values this controller writes. */
217
330
  #inTransientState() {
218
331
  const state = this.element.getAttribute("data-state");
219
332
  return state !== null && TRANSIENT_STATES.has(state);
220
333
  }
221
- /**
222
- * Returns the completion state to idle for the snapshot Turbo is about to take,
223
- * so a page reached with the Back button does not report a copy that happened
224
- * before the navigation. Only a state this controller wrote is rewound — an
225
- * authored one is the consumer's and has to survive into the snapshot, exactly as
226
- * `connect()` leaves it alone. State only — no `copy` is dispatched, which would
227
- * claim a fresh copy ran.
228
- */
229
- #rewind() {
230
- if (!this.#inTransientState()) return;
231
- this.#timers.clearAll();
232
- this.#reset();
233
- }
234
- /**
235
- * Reflects the result, announces it, and schedules the return to idle.
236
- *
237
- * @stimeoRenderRoot
238
- */
239
334
  #reportResult(success) {
240
- this.element.setAttribute("data-state", success ? "copied" : "error");
241
- if (this.hasFeedbackTarget) {
242
- this.feedbackTarget.textContent = success ? this.copiedLabelValue : this.errorLabelValue;
243
- }
335
+ this.#result = success;
336
+ this.#renderResult(true);
244
337
  this.#announceResult(success);
245
338
  this.#scheduleReset();
246
339
  }
247
- /**
248
- * Reads the result out through the shared announcer.
249
- *
250
- * @stimeoRuntimeOnly `announceCopiedText` / `announceErrorText` word the one announcement a copy
251
- * makes.
252
- */
340
+ #renderResult(force = false) {
341
+ if (this.#result === null) {
342
+ setDefaultAttribute(this.element, "data-state", "idle");
343
+ return;
344
+ }
345
+ this.element.setAttribute("data-state", this.#result ? "copied" : "error");
346
+ if (!this.hasFeedbackTarget) return;
347
+ const element = this.feedbackTarget;
348
+ if (!force && (element !== this.#feedback?.element || !this.#ownsFeedback(element))) return;
349
+ const text = this.#result ? this.copiedLabelValue : this.errorLabelValue;
350
+ const original = element === this.#feedback?.element ? this.#feedback.original : element.textContent ?? "";
351
+ this.#feedback = { element, original };
352
+ this.#feedbackText.write(element, text, original, force);
353
+ this.#written.add(element);
354
+ }
355
+ #ownsFeedback(element) {
356
+ return this.#feedbackText.owns(element) || !this.#feedbackText.hasRecord(element) && this.#feedbackText.owns(element, { source: "live", allowOriginal: true });
357
+ }
253
358
  #announceResult(success) {
254
359
  announce(success ? this.announceCopiedTextValue : this.announceErrorTextValue);
255
360
  }
256
- /**
257
- * Arms the return to idle for the result just shown.
258
- *
259
- * @stimeoRuntimeOnly `feedbackDuration` is the delay of the one timer this call arms, and the
260
- * reset that timer runs reads no Value.
261
- */
262
361
  #scheduleReset() {
263
362
  this.#timers.clearAll();
264
- if (this.feedbackDurationValue > 0) {
265
- this.#timers.set(() => this.#reset(), this.feedbackDurationValue);
363
+ if (this.#safeFeedbackDuration > 0) {
364
+ this.#timers.set(() => this.#reset(), this.#safeFeedbackDuration);
266
365
  }
267
366
  }
268
- /**
269
- * Rewrites the slot to `label` while `state` is shown and the slot still reads
270
- * `previous`, the label this controller wrote for that result.
271
- */
272
367
  #followLabel(state, label, previous) {
273
368
  if (!this.#connected) return;
274
369
  if (this.element.getAttribute("data-state") !== state || !this.hasFeedbackTarget) return;
275
- if (this.feedbackTarget.textContent !== previous) return;
276
- this.feedbackTarget.textContent = label;
370
+ const element = this.feedbackTarget;
371
+ if (element !== this.#feedback?.element || element.textContent !== previous || !this.#ownsFeedback(element))
372
+ return;
373
+ this.#feedbackText.write(element, label);
374
+ this.#written.add(element);
277
375
  }
278
- /** Returns to the idle state and empties the completion slot. */
279
376
  #reset() {
377
+ this.#result = null;
280
378
  this.element.setAttribute("data-state", "idle");
281
- if (this.hasFeedbackTarget) {
282
- this.feedbackTarget.textContent = "";
379
+ for (const element of this.#written) {
380
+ if (this.feedbackTargets.includes(element))
381
+ this.#feedbackText.clear(
382
+ element,
383
+ this.#feedbackText.hasRecord(element) ? {} : { source: "live" }
384
+ );
385
+ this.#feedbackText.forget(element);
283
386
  }
387
+ this.#written.clear();
388
+ }
389
+ get #safeFeedbackDuration() {
390
+ return this.#numbers.read(
391
+ this,
392
+ "feedbackDuration",
393
+ this.feedbackDurationValue,
394
+ _ClipboardController.values.feedbackDuration.default,
395
+ _ClipboardController.valueConstraints.feedbackDuration
396
+ );
284
397
  }
285
398
  };
286
399
 
287
400
  export { ClipboardController };
288
- //# sourceMappingURL=clipboard_controller.js.map
289
401
  //# sourceMappingURL=clipboard_controller.js.map