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,19 +1,14 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/stick_to_bottom_controller.ts
4
-
5
- // src/utils/layout_observer.ts
6
3
  var LayoutObserver = class {
7
4
  #callback;
8
5
  #resizeObserverFactory;
9
6
  #resizeObserver = null;
10
7
  #observingViewport = false;
11
8
  #loadContainer = null;
12
- /** Stable bound handler so add/removeEventListener target the same reference. */
13
9
  #handleViewportResize = () => {
14
10
  this.#callback();
15
11
  };
16
- /** Stable bound handler for the capture-phase `load`; see {@link observeDescendantLoads}. */
17
12
  #handleDescendantLoad = () => {
18
13
  this.#callback();
19
14
  };
@@ -21,11 +16,6 @@ var LayoutObserver = class {
21
16
  this.#callback = callback;
22
17
  this.#resizeObserverFactory = options.resizeObserverFactory ?? (typeof ResizeObserver === "undefined" ? null : (cb) => new ResizeObserver(cb));
23
18
  }
24
- /**
25
- * Starts observing an element's size. Repeated calls observe additional
26
- * elements through the same shared observer. No-ops when no
27
- * `ResizeObserver` implementation is available.
28
- */
29
19
  observe(element) {
30
20
  if (!this.#resizeObserverFactory) return;
31
21
  if (!this.#resizeObserver) {
@@ -35,47 +25,28 @@ var LayoutObserver = class {
35
25
  }
36
26
  this.#resizeObserver.observe(element);
37
27
  }
38
- /** Stops observing a single element while leaving any others in place. */
39
28
  unobserve(element) {
40
29
  this.#resizeObserver?.unobserve(element);
41
30
  }
42
- /** Starts observing viewport resizes. Idempotent: the listener is added once. */
43
31
  observeViewport() {
44
32
  if (this.#observingViewport) return;
45
33
  this.#observingViewport = true;
46
34
  window.addEventListener("resize", this.#handleViewportResize);
47
35
  }
48
- /** Stops observing viewport resizes without affecting element observation. */
49
36
  unobserveViewport() {
50
37
  if (!this.#observingViewport) return;
51
38
  this.#observingViewport = false;
52
39
  window.removeEventListener("resize", this.#handleViewportResize);
53
40
  }
54
- /**
55
- * Starts reporting a `load` from anywhere inside `container` — an image or a
56
- * frame settling changes the box it sits in, and it measures as zero high until
57
- * then. `load` does not bubble, so the subscription is a capture-phase listener
58
- * on the container itself and nothing the caller spells.
59
- *
60
- * **One container at a time.** A further call moves the observation, so a widget
61
- * whose content element is swapped at runtime releases the element it let go by
62
- * naming the new one — there is no second place for the release to drift from.
63
- */
64
41
  observeDescendantLoads(container) {
65
42
  this.unobserveDescendantLoads();
66
43
  this.#loadContainer = container;
67
44
  container.addEventListener("load", this.#handleDescendantLoad, true);
68
45
  }
69
- /** Stops reporting descendant loads without affecting element or viewport observation. */
70
46
  unobserveDescendantLoads() {
71
47
  this.#loadContainer?.removeEventListener("load", this.#handleDescendantLoad, true);
72
48
  this.#loadContainer = null;
73
49
  }
74
- /**
75
- * Releases every observation: disconnects the {@link ResizeObserver} and removes
76
- * the viewport and descendant-load listeners. Safe to call multiple times. Call
77
- * this from a controller's `disconnect()`.
78
- */
79
50
  disconnect() {
80
51
  this.#resizeObserver?.disconnect();
81
52
  this.#resizeObserver = null;
@@ -84,21 +55,155 @@ var LayoutObserver = class {
84
55
  }
85
56
  };
86
57
 
87
- // src/utils/reduced_motion.ts
58
+ var ListenerSet = class {
59
+ #abort = new AbortController();
60
+ add(target, type, handler, options) {
61
+ target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
62
+ }
63
+ dispose() {
64
+ this.#abort.abort();
65
+ this.#abort = new AbortController();
66
+ }
67
+ };
68
+
69
+ var MicrotaskCoalescer = class {
70
+ #run;
71
+ #queued = false;
72
+ #active = false;
73
+ #generation = 0;
74
+ constructor(run) {
75
+ this.#run = run;
76
+ }
77
+ activate() {
78
+ this.#active = true;
79
+ }
80
+ cancel() {
81
+ this.#active = false;
82
+ this.#queued = false;
83
+ this.#generation += 1;
84
+ }
85
+ get pending() {
86
+ return this.#queued;
87
+ }
88
+ schedule() {
89
+ if (!this.#active || this.#queued) return;
90
+ this.#queued = true;
91
+ const generation = this.#generation;
92
+ queueMicrotask(() => {
93
+ if (generation !== this.#generation || !this.#queued || !this.#active) return;
94
+ this.#queued = false;
95
+ this.#run();
96
+ });
97
+ }
98
+ };
99
+
100
+ var MorphRenderWatcher = class {
101
+ #listeners = new ListenerSet();
102
+ #pass;
103
+ #element = null;
104
+ #onMorph = () => this.#pass.schedule();
105
+ constructor(run) {
106
+ this.#pass = new MicrotaskCoalescer(run);
107
+ }
108
+ observe(element) {
109
+ if (this.#element === element) return;
110
+ this.disconnect();
111
+ this.#element = element;
112
+ this.#pass.activate();
113
+ this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
114
+ }
115
+ schedule() {
116
+ this.#pass.schedule();
117
+ }
118
+ get pending() {
119
+ return this.#pass.pending;
120
+ }
121
+ disconnect() {
122
+ this.#listeners.dispose();
123
+ this.#pass.cancel();
124
+ this.#element = null;
125
+ }
126
+ };
127
+
128
+ var NUMBER_BOUNDS = {
129
+ nonNegative: { finite: true, min: 0 }};
130
+ function matchesNumberBounds(value, bounds) {
131
+ if (!Number.isFinite(value)) {
132
+ const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
133
+ if (direction === null) return false;
134
+ if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
135
+ }
136
+ if (bounds.min !== void 0 && value < bounds.min) return false;
137
+ if (bounds.max !== void 0 && value > bounds.max) return false;
138
+ if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
139
+ if (bounds.integer && !Number.isInteger(value)) return false;
140
+ if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
141
+ return true;
142
+ }
143
+
144
+ function readNumber(raw, fallback, bounds) {
145
+ return matchesNumberBounds(raw, bounds) ? raw : fallback;
146
+ }
147
+
148
+ var NumberValueReader = class {
149
+ #lastRejected = /* @__PURE__ */ new Map();
150
+ read(owner, name, raw, fallback, bounds) {
151
+ const resolved = readNumber(raw, fallback, bounds);
152
+ if (matchesNumberBounds(raw, bounds)) {
153
+ this.#lastRejected.delete(name);
154
+ return resolved;
155
+ }
156
+ const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;
157
+ const literal = owner.element.getAttribute(attribute);
158
+ if (literal === null) {
159
+ this.#lastRejected.delete(name);
160
+ return resolved;
161
+ }
162
+ if (this.#lastRejected.get(name) !== literal) {
163
+ this.#lastRejected.set(name, literal);
164
+ console.warn(
165
+ `Stimeo UI: "${owner.identifier}" has an invalid number Value "${name}" declaration ${JSON.stringify(literal)}; using ${fallback}.`
166
+ );
167
+ }
168
+ return resolved;
169
+ }
170
+ };
171
+
88
172
  function prefersReducedMotion() {
89
173
  return typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
90
174
  }
91
175
 
92
- // src/utils/state_regions.ts
93
- var StateRegions = class {
176
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
177
+ if (element.getAttribute(name) === value) return false;
178
+ if (value === null) element.removeAttribute(name);
179
+ else element.setAttribute(name, value);
180
+ return true;
181
+ }
182
+
183
+ function sharedRegistry(key, create) {
184
+ const symbol = Symbol.for(key);
185
+ const scope = globalThis;
186
+ const existing = scope[symbol];
187
+ if (existing !== void 0) return existing;
188
+ const registry = create();
189
+ Object.defineProperty(globalThis, symbol, { value: registry });
190
+ return registry;
191
+ }
192
+
193
+ var StateRegions = class _StateRegions {
194
+ static #registry = sharedRegistry(
195
+ "stimeo-ui.state-regions.registry.v1",
196
+ () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Set() })
197
+ );
94
198
  #whenTrue;
95
199
  #whenFalse;
96
- #taken = /* @__PURE__ */ new WeakSet();
97
- constructor(options) {
200
+ #record;
201
+ constructor(options, owner) {
98
202
  this.#whenTrue = options.whenTrue;
99
203
  this.#whenFalse = options.whenFalse ?? null;
204
+ this.#record = `data-${owner}-hidden-region`;
205
+ _StateRegions.#registry.names.add(this.#record);
100
206
  }
101
- /** Shows the regions inside `host` that belong to `isTrue` and hides the others. */
102
207
  reflect(host, isTrue) {
103
208
  const shown = this.#inside(host, this.#whenTrue());
104
209
  if (!this.#whenFalse) {
@@ -114,112 +219,192 @@ var StateRegions = class {
114
219
  for (const region of shown) this.#write(region, !isTrue);
115
220
  for (const region of hiddenSide) this.#write(region, isTrue);
116
221
  }
117
- /** Writes `hidden` where it moves, noting which regions it takes out of view. */
222
+ release(host) {
223
+ for (const region of [host, ...host.querySelectorAll("*")]) {
224
+ if (!(region instanceof HTMLElement)) continue;
225
+ const stack = this.#held(region);
226
+ const hold = stack && this.#take(stack);
227
+ if (!stack || !hold) continue;
228
+ const owns = region.hidden === hold.written && !this.#covered(region, stack, hold);
229
+ const index = stack.indexOf(hold);
230
+ stack.splice(index, 1);
231
+ const above = stack[index];
232
+ if (above) above.linked &&= hold.linked;
233
+ if (owns) {
234
+ const below = hold.linked ? stack[index - 1] : void 0;
235
+ if (below) {
236
+ if (region.hidden !== below.written) region.hidden = below.written;
237
+ } else {
238
+ setAttributeIfChanged(region, "hidden", hold.authored);
239
+ }
240
+ }
241
+ this.#mark(region, stack);
242
+ }
243
+ }
118
244
  #write(region, hidden) {
119
- if (hidden) this.#taken.add(region);
120
- else this.#taken.delete(region);
121
- if (region.hidden !== hidden) region.hidden = hidden;
245
+ const stack = this.#stack(region);
246
+ const hold = this.#take(stack) ?? this.#acquire(region, stack);
247
+ const shows = !this.#covered(region, stack, hold);
248
+ hold.written = hidden;
249
+ if (shows && region.hidden !== hidden) region.hidden = hidden;
250
+ this.#mark(region, stack);
122
251
  }
123
- /** Returns a region this instance hid; one it never hid keeps what it carries. */
124
252
  #give(region) {
125
- if (this.#taken.delete(region)) region.hidden = false;
253
+ const stack = this.#held(region);
254
+ if (stack && this.#take(stack)?.written) this.#write(region, false);
255
+ }
256
+ #held(region) {
257
+ return _StateRegions.#registry.stacks.has(region) || region.hasAttribute(this.#record) ? this.#stack(region) : void 0;
258
+ }
259
+ #stack(region) {
260
+ const stacks = _StateRegions.#registry.stacks;
261
+ const stack = stacks.get(region) ?? this.#seed(region);
262
+ stacks.set(region, stack);
263
+ return stack;
264
+ }
265
+ #seed(region) {
266
+ const found = [];
267
+ for (const record of _StateRegions.#registry.names) {
268
+ const read = this.#recorded(region, record);
269
+ if (read) found.push({ ...read, record });
270
+ }
271
+ const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
272
+ return found.sort((one, other) => depth(one) - depth(other)).map(({ record, authored, written, linked }, index) => ({
273
+ instance: null,
274
+ record,
275
+ authored,
276
+ written,
277
+ linked: linked && index > 0
278
+ }));
279
+ }
280
+ #take(stack) {
281
+ const hold = stack.find((held) => held.instance === this) ?? stack.find((held) => held.instance === null && held.record === this.#record);
282
+ if (hold) hold.instance = this;
283
+ return hold;
284
+ }
285
+ #covered(region, stack, hold) {
286
+ return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === region.hidden);
287
+ }
288
+ #acquire(region, stack) {
289
+ const top = stack.at(-1);
290
+ const over = top && region.hidden === top.written ? top : void 0;
291
+ const hold = {
292
+ instance: this,
293
+ record: this.#record,
294
+ authored: over ? over.authored : region.getAttribute("hidden"),
295
+ written: false,
296
+ linked: over !== void 0
297
+ };
298
+ stack.push(hold);
299
+ return hold;
300
+ }
301
+ #mark(region, stack) {
302
+ const records = /* @__PURE__ */ new Map([[this.#record, null]]);
303
+ stack.forEach((hold, index) => {
304
+ const names = stack.slice(0, index).map((under) => under.record);
305
+ const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
306
+ const marker = hold.linked || beneath.length === 0 ? [] : [false];
307
+ records.set(
308
+ hold.record,
309
+ region.getAttribute("hidden") === hold.authored && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.authored, hold.written, ...marker, ...beneath])
310
+ );
311
+ });
312
+ for (const [name, recorded] of records) {
313
+ setAttributeIfChanged(region, name, recorded);
314
+ }
315
+ }
316
+ #recorded(region, name) {
317
+ try {
318
+ const parsed = JSON.parse(region.getAttribute(name) ?? "null");
319
+ if (!Array.isArray(parsed)) return null;
320
+ const [authored, written, ...rest] = parsed;
321
+ if (authored !== null && typeof authored !== "string") return null;
322
+ const linked = rest[0] !== false;
323
+ const beneath = linked ? rest : rest.slice(1);
324
+ if (!beneath.every((under) => typeof under === "string")) return null;
325
+ return typeof written === "boolean" ? { authored, written, linked, beneath } : null;
326
+ } catch {
327
+ return null;
328
+ }
126
329
  }
127
- /** The declared regions that sit within `host`, which may be the host itself. */
128
330
  #inside(host, regions) {
129
331
  return regions.filter((region) => host.contains(region));
130
332
  }
131
333
  };
132
334
 
133
- // src/controllers/stick_to_bottom_controller.ts
134
335
  var DEFAULT_THRESHOLD = 80;
135
336
  var countElements = (nodes) => {
136
337
  let n = 0;
137
338
  for (const node of nodes) if (node.nodeType === Node.ELEMENT_NODE) n += 1;
138
339
  return n;
139
340
  };
140
- var StickToBottomController = class extends Controller {
341
+ var StickToBottomController = class _StickToBottomController extends Controller {
342
+ #numbers = new NumberValueReader();
141
343
  static targets = ["content", "hasNew"];
142
344
  static values = {
143
345
  threshold: { type: Number, default: DEFAULT_THRESHOLD },
144
346
  behavior: { type: String, default: "auto" },
145
347
  pinOnConnect: { type: Boolean, default: false }
146
348
  };
349
+ static valueConstraints = {
350
+ threshold: NUMBER_BOUNDS.nonNegative
351
+ };
147
352
  static actions = ["scrollToBottom"];
148
353
  static events = ["pin", "new"];
149
354
  #observer = null;
150
- /** The element the append observer currently holds, so a swap can be detected. */
151
355
  #watched = null;
152
- /** Watches for the box a container connected without one is still waiting on. */
153
356
  #layout = new LayoutObserver(() => this.#onLaidOut());
154
357
  #awaitingLayout = false;
155
358
  #connected = false;
156
359
  #pinned = false;
157
360
  #hasNew = false;
158
- /** Owns `hidden` on the regions declared for the has-new state. */
159
- #hasNewRegion = new StateRegions({ whenTrue: () => this.hasNewTargets });
361
+ #hasNewRegion = new StateRegions(
362
+ { whenTrue: () => this.hasNewTargets },
363
+ this.identifier
364
+ );
160
365
  #onScroll = () => this.#updatePinned();
366
+ #morphRender = new MorphRenderWatcher(() => {
367
+ this.#updatePinned();
368
+ this.#setHasNew(this.#hasNew);
369
+ });
370
+ #listeners = new ListenerSet();
161
371
  connect() {
372
+ this.#morphRender.observe(this.element);
162
373
  this.#connected = true;
163
374
  if (this.pinOnConnectValue && this.#measurable()) this.#scrollToBottom("instant");
164
375
  this.#setHasNew(false);
165
376
  this.#pinned = this.#isPinned();
166
377
  this.#reflectPinned();
167
- this.element.addEventListener("scroll", this.#onScroll, { passive: true });
378
+ this.#listeners.add(this.element, "scroll", this.#onScroll, { passive: true });
168
379
  this.#syncWatched();
169
380
  if (!this.#measurable()) this.#waitForLayout();
170
381
  }
171
382
  disconnect() {
383
+ this.#morphRender.disconnect();
172
384
  this.#connected = false;
173
- this.element.removeEventListener("scroll", this.#onScroll);
385
+ this.#listeners.dispose();
174
386
  this.#stopWatching();
175
387
  this.#stopWaitingForLayout();
176
388
  }
177
- /** Moves the append watch onto a `content` target that arrived at runtime. */
178
389
  contentTargetConnected() {
179
390
  this.#syncWatched();
180
391
  }
181
- /** Moves the append watch off a `content` target that left, back onto the container. */
182
392
  contentTargetDisconnected() {
183
393
  this.#syncWatched();
184
394
  }
185
- /**
186
- * Settles a has-new region that arrived at runtime on the side the flag is currently
187
- * on, the way a region present at connect is settled by the connect-time normalization.
188
- *
189
- * Stimulus attaches targets before `connect()`, and a container that leaves the document
190
- * and comes back keeps its controller, so in that window the flag still reads the
191
- * arrival of the connection that ended. A region attached there is left to the
192
- * connect-time normalization, which drops the flag and settles the region in one write.
193
- */
194
395
  hasNewTargetConnected() {
195
396
  if (!this.#connected) return;
196
397
  this.#hasNewRegion.reflect(this.element, this.#hasNew);
197
398
  }
198
- /**
199
- * Re-derives pinned when the distance that counts as the bottom is changed at runtime
200
- * (a morph that swaps the attribute on a retained element).
201
- */
202
399
  thresholdValueChanged() {
203
400
  if (!this.#connected) return;
204
401
  this.#updatePinned();
205
402
  }
206
- /**
207
- * Jumps to the bottom and re-pins (wired to a "new messages" button).
208
- *
209
- * The has-new flag clears on request — the user has acknowledged the arrival — while
210
- * pinned is read back from where the scroll landed: a jump that arrives by the time
211
- * this returns pins immediately, an animated one settles from its own scroll events,
212
- * and a jump the engine cannot honor leaves the container unpinned, so the next append
213
- * flags it again instead of being swallowed by a pinned state that does not hold.
214
- *
215
- * Which of those happens is not this method's to decide — see {@link behaviorValue}.
216
- */
217
403
  scrollToBottom() {
218
404
  this.#scrollToBottom();
219
405
  this.#setHasNew(false);
220
406
  this.#updatePinned();
221
407
  }
222
- /** Follows appended children while pinned; otherwise flags new content. */
223
408
  #onMutations(mutations) {
224
409
  let added = 0;
225
410
  for (const mutation of mutations) added += countElements(mutation.addedNodes);
@@ -231,19 +416,13 @@ var StickToBottomController = class extends Controller {
231
416
  this.dispatch("new", { detail: { count: added } });
232
417
  }
233
418
  }
234
- /**
235
- * Recomputes pinned from the scroll position and reflects it on a transition.
236
- *
237
- * @stimeoRenderRoot
238
- */
239
419
  #updatePinned() {
240
420
  const pinned = this.#isPinned();
241
- if (pinned === this.#pinned) return;
421
+ const changed = pinned !== this.#pinned;
242
422
  this.#pinned = pinned;
243
423
  this.#reflectPinned();
244
- this.dispatch("pin", { detail: { pinned } });
424
+ if (changed) this.dispatch("pin", { detail: { pinned } });
245
425
  }
246
- /** Mirrors the current `#pinned` onto the state hooks (clearing has-new once pinned). */
247
426
  #reflectPinned() {
248
427
  if (this.#pinned) {
249
428
  this.element.setAttribute("data-pinned", "true");
@@ -252,10 +431,6 @@ var StickToBottomController = class extends Controller {
252
431
  this.element.removeAttribute("data-pinned");
253
432
  }
254
433
  }
255
- /**
256
- * Mirrors whether content has arrived that the container did not follow onto the state
257
- * hook and onto the regions declared for that state.
258
- */
259
434
  #setHasNew(hasNew) {
260
435
  this.#hasNew = hasNew;
261
436
  if (hasNew) {
@@ -265,61 +440,31 @@ var StickToBottomController = class extends Controller {
265
440
  }
266
441
  this.#hasNewRegion.reflect(this.element, hasNew);
267
442
  }
268
- /** Whether the container currently sits within `threshold` of its bottom. */
269
443
  #isPinned() {
270
444
  if (!this.#measurable()) return false;
271
445
  const el = this.element;
272
446
  return el.scrollHeight - el.clientHeight - el.scrollTop <= this.#threshold;
273
447
  }
274
- /**
275
- * The distance from the bottom that counts as pinned: a finite, non-negative number of
276
- * pixels. Anything else names no distance the container can be at, and settles the
277
- * comparison the same way at every scroll position, so it falls back to the default.
278
- * `Number` reads `"abc"` as `NaN` and every comparison against it is false; a negative
279
- * distance sits below the closest the container ever gets; `Infinity` is never
280
- * exceeded. The first two stop following and flag every append as new, and the last
281
- * never stops following — it takes the reading position the flag exists to protect.
282
- * Zero is a real declaration: it pins at the exact bottom only.
283
- */
284
448
  get #threshold() {
285
- const declared = this.thresholdValue;
286
- return Number.isFinite(declared) && declared >= 0 ? declared : DEFAULT_THRESHOLD;
287
- }
288
- /**
289
- * Whether the container has a box to scroll and to measure. One that is not rendered
290
- * (inside a closed panel) reports every metric as 0, which reads as "already at the
291
- * bottom" — a position describing no layout the user will ever see.
292
- */
449
+ return this.#safeThreshold;
450
+ }
293
451
  #measurable() {
294
452
  return this.element.clientHeight > 0;
295
453
  }
296
- /**
297
- * Holds the pinned decision until the container is laid out — otherwise the panel opens
298
- * at the top while the state claims the bottom, and the appends that arrived meanwhile
299
- * were followed into a box that could not move rather than flagged.
300
- */
301
454
  #waitForLayout() {
302
455
  this.#awaitingLayout = true;
303
456
  this.#layout.observe(this.element);
304
457
  }
305
- /** Runs the held decision once the container has the box it was waiting for. */
306
458
  #onLaidOut() {
307
459
  if (!this.#awaitingLayout || !this.#measurable()) return;
308
460
  this.#stopWaitingForLayout();
309
461
  if (this.pinOnConnectValue) this.#scrollToBottom("instant");
310
462
  this.#updatePinned();
311
463
  }
312
- /** Releases the layout watch, whether or not the held decision ever ran. */
313
464
  #stopWaitingForLayout() {
314
465
  this.#awaitingLayout = false;
315
466
  this.#layout.disconnect();
316
467
  }
317
- /**
318
- * Scrolls to the bottom, clamped by the engine to the maximum scroll offset — which is
319
- * 0 for a container tall enough to hold its whole content, so the jump moves nothing
320
- * there. `behavior` defaults to the configured follow behavior; pass `"instant"` for a
321
- * jump that must not animate.
322
- */
323
468
  #scrollToBottom(behavior = this.#behavior()) {
324
469
  const top = this.element.scrollHeight;
325
470
  if (typeof this.element.scrollTo === "function") {
@@ -328,17 +473,6 @@ var StickToBottomController = class extends Controller {
328
473
  this.element.scrollTop = top;
329
474
  }
330
475
  }
331
- /**
332
- * Points the append watch at the current `content` target, or at the container when
333
- * there is none. Re-resolved whenever that target changes, so a swap does not leave the
334
- * observer holding a detached node whose appends nobody sees.
335
- *
336
- * Stimulus runs the target callbacks outside the connected window too — before
337
- * `connect()` for a target already in the DOM, and after `disconnect()` while the
338
- * element is torn down — where this would arm an observer nothing releases. Re-syncing
339
- * to the target already held is left alone, so an arrival still in flight is not
340
- * dropped with the observer that was about to deliver it.
341
- */
342
476
  #syncWatched() {
343
477
  if (!this.#connected) return;
344
478
  const next = this.hasContentTarget ? this.contentTarget : this.element;
@@ -349,24 +483,25 @@ var StickToBottomController = class extends Controller {
349
483
  this.#observer = new MutationObserver((mutations) => this.#onMutations(mutations));
350
484
  this.#observer.observe(next, { childList: true });
351
485
  }
352
- /** Releases the append watch and the element it held. */
353
486
  #stopWatching() {
354
487
  this.#observer?.disconnect();
355
488
  this.#observer = null;
356
489
  this.#watched = null;
357
490
  }
358
- /**
359
- * The behavior a follow-scroll runs with. `"auto"` is **not** a request to arrive at
360
- * once: it hands the decision to the element's computed `scroll-behavior`, so a
361
- * consumer stylesheet saying `smooth` animates these scrolls too. Only `"instant"`
362
- * overrides that CSS, which is why reduced motion and the `pinOnConnect` jump name it.
363
- */
364
491
  #behavior() {
365
492
  if (prefersReducedMotion()) return "instant";
366
493
  return this.behaviorValue === "smooth" ? "smooth" : "auto";
367
494
  }
495
+ get #safeThreshold() {
496
+ return this.#numbers.read(
497
+ this,
498
+ "threshold",
499
+ this.thresholdValue,
500
+ _StickToBottomController.values.threshold.default,
501
+ _StickToBottomController.valueConstraints.threshold
502
+ );
503
+ }
368
504
  };
369
505
 
370
506
  export { StickToBottomController };
371
- //# sourceMappingURL=stick_to_bottom_controller.js.map
372
507
  //# sourceMappingURL=stick_to_bottom_controller.js.map