stimeo-ui 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/README.md +27 -11
  3. package/dist/cable/index.d.ts +88 -31
  4. package/dist/cable/index.js +384 -449
  5. package/dist/cable/index.js.map +1 -1
  6. package/dist/coerce-JtZVNG5h.d.ts +20 -0
  7. package/dist/controllers/accordion_controller.d.ts +4 -2
  8. package/dist/controllers/accordion_controller.js +174 -55
  9. package/dist/controllers/accordion_controller.js.map +1 -1
  10. package/dist/controllers/alert_dialog_controller.d.ts +12 -2
  11. package/dist/controllers/alert_dialog_controller.js +903 -235
  12. package/dist/controllers/alert_dialog_controller.js.map +1 -1
  13. package/dist/controllers/announcer_controller.d.ts +37 -5
  14. package/dist/controllers/announcer_controller.js +238 -205
  15. package/dist/controllers/announcer_controller.js.map +1 -1
  16. package/dist/controllers/aspect_ratio_controller.js +0 -10
  17. package/dist/controllers/aspect_ratio_controller.js.map +1 -1
  18. package/dist/controllers/auto_submit_controller.d.ts +30 -6
  19. package/dist/controllers/auto_submit_controller.js +414 -145
  20. package/dist/controllers/auto_submit_controller.js.map +1 -1
  21. package/dist/controllers/avatar_controller.js +185 -107
  22. package/dist/controllers/avatar_controller.js.map +1 -1
  23. package/dist/controllers/breadcrumb_controller.js +0 -130
  24. package/dist/controllers/breadcrumb_controller.js.map +1 -1
  25. package/dist/controllers/bulk_select_controller.d.ts +21 -3
  26. package/dist/controllers/bulk_select_controller.js +282 -58
  27. package/dist/controllers/bulk_select_controller.js.map +1 -1
  28. package/dist/controllers/calendar_controller.d.ts +38 -16
  29. package/dist/controllers/calendar_controller.js +228 -260
  30. package/dist/controllers/calendar_controller.js.map +1 -1
  31. package/dist/controllers/carousel_controller.d.ts +43 -12
  32. package/dist/controllers/carousel_controller.js +536 -436
  33. package/dist/controllers/carousel_controller.js.map +1 -1
  34. package/dist/controllers/character_counter_controller.d.ts +44 -7
  35. package/dist/controllers/character_counter_controller.js +493 -207
  36. package/dist/controllers/character_counter_controller.js.map +1 -1
  37. package/dist/controllers/checkbox_controller.d.ts +7 -2
  38. package/dist/controllers/checkbox_controller.js +38 -74
  39. package/dist/controllers/checkbox_controller.js.map +1 -1
  40. package/dist/controllers/clipboard_controller.d.ts +16 -5
  41. package/dist/controllers/clipboard_controller.js +261 -149
  42. package/dist/controllers/clipboard_controller.js.map +1 -1
  43. package/dist/controllers/collapsible_controller.d.ts +17 -5
  44. package/dist/controllers/collapsible_controller.js +304 -120
  45. package/dist/controllers/collapsible_controller.js.map +1 -1
  46. package/dist/controllers/color_picker_controller.d.ts +18 -6
  47. package/dist/controllers/color_picker_controller.js +178 -146
  48. package/dist/controllers/color_picker_controller.js.map +1 -1
  49. package/dist/controllers/combobox_controller.d.ts +24 -6
  50. package/dist/controllers/combobox_controller.js +522 -156
  51. package/dist/controllers/combobox_controller.js.map +1 -1
  52. package/dist/controllers/command_palette_controller.d.ts +51 -20
  53. package/dist/controllers/command_palette_controller.js +1156 -395
  54. package/dist/controllers/command_palette_controller.js.map +1 -1
  55. package/dist/controllers/conditional_fields_controller.d.ts +15 -2
  56. package/dist/controllers/conditional_fields_controller.js +300 -171
  57. package/dist/controllers/conditional_fields_controller.js.map +1 -1
  58. package/dist/controllers/confirm_controller.d.ts +49 -12
  59. package/dist/controllers/confirm_controller.js +980 -262
  60. package/dist/controllers/confirm_controller.js.map +1 -1
  61. package/dist/controllers/context_menu_controller.d.ts +80 -18
  62. package/dist/controllers/context_menu_controller.js +346 -153
  63. package/dist/controllers/context_menu_controller.js.map +1 -1
  64. package/dist/controllers/count_up_controller.d.ts +13 -1
  65. package/dist/controllers/count_up_controller.js +73 -21
  66. package/dist/controllers/count_up_controller.js.map +1 -1
  67. package/dist/controllers/countdown_controller.d.ts +47 -3
  68. package/dist/controllers/countdown_controller.js +281 -158
  69. package/dist/controllers/countdown_controller.js.map +1 -1
  70. package/dist/controllers/currency_input_controller.d.ts +93 -10
  71. package/dist/controllers/currency_input_controller.js +575 -225
  72. package/dist/controllers/currency_input_controller.js.map +1 -1
  73. package/dist/controllers/data_grid_controller.d.ts +25 -12
  74. package/dist/controllers/data_grid_controller.js +248 -214
  75. package/dist/controllers/data_grid_controller.js.map +1 -1
  76. package/dist/controllers/date_range_picker_controller.d.ts +42 -14
  77. package/dist/controllers/date_range_picker_controller.js +338 -235
  78. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  79. package/dist/controllers/dialog_controller.d.ts +17 -6
  80. package/dist/controllers/dialog_controller.js +899 -237
  81. package/dist/controllers/dialog_controller.js.map +1 -1
  82. package/dist/controllers/direct_upload_controller.d.ts +25 -8
  83. package/dist/controllers/direct_upload_controller.js +97 -167
  84. package/dist/controllers/direct_upload_controller.js.map +1 -1
  85. package/dist/controllers/dirty_form_controller.d.ts +6 -1
  86. package/dist/controllers/dirty_form_controller.js +72 -69
  87. package/dist/controllers/dirty_form_controller.js.map +1 -1
  88. package/dist/controllers/dismissible_controller.d.ts +19 -0
  89. package/dist/controllers/dismissible_controller.js +196 -24
  90. package/dist/controllers/dismissible_controller.js.map +1 -1
  91. package/dist/controllers/drawer_controller.d.ts +39 -11
  92. package/dist/controllers/drawer_controller.js +974 -355
  93. package/dist/controllers/drawer_controller.js.map +1 -1
  94. package/dist/controllers/dropdown_controller.d.ts +31 -1
  95. package/dist/controllers/dropdown_controller.js +339 -96
  96. package/dist/controllers/dropdown_controller.js.map +1 -1
  97. package/dist/controllers/editable_controller.d.ts +12 -1
  98. package/dist/controllers/editable_controller.js +315 -88
  99. package/dist/controllers/editable_controller.js.map +1 -1
  100. package/dist/controllers/empty_state_controller.js +79 -58
  101. package/dist/controllers/empty_state_controller.js.map +1 -1
  102. package/dist/controllers/file_dropzone_controller.d.ts +63 -18
  103. package/dist/controllers/file_dropzone_controller.js +322 -211
  104. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  105. package/dist/controllers/filter_controller.js +77 -42
  106. package/dist/controllers/filter_controller.js.map +1 -1
  107. package/dist/controllers/flash_controller.d.ts +35 -12
  108. package/dist/controllers/flash_controller.js +238 -347
  109. package/dist/controllers/flash_controller.js.map +1 -1
  110. package/dist/controllers/focus_controller.d.ts +15 -6
  111. package/dist/controllers/focus_controller.js +679 -240
  112. package/dist/controllers/focus_controller.js.map +1 -1
  113. package/dist/controllers/form_field_controller.js +156 -132
  114. package/dist/controllers/form_field_controller.js.map +1 -1
  115. package/dist/controllers/form_validation_controller.d.ts +3 -3
  116. package/dist/controllers/form_validation_controller.js +31 -97
  117. package/dist/controllers/form_validation_controller.js.map +1 -1
  118. package/dist/controllers/frame_loading_controller.d.ts +47 -14
  119. package/dist/controllers/frame_loading_controller.js +275 -217
  120. package/dist/controllers/frame_loading_controller.js.map +1 -1
  121. package/dist/controllers/highlight_controller.d.ts +27 -6
  122. package/dist/controllers/highlight_controller.js +107 -75
  123. package/dist/controllers/highlight_controller.js.map +1 -1
  124. package/dist/controllers/hover_card_controller.d.ts +60 -4
  125. package/dist/controllers/hover_card_controller.js +327 -130
  126. package/dist/controllers/hover_card_controller.js.map +1 -1
  127. package/dist/controllers/idle_controller.d.ts +48 -6
  128. package/dist/controllers/idle_controller.js +271 -101
  129. package/dist/controllers/idle_controller.js.map +1 -1
  130. package/dist/controllers/input_mask_controller.d.ts +30 -13
  131. package/dist/controllers/input_mask_controller.js +483 -97
  132. package/dist/controllers/input_mask_controller.js.map +1 -1
  133. package/dist/controllers/intersection_controller.d.ts +32 -13
  134. package/dist/controllers/intersection_controller.js +150 -106
  135. package/dist/controllers/intersection_controller.js.map +1 -1
  136. package/dist/controllers/lazy_frame_controller.d.ts +19 -2
  137. package/dist/controllers/lazy_frame_controller.js +24 -68
  138. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  139. package/dist/controllers/listbox_controller.d.ts +44 -9
  140. package/dist/controllers/listbox_controller.js +523 -240
  141. package/dist/controllers/listbox_controller.js.map +1 -1
  142. package/dist/controllers/local_time_controller.d.ts +9 -7
  143. package/dist/controllers/local_time_controller.js +102 -77
  144. package/dist/controllers/local_time_controller.js.map +1 -1
  145. package/dist/controllers/masonry_controller.d.ts +11 -3
  146. package/dist/controllers/masonry_controller.js +80 -96
  147. package/dist/controllers/masonry_controller.js.map +1 -1
  148. package/dist/controllers/menu_controller.d.ts +55 -11
  149. package/dist/controllers/menu_controller.js +302 -188
  150. package/dist/controllers/menu_controller.js.map +1 -1
  151. package/dist/controllers/menubar_controller.d.ts +51 -9
  152. package/dist/controllers/menubar_controller.js +232 -345
  153. package/dist/controllers/menubar_controller.js.map +1 -1
  154. package/dist/controllers/meter_controller.d.ts +33 -20
  155. package/dist/controllers/meter_controller.js +417 -87
  156. package/dist/controllers/meter_controller.js.map +1 -1
  157. package/dist/controllers/multi_select_controller.d.ts +48 -18
  158. package/dist/controllers/multi_select_controller.js +785 -393
  159. package/dist/controllers/multi_select_controller.js.map +1 -1
  160. package/dist/controllers/navigation_menu_controller.d.ts +27 -6
  161. package/dist/controllers/navigation_menu_controller.js +190 -250
  162. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  163. package/dist/controllers/nested_form_controller.d.ts +10 -0
  164. package/dist/controllers/nested_form_controller.js +396 -192
  165. package/dist/controllers/nested_form_controller.js.map +1 -1
  166. package/dist/controllers/network_status_controller.d.ts +23 -0
  167. package/dist/controllers/network_status_controller.js +268 -62
  168. package/dist/controllers/network_status_controller.js.map +1 -1
  169. package/dist/controllers/number_input_controller.d.ts +50 -8
  170. package/dist/controllers/number_input_controller.js +610 -303
  171. package/dist/controllers/number_input_controller.js.map +1 -1
  172. package/dist/controllers/optimistic_controller.d.ts +8 -5
  173. package/dist/controllers/optimistic_controller.js +45 -87
  174. package/dist/controllers/optimistic_controller.js.map +1 -1
  175. package/dist/controllers/otp_controller.d.ts +55 -8
  176. package/dist/controllers/otp_controller.js +658 -255
  177. package/dist/controllers/otp_controller.js.map +1 -1
  178. package/dist/controllers/overflow_indicator_controller.d.ts +5 -0
  179. package/dist/controllers/overflow_indicator_controller.js +122 -113
  180. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  181. package/dist/controllers/overflow_menu_controller.d.ts +58 -20
  182. package/dist/controllers/overflow_menu_controller.js +470 -295
  183. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  184. package/dist/controllers/pagination_controller.d.ts +37 -7
  185. package/dist/controllers/pagination_controller.js +332 -123
  186. package/dist/controllers/pagination_controller.js.map +1 -1
  187. package/dist/controllers/password_reveal_controller.d.ts +46 -8
  188. package/dist/controllers/password_reveal_controller.js +392 -121
  189. package/dist/controllers/password_reveal_controller.js.map +1 -1
  190. package/dist/controllers/password_strength_controller.d.ts +15 -6
  191. package/dist/controllers/password_strength_controller.js +111 -158
  192. package/dist/controllers/password_strength_controller.js.map +1 -1
  193. package/dist/controllers/persist_controller.d.ts +11 -4
  194. package/dist/controllers/persist_controller.js +165 -111
  195. package/dist/controllers/persist_controller.js.map +1 -1
  196. package/dist/controllers/pointer_drag_controller.d.ts +35 -12
  197. package/dist/controllers/pointer_drag_controller.js +434 -188
  198. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  199. package/dist/controllers/popover_controller.d.ts +41 -5
  200. package/dist/controllers/popover_controller.js +269 -113
  201. package/dist/controllers/popover_controller.js.map +1 -1
  202. package/dist/controllers/portal_controller.d.ts +44 -4
  203. package/dist/controllers/portal_controller.js +215 -76
  204. package/dist/controllers/portal_controller.js.map +1 -1
  205. package/dist/controllers/preview_guard_controller.d.ts +10 -4
  206. package/dist/controllers/preview_guard_controller.js +243 -116
  207. package/dist/controllers/preview_guard_controller.js.map +1 -1
  208. package/dist/controllers/progress_controller.d.ts +20 -19
  209. package/dist/controllers/progress_controller.js +391 -78
  210. package/dist/controllers/progress_controller.js.map +1 -1
  211. package/dist/controllers/radio_group_controller.d.ts +21 -9
  212. package/dist/controllers/radio_group_controller.js +278 -211
  213. package/dist/controllers/radio_group_controller.js.map +1 -1
  214. package/dist/controllers/range_slider_controller.d.ts +47 -6
  215. package/dist/controllers/range_slider_controller.js +220 -113
  216. package/dist/controllers/range_slider_controller.js.map +1 -1
  217. package/dist/controllers/rating_controller.d.ts +20 -4
  218. package/dist/controllers/rating_controller.js +458 -211
  219. package/dist/controllers/rating_controller.js.map +1 -1
  220. package/dist/controllers/read_more_controller.d.ts +2 -0
  221. package/dist/controllers/read_more_controller.js +138 -63
  222. package/dist/controllers/read_more_controller.js.map +1 -1
  223. package/dist/controllers/reading_progress_controller.d.ts +1 -1
  224. package/dist/controllers/reading_progress_controller.js +166 -137
  225. package/dist/controllers/reading_progress_controller.js.map +1 -1
  226. package/dist/controllers/relative_time_controller.d.ts +20 -6
  227. package/dist/controllers/relative_time_controller.js +211 -112
  228. package/dist/controllers/relative_time_controller.js.map +1 -1
  229. package/dist/controllers/reset_on_restore_controller.d.ts +85 -0
  230. package/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +103 -38
  231. package/dist/controllers/reset_on_restore_controller.js.map +1 -0
  232. package/dist/controllers/resizable_controller.d.ts +31 -2
  233. package/dist/controllers/resizable_controller.js +299 -150
  234. package/dist/controllers/resizable_controller.js.map +1 -1
  235. package/dist/controllers/roving_controller.d.ts +3 -3
  236. package/dist/controllers/roving_controller.js +49 -88
  237. package/dist/controllers/roving_controller.js.map +1 -1
  238. package/dist/controllers/scroll_area_controller.d.ts +7 -3
  239. package/dist/controllers/scroll_area_controller.js +490 -246
  240. package/dist/controllers/scroll_area_controller.js.map +1 -1
  241. package/dist/controllers/scroll_restore_controller.d.ts +3 -3
  242. package/dist/controllers/scroll_restore_controller.js +14 -55
  243. package/dist/controllers/scroll_restore_controller.js.map +1 -1
  244. package/dist/controllers/scroll_visibility_controller.d.ts +28 -12
  245. package/dist/controllers/scroll_visibility_controller.js +432 -149
  246. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  247. package/dist/controllers/scrollspy_controller.d.ts +6 -1
  248. package/dist/controllers/scrollspy_controller.js +193 -248
  249. package/dist/controllers/scrollspy_controller.js.map +1 -1
  250. package/dist/controllers/separator_controller.d.ts +20 -5
  251. package/dist/controllers/separator_controller.js +285 -142
  252. package/dist/controllers/separator_controller.js.map +1 -1
  253. package/dist/controllers/sidebar_controller.d.ts +65 -8
  254. package/dist/controllers/sidebar_controller.js +1069 -404
  255. package/dist/controllers/sidebar_controller.js.map +1 -1
  256. package/dist/controllers/skeleton_controller.d.ts +23 -0
  257. package/dist/controllers/skeleton_controller.js +259 -101
  258. package/dist/controllers/skeleton_controller.js.map +1 -1
  259. package/dist/controllers/slider_controller.d.ts +29 -2
  260. package/dist/controllers/slider_controller.js +187 -86
  261. package/dist/controllers/slider_controller.js.map +1 -1
  262. package/dist/controllers/smart_sticky_header_controller.d.ts +22 -4
  263. package/dist/controllers/smart_sticky_header_controller.js +173 -66
  264. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  265. package/dist/controllers/sortable_controller.d.ts +4 -4
  266. package/dist/controllers/sortable_controller.js +26 -125
  267. package/dist/controllers/sortable_controller.js.map +1 -1
  268. package/dist/controllers/spinner_controller.d.ts +39 -4
  269. package/dist/controllers/spinner_controller.js +288 -173
  270. package/dist/controllers/spinner_controller.js.map +1 -1
  271. package/dist/controllers/step_indicator_controller.d.ts +9 -4
  272. package/dist/controllers/step_indicator_controller.js +105 -46
  273. package/dist/controllers/step_indicator_controller.js.map +1 -1
  274. package/dist/controllers/stepper_controller.d.ts +14 -6
  275. package/dist/controllers/stepper_controller.js +120 -73
  276. package/dist/controllers/stepper_controller.js.map +1 -1
  277. package/dist/controllers/stick_to_bottom_controller.d.ts +9 -1
  278. package/dist/controllers/stick_to_bottom_controller.js +275 -140
  279. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  280. package/dist/controllers/sticky_observer_controller.d.ts +11 -0
  281. package/dist/controllers/sticky_observer_controller.js +220 -49
  282. package/dist/controllers/sticky_observer_controller.js.map +1 -1
  283. package/dist/controllers/submit_once_controller.d.ts +24 -8
  284. package/dist/controllers/submit_once_controller.js +376 -227
  285. package/dist/controllers/submit_once_controller.js.map +1 -1
  286. package/dist/controllers/switch_controller.d.ts +18 -4
  287. package/dist/controllers/switch_controller.js +201 -84
  288. package/dist/controllers/switch_controller.js.map +1 -1
  289. package/dist/controllers/tabs_controller.d.ts +9 -6
  290. package/dist/controllers/tabs_controller.js +41 -30
  291. package/dist/controllers/tabs_controller.js.map +1 -1
  292. package/dist/controllers/tags_input_controller.d.ts +16 -3
  293. package/dist/controllers/tags_input_controller.js +293 -173
  294. package/dist/controllers/tags_input_controller.js.map +1 -1
  295. package/dist/controllers/textarea_autosize_controller.d.ts +11 -1
  296. package/dist/controllers/textarea_autosize_controller.js +108 -74
  297. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  298. package/dist/controllers/theme_controller.d.ts +24 -11
  299. package/dist/controllers/theme_controller.js +140 -116
  300. package/dist/controllers/theme_controller.js.map +1 -1
  301. package/dist/controllers/time_picker_controller.d.ts +55 -5
  302. package/dist/controllers/time_picker_controller.js +331 -127
  303. package/dist/controllers/time_picker_controller.js.map +1 -1
  304. package/dist/controllers/toast_controller.d.ts +40 -16
  305. package/dist/controllers/toast_controller.js +244 -324
  306. package/dist/controllers/toast_controller.js.map +1 -1
  307. package/dist/controllers/toggle_group_controller.d.ts +14 -6
  308. package/dist/controllers/toggle_group_controller.js +252 -191
  309. package/dist/controllers/toggle_group_controller.js.map +1 -1
  310. package/dist/controllers/toolbar_controller.d.ts +8 -6
  311. package/dist/controllers/toolbar_controller.js +219 -120
  312. package/dist/controllers/toolbar_controller.js.map +1 -1
  313. package/dist/controllers/tooltip_controller.d.ts +49 -4
  314. package/dist/controllers/tooltip_controller.js +158 -124
  315. package/dist/controllers/tooltip_controller.js.map +1 -1
  316. package/dist/controllers/transition_controller.d.ts +22 -4
  317. package/dist/controllers/transition_controller.js +123 -119
  318. package/dist/controllers/transition_controller.js.map +1 -1
  319. package/dist/controllers/tree_view_controller.d.ts +22 -12
  320. package/dist/controllers/tree_view_controller.js +283 -369
  321. package/dist/controllers/tree_view_controller.js.map +1 -1
  322. package/dist/index.d.ts +10 -5
  323. package/dist/index.js +8573 -10410
  324. package/dist/index.js.map +1 -1
  325. package/dist/inspector/cli.d.ts +38 -14
  326. package/dist/inspector/cli.js +108 -40
  327. package/dist/inspector/cli.js.map +1 -1
  328. package/dist/inspector/cli_bin.js +145 -64
  329. package/dist/inspector/cli_bin.js.map +1 -1
  330. package/dist/inspector/examples.json +20 -20
  331. package/dist/inspector/manifest.json +802 -101
  332. package/dist/positioning/index.d.ts +15 -7
  333. package/dist/positioning/index.js +154 -47
  334. package/dist/positioning/index.js.map +1 -1
  335. package/package.json +11 -10
  336. package/dist/controllers/reset_before_cache_controller.d.ts +0 -76
  337. package/dist/controllers/reset_before_cache_controller.js.map +0 -1
@@ -1,8 +1,5 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/form_field_controller.ts
4
-
5
- // src/utils/announce.ts
6
3
  function announce(message, options = {}) {
7
4
  const text = message.trim();
8
5
  if (text.length === 0) return;
@@ -13,13 +10,22 @@ function announce(message, options = {}) {
13
10
  );
14
11
  }
15
12
 
16
- // src/utils/aria_ids.ts
17
- var counter = 0;
13
+ function sharedRegistry(key, create) {
14
+ const symbol = Symbol.for(key);
15
+ const scope = globalThis;
16
+ const existing = scope[symbol];
17
+ if (existing !== void 0) return existing;
18
+ const registry2 = create();
19
+ Object.defineProperty(globalThis, symbol, { value: registry2 });
20
+ return registry2;
21
+ }
22
+
23
+ var ids = sharedRegistry("stimeo-ui.aria-ids.registry.v1", () => ({ counter: 0 }));
18
24
  function uniqueId(prefix = "stimeo") {
19
25
  let candidate;
20
26
  do {
21
- counter += 1;
22
- candidate = `${prefix}-${counter}`;
27
+ ids.counter += 1;
28
+ candidate = `${prefix}-${ids.counter}`;
23
29
  } while (typeof document !== "undefined" && document.getElementById(candidate) !== null);
24
30
  return candidate;
25
31
  }
@@ -30,103 +36,173 @@ function ensureId(element, prefix = "stimeo") {
30
36
  return id;
31
37
  }
32
38
 
33
- // src/utils/attribute_lease.ts
39
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
40
+ if (element.getAttribute(name) === value) return false;
41
+ if (value === null) element.removeAttribute(name);
42
+ else element.setAttribute(name, value);
43
+ return true;
44
+ }
45
+
46
+ var registry = sharedRegistry(
47
+ "stimeo-ui.attribute-lease.registry.v1",
48
+ () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
49
+ );
50
+ function isAttributeValue(value) {
51
+ return value === null || typeof value === "string";
52
+ }
53
+ function readLeaseRecord(element, record) {
54
+ try {
55
+ const parsed = JSON.parse(element.getAttribute(record) ?? "null");
56
+ if (!Array.isArray(parsed)) return void 0;
57
+ const [original, written, ...rest] = parsed;
58
+ const linked = rest[0] !== false;
59
+ const beneath = linked ? rest : rest.slice(1);
60
+ if (!beneath.every((under) => typeof under === "string")) return void 0;
61
+ return isAttributeValue(original) && isAttributeValue(written) ? { original, written, linked, beneath } : void 0;
62
+ } catch {
63
+ return void 0;
64
+ }
65
+ }
66
+ function attributeStack(element, attribute) {
67
+ const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
68
+ registry.stacks.set(element, byAttribute);
69
+ const known = byAttribute.get(attribute);
70
+ if (known) return known;
71
+ const found = [];
72
+ for (const record of registry.names.get(attribute) ?? []) {
73
+ const read = readLeaseRecord(element, record);
74
+ if (read) found.push({ ...read, record });
75
+ }
76
+ const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
77
+ const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
78
+ lease: null,
79
+ record,
80
+ written,
81
+ original,
82
+ linked: linked && index > 0
83
+ }));
84
+ byAttribute.set(attribute, stack);
85
+ return stack;
86
+ }
87
+ function findHold(stack, lease, record) {
88
+ return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
89
+ }
34
90
  var AttributeLease = class {
35
91
  #attribute;
36
- #records = /* @__PURE__ */ new Map();
37
- /** @param attribute - The attribute whose temporary values this lease owns. */
38
- constructor(attribute) {
92
+ #record;
93
+ #base;
94
+ #preserveAuthor;
95
+ #held = /* @__PURE__ */ new Set();
96
+ constructor(attribute, owner, options = {}) {
39
97
  this.#attribute = attribute;
98
+ this.#record = `data-${owner}-${attribute}-lease`;
99
+ this.#base = options.base === true;
100
+ this.#preserveAuthor = options.preserveAuthor === true;
101
+ const names = registry.names;
102
+ names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
40
103
  }
41
- /** Writes or removes the leased attribute while preserving its authored value. */
42
104
  write(element, value) {
43
- const existing = this.#records.get(element);
44
- if (existing) {
45
- existing.written = value;
46
- } else {
47
- this.#records.set(element, {
48
- original: element.getAttribute(this.#attribute),
49
- written: value
50
- });
51
- }
52
- this.#reflect(element, value);
105
+ const stack = attributeStack(element, this.#attribute);
106
+ const hold = this.#take(stack) ?? this.#acquire(element, stack);
107
+ this.#held.add(element);
108
+ const shows = !this.#covered(element, stack, hold);
109
+ hold.written = value;
110
+ this.#mark(element, stack);
111
+ if (shows) this.#reflect(element, value);
53
112
  }
54
- /** Returns one lease without overwriting a value subsequently authored by a consumer. */
55
113
  return(element) {
56
- const record = this.#records.get(element);
57
- if (!record) return;
58
- this.#records.delete(element);
59
- const stillOwned = element.getAttribute(this.#attribute) === record.written;
60
- if (stillOwned) this.#reflect(element, record.original);
114
+ const held = this.#held.delete(element);
115
+ const known = registry.stacks.get(element)?.has(this.#attribute);
116
+ const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
117
+ const hold = this.#take(stack);
118
+ if (!hold) return false;
119
+ const carries = element.getAttribute(this.#attribute) === hold.written;
120
+ const owns = carries && !this.#covered(element, stack, hold);
121
+ const index = stack.indexOf(hold);
122
+ stack.splice(index, 1);
123
+ const above = stack[index];
124
+ if (above) above.linked &&= hold.linked;
125
+ this.#mark(element, stack);
126
+ if (!owns) return true;
127
+ const below = hold.linked ? stack[index - 1] : void 0;
128
+ this.#reflect(element, below ? below.written : hold.original);
129
+ return true;
61
130
  }
62
- /** Reflects only a real value transition, avoiding self-triggered mutation work. */
63
- #reflect(element, value) {
64
- if (element.getAttribute(this.#attribute) === value) return;
65
- if (value === null) element.removeAttribute(this.#attribute);
66
- else element.setAttribute(this.#attribute, value);
67
- }
68
- /** Returns every outstanding lease using the same ownership check as {@link return}. */
69
131
  returnAll() {
70
- for (const element of Array.from(this.#records.keys())) this.return(element);
71
- }
72
- };
73
-
74
- // src/utils/before_cache_reset.ts
75
- var BeforeCacheReset = class _BeforeCacheReset {
76
- /** Every subscribed instance, iterated by the one shared document listener. */
77
- static #subscribers = /* @__PURE__ */ new Set();
78
- /** The shared listener; installed while at least one instance is subscribed. */
79
- static #onBeforeCache = () => {
80
- for (const subscriber of _BeforeCacheReset.#subscribers) subscriber.#rewind();
81
- };
82
- #rewind;
83
- /** @param rewind - the pass that returns this controller's state to its initial form. */
84
- constructor(rewind) {
85
- this.#rewind = rewind;
86
- }
87
- /** Subscribes to `turbo:before-cache`; call from `connect()`. Idempotent. */
88
- activate() {
89
- const first = _BeforeCacheReset.#subscribers.size === 0;
90
- _BeforeCacheReset.#subscribers.add(this);
91
- if (first) {
92
- document.addEventListener("turbo:before-cache", _BeforeCacheReset.#onBeforeCache);
132
+ for (const element of Array.from(this.#held)) this.return(element);
133
+ }
134
+ #take(stack) {
135
+ const hold = findHold(stack, this, this.#record);
136
+ if (hold) hold.lease = this;
137
+ return hold;
138
+ }
139
+ #acquire(element, stack) {
140
+ const current = element.getAttribute(this.#attribute);
141
+ const top = stack.at(-1);
142
+ const bottom = stack[0];
143
+ const over = top?.written === current ? top : void 0;
144
+ const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
145
+ const hold = {
146
+ lease: this,
147
+ record: this.#record,
148
+ written: current,
149
+ original: from ? from.original : current,
150
+ linked: !this.#base && over !== void 0
151
+ };
152
+ if (this.#base && bottom) {
153
+ bottom.linked = true;
154
+ stack.unshift(hold);
155
+ } else stack.push(hold);
156
+ return hold;
157
+ }
158
+ #covered(element, stack, hold) {
159
+ const current = element.getAttribute(this.#attribute);
160
+ return stack.slice(stack.indexOf(hold) + 1).some((above) => above.written === current);
161
+ }
162
+ #mark(element, stack) {
163
+ const records = /* @__PURE__ */ new Map([[this.#record, null]]);
164
+ stack.forEach((hold, index) => {
165
+ const names = stack.slice(0, index).map((under) => under.record);
166
+ const beneath = [...new Set(names.reverse())].filter((name) => name !== hold.record);
167
+ const marker = hold.linked || beneath.length === 0 ? [] : [false];
168
+ records.set(
169
+ hold.record,
170
+ hold.written === hold.original && beneath.length === 0 && index === stack.length - 1 ? null : JSON.stringify([hold.original, hold.written, ...marker, ...beneath])
171
+ );
172
+ });
173
+ for (const [name, recorded] of records) {
174
+ setAttributeIfChanged(element, name, recorded);
93
175
  }
94
176
  }
95
- /** Unsubscribes; call from `disconnect()`. Safe when never subscribed. */
96
- deactivate() {
97
- _BeforeCacheReset.#subscribers.delete(this);
98
- if (_BeforeCacheReset.#subscribers.size > 0) return;
99
- document.removeEventListener("turbo:before-cache", _BeforeCacheReset.#onBeforeCache);
177
+ #reflect(element, value) {
178
+ setAttributeIfChanged(element, this.#attribute, value);
100
179
  }
101
180
  };
102
181
 
103
- // src/utils/event_owner.ts
104
182
  function ownerIndex(candidates, node) {
105
183
  if (!(node instanceof Node)) return -1;
106
184
  return candidates.findIndex((candidate) => candidate.contains(node));
107
185
  }
108
186
 
109
- // src/utils/microtask_coalescer.ts
110
187
  var MicrotaskCoalescer = class {
111
188
  #run;
112
189
  #queued = false;
113
190
  #active = false;
114
191
  #generation = 0;
115
- /** @param run - the single reconciliation pass, invoked at most once per batch. */
116
192
  constructor(run) {
117
193
  this.#run = run;
118
194
  }
119
- /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */
120
195
  activate() {
121
196
  this.#active = true;
122
197
  }
123
- /** Closes the window and drops any pending pass; call from `disconnect()`. */
124
198
  cancel() {
125
199
  this.#active = false;
126
200
  this.#queued = false;
127
201
  this.#generation += 1;
128
202
  }
129
- /** Requests one pass after the batch settles. Idempotent; inert outside the window. */
203
+ get pending() {
204
+ return this.#queued;
205
+ }
130
206
  schedule() {
131
207
  if (!this.#active || this.#queued) return;
132
208
  this.#queued = true;
@@ -139,7 +215,6 @@ var MicrotaskCoalescer = class {
139
215
  }
140
216
  };
141
217
 
142
- // src/controllers/form_field_controller.ts
143
218
  var OBSERVED_ATTRIBUTES = ["hidden", "id"];
144
219
  var FormFieldController = class extends Controller {
145
220
  static targets = ["control", "description", "error"];
@@ -148,18 +223,21 @@ var FormFieldController = class extends Controller {
148
223
  };
149
224
  static actions = ["clearError", "setError"];
150
225
  static events = ["validate"];
151
- /** Root attribute (CSS hook) reflecting the invalid state, in this controller's namespace. */
152
226
  get #invalidAttribute() {
153
227
  return `data-${this.identifier}-invalid`;
154
228
  }
155
- /** Collapses one target/morph batch into one silent ARIA reconciliation. */
156
229
  #reconcile = new MicrotaskCoalescer(() => this.#reconcileDom());
157
- /** Returns borrowed control ARIA before Turbo snapshots the page. */
158
- #beforeCache = new BeforeCacheReset(() => this.#rewindForCache());
159
- #ariaDescribedBy = new AttributeLease("aria-describedby");
160
- #ariaErrorMessage = new AttributeLease("aria-errormessage");
161
- #ariaInvalid = new AttributeLease("aria-invalid");
162
- /** Watches retained target ids, error visibility, and error content. */
230
+ #ariaDescribedBy = new AttributeLease("aria-describedby", this.identifier, {
231
+ base: true
232
+ });
233
+ #ariaErrorMessage = new AttributeLease(
234
+ "aria-errormessage",
235
+ this.identifier,
236
+ { base: true }
237
+ );
238
+ #ariaInvalid = new AttributeLease("aria-invalid", this.identifier, {
239
+ base: true
240
+ });
163
241
  #observer = new MutationObserver((records) => {
164
242
  if (records.some((record) => this.#isRelevantMutation(record))) {
165
243
  this.#reconcile.schedule();
@@ -169,11 +247,8 @@ var FormFieldController = class extends Controller {
169
247
  #baseDescribedBy = [];
170
248
  #explicitInvalid = false;
171
249
  #initialized = false;
172
- /** Wires the initial graph and starts retained-target reconciliation. */
173
250
  connect() {
174
251
  this.#reconcile.activate();
175
- this.#ensureAssociationIds();
176
- this.#beforeCache.activate();
177
252
  if (!this.#initialized) {
178
253
  this.#explicitInvalid = this.element.hasAttribute(this.#invalidAttribute) && this.#shownErrors().length === 0;
179
254
  this.#initialized = true;
@@ -187,49 +262,29 @@ var FormFieldController = class extends Controller {
187
262
  subtree: true
188
263
  });
189
264
  }
190
- /** Releases observers, queued work, and ARIA borrowed on the current control. */
191
265
  disconnect() {
192
266
  this.#reconcile.cancel();
193
267
  this.#observer.disconnect();
194
- this.#beforeCache.deactivate();
195
268
  this.#activeControl && this.#releaseControl(this.#activeControl);
196
269
  }
197
- /** Reconciles a control inserted or replaced at runtime. */
198
270
  controlTargetConnected() {
199
271
  this.#reconcile.schedule();
200
272
  }
201
- /** Schedules restoration of authored ARIA when a control leaves this field. */
202
273
  controlTargetDisconnected() {
203
274
  this.#reconcile.schedule();
204
275
  }
205
- /** Reconciles a description inserted or replaced at runtime. */
206
276
  descriptionTargetConnected() {
207
277
  this.#reconcile.schedule();
208
278
  }
209
- /** Removes a departed description from the control's association graph. */
210
279
  descriptionTargetDisconnected() {
211
280
  this.#reconcile.schedule();
212
281
  }
213
- /** Reconciles an error region inserted or replaced at runtime. */
214
282
  errorTargetConnected() {
215
283
  this.#reconcile.schedule();
216
284
  }
217
- /** Removes a departed error from invalid state and the association graph. */
218
285
  errorTargetDisconnected() {
219
286
  this.#reconcile.schedule();
220
287
  }
221
- /**
222
- * Marks the field invalid and shows the error message. Bound via `data-action`
223
- * (`#setError`) or callable directly.
224
- *
225
- * A non-empty shown message is announced exactly once through the shared
226
- * assertive announcer. Initial/server reconciliation is deliberately silent.
227
- *
228
- * @param arg - Either the message string, or the action event whose
229
- * `data-stimeo--form-field-message-param` supplies it. When no message is
230
- * resolvable, any already-populated error targets are simply (re)shown.
231
- * @param options - Programmatic overrides. Stimulus actions use the Values.
232
- */
233
288
  setError(arg, options = {}) {
234
289
  const message = this.#resolveMessage(arg);
235
290
  if (message !== null && this.hasErrorTarget) {
@@ -246,13 +301,6 @@ var FormFieldController = class extends Controller {
246
301
  announce(shownMessage, { assertive: true });
247
302
  if (options.focus ?? this.focusOnErrorValue) this.#activeControl?.focus();
248
303
  }
249
- /**
250
- * Clears the error: empties and hides every error target and marks the field
251
- * valid. Bound via `data-action` (`#clearError`) or callable directly.
252
- *
253
- * Clearing is silent: the visual/ARIA state and validation event are sufficient,
254
- * while success wording remains an explicit consumer announcement.
255
- */
256
304
  clearError() {
257
305
  for (const error of this.errorTargets) {
258
306
  error.replaceChildren();
@@ -263,10 +311,6 @@ var FormFieldController = class extends Controller {
263
311
  const detail = { valid: true, message: "" };
264
312
  this.dispatch("validate", { detail });
265
313
  }
266
- /**
267
- * Rebuilds ids and derived ARIA from the settled target graph without reporting
268
- * a user validation action.
269
- */
270
314
  #reconcileDom() {
271
315
  this.#ensureAssociationIds();
272
316
  this.#adoptCurrentControl();
@@ -284,7 +328,6 @@ var FormFieldController = class extends Controller {
284
328
  const describedBy = this.#uniqueTokens([...this.#baseDescribedBy, ...associationIds]);
285
329
  this.#ariaDescribedBy.write(control, describedBy.length > 0 ? describedBy.join(" ") : null);
286
330
  }
287
- /** Assigns stable ids before either capture or reflection uses them. */
288
331
  #ensureAssociationIds() {
289
332
  for (const description of this.descriptionTargets) {
290
333
  ensureId(description, "stimeo--form-field-desc");
@@ -293,7 +336,6 @@ var FormFieldController = class extends Controller {
293
336
  ensureId(error, "stimeo--form-field-error");
294
337
  }
295
338
  }
296
- /** Switches ARIA ownership when the singular current control target changes. */
297
339
  #adoptCurrentControl() {
298
340
  const next = this.hasControlTarget ? this.controlTarget : null;
299
341
  if (next === this.#activeControl) return;
@@ -301,7 +343,6 @@ var FormFieldController = class extends Controller {
301
343
  this.#activeControl = next;
302
344
  this.#baseDescribedBy = next ? this.#externalDescribedByTokens(next) : [];
303
345
  }
304
- /** Restores one departed control without overwriting later consumer edits. */
305
346
  #releaseControl(control) {
306
347
  this.#ariaDescribedBy.return(control);
307
348
  this.#ariaErrorMessage.return(control);
@@ -311,26 +352,19 @@ var FormFieldController = class extends Controller {
311
352
  this.#baseDescribedBy = [];
312
353
  }
313
354
  }
314
- /** Error targets currently visible and non-empty, in document order. */
315
355
  #shownErrors() {
316
356
  return this.#orderedElements(
317
357
  this.errorTargets.filter((error) => !error.hidden && (error.textContent ?? "").trim() !== "")
318
358
  );
319
359
  }
320
- /** Text of the first shown error, for validation detail and announcement. */
321
360
  #shownMessage() {
322
361
  return (this.#shownErrors()[0]?.textContent ?? "").trim();
323
362
  }
324
- /** Resolves a message from a string argument or an action event's params. */
325
363
  #resolveMessage(arg) {
326
364
  if (typeof arg === "string") return arg;
327
365
  const message = arg?.params?.message;
328
366
  return typeof message === "string" ? message : null;
329
367
  }
330
- /**
331
- * Tokens authored on a newly adopted control, excluding ids this controller
332
- * owns through its current description/error targets.
333
- */
334
368
  #externalDescribedByTokens(control) {
335
369
  const owned = /* @__PURE__ */ new Set([
336
370
  ...this.descriptionTargets.map((description) => description.id),
@@ -341,7 +375,6 @@ var FormFieldController = class extends Controller {
341
375
  existing.split(/\s+/).filter((token) => token.length > 0 && !owned.has(token))
342
376
  );
343
377
  }
344
- /** Deduplicates ARIA tokens without disturbing their first occurrence. */
345
378
  #uniqueTokens(tokens) {
346
379
  const seen = /* @__PURE__ */ new Set();
347
380
  return tokens.filter((token) => {
@@ -350,14 +383,12 @@ var FormFieldController = class extends Controller {
350
383
  return true;
351
384
  });
352
385
  }
353
- /** Returns unique current targets in DOM order before serializing IDREF lists. */
354
386
  #orderedElements(elements) {
355
387
  const candidates = new Set(elements);
356
388
  return [this.element, ...this.element.querySelectorAll("*")].filter(
357
389
  (element) => candidates.has(element)
358
390
  );
359
391
  }
360
- /** Whether one retained-node mutation can alter this controller's derived state. */
361
392
  #isRelevantMutation(record) {
362
393
  const target = record.target;
363
394
  if (record.type === "attributes") {
@@ -367,14 +398,7 @@ var FormFieldController = class extends Controller {
367
398
  }
368
399
  return ownerIndex(this.errorTargets, target) !== -1;
369
400
  }
370
- /** Returns borrowed control ARIA before Turbo snapshots the page. */
371
- #rewindForCache() {
372
- this.#ariaDescribedBy.returnAll();
373
- this.#ariaErrorMessage.returnAll();
374
- this.#ariaInvalid.returnAll();
375
- }
376
401
  };
377
402
 
378
403
  export { FormFieldController };
379
- //# sourceMappingURL=form_field_controller.js.map
380
404
  //# sourceMappingURL=form_field_controller.js.map