stimeo-ui 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +8 -1
  3. package/dist/cable/index.d.ts +79 -23
  4. package/dist/cable/index.js +363 -436
  5. package/dist/cable/index.js.map +1 -1
  6. package/dist/controllers/accordion_controller.d.ts +4 -2
  7. package/dist/controllers/accordion_controller.js +166 -55
  8. package/dist/controllers/accordion_controller.js.map +1 -1
  9. package/dist/controllers/alert_dialog_controller.d.ts +12 -2
  10. package/dist/controllers/alert_dialog_controller.js +862 -221
  11. package/dist/controllers/alert_dialog_controller.js.map +1 -1
  12. package/dist/controllers/announcer_controller.d.ts +35 -5
  13. package/dist/controllers/announcer_controller.js +135 -198
  14. package/dist/controllers/announcer_controller.js.map +1 -1
  15. package/dist/controllers/aspect_ratio_controller.js +0 -10
  16. package/dist/controllers/aspect_ratio_controller.js.map +1 -1
  17. package/dist/controllers/auto_submit_controller.d.ts +30 -6
  18. package/dist/controllers/auto_submit_controller.js +271 -127
  19. package/dist/controllers/auto_submit_controller.js.map +1 -1
  20. package/dist/controllers/avatar_controller.js +171 -105
  21. package/dist/controllers/avatar_controller.js.map +1 -1
  22. package/dist/controllers/breadcrumb_controller.js +0 -130
  23. package/dist/controllers/breadcrumb_controller.js.map +1 -1
  24. package/dist/controllers/bulk_select_controller.d.ts +18 -0
  25. package/dist/controllers/bulk_select_controller.js +262 -52
  26. package/dist/controllers/bulk_select_controller.js.map +1 -1
  27. package/dist/controllers/calendar_controller.d.ts +24 -5
  28. package/dist/controllers/calendar_controller.js +175 -209
  29. package/dist/controllers/calendar_controller.js.map +1 -1
  30. package/dist/controllers/carousel_controller.d.ts +34 -7
  31. package/dist/controllers/carousel_controller.js +461 -399
  32. package/dist/controllers/carousel_controller.js.map +1 -1
  33. package/dist/controllers/character_counter_controller.d.ts +17 -1
  34. package/dist/controllers/character_counter_controller.js +246 -156
  35. package/dist/controllers/character_counter_controller.js.map +1 -1
  36. package/dist/controllers/checkbox_controller.d.ts +7 -2
  37. package/dist/controllers/checkbox_controller.js +32 -74
  38. package/dist/controllers/checkbox_controller.js.map +1 -1
  39. package/dist/controllers/clipboard_controller.d.ts +16 -5
  40. package/dist/controllers/clipboard_controller.js +168 -147
  41. package/dist/controllers/clipboard_controller.js.map +1 -1
  42. package/dist/controllers/collapsible_controller.d.ts +16 -4
  43. package/dist/controllers/collapsible_controller.js +301 -120
  44. package/dist/controllers/collapsible_controller.js.map +1 -1
  45. package/dist/controllers/color_picker_controller.d.ts +18 -6
  46. package/dist/controllers/color_picker_controller.js +149 -139
  47. package/dist/controllers/color_picker_controller.js.map +1 -1
  48. package/dist/controllers/combobox_controller.d.ts +23 -5
  49. package/dist/controllers/combobox_controller.js +360 -133
  50. package/dist/controllers/combobox_controller.js.map +1 -1
  51. package/dist/controllers/command_palette_controller.d.ts +45 -14
  52. package/dist/controllers/command_palette_controller.js +970 -358
  53. package/dist/controllers/command_palette_controller.js.map +1 -1
  54. package/dist/controllers/conditional_fields_controller.d.ts +15 -2
  55. package/dist/controllers/conditional_fields_controller.js +166 -124
  56. package/dist/controllers/conditional_fields_controller.js.map +1 -1
  57. package/dist/controllers/confirm_controller.d.ts +49 -12
  58. package/dist/controllers/confirm_controller.js +939 -248
  59. package/dist/controllers/confirm_controller.js.map +1 -1
  60. package/dist/controllers/context_menu_controller.d.ts +31 -4
  61. package/dist/controllers/context_menu_controller.js +256 -128
  62. package/dist/controllers/context_menu_controller.js.map +1 -1
  63. package/dist/controllers/count_up_controller.d.ts +13 -1
  64. package/dist/controllers/count_up_controller.js +73 -21
  65. package/dist/controllers/count_up_controller.js.map +1 -1
  66. package/dist/controllers/countdown_controller.d.ts +45 -1
  67. package/dist/controllers/countdown_controller.js +183 -148
  68. package/dist/controllers/countdown_controller.js.map +1 -1
  69. package/dist/controllers/currency_input_controller.d.ts +21 -2
  70. package/dist/controllers/currency_input_controller.js +134 -158
  71. package/dist/controllers/currency_input_controller.js.map +1 -1
  72. package/dist/controllers/data_grid_controller.d.ts +15 -4
  73. package/dist/controllers/data_grid_controller.js +114 -186
  74. package/dist/controllers/data_grid_controller.js.map +1 -1
  75. package/dist/controllers/date_range_picker_controller.d.ts +30 -5
  76. package/dist/controllers/date_range_picker_controller.js +288 -206
  77. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  78. package/dist/controllers/dialog_controller.d.ts +13 -1
  79. package/dist/controllers/dialog_controller.js +858 -223
  80. package/dist/controllers/dialog_controller.js.map +1 -1
  81. package/dist/controllers/direct_upload_controller.d.ts +24 -7
  82. package/dist/controllers/direct_upload_controller.js +73 -153
  83. package/dist/controllers/direct_upload_controller.js.map +1 -1
  84. package/dist/controllers/dirty_form_controller.js +14 -48
  85. package/dist/controllers/dirty_form_controller.js.map +1 -1
  86. package/dist/controllers/dismissible_controller.d.ts +19 -0
  87. package/dist/controllers/dismissible_controller.js +175 -21
  88. package/dist/controllers/dismissible_controller.js.map +1 -1
  89. package/dist/controllers/drawer_controller.d.ts +39 -11
  90. package/dist/controllers/drawer_controller.js +933 -341
  91. package/dist/controllers/drawer_controller.js.map +1 -1
  92. package/dist/controllers/dropdown_controller.d.ts +31 -1
  93. package/dist/controllers/dropdown_controller.js +312 -82
  94. package/dist/controllers/dropdown_controller.js.map +1 -1
  95. package/dist/controllers/editable_controller.d.ts +12 -1
  96. package/dist/controllers/editable_controller.js +158 -68
  97. package/dist/controllers/editable_controller.js.map +1 -1
  98. package/dist/controllers/empty_state_controller.js +67 -53
  99. package/dist/controllers/empty_state_controller.js.map +1 -1
  100. package/dist/controllers/file_dropzone_controller.d.ts +60 -18
  101. package/dist/controllers/file_dropzone_controller.js +311 -207
  102. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  103. package/dist/controllers/filter_controller.js +67 -39
  104. package/dist/controllers/filter_controller.js.map +1 -1
  105. package/dist/controllers/flash_controller.d.ts +31 -8
  106. package/dist/controllers/flash_controller.js +172 -314
  107. package/dist/controllers/flash_controller.js.map +1 -1
  108. package/dist/controllers/focus_controller.d.ts +12 -3
  109. package/dist/controllers/focus_controller.js +654 -240
  110. package/dist/controllers/focus_controller.js.map +1 -1
  111. package/dist/controllers/form_field_controller.js +147 -132
  112. package/dist/controllers/form_field_controller.js.map +1 -1
  113. package/dist/controllers/form_validation_controller.js +13 -86
  114. package/dist/controllers/form_validation_controller.js.map +1 -1
  115. package/dist/controllers/frame_loading_controller.d.ts +41 -9
  116. package/dist/controllers/frame_loading_controller.js +264 -213
  117. package/dist/controllers/frame_loading_controller.js.map +1 -1
  118. package/dist/controllers/highlight_controller.d.ts +22 -2
  119. package/dist/controllers/highlight_controller.js +107 -75
  120. package/dist/controllers/highlight_controller.js.map +1 -1
  121. package/dist/controllers/hover_card_controller.d.ts +56 -3
  122. package/dist/controllers/hover_card_controller.js +309 -118
  123. package/dist/controllers/hover_card_controller.js.map +1 -1
  124. package/dist/controllers/idle_controller.d.ts +42 -1
  125. package/dist/controllers/idle_controller.js +267 -101
  126. package/dist/controllers/idle_controller.js.map +1 -1
  127. package/dist/controllers/input_mask_controller.js +71 -72
  128. package/dist/controllers/input_mask_controller.js.map +1 -1
  129. package/dist/controllers/intersection_controller.d.ts +32 -13
  130. package/dist/controllers/intersection_controller.js +147 -106
  131. package/dist/controllers/intersection_controller.js.map +1 -1
  132. package/dist/controllers/lazy_frame_controller.d.ts +16 -0
  133. package/dist/controllers/lazy_frame_controller.js +9 -65
  134. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  135. package/dist/controllers/listbox_controller.d.ts +34 -2
  136. package/dist/controllers/listbox_controller.js +306 -204
  137. package/dist/controllers/listbox_controller.js.map +1 -1
  138. package/dist/controllers/local_time_controller.d.ts +1 -1
  139. package/dist/controllers/local_time_controller.js +54 -64
  140. package/dist/controllers/local_time_controller.js.map +1 -1
  141. package/dist/controllers/masonry_controller.d.ts +11 -3
  142. package/dist/controllers/masonry_controller.js +70 -93
  143. package/dist/controllers/masonry_controller.js.map +1 -1
  144. package/dist/controllers/menu_controller.d.ts +32 -7
  145. package/dist/controllers/menu_controller.js +214 -156
  146. package/dist/controllers/menu_controller.js.map +1 -1
  147. package/dist/controllers/menubar_controller.d.ts +4 -4
  148. package/dist/controllers/menubar_controller.js +170 -329
  149. package/dist/controllers/menubar_controller.js.map +1 -1
  150. package/dist/controllers/meter_controller.d.ts +20 -0
  151. package/dist/controllers/meter_controller.js +151 -67
  152. package/dist/controllers/meter_controller.js.map +1 -1
  153. package/dist/controllers/multi_select_controller.d.ts +32 -4
  154. package/dist/controllers/multi_select_controller.js +593 -358
  155. package/dist/controllers/multi_select_controller.js.map +1 -1
  156. package/dist/controllers/navigation_menu_controller.d.ts +8 -1
  157. package/dist/controllers/navigation_menu_controller.js +124 -232
  158. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  159. package/dist/controllers/nested_form_controller.d.ts +10 -0
  160. package/dist/controllers/nested_form_controller.js +352 -182
  161. package/dist/controllers/nested_form_controller.js.map +1 -1
  162. package/dist/controllers/network_status_controller.d.ts +23 -0
  163. package/dist/controllers/network_status_controller.js +242 -54
  164. package/dist/controllers/network_status_controller.js.map +1 -1
  165. package/dist/controllers/number_input_controller.d.ts +26 -2
  166. package/dist/controllers/number_input_controller.js +320 -263
  167. package/dist/controllers/number_input_controller.js.map +1 -1
  168. package/dist/controllers/optimistic_controller.js +16 -76
  169. package/dist/controllers/optimistic_controller.js.map +1 -1
  170. package/dist/controllers/otp_controller.d.ts +20 -4
  171. package/dist/controllers/otp_controller.js +198 -193
  172. package/dist/controllers/otp_controller.js.map +1 -1
  173. package/dist/controllers/overflow_indicator_controller.d.ts +5 -0
  174. package/dist/controllers/overflow_indicator_controller.js +116 -113
  175. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  176. package/dist/controllers/overflow_menu_controller.d.ts +48 -11
  177. package/dist/controllers/overflow_menu_controller.js +343 -283
  178. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  179. package/dist/controllers/pagination_controller.d.ts +35 -6
  180. package/dist/controllers/pagination_controller.js +295 -119
  181. package/dist/controllers/pagination_controller.js.map +1 -1
  182. package/dist/controllers/password_reveal_controller.d.ts +45 -8
  183. package/dist/controllers/password_reveal_controller.js +389 -121
  184. package/dist/controllers/password_reveal_controller.js.map +1 -1
  185. package/dist/controllers/password_strength_controller.d.ts +14 -5
  186. package/dist/controllers/password_strength_controller.js +99 -153
  187. package/dist/controllers/password_strength_controller.js.map +1 -1
  188. package/dist/controllers/persist_controller.d.ts +11 -4
  189. package/dist/controllers/persist_controller.js +237 -103
  190. package/dist/controllers/persist_controller.js.map +1 -1
  191. package/dist/controllers/pointer_drag_controller.d.ts +19 -7
  192. package/dist/controllers/pointer_drag_controller.js +185 -165
  193. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  194. package/dist/controllers/popover_controller.d.ts +38 -2
  195. package/dist/controllers/popover_controller.js +236 -97
  196. package/dist/controllers/popover_controller.js.map +1 -1
  197. package/dist/controllers/portal_controller.d.ts +44 -4
  198. package/dist/controllers/portal_controller.js +209 -76
  199. package/dist/controllers/portal_controller.js.map +1 -1
  200. package/dist/controllers/preview_guard_controller.d.ts +10 -4
  201. package/dist/controllers/preview_guard_controller.js +232 -116
  202. package/dist/controllers/preview_guard_controller.js.map +1 -1
  203. package/dist/controllers/progress_controller.d.ts +11 -0
  204. package/dist/controllers/progress_controller.js +125 -56
  205. package/dist/controllers/progress_controller.js.map +1 -1
  206. package/dist/controllers/radio_group_controller.d.ts +14 -5
  207. package/dist/controllers/radio_group_controller.js +117 -137
  208. package/dist/controllers/radio_group_controller.js.map +1 -1
  209. package/dist/controllers/range_slider_controller.d.ts +43 -3
  210. package/dist/controllers/range_slider_controller.js +192 -105
  211. package/dist/controllers/range_slider_controller.js.map +1 -1
  212. package/dist/controllers/rating_controller.d.ts +20 -4
  213. package/dist/controllers/rating_controller.js +418 -207
  214. package/dist/controllers/rating_controller.js.map +1 -1
  215. package/dist/controllers/read_more_controller.d.ts +2 -0
  216. package/dist/controllers/read_more_controller.js +134 -63
  217. package/dist/controllers/read_more_controller.js.map +1 -1
  218. package/dist/controllers/reading_progress_controller.d.ts +1 -1
  219. package/dist/controllers/reading_progress_controller.js +147 -135
  220. package/dist/controllers/reading_progress_controller.js.map +1 -1
  221. package/dist/controllers/relative_time_controller.d.ts +18 -4
  222. package/dist/controllers/relative_time_controller.js +145 -110
  223. package/dist/controllers/relative_time_controller.js.map +1 -1
  224. package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
  225. package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +97 -38
  226. package/dist/controllers/reset_on_restore_controller.js.map +1 -0
  227. package/dist/controllers/resizable_controller.d.ts +28 -2
  228. package/dist/controllers/resizable_controller.js +255 -139
  229. package/dist/controllers/resizable_controller.js.map +1 -1
  230. package/dist/controllers/roving_controller.js +39 -84
  231. package/dist/controllers/roving_controller.js.map +1 -1
  232. package/dist/controllers/scroll_area_controller.d.ts +7 -3
  233. package/dist/controllers/scroll_area_controller.js +428 -225
  234. package/dist/controllers/scroll_area_controller.js.map +1 -1
  235. package/dist/controllers/scroll_restore_controller.js +0 -53
  236. package/dist/controllers/scroll_restore_controller.js.map +1 -1
  237. package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
  238. package/dist/controllers/scroll_visibility_controller.js +395 -145
  239. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  240. package/dist/controllers/scrollspy_controller.d.ts +6 -1
  241. package/dist/controllers/scrollspy_controller.js +181 -242
  242. package/dist/controllers/scrollspy_controller.js.map +1 -1
  243. package/dist/controllers/separator_controller.d.ts +19 -4
  244. package/dist/controllers/separator_controller.js +267 -140
  245. package/dist/controllers/separator_controller.js.map +1 -1
  246. package/dist/controllers/sidebar_controller.d.ts +64 -7
  247. package/dist/controllers/sidebar_controller.js +1023 -386
  248. package/dist/controllers/sidebar_controller.js.map +1 -1
  249. package/dist/controllers/skeleton_controller.d.ts +23 -0
  250. package/dist/controllers/skeleton_controller.js +248 -97
  251. package/dist/controllers/skeleton_controller.js.map +1 -1
  252. package/dist/controllers/slider_controller.d.ts +27 -1
  253. package/dist/controllers/slider_controller.js +159 -79
  254. package/dist/controllers/slider_controller.js.map +1 -1
  255. package/dist/controllers/smart_sticky_header_controller.d.ts +21 -3
  256. package/dist/controllers/smart_sticky_header_controller.js +162 -63
  257. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  258. package/dist/controllers/sortable_controller.js +0 -112
  259. package/dist/controllers/sortable_controller.js.map +1 -1
  260. package/dist/controllers/spinner_controller.d.ts +39 -4
  261. package/dist/controllers/spinner_controller.js +277 -169
  262. package/dist/controllers/spinner_controller.js.map +1 -1
  263. package/dist/controllers/step_indicator_controller.d.ts +5 -0
  264. package/dist/controllers/step_indicator_controller.js +99 -46
  265. package/dist/controllers/step_indicator_controller.js.map +1 -1
  266. package/dist/controllers/stepper_controller.d.ts +12 -3
  267. package/dist/controllers/stepper_controller.js +114 -73
  268. package/dist/controllers/stepper_controller.js.map +1 -1
  269. package/dist/controllers/stick_to_bottom_controller.d.ts +6 -0
  270. package/dist/controllers/stick_to_bottom_controller.js +262 -138
  271. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  272. package/dist/controllers/sticky_observer_controller.d.ts +11 -0
  273. package/dist/controllers/sticky_observer_controller.js +214 -49
  274. package/dist/controllers/sticky_observer_controller.js.map +1 -1
  275. package/dist/controllers/submit_once_controller.d.ts +23 -8
  276. package/dist/controllers/submit_once_controller.js +294 -205
  277. package/dist/controllers/submit_once_controller.js.map +1 -1
  278. package/dist/controllers/switch_controller.d.ts +12 -1
  279. package/dist/controllers/switch_controller.js +33 -60
  280. package/dist/controllers/switch_controller.js.map +1 -1
  281. package/dist/controllers/tabs_controller.d.ts +2 -2
  282. package/dist/controllers/tabs_controller.js +35 -29
  283. package/dist/controllers/tabs_controller.js.map +1 -1
  284. package/dist/controllers/tags_input_controller.d.ts +12 -0
  285. package/dist/controllers/tags_input_controller.js +136 -145
  286. package/dist/controllers/tags_input_controller.js.map +1 -1
  287. package/dist/controllers/textarea_autosize_controller.d.ts +10 -0
  288. package/dist/controllers/textarea_autosize_controller.js +71 -58
  289. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  290. package/dist/controllers/theme_controller.d.ts +21 -9
  291. package/dist/controllers/theme_controller.js +130 -112
  292. package/dist/controllers/theme_controller.js.map +1 -1
  293. package/dist/controllers/time_picker_controller.d.ts +18 -1
  294. package/dist/controllers/time_picker_controller.js +146 -80
  295. package/dist/controllers/time_picker_controller.js.map +1 -1
  296. package/dist/controllers/toast_controller.d.ts +36 -11
  297. package/dist/controllers/toast_controller.js +186 -297
  298. package/dist/controllers/toast_controller.js.map +1 -1
  299. package/dist/controllers/toggle_group_controller.d.ts +12 -3
  300. package/dist/controllers/toggle_group_controller.js +95 -136
  301. package/dist/controllers/toggle_group_controller.js.map +1 -1
  302. package/dist/controllers/toolbar_controller.js +68 -98
  303. package/dist/controllers/toolbar_controller.js.map +1 -1
  304. package/dist/controllers/tooltip_controller.d.ts +45 -3
  305. package/dist/controllers/tooltip_controller.js +158 -124
  306. package/dist/controllers/tooltip_controller.js.map +1 -1
  307. package/dist/controllers/transition_controller.d.ts +22 -4
  308. package/dist/controllers/transition_controller.js +123 -119
  309. package/dist/controllers/transition_controller.js.map +1 -1
  310. package/dist/controllers/tree_view_controller.d.ts +21 -11
  311. package/dist/controllers/tree_view_controller.js +150 -345
  312. package/dist/controllers/tree_view_controller.js.map +1 -1
  313. package/dist/index.d.ts +8 -5
  314. package/dist/index.js +6370 -9346
  315. package/dist/index.js.map +1 -1
  316. package/dist/inspector/cli.d.ts +23 -3
  317. package/dist/inspector/cli.js +92 -37
  318. package/dist/inspector/cli.js.map +1 -1
  319. package/dist/inspector/cli_bin.js +92 -56
  320. package/dist/inspector/cli_bin.js.map +1 -1
  321. package/dist/inspector/examples.json +8 -8
  322. package/dist/inspector/manifest.json +787 -100
  323. package/dist/positioning/index.d.ts +8 -0
  324. package/dist/positioning/index.js +148 -47
  325. package/dist/positioning/index.js.map +1 -1
  326. package/package.json +6 -6
  327. package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
  328. package/dist/controllers/reset_before_cache_controller.js.map +0 -1
@@ -38,16 +38,39 @@ declare class SkeletonController extends Controller<HTMLElement> {
38
38
  default: number;
39
39
  };
40
40
  };
41
+ static valueConstraints: {
42
+ minDuration: {
43
+ readonly finite: true;
44
+ readonly min: 0;
45
+ readonly max: 2147483647;
46
+ };
47
+ };
41
48
  static actions: readonly ["ready", "reset"];
42
49
  static events: readonly ["ready"];
43
50
  readonly placeholderTarget: HTMLElement;
51
+ readonly placeholderTargets: HTMLElement[];
44
52
  readonly contentTarget: HTMLElement;
53
+ readonly contentTargets: HTMLElement[];
45
54
  readonly hasPlaceholderTarget: boolean;
46
55
  readonly hasContentTarget: boolean;
47
56
  minDurationValue: number;
48
57
  announceReadyTextValue: string;
49
58
  connect(): void;
50
59
  disconnect(): void;
60
+ /** Shows or hides a placeholder that arrives at runtime as the phase calls for. */
61
+ placeholderTargetConnected(): void;
62
+ /**
63
+ * Gives a placeholder that no longer resolves its own `hidden` back, even after
64
+ * `disconnect()`, and while connected repaints the placeholder that stays.
65
+ */
66
+ placeholderTargetDisconnected(placeholder: HTMLElement): void;
67
+ /** Shows or hides content that arrives at runtime as the phase calls for. */
68
+ contentTargetConnected(): void;
69
+ /**
70
+ * Gives content that no longer resolves its own `hidden` back, even after
71
+ * `disconnect()`, and while connected repaints the content that stays.
72
+ */
73
+ contentTargetDisconnected(content: HTMLElement): void;
51
74
  /** Swaps to the real content. Honors `minDuration` to prevent a flash. */
52
75
  ready(): void;
53
76
  /** Returns to the loading state (e.g. a Turbo Stream re-fetch). */
@@ -1,8 +1,5 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/skeleton_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;
@@ -19,88 +16,203 @@ function fillTemplate(template, values) {
19
16
  });
20
17
  }
21
18
 
22
- // src/utils/detach_gate.ts
19
+ function sharedRegistry(key, create) {
20
+ const symbol = Symbol.for(key);
21
+ const scope = globalThis;
22
+ const existing = scope[symbol];
23
+ if (existing !== void 0) return existing;
24
+ const registry = create();
25
+ Object.defineProperty(globalThis, symbol, { value: registry });
26
+ return registry;
27
+ }
28
+
29
+ function isAttributeValue(value) {
30
+ return value === null || typeof value === "string";
31
+ }
32
+ function readLeaseRecord(element, record) {
33
+ try {
34
+ const parsed = JSON.parse(element.getAttribute(record) ?? "null");
35
+ if (!Array.isArray(parsed)) return void 0;
36
+ const [original, written, ...rest] = parsed;
37
+ const linked = rest[0] !== false;
38
+ const beneath = linked ? rest : rest.slice(1);
39
+ if (!beneath.every((under) => typeof under === "string")) return void 0;
40
+ return isAttributeValue(original) && isAttributeValue(written) ? { original, written, linked, beneath } : void 0;
41
+ } catch {
42
+ return void 0;
43
+ }
44
+ }
45
+ var AttributeLease = class _AttributeLease {
46
+ static #registry = sharedRegistry(
47
+ "stimeo-ui.attribute-lease.registry.v1",
48
+ () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
49
+ );
50
+ #attribute;
51
+ #record;
52
+ #base;
53
+ #held = /* @__PURE__ */ new Set();
54
+ constructor(attribute, owner, options = {}) {
55
+ this.#attribute = attribute;
56
+ this.#record = `data-${owner}-${attribute}-lease`;
57
+ this.#base = options.base === true;
58
+ const names = _AttributeLease.#registry.names;
59
+ names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
60
+ }
61
+ write(element, value) {
62
+ const stack = this.#stack(element);
63
+ const hold = this.#take(stack) ?? this.#acquire(element, stack);
64
+ this.#held.add(element);
65
+ const shows = !this.#covered(element, stack, hold);
66
+ hold.written = value;
67
+ this.#mark(element, stack);
68
+ if (shows) this.#reflect(element, value);
69
+ }
70
+ return(element) {
71
+ const held = this.#held.delete(element);
72
+ const known = _AttributeLease.#registry.stacks.get(element)?.has(this.#attribute);
73
+ const stack = held || known || element.hasAttribute(this.#record) ? this.#stack(element) : [];
74
+ const hold = this.#take(stack);
75
+ if (!hold) return false;
76
+ const carries = element.getAttribute(this.#attribute) === hold.written;
77
+ const owns = carries && !this.#covered(element, stack, hold);
78
+ const index = stack.indexOf(hold);
79
+ stack.splice(index, 1);
80
+ const above = stack[index];
81
+ if (above) above.linked &&= hold.linked;
82
+ this.#mark(element, stack);
83
+ if (!owns) return true;
84
+ const below = hold.linked ? stack[index - 1] : void 0;
85
+ this.#reflect(element, below ? below.written : hold.original);
86
+ return true;
87
+ }
88
+ returnAll() {
89
+ for (const element of Array.from(this.#held)) this.return(element);
90
+ }
91
+ #stack(element) {
92
+ const stacks = _AttributeLease.#registry.stacks;
93
+ const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
94
+ stacks.set(element, byAttribute);
95
+ const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
96
+ byAttribute.set(this.#attribute, stack);
97
+ return stack;
98
+ }
99
+ #seed(element) {
100
+ const found = [];
101
+ for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
102
+ const read = readLeaseRecord(element, record);
103
+ if (read) found.push({ ...read, record });
104
+ }
105
+ const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
106
+ return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
107
+ lease: null,
108
+ record,
109
+ written,
110
+ original,
111
+ linked: linked && index > 0
112
+ }));
113
+ }
114
+ #take(stack) {
115
+ const hold = stack.find((held) => held.lease === this) ?? stack.find((held) => held.lease === null && held.record === this.#record);
116
+ if (hold) hold.lease = this;
117
+ return hold;
118
+ }
119
+ #acquire(element, stack) {
120
+ const current = element.getAttribute(this.#attribute);
121
+ const top = stack.at(-1);
122
+ const bottom = stack[0];
123
+ const over = top?.written === current ? top : void 0;
124
+ const from = this.#base ? bottom : over;
125
+ const hold = {
126
+ lease: this,
127
+ record: this.#record,
128
+ written: current,
129
+ original: from ? from.original : current,
130
+ linked: !this.#base && over !== void 0
131
+ };
132
+ if (this.#base && bottom) {
133
+ bottom.linked = true;
134
+ stack.unshift(hold);
135
+ } else stack.push(hold);
136
+ return hold;
137
+ }
138
+ #covered(element, stack, hold) {
139
+ const current = element.getAttribute(this.#attribute);
140
+ return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === current);
141
+ }
142
+ #mark(element, stack) {
143
+ const records = /* @__PURE__ */ new Map([[this.#record, null]]);
144
+ stack.forEach((hold, index) => {
145
+ const names = stack.slice(0, index).map((under) => under.record);
146
+ const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
147
+ const marker = hold.linked || beneath.length === 0 ? [] : [false];
148
+ records.set(
149
+ hold.record,
150
+ hold.written === hold.original && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.original, hold.written, ...marker, ...beneath])
151
+ );
152
+ });
153
+ for (const [name, recorded] of records) {
154
+ if (element.getAttribute(name) === recorded) continue;
155
+ if (recorded === null) element.removeAttribute(name);
156
+ else element.setAttribute(name, recorded);
157
+ }
158
+ }
159
+ #reflect(element, value) {
160
+ if (element.getAttribute(this.#attribute) === value) return;
161
+ if (value === null) element.removeAttribute(this.#attribute);
162
+ else element.setAttribute(this.#attribute, value);
163
+ }
164
+ };
165
+
23
166
  var DetachGate = class _DetachGate {
24
- /** Set while a probe is queued, waiting for a reconnect to cancel it. */
25
167
  #pending = false;
26
- /**
27
- * True while a probe is queued — the last disconnect was ambiguous and no
28
- * reconnect has cancelled it yet. Read it from `connect()` to tell the
29
- * reconnect half of an in-page move from a first connect: a controller whose
30
- * initialisation restarts a measurement (a min-duration floor, an elapsed
31
- * counter) must skip it for the move, where nothing actually restarted.
32
- */
33
168
  get pending() {
34
169
  return this.#pending;
35
170
  }
36
- /**
37
- * True when the disconnect is definitely a real detach — the element left
38
- * the document, or `data-controller` no longer lists the identifier. False
39
- * means ambiguous (in-page move or observed-root exit), NOT "alive".
40
- */
41
171
  static isDetached(host) {
42
- if (!host.element.isConnected) return true;
43
- const tokens = (host.element.getAttribute("data-controller") ?? "").split(/\s+/);
44
- return !tokens.includes(host.identifier);
45
- }
46
- /**
47
- * Call from `disconnect()`: runs `teardown` synchronously on a definite
48
- * detach (fast path), otherwise defers it one microtask — a reconnect
49
- * ({@link cancel} from `connect()`) keeps the state, no reconnect runs it.
50
- * One microtask is the whole probe window: Stimulus reconnects a moved
51
- * element within the same mutation batch, before the checkpoint drains.
52
- */
172
+ return !host.element.isConnected || !_DetachGate.#listed(host);
173
+ }
53
174
  disconnected(host, teardown) {
54
- if (_DetachGate.isDetached(host)) {
175
+ const carried = _DetachGate.#carried(host);
176
+ if (!carried && _DetachGate.isDetached(host)) {
55
177
  this.#pending = false;
56
178
  teardown();
57
179
  return;
58
180
  }
59
181
  this.#pending = true;
60
- queueMicrotask(() => {
182
+ const probe = () => {
61
183
  if (!this.#pending) return;
62
184
  this.#pending = false;
63
185
  teardown();
64
- });
186
+ };
187
+ if (carried) setTimeout(probe, 0);
188
+ else queueMicrotask(probe);
189
+ }
190
+ static #carried(host) {
191
+ const element = host.element;
192
+ return !element.isConnected && element.closest("[data-turbo-permanent]") !== null && _DetachGate.#listed(host);
193
+ }
194
+ static #listed(host) {
195
+ const tokens = (host.element.getAttribute("data-controller") ?? "").split(/\s+/);
196
+ return tokens.includes(host.identifier);
65
197
  }
66
- /**
67
- * Disarms a pending probe. Call from `connect()` (the reconnect that proves
68
- * an in-page move) and from the head of any teardown path not routed through
69
- * {@link disconnected} (disabled-toggle, Escape), so an orphaned probe can
70
- * never run the teardown a second time.
71
- */
72
198
  cancel() {
73
199
  this.#pending = false;
74
200
  }
75
201
  };
76
202
 
77
- // src/utils/min_duration_floor.ts
78
203
  var MinDurationFloor = class {
79
204
  #timers;
80
- /** Pending finish timer id, or `null` when nothing is held back. */
81
205
  #timerId = null;
82
- /** Epoch ms the floor is measured from. */
83
206
  #since = 0;
84
- /** @param timers - the controller's registry; the floor schedules into it. */
85
207
  constructor(timers) {
86
208
  this.#timers = timers;
87
209
  }
88
- /** Starts the floor: call when the state being held becomes visible. */
89
210
  begin() {
90
211
  this.#since = Date.now();
91
212
  }
92
- /** True while a finish is held back waiting for the floor to elapse. */
93
213
  get pending() {
94
214
  return this.#timerId !== null;
95
215
  }
96
- /**
97
- * Runs `finish` once the floor has elapsed, immediately when it already has.
98
- *
99
- * A held-back finish is **replaced**, never stacked: only the most recently
100
- * queued id is cancellable, so a second timer would outlive every cancel and
101
- * end a state that has since restarted. Controllers that want the first signal
102
- * to win guard on {@link pending} before calling.
103
- */
104
216
  schedule(minDuration, finish) {
105
217
  this.cancel();
106
218
  const remaining = minDuration - (Date.now() - this.#since);
@@ -113,7 +225,6 @@ var MinDurationFloor = class {
113
225
  finish();
114
226
  }
115
227
  }
116
- /** Drops a held-back finish. Safe when none is queued, or after a bulk clear. */
117
228
  cancel() {
118
229
  if (this.#timerId !== null) {
119
230
  this.#timers.clear(this.#timerId);
@@ -122,43 +233,70 @@ var MinDurationFloor = class {
122
233
  }
123
234
  };
124
235
 
125
- // src/utils/safe_timeout.ts
236
+ var MAX_TIMER_DELAY_MS = 2147483647;
237
+
238
+ var NUMBER_BOUNDS = {
239
+ timer: { finite: true, min: 0, max: MAX_TIMER_DELAY_MS }};
240
+ function matchesNumberBounds(value, bounds) {
241
+ if (!Number.isFinite(value)) {
242
+ const direction = value === Infinity ? "positive" : value === -Infinity ? "negative" : null;
243
+ if (direction === null) return false;
244
+ if (bounds.allowInfinity !== "both" && bounds.allowInfinity !== direction) return false;
245
+ }
246
+ if (bounds.min !== void 0 && value < bounds.min) return false;
247
+ if (bounds.max !== void 0 && value > bounds.max) return false;
248
+ if (bounds.exclusiveMin !== void 0 && value <= bounds.exclusiveMin) return false;
249
+ if (bounds.integer && !Number.isInteger(value)) return false;
250
+ if (bounds.allowedValues !== void 0 && !bounds.allowedValues.includes(value)) return false;
251
+ return true;
252
+ }
253
+
254
+ function readNumber(raw, fallback, bounds) {
255
+ return matchesNumberBounds(raw, bounds) ? raw : fallback;
256
+ }
257
+
258
+ var NumberValueReader = class {
259
+ #lastRejected = /* @__PURE__ */ new Map();
260
+ read(owner, name, raw, fallback, bounds) {
261
+ const resolved = readNumber(raw, fallback, bounds);
262
+ if (matchesNumberBounds(raw, bounds)) {
263
+ this.#lastRejected.delete(name);
264
+ return resolved;
265
+ }
266
+ const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;
267
+ const literal = owner.element.getAttribute(attribute);
268
+ if (literal === null) {
269
+ this.#lastRejected.delete(name);
270
+ return resolved;
271
+ }
272
+ if (this.#lastRejected.get(name) !== literal) {
273
+ this.#lastRejected.set(name, literal);
274
+ console.warn(
275
+ `Stimeo UI: "${owner.identifier}" has an invalid number Value "${name}" declaration ${JSON.stringify(literal)}; using ${fallback}.`
276
+ );
277
+ }
278
+ return resolved;
279
+ }
280
+ };
281
+
126
282
  var TimerRegistry = class {
127
- /** Live timer ids that have not yet been cleared (or, for timeouts, fired). */
128
283
  ids = /* @__PURE__ */ new Set();
129
- /**
130
- * Cancels a single tracked timer.
131
- *
132
- * No-ops if the id is unknown (already cleared, fired, or never owned by this
133
- * registry), so callers can clear defensively without guarding.
134
- */
135
284
  clear(id) {
136
285
  if (this.ids.delete(id)) {
137
286
  this.cancel(id);
138
287
  }
139
288
  }
140
- /**
141
- * Cancels every tracked timer. Call this from a controller's `disconnect()`
142
- * to guarantee no timer outlives the element.
143
- */
144
289
  clearAll() {
145
290
  for (const id of this.ids) {
146
291
  this.cancel(id);
147
292
  }
148
293
  this.ids.clear();
149
294
  }
150
- /** Number of timers currently tracked (pending). */
151
295
  get size() {
152
296
  return this.ids.size;
153
297
  }
154
298
  };
155
299
  var SafeTimeout = class extends TimerRegistry {
156
- /**
157
- * Schedules `callback` after `delay` ms and returns the timer id.
158
- *
159
- * The id is removed from the registry automatically when the timeout fires,
160
- * so {@link TimerRegistry.size | size} reflects only still-pending timers.
161
- */
162
300
  set(callback, delay) {
163
301
  const id = this.schedule(() => {
164
302
  this.ids.delete(id);
@@ -175,19 +313,25 @@ var SafeTimeout = class extends TimerRegistry {
175
313
  }
176
314
  };
177
315
 
178
- // src/controllers/skeleton_controller.ts
179
- var SkeletonController = class extends Controller {
316
+ var SkeletonController = class _SkeletonController extends Controller {
317
+ #numbers = new NumberValueReader();
180
318
  static targets = ["placeholder", "content"];
181
319
  static values = {
182
320
  announceReadyText: { type: String, default: "" },
183
321
  minDuration: { type: Number, default: 0 }
184
322
  };
323
+ static valueConstraints = {
324
+ minDuration: NUMBER_BOUNDS.timer
325
+ };
185
326
  static actions = ["ready", "reset"];
186
327
  static events = ["ready"];
187
328
  #timers = new SafeTimeout();
188
329
  #floor = new MinDurationFloor(this.#timers);
189
330
  #gate = new DetachGate();
331
+ #hidden = new AttributeLease("hidden", this.identifier);
332
+ #connected = false;
190
333
  connect() {
334
+ this.#connected = true;
191
335
  const moved = this.#gate.pending;
192
336
  this.#gate.cancel();
193
337
  if (!moved && this.#state !== "ready") {
@@ -195,57 +339,64 @@ var SkeletonController = class extends Controller {
195
339
  }
196
340
  }
197
341
  disconnect() {
342
+ this.#connected = false;
198
343
  this.#gate.disconnected(this, () => this.#teardown());
199
344
  }
200
- /** Swaps to the real content. Honors `minDuration` to prevent a flash. */
345
+ placeholderTargetConnected() {
346
+ if (this.#connected) this.#reflect(this.#state === "ready");
347
+ }
348
+ placeholderTargetDisconnected(placeholder) {
349
+ if (!this.placeholderTargets.includes(placeholder)) this.#hidden.return(placeholder);
350
+ if (this.#connected) this.#reflect(this.#state === "ready");
351
+ }
352
+ contentTargetConnected() {
353
+ if (this.#connected) this.#reflect(this.#state === "ready");
354
+ }
355
+ contentTargetDisconnected(content) {
356
+ if (!this.contentTargets.includes(content)) this.#hidden.return(content);
357
+ if (this.#connected) this.#reflect(this.#state === "ready");
358
+ }
201
359
  ready() {
202
360
  if (this.#state === "ready" || this.#floor.pending) return;
203
- this.#floor.schedule(this.minDurationValue, () => this.#reveal());
361
+ this.#floor.schedule(this.#safeMinDuration, () => this.#reveal());
204
362
  }
205
- /** Returns to the loading state (e.g. a Turbo Stream re-fetch). */
206
363
  reset() {
207
364
  this.#floor.cancel();
208
365
  this.#enterLoading();
209
366
  }
210
- /** Shows the placeholder, hides content, and marks the region busy. */
211
367
  #enterLoading() {
212
368
  this.#floor.begin();
213
- if (this.hasPlaceholderTarget) this.placeholderTarget.hidden = false;
214
- if (this.hasContentTarget) this.contentTarget.hidden = true;
369
+ this.#reflect(false);
215
370
  this.element.setAttribute("aria-busy", "true");
216
371
  this.element.setAttribute("data-state", "loading");
217
372
  }
218
- /**
219
- * Hides the placeholder, shows content, and clears the busy state.
220
- *
221
- * @stimeoRuntimeOnly `announceReadyText` is the wording of the one announcement this reveal
222
- * makes.
223
- */
224
373
  #reveal() {
225
- if (this.hasPlaceholderTarget) this.placeholderTarget.hidden = true;
226
- if (this.hasContentTarget) this.contentTarget.hidden = false;
374
+ this.#reflect(true);
227
375
  this.element.setAttribute("aria-busy", "false");
228
376
  this.element.setAttribute("data-state", "ready");
229
377
  this.dispatch("ready", { detail: {} });
230
378
  announce(fillTemplate(this.announceReadyTextValue, {}));
231
379
  }
232
- /**
233
- * Drops the held reveal on a real detach. The markup keeps whatever it last
234
- * held: an element on its way out of the document has no reader left, and one
235
- * whose `data-controller` dropped the identifier no longer resolves its own
236
- * targets, so the rollback could only ever be partial.
237
- */
380
+ #reflect(ready) {
381
+ if (this.hasPlaceholderTarget) this.#hidden.write(this.placeholderTarget, ready ? "" : null);
382
+ if (this.hasContentTarget) this.#hidden.write(this.contentTarget, ready ? null : "");
383
+ }
238
384
  #teardown() {
239
- this.#gate.cancel();
240
- this.#timers.clearAll();
241
385
  this.#floor.cancel();
242
386
  }
243
- /** Current lifecycle phase as reflected on `data-state`. */
244
387
  get #state() {
245
388
  return this.element.getAttribute("data-state") ?? "loading";
246
389
  }
390
+ get #safeMinDuration() {
391
+ return this.#numbers.read(
392
+ this,
393
+ "minDuration",
394
+ this.minDurationValue,
395
+ _SkeletonController.values.minDuration.default,
396
+ _SkeletonController.valueConstraints.minDuration
397
+ );
398
+ }
247
399
  };
248
400
 
249
401
  export { SkeletonController };
250
- //# sourceMappingURL=skeleton_controller.js.map
251
402
  //# sourceMappingURL=skeleton_controller.js.map