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
@@ -1,13 +1,31 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/theme_controller.ts
3
+ var FOCUS_EVENTS = /* @__PURE__ */ new Set(["blur", "focus", "focusin", "focusout"]);
4
+ var POINTER_EVENTS = /* @__PURE__ */ new Set(["mouseenter", "mouseleave", "pointerenter", "pointerleave"]);
5
+ function stateReasonFor(event) {
6
+ if (!event) return "api";
7
+ if (FOCUS_EVENTS.has(event.type)) return "focus";
8
+ if (POINTER_EVENTS.has(event.type)) return "pointer";
9
+ return "user";
10
+ }
11
+
12
+ function actionSource(source) {
13
+ if (source instanceof HTMLElement) {
14
+ return { event: null, host: source, origin: source, reason: "api" };
15
+ }
16
+ const event = source ?? null;
17
+ return {
18
+ event,
19
+ host: event?.currentTarget instanceof Element ? event.currentTarget : null,
20
+ origin: event?.target instanceof Element ? event.target : null,
21
+ reason: stateReasonFor(event)
22
+ };
23
+ }
4
24
 
5
- // src/utils/logical_scroll.ts
6
25
  function isRtl(element) {
7
26
  return window.getComputedStyle(element).direction === "rtl";
8
27
  }
9
28
 
10
- // src/utils/arrow_step.ts
11
29
  function logicalArrowStep(key, element) {
12
30
  if (key === "ArrowDown") return 1;
13
31
  if (key === "ArrowUp") return -1;
@@ -23,7 +41,6 @@ function hasModifierChord(event) {
23
41
  return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
24
42
  }
25
43
 
26
- // src/utils/declared_value.ts
27
44
  function parseDeclared(raw, parse, fallback) {
28
45
  try {
29
46
  return parse(raw);
@@ -43,31 +60,78 @@ function validSelector(element, raw, fallback) {
43
60
  );
44
61
  }
45
62
 
46
- // src/utils/roving_tabindex.ts
63
+ var ListenerSet = class {
64
+ #abort = new AbortController();
65
+ add(target, type, handler, options) {
66
+ target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
67
+ }
68
+ dispose() {
69
+ this.#abort.abort();
70
+ this.#abort = new AbortController();
71
+ }
72
+ };
73
+
74
+ var MicrotaskCoalescer = class {
75
+ #run;
76
+ #queued = false;
77
+ #active = false;
78
+ #generation = 0;
79
+ constructor(run) {
80
+ this.#run = run;
81
+ }
82
+ activate() {
83
+ this.#active = true;
84
+ }
85
+ cancel() {
86
+ this.#active = false;
87
+ this.#queued = false;
88
+ this.#generation += 1;
89
+ }
90
+ schedule() {
91
+ if (!this.#active || this.#queued) return;
92
+ this.#queued = true;
93
+ const generation = this.#generation;
94
+ queueMicrotask(() => {
95
+ if (generation !== this.#generation || !this.#queued || !this.#active) return;
96
+ this.#queued = false;
97
+ this.#run();
98
+ });
99
+ }
100
+ };
101
+
102
+ var MorphRenderWatcher = class {
103
+ #listeners = new ListenerSet();
104
+ #pass;
105
+ #element = null;
106
+ #onMorph = () => this.#pass.schedule();
107
+ constructor(run) {
108
+ this.#pass = new MicrotaskCoalescer(run);
109
+ }
110
+ observe(element) {
111
+ if (this.#element === element) return;
112
+ this.disconnect();
113
+ this.#element = element;
114
+ this.#pass.activate();
115
+ this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
116
+ }
117
+ schedule() {
118
+ this.#pass.schedule();
119
+ }
120
+ disconnect() {
121
+ this.#listeners.dispose();
122
+ this.#pass.cancel();
123
+ this.#element = null;
124
+ }
125
+ };
126
+
47
127
  var RovingTabindex = class {
48
- /** Returns the current ordered item elements; called on every operation. */
49
128
  #getItems;
50
- /**
51
- * @param getItems - Returns the current ordered item elements. Called on every
52
- * operation so the live target list is always used.
53
- */
54
129
  constructor(getItems) {
55
130
  this.#getItems = getItems;
56
131
  }
57
- /** Index of the currently tabbable item (`tabindex="0"`), or `-1` if none. */
58
132
  get activeIndex() {
59
133
  return this.#getItems().findIndex((item) => item.tabIndex === 0);
60
134
  }
61
- /**
62
- * Makes exactly the item at `index` tabbable (`tabindex="0"`) and removes every
63
- * other item from the Tab sequence (`tabindex="-1"`). An out-of-range `index`
64
- * (e.g. `-1`) leaves all items at `-1`, which a controller can use to express
65
- * "nothing is currently tabbable".
66
- *
67
- * @param index - Position of the item to make tabbable.
68
- * @param options - Pass `{ focus: true }` to also move DOM focus to that item,
69
- * and `items` to reuse an event-scoped collection snapshot.
70
- */
71
135
  setActive(index, options = {}) {
72
136
  const { focus = false } = options;
73
137
  const items = options.items ?? this.#getItems();
@@ -83,7 +147,6 @@ function rovingMove(current, length, delta, wrap) {
83
147
  return (next + length) % length;
84
148
  }
85
149
 
86
- // src/utils/safe_storage.ts
87
150
  function readLocalStorage(key) {
88
151
  try {
89
152
  return { ok: true, value: window.localStorage.getItem(key) };
@@ -100,7 +163,10 @@ function writeLocalStorage(key, value) {
100
163
  }
101
164
  }
102
165
 
103
- // src/controllers/theme_controller.ts
166
+ function targetSelector(identifier, name) {
167
+ return `[data-${identifier}-target~="${name}"]`;
168
+ }
169
+
104
170
  var MODES = ["light", "dark", "system"];
105
171
  var isMode = (value) => typeof value === "string" && MODES.includes(value);
106
172
  var DEFAULT_MODE = "system";
@@ -114,30 +180,19 @@ var ThemeController = class extends Controller {
114
180
  };
115
181
  static actions = ["set", "toggle"];
116
182
  static events = ["change", "reconcile"];
117
- /** The OS dark-mode query, watched so `system` tracks live changes. */
118
183
  #media = null;
119
- /** Gate for the target and `mode` callbacks, which Stimulus runs before `connect()`. */
120
184
  #connected = false;
121
- /** The `target` declaration after validation; the default when unparsable. */
122
185
  #targetSelector = DEFAULT_TARGET;
123
- /** Owns the single Tab stop across the option set (APG radiogroup). */
186
+ #storageKeyRead = null;
124
187
  #roving = new RovingTabindex(() => this.optionTargets);
125
- /**
126
- * The pair on screen as last reported or re-seeded, so a move can be told from a
127
- * repeat. Neither side is readable after the fact — assigning the Value updates the
128
- * mode before any comparison, and the OS query has already flipped by the time it
129
- * notifies — so what was reported has to be kept rather than recomputed.
130
- */
131
188
  #published = {
132
189
  mode: DEFAULT_MODE,
133
190
  resolved: "light"
134
191
  };
135
- /** Re-resolves while in `system` mode when the OS preference flips. */
136
192
  #onMediaChange = () => {
137
193
  if (this.#mode !== "system") return;
138
- this.#commit();
194
+ this.#commit("media");
139
195
  };
140
- /** Arrow/Home/End navigation for the radiogroup (APG radio pattern). */
141
196
  #onKeydown = (event) => {
142
197
  if (event.defaultPrevented) return;
143
198
  if (isReservedArrowChord(event)) return;
@@ -169,7 +224,13 @@ var ThemeController = class extends Controller {
169
224
  const mode = this.#optionMode(option);
170
225
  if (mode) this.#setMode(mode);
171
226
  };
227
+ #morph = new MorphRenderWatcher(() => {
228
+ this.#applyTheme();
229
+ this.#reconcileControls();
230
+ });
172
231
  connect() {
232
+ this.#morph.observe(this.element);
233
+ this.#storageKeyRead = this.storageKeyValue;
173
234
  const stored = this.#readStored();
174
235
  if (stored) this.modeValue = stored;
175
236
  this.#media = window.matchMedia?.("(prefers-color-scheme: dark)") ?? null;
@@ -181,25 +242,15 @@ var ThemeController = class extends Controller {
181
242
  this.#published = this.#current;
182
243
  }
183
244
  disconnect() {
245
+ this.#morph.disconnect();
184
246
  this.#connected = false;
185
247
  this.#media?.removeEventListener("change", this.#onMediaChange);
186
248
  this.element.removeEventListener("keydown", this.#onKeydown);
187
249
  }
188
- /** Validates the `target` declaration once, so the render path never parses. */
189
250
  targetValueChanged() {
190
251
  this.#targetSelector = validSelector(this.element, this.targetValue, DEFAULT_TARGET);
252
+ this.#morph.schedule();
191
253
  }
192
- /**
193
- * Re-renders for a `mode` declaration changed after connect — a Turbo morph
194
- * re-rendering the server's markup over the live element, or a script.
195
- *
196
- * A stored choice outranks the declaration: a Value that disagrees with it is written
197
- * back to it, so a morph that brings the server's default never overrides what the
198
- * user saved. Without one, the declaration is applied. Either way storage is left
199
- * alone, and a pair on screen that moved is reported as `reconcile`, not `change` —
200
- * the page moved the declaration, not a selection. The reported pair is re-seeded
201
- * first, so the next selection is compared with what is on screen.
202
- */
203
254
  modeValueChanged() {
204
255
  if (!this.#connected) return;
205
256
  if (this.modeValue === this.#published.mode) return;
@@ -208,67 +259,53 @@ var ThemeController = class extends Controller {
208
259
  this.#applyTheme();
209
260
  this.#reconcileControls();
210
261
  }
211
- /** Re-derives the single Tab stop and ARIA for an option set that changed. */
262
+ storageKeyValueChanged() {
263
+ if (!this.#connected) return;
264
+ const key = this.storageKeyValue;
265
+ if (key === this.#storageKeyRead) return;
266
+ this.#storageKeyRead = key;
267
+ const stored = this.#readStored();
268
+ if (stored === null || stored === this.modeValue) return;
269
+ this.modeValue = stored;
270
+ this.#applyTheme();
271
+ this.#reconcileControls();
272
+ }
212
273
  optionTargetConnected() {
213
- if (this.#connected) this.#reconcileControls();
274
+ if (this.#connected) this.#morph.schedule();
214
275
  }
215
- /** Re-derives them again when an option leaves, so a Tab stop always remains. */
216
276
  optionTargetDisconnected() {
217
- if (this.#connected) this.#reconcileControls();
218
- }
219
- /**
220
- * Selects the mode the activated option declares.
221
- *
222
- * Read through the same lane that decides which option is checked, so the two
223
- * can never disagree about what an option declares.
224
- */
225
- set(event) {
226
- const option = event.currentTarget;
227
- if (!(option instanceof HTMLElement)) return;
277
+ if (this.#connected) this.#morph.schedule();
278
+ }
279
+ set(source) {
280
+ const { host, origin, reason } = actionSource(source);
281
+ const option = host?.closest(targetSelector(this.identifier, "option"));
282
+ if (!option || !this.optionTargets.includes(option)) return;
283
+ if (origin && origin.closest(`[data-controller~="${this.identifier}"]`) !== this.element)
284
+ return;
228
285
  const mode = this.#optionMode(option);
229
- if (mode) this.#setMode(mode);
286
+ if (mode) this.#setMode(mode, reason);
230
287
  }
231
- /** Toggles light↔dark for the 2-value single-button contract. */
232
- toggle() {
233
- this.#setMode(this.#resolved() === "dark" ? "light" : "dark");
288
+ toggle(event) {
289
+ const mode = this.#readStored() ?? this.#mode;
290
+ const dark = mode === "dark" || mode === "system" && this.#media?.matches === true;
291
+ this.#setMode(dark ? "light" : "dark", stateReasonFor(event));
234
292
  }
235
- /** Central mode change: persist, apply to the root, resync controls, announce. */
236
- #setMode(mode) {
293
+ #setMode(mode, reason = "user") {
237
294
  this.modeValue = mode;
238
295
  this.#writeStored(mode);
239
- this.#commit();
240
- }
241
- /**
242
- * Applies the current mode and reports it, but reports only a real move: the
243
- * event means "the selection or the effective theme moved", so re-choosing the
244
- * option already chosen is not one.
245
- */
246
- #commit() {
296
+ this.#commit(reason);
297
+ }
298
+ #commit(reason) {
247
299
  this.#applyTheme();
248
300
  this.#syncControls();
249
301
  const moved = this.#settle();
250
- if (moved) this.dispatch("change", { detail: moved });
251
- }
252
- /**
253
- * Re-derives the controls from the mode on screen for a change the page made — a
254
- * `mode` declaration or an option set — and reports a pair that moved since the
255
- * last report as `reconcile`. An option coming or going moves neither half of the
256
- * pair, so of these changes only a declaration reports.
257
- */
302
+ if (moved) this.dispatch("change", { detail: { ...moved, reason } });
303
+ }
258
304
  #reconcileControls() {
259
305
  this.#syncControls();
260
306
  const moved = this.#settle();
261
307
  if (moved) this.dispatch("reconcile", { detail: moved });
262
308
  }
263
- /**
264
- * Takes the pair on screen as the reported one and returns it when it differs
265
- * from the one reported before, or `null` when neither half moved.
266
- *
267
- * The baseline moves before anything is dispatched, so a listener that selects
268
- * another mode is measured from the pair it was just told about. What is
269
- * returned is a copy: the baseline has to survive a listener that writes to what
270
- * it was handed, or the next unchanged operation reads as a move.
271
- */
272
309
  #settle() {
273
310
  const next = this.#current;
274
311
  const last = this.#published;
@@ -276,15 +313,9 @@ var ThemeController = class extends Controller {
276
313
  if (last.mode === next.mode && last.resolved === next.resolved) return null;
277
314
  return { ...next };
278
315
  }
279
- /** The pair the `change` and `reconcile` details carry, read from current state. */
280
316
  get #current() {
281
317
  return { mode: this.#mode, resolved: this.#resolved() };
282
318
  }
283
- /**
284
- * Writes `data-theme` + `color-scheme` (the resolved theme) onto the target.
285
- *
286
- * @stimeoRenderRoot
287
- */
288
319
  #applyTheme() {
289
320
  const root = this.#targetElement();
290
321
  if (!root) return;
@@ -292,11 +323,6 @@ var ThemeController = class extends Controller {
292
323
  root.setAttribute("data-theme", resolved);
293
324
  root.style.setProperty("color-scheme", resolved);
294
325
  }
295
- /**
296
- * Keeps the radiogroup (aria-checked + roving tabindex) or toggle (aria-pressed) in sync.
297
- *
298
- * @stimeoRenderRoot
299
- */
300
326
  #syncControls() {
301
327
  const options = this.optionTargets;
302
328
  if (options.length > 0) {
@@ -314,43 +340,35 @@ var ThemeController = class extends Controller {
314
340
  this.element.setAttribute("aria-pressed", String(this.#resolved() === "dark"));
315
341
  }
316
342
  }
317
- /** Whether the controller element is the button of the 2-value contract. */
318
343
  get #isToggleButton() {
319
344
  return this.element.tagName === "BUTTON" || this.element.getAttribute("role") === "button";
320
345
  }
321
- /** The selected mode after validation; an unreadable declaration is the default. */
322
346
  get #mode() {
323
347
  return isMode(this.modeValue) ? this.modeValue : DEFAULT_MODE;
324
348
  }
325
- /** The effective theme: the OS preference when `system`, else the mode itself. */
326
349
  #resolved() {
327
350
  const mode = this.#mode;
328
351
  if (mode === "dark") return "dark";
329
352
  if (mode === "light") return "light";
330
353
  return this.#media?.matches ? "dark" : "light";
331
354
  }
332
- /** An option's mode from its `data-value`, or `null` when that is not one of the three. */
333
355
  #optionMode(option) {
334
356
  const mode = option.getAttribute("data-value");
335
357
  return isMode(mode) ? mode : null;
336
358
  }
337
- /** Resolves the state-hook target (`<html>` by default). */
338
359
  #targetElement() {
339
360
  const selector = this.#targetSelector;
340
361
  if (selector === DEFAULT_TARGET || selector === ":root") return document.documentElement;
341
362
  return document.querySelector(selector);
342
363
  }
343
- /** Reads a persisted, validated mode from `localStorage` (null when absent/blocked). */
344
364
  #readStored() {
345
365
  const result = readLocalStorage(this.storageKeyValue);
346
366
  return result.ok && isMode(result.value) ? result.value : null;
347
367
  }
348
- /** Persists the mode, swallowing storage errors (private mode / quota). */
349
368
  #writeStored(mode) {
350
369
  writeLocalStorage(this.storageKeyValue, mode);
351
370
  }
352
371
  };
353
372
 
354
373
  export { ThemeController };
355
- //# sourceMappingURL=theme_controller.js.map
356
374
  //# sourceMappingURL=theme_controller.js.map