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,44 +1,82 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/idle_controller.ts
3
+ var ListenerSet = class {
4
+ #abort = new AbortController();
5
+ add(target, type, handler, options) {
6
+ target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
7
+ }
8
+ dispose() {
9
+ this.#abort.abort();
10
+ this.#abort = new AbortController();
11
+ }
12
+ };
13
+
14
+ var MAX_TIMER_DELAY_MS = 2147483647;
15
+
16
+ var NUMBER_BOUNDS = {
17
+ nonNegative: { finite: true, min: 0 },
18
+ positiveTimer: { finite: true, exclusiveMin: 0, max: MAX_TIMER_DELAY_MS }
19
+ };
20
+ function matchesNumberBounds(value, bounds) {
21
+ if (!Number.isFinite(value)) {
22
+ const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
23
+ if (direction === null) return false;
24
+ if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
25
+ }
26
+ if (bounds.min !== void 0 && value < bounds.min) return false;
27
+ if (bounds.max !== void 0 && value > bounds.max) return false;
28
+ if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
29
+ if (bounds.integer && !Number.isInteger(value)) return false;
30
+ if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
31
+ return true;
32
+ }
33
+
34
+ function readNumber(raw, fallback, bounds) {
35
+ return matchesNumberBounds(raw, bounds) ? raw : fallback;
36
+ }
37
+
38
+ var NumberValueReader = class {
39
+ #lastRejected = /* @__PURE__ */ new Map();
40
+ read(owner, name, raw, fallback, bounds) {
41
+ const resolved = readNumber(raw, fallback, bounds);
42
+ if (matchesNumberBounds(raw, bounds)) {
43
+ this.#lastRejected.delete(name);
44
+ return resolved;
45
+ }
46
+ const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;
47
+ const literal = owner.element.getAttribute(attribute);
48
+ if (literal === null) {
49
+ this.#lastRejected.delete(name);
50
+ return resolved;
51
+ }
52
+ if (this.#lastRejected.get(name) !== literal) {
53
+ this.#lastRejected.set(name, literal);
54
+ console.warn(
55
+ `Stimeo UI: "${owner.identifier}" has an invalid number Value "${name}" declaration ${JSON.stringify(literal)}; using ${fallback}.`
56
+ );
57
+ }
58
+ return resolved;
59
+ }
60
+ };
4
61
 
5
- // src/utils/safe_timeout.ts
6
62
  var TimerRegistry = class {
7
- /** Live timer ids that have not yet been cleared (or, for timeouts, fired). */
8
63
  ids = /* @__PURE__ */ new Set();
9
- /**
10
- * Cancels a single tracked timer.
11
- *
12
- * No-ops if the id is unknown (already cleared, fired, or never owned by this
13
- * registry), so callers can clear defensively without guarding.
14
- */
15
64
  clear(id) {
16
65
  if (this.ids.delete(id)) {
17
66
  this.cancel(id);
18
67
  }
19
68
  }
20
- /**
21
- * Cancels every tracked timer. Call this from a controller's `disconnect()`
22
- * to guarantee no timer outlives the element.
23
- */
24
69
  clearAll() {
25
70
  for (const id of this.ids) {
26
71
  this.cancel(id);
27
72
  }
28
73
  this.ids.clear();
29
74
  }
30
- /** Number of timers currently tracked (pending). */
31
75
  get size() {
32
76
  return this.ids.size;
33
77
  }
34
78
  };
35
79
  var SafeTimeout = class extends TimerRegistry {
36
- /**
37
- * Schedules `callback` after `delay` ms and returns the timer id.
38
- *
39
- * The id is removed from the registry automatically when the timeout fires,
40
- * so {@link TimerRegistry.size | size} reflects only still-pending timers.
41
- */
42
80
  set(callback, delay) {
43
81
  const id = this.schedule(() => {
44
82
  this.ids.delete(id);
@@ -55,16 +93,37 @@ var SafeTimeout = class extends TimerRegistry {
55
93
  }
56
94
  };
57
95
 
58
- // src/utils/state_regions.ts
59
- var StateRegions = class {
96
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
97
+ if (element.getAttribute(name) === value) return false;
98
+ if (value === null) element.removeAttribute(name);
99
+ else element.setAttribute(name, value);
100
+ return true;
101
+ }
102
+
103
+ function sharedRegistry(key, create) {
104
+ const symbol = Symbol.for(key);
105
+ const scope = globalThis;
106
+ const existing = scope[symbol];
107
+ if (existing !== void 0) return existing;
108
+ const registry = create();
109
+ Object.defineProperty(globalThis, symbol, { value: registry });
110
+ return registry;
111
+ }
112
+
113
+ var StateRegions = class _StateRegions {
114
+ static #registry = sharedRegistry(
115
+ "stimeo-ui.state-regions.registry.v1",
116
+ () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Set() })
117
+ );
60
118
  #whenTrue;
61
119
  #whenFalse;
62
- #taken = /* @__PURE__ */ new WeakSet();
63
- constructor(options) {
120
+ #record;
121
+ constructor(options, owner) {
64
122
  this.#whenTrue = options.whenTrue;
65
123
  this.#whenFalse = options.whenFalse ?? null;
124
+ this.#record = `data-${owner}-hidden-region`;
125
+ _StateRegions.#registry.names.add(this.#record);
66
126
  }
67
- /** Shows the regions inside `host` that belong to `isTrue` and hides the others. */
68
127
  reflect(host, isTrue) {
69
128
  const shown = this.#inside(host, this.#whenTrue());
70
129
  if (!this.#whenFalse) {
@@ -80,23 +139,119 @@ var StateRegions = class {
80
139
  for (const region of shown) this.#write(region, !isTrue);
81
140
  for (const region of hiddenSide) this.#write(region, isTrue);
82
141
  }
83
- /** Writes `hidden` where it moves, noting which regions it takes out of view. */
142
+ release(host) {
143
+ for (const region of [host, ...host.querySelectorAll("*")]) {
144
+ if (!(region instanceof HTMLElement)) continue;
145
+ const stack = this.#held(region);
146
+ const hold = stack && this.#take(stack);
147
+ if (!stack || !hold) continue;
148
+ const owns = region.hidden === hold.written && !this.#covered(region, stack, hold);
149
+ const index = stack.indexOf(hold);
150
+ stack.splice(index, 1);
151
+ const above = stack[index];
152
+ if (above) above.linked &&= hold.linked;
153
+ if (owns) {
154
+ const below = hold.linked ? stack[index - 1] : void 0;
155
+ if (below) {
156
+ if (region.hidden !== below.written) region.hidden = below.written;
157
+ } else {
158
+ setAttributeIfChanged(region, "hidden", hold.authored);
159
+ }
160
+ }
161
+ this.#mark(region, stack);
162
+ }
163
+ }
84
164
  #write(region, hidden) {
85
- if (hidden) this.#taken.add(region);
86
- else this.#taken.delete(region);
87
- if (region.hidden !== hidden) region.hidden = hidden;
165
+ const stack = this.#stack(region);
166
+ const hold = this.#take(stack) ?? this.#acquire(region, stack);
167
+ const shows = !this.#covered(region, stack, hold);
168
+ hold.written = hidden;
169
+ if (shows && region.hidden !== hidden) region.hidden = hidden;
170
+ this.#mark(region, stack);
88
171
  }
89
- /** Returns a region this instance hid; one it never hid keeps what it carries. */
90
172
  #give(region) {
91
- if (this.#taken.delete(region)) region.hidden = false;
173
+ const stack = this.#held(region);
174
+ if (stack && this.#take(stack)?.written) this.#write(region, false);
175
+ }
176
+ #held(region) {
177
+ return _StateRegions.#registry.stacks.has(region) || region.hasAttribute(this.#record) ? this.#stack(region) : void 0;
178
+ }
179
+ #stack(region) {
180
+ const stacks = _StateRegions.#registry.stacks;
181
+ const stack = stacks.get(region) ?? this.#seed(region);
182
+ stacks.set(region, stack);
183
+ return stack;
184
+ }
185
+ #seed(region) {
186
+ const found = [];
187
+ for (const record of _StateRegions.#registry.names) {
188
+ const read = this.#recorded(region, record);
189
+ if (read) found.push({ ...read, record });
190
+ }
191
+ const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
192
+ return found.sort((one, other) => depth(one) - depth(other)).map(({ record, authored, written, linked }, index) => ({
193
+ instance: null,
194
+ record,
195
+ authored,
196
+ written,
197
+ linked: linked && index > 0
198
+ }));
199
+ }
200
+ #take(stack) {
201
+ const hold = stack.find((held) => held.instance === this) ?? stack.find((held) => held.instance === null && held.record === this.#record);
202
+ if (hold) hold.instance = this;
203
+ return hold;
204
+ }
205
+ #covered(region, stack, hold) {
206
+ return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === region.hidden);
207
+ }
208
+ #acquire(region, stack) {
209
+ const top = stack.at(-1);
210
+ const over = top && region.hidden === top.written ? top : void 0;
211
+ const hold = {
212
+ instance: this,
213
+ record: this.#record,
214
+ authored: over ? over.authored : region.getAttribute("hidden"),
215
+ written: false,
216
+ linked: over !== void 0
217
+ };
218
+ stack.push(hold);
219
+ return hold;
220
+ }
221
+ #mark(region, stack) {
222
+ const records = /* @__PURE__ */ new Map([[this.#record, null]]);
223
+ stack.forEach((hold, index) => {
224
+ const names = stack.slice(0, index).map((under) => under.record);
225
+ const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
226
+ const marker = hold.linked || beneath.length === 0 ? [] : [false];
227
+ records.set(
228
+ hold.record,
229
+ region.getAttribute("hidden") === hold.authored && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.authored, hold.written, ...marker, ...beneath])
230
+ );
231
+ });
232
+ for (const [name, recorded] of records) {
233
+ setAttributeIfChanged(region, name, recorded);
234
+ }
235
+ }
236
+ #recorded(region, name) {
237
+ try {
238
+ const parsed = JSON.parse(region.getAttribute(name) ?? "null");
239
+ if (!Array.isArray(parsed)) return null;
240
+ const [authored, written, ...rest] = parsed;
241
+ if (authored !== null && typeof authored !== "string") return null;
242
+ const linked = rest[0] !== false;
243
+ const beneath = linked ? rest : rest.slice(1);
244
+ if (!beneath.every((under) => typeof under === "string")) return null;
245
+ return typeof written === "boolean" ? { authored, written, linked, beneath } : null;
246
+ } catch {
247
+ return null;
248
+ }
92
249
  }
93
- /** The declared regions that sit within `host`, which may be the host itself. */
94
250
  #inside(host, regions) {
95
251
  return regions.filter((region) => host.contains(region));
96
252
  }
97
253
  };
98
254
 
99
- // src/utils/string_list.ts
100
255
  function parseStringList(raw, fallback = []) {
101
256
  const text = raw.trim();
102
257
  if (text.length === 0) return [...fallback];
@@ -110,7 +265,6 @@ function parseStringList(raw, fallback = []) {
110
265
  return parsed.filter((entry) => typeof entry === "string");
111
266
  }
112
267
 
113
- // src/controllers/idle_controller.ts
114
268
  var DEFAULT_ACTIVITY_EVENTS = [
115
269
  "mousemove",
116
270
  "mousedown",
@@ -119,31 +273,31 @@ var DEFAULT_ACTIVITY_EVENTS = [
119
273
  "touchstart",
120
274
  "scroll"
121
275
  ];
122
- var IdleController = class extends Controller {
276
+ var IdleController = class _IdleController extends Controller {
277
+ #numbers = new NumberValueReader();
123
278
  static values = {
124
279
  timeout: { type: Number, default: 9e5 },
125
280
  promptBefore: { type: Number, default: 0 },
126
- // A JSON list read through `parseStringList` rather than Stimulus's `Array`
127
- // type: that reader throws out of the value observer before any callback
128
- // runs, so one malformed attribute would stop the detector connecting.
129
281
  events: { type: String, default: "" }
130
282
  };
283
+ static valueConstraints = {
284
+ timeout: NUMBER_BOUNDS.positiveTimer,
285
+ promptBefore: NUMBER_BOUNDS.nonNegative
286
+ };
131
287
  static targets = ["prompt", "idle"];
132
288
  static events = ["prompt", "idle", "active"];
133
- /** The regions of the warning window, revealed alongside `data-prompt`. */
134
- #promptRegions = new StateRegions({ whenTrue: () => this.promptTargets });
135
- /** The regions of the elapsed timeout, revealed alongside `data-idle`. */
136
- #idleRegions = new StateRegions({ whenTrue: () => this.idleTargets });
289
+ #promptRegions = new StateRegions(
290
+ { whenTrue: () => this.promptTargets },
291
+ this.identifier
292
+ );
293
+ #idleRegions = new StateRegions({ whenTrue: () => this.idleTargets }, this.identifier);
137
294
  #timeouts = new SafeTimeout();
138
295
  #idle = false;
139
296
  #prompted = false;
140
- /** Timestamp of the last activity; the timers self-reschedule against it. */
141
297
  #lastActivity = 0;
142
- /**
143
- * Activity types actually registered on `document`, so `disconnect()` unbinds the
144
- * same set even when `events` changed while connected (a Turbo morph can rewrite
145
- * the Value in place, and the removal must match the registration, not the Value).
146
- */
298
+ #connected = false;
299
+ #activityListeners = new ListenerSet();
300
+ #visibilityListeners = new ListenerSet();
147
301
  #boundEvents = [];
148
302
  #onActivity = () => {
149
303
  this.#lastActivity = Date.now();
@@ -159,50 +313,65 @@ var IdleController = class extends Controller {
159
313
  if (document.visibilityState === "visible") this.#onActivity();
160
314
  };
161
315
  connect() {
316
+ this.#connected = true;
162
317
  this.#idle = false;
163
318
  this.#prompted = false;
164
319
  this.#reflect();
165
- this.#boundEvents = parseStringList(this.eventsValue, DEFAULT_ACTIVITY_EVENTS);
166
- for (const type of this.#boundEvents) {
167
- document.addEventListener(type, this.#onActivity, { passive: true, capture: true });
168
- }
169
- document.addEventListener("visibilitychange", this.#onVisibility);
320
+ this.#bindActivity(parseStringList(this.eventsValue, DEFAULT_ACTIVITY_EVENTS));
321
+ this.#visibilityListeners.add(document, "visibilitychange", this.#onVisibility);
170
322
  this.#arm();
171
323
  }
172
324
  disconnect() {
173
- for (const type of this.#boundEvents) {
174
- document.removeEventListener(type, this.#onActivity, { capture: true });
175
- }
176
- this.#boundEvents = [];
177
- document.removeEventListener("visibilitychange", this.#onVisibility);
325
+ this.#connected = false;
326
+ this.#activityListeners.dispose();
327
+ this.#visibilityListeners.dispose();
178
328
  this.#timeouts.clearAll();
179
329
  }
180
- /**
181
- * Schedules the prompt and idle checks from the current activity baseline.
182
- *
183
- * @stimeoRuntimeOnly `timeout` and `promptBefore` time the checks this call arms.
184
- */
330
+ eventsValueChanged() {
331
+ if (!this.#connected) return;
332
+ const types = parseStringList(this.eventsValue, DEFAULT_ACTIVITY_EVENTS);
333
+ if (types.length === this.#boundEvents.length && types.every((type, index) => type === this.#boundEvents[index]))
334
+ return;
335
+ this.#bindActivity(types);
336
+ }
337
+ timeoutValueChanged() {
338
+ if (this.#connected) this.#schedule();
339
+ }
340
+ promptBeforeValueChanged() {
341
+ if (this.#connected) this.#schedule();
342
+ }
343
+ #bindActivity(types) {
344
+ this.#activityListeners.dispose();
345
+ for (const type of types) {
346
+ this.#activityListeners.add(document, type, this.#onActivity, {
347
+ passive: true,
348
+ capture: true
349
+ });
350
+ }
351
+ this.#boundEvents = types;
352
+ }
185
353
  #arm() {
186
- this.#timeouts.clearAll();
187
354
  this.#lastActivity = Date.now();
188
- const { promptBeforeValue: prompt, timeoutValue: timeout } = this;
189
- if (prompt > 0 && prompt < timeout) {
190
- this.#timeouts.set(() => this.#checkPrompt(), timeout - prompt);
191
- }
192
- this.#timeouts.set(() => this.#checkIdle(), timeout);
193
- }
194
- /**
195
- * Idle-timer callback: go idle only if there has genuinely been no activity for
196
- * `timeout`; otherwise reschedule for the remaining time. This lets activity events
197
- * stay O(1) (a timestamp write) while the deadline still tracks the last activity.
198
- *
199
- * @stimeoRuntimeOnly `timeout` sets the deadline this one check compares against; the phase it
200
- * shows follows the elapsed time.
201
- */
355
+ this.#schedule();
356
+ }
357
+ #schedule() {
358
+ this.#timeouts.clearAll();
359
+ if (this.#idle) return;
360
+ const elapsed = Date.now() - this.#lastActivity;
361
+ const timeout = this.#safeTimeout;
362
+ const prompt = this.#safePromptBefore;
363
+ this.#timeouts.set(() => this.#checkIdle(), this.#delayFor(timeout - elapsed));
364
+ if (this.#prompted || prompt <= 0 || prompt >= timeout) return;
365
+ const left = Math.min(prompt, timeout - elapsed);
366
+ this.#timeouts.set(() => this.#checkPrompt(left), this.#delayFor(timeout - prompt - elapsed));
367
+ }
368
+ #delayFor(remaining) {
369
+ return Math.min(Math.max(remaining, 0), MAX_TIMER_DELAY_MS);
370
+ }
202
371
  #checkIdle() {
203
- const remaining = this.timeoutValue - (Date.now() - this.#lastActivity);
372
+ const remaining = this.#safeTimeout - (Date.now() - this.#lastActivity);
204
373
  if (remaining > 0) {
205
- this.#timeouts.set(() => this.#checkIdle(), remaining);
374
+ this.#timeouts.set(() => this.#checkIdle(), Math.min(remaining, MAX_TIMER_DELAY_MS));
206
375
  return;
207
376
  }
208
377
  this.#idle = true;
@@ -210,39 +379,23 @@ var IdleController = class extends Controller {
210
379
  this.#reflect();
211
380
  this.dispatch("idle", { detail: {} });
212
381
  }
213
- /**
214
- * Prompt-timer callback: warn at `promptBefore` before the idle deadline. A window
215
- * narrowed while the cycle runs can push the warning onto the deadline or past it,
216
- * and the phase it belongs to is the one before idle, so a lapsed cycle keeps the
217
- * phase it reached. The next window opens with the cycle that activity arms.
218
- *
219
- * @stimeoRuntimeOnly `timeout` and `promptBefore` set the deadlines this one check compares
220
- * against; the phase it shows follows the elapsed time.
221
- */
222
- #checkPrompt() {
382
+ #checkPrompt(left = this.#safePromptBefore) {
223
383
  if (this.#idle) return;
224
- const remaining = this.timeoutValue - this.promptBeforeValue - (Date.now() - this.#lastActivity);
384
+ const remaining = this.#safeTimeout - this.#safePromptBefore - (Date.now() - this.#lastActivity);
225
385
  if (remaining > 0) {
226
- this.#timeouts.set(() => this.#checkPrompt(), remaining);
386
+ this.#timeouts.set(() => this.#checkPrompt(), Math.min(remaining, MAX_TIMER_DELAY_MS));
227
387
  return;
228
388
  }
229
389
  this.#prompted = true;
230
390
  this.#reflect();
231
- this.dispatch("prompt", { detail: { remaining: this.promptBeforeValue } });
391
+ this.dispatch("prompt", { detail: { remaining: left } });
232
392
  }
233
- /** Applies the current phase to a warning region inserted or replaced at runtime. */
234
393
  promptTargetConnected() {
235
394
  this.#promptRegions.reflect(this.element, this.#prompted);
236
395
  }
237
- /** Applies the current phase to an idle region inserted or replaced at runtime. */
238
396
  idleTargetConnected() {
239
397
  this.#idleRegions.reflect(this.element, this.#idle);
240
398
  }
241
- /**
242
- * Writes the phase to the element and to the declared regions. Both hooks and both
243
- * regions are a pure function of the two flags, so every place that moves a flag ends
244
- * here and the markup can never disagree with the phase the detector is in.
245
- */
246
399
  #reflect() {
247
400
  const { element } = this;
248
401
  if (this.#prompted) element.setAttribute("data-prompt", "true");
@@ -252,8 +405,25 @@ var IdleController = class extends Controller {
252
405
  this.#promptRegions.reflect(element, this.#prompted);
253
406
  this.#idleRegions.reflect(element, this.#idle);
254
407
  }
408
+ get #safeTimeout() {
409
+ return this.#numbers.read(
410
+ this,
411
+ "timeout",
412
+ this.timeoutValue,
413
+ _IdleController.values.timeout.default,
414
+ _IdleController.valueConstraints.timeout
415
+ );
416
+ }
417
+ get #safePromptBefore() {
418
+ return this.#numbers.read(
419
+ this,
420
+ "promptBefore",
421
+ this.promptBeforeValue,
422
+ _IdleController.values.promptBefore.default,
423
+ _IdleController.valueConstraints.promptBefore
424
+ );
425
+ }
255
426
  };
256
427
 
257
428
  export { IdleController };
258
- //# sourceMappingURL=idle_controller.js.map
259
429
  //# sourceMappingURL=idle_controller.js.map