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,13 +1,9 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
- // src/controllers/color_picker_controller.ts
4
-
5
- // src/utils/logical_scroll.ts
6
3
  function isRtl(element) {
7
4
  return window.getComputedStyle(element).direction === "rtl";
8
5
  }
9
6
 
10
- // src/utils/arrow_step.ts
11
7
  function logicalArrowKey(key, element) {
12
8
  if (key !== "ArrowRight" && key !== "ArrowLeft") return key;
13
9
  if (!isRtl(element)) return key;
@@ -17,15 +13,32 @@ function isReservedArrowChord(event, allow = []) {
17
13
  if (!event.key.startsWith("Arrow")) return false;
18
14
  return event.altKey && !allow.includes("alt") || event.ctrlKey && !allow.includes("ctrl") || event.metaKey && !allow.includes("meta") || event.shiftKey && !allow.includes("shift");
19
15
  }
16
+ function hasModifierChord(event) {
17
+ return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
18
+ }
19
+
20
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
21
+ if (element.getAttribute(name) === value) return false;
22
+ if (value === null) element.removeAttribute(name);
23
+ else element.setAttribute(name, value);
24
+ return true;
25
+ }
20
26
 
21
- // src/utils/coerce.ts
22
27
  function toFiniteNumber(raw) {
23
- if (raw === null || raw === void 0 || raw === "") return null;
24
- const value = typeof raw === "number" ? raw : Number(raw);
28
+ if (typeof raw !== "number" && typeof raw !== "string") return null;
29
+ if (typeof raw === "string" && raw.trim().length === 0) return null;
30
+ const value = Number(raw);
25
31
  return Number.isFinite(value) ? value : null;
26
32
  }
27
33
 
28
- // src/utils/field_mirror.ts
34
+ function ownerIndex(candidates, node) {
35
+ if (!(node instanceof Node)) return -1;
36
+ return candidates.findIndex((candidate) => candidate.contains(node));
37
+ }
38
+ function ownerOf(candidates, node) {
39
+ return candidates[ownerIndex(candidates, node)] ?? null;
40
+ }
41
+
29
42
  function writeField(field, value) {
30
43
  if (field.value === value) return false;
31
44
  field.value = value;
@@ -35,27 +48,36 @@ function commitField(target) {
35
48
  target.dispatchEvent(new Event("change", { bubbles: true }));
36
49
  }
37
50
 
38
- // src/utils/microtask_coalescer.ts
51
+ var ListenerSet = class {
52
+ #abort = new AbortController();
53
+ add(target, type, handler, options) {
54
+ target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
55
+ }
56
+ dispose() {
57
+ this.#abort.abort();
58
+ this.#abort = new AbortController();
59
+ }
60
+ };
61
+
39
62
  var MicrotaskCoalescer = class {
40
63
  #run;
41
64
  #queued = false;
42
65
  #active = false;
43
66
  #generation = 0;
44
- /** @param run - the single reconciliation pass, invoked at most once per batch. */
45
67
  constructor(run) {
46
68
  this.#run = run;
47
69
  }
48
- /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */
49
70
  activate() {
50
71
  this.#active = true;
51
72
  }
52
- /** Closes the window and drops any pending pass; call from `disconnect()`. */
53
73
  cancel() {
54
74
  this.#active = false;
55
75
  this.#queued = false;
56
76
  this.#generation += 1;
57
77
  }
58
- /** Requests one pass after the batch settles. Idempotent; inert outside the window. */
78
+ get pending() {
79
+ return this.#queued;
80
+ }
59
81
  schedule() {
60
82
  if (!this.#active || this.#queued) return;
61
83
  this.#queued = true;
@@ -68,7 +90,45 @@ var MicrotaskCoalescer = class {
68
90
  }
69
91
  };
70
92
 
71
- // src/utils/owned_pointer_session.ts
93
+ var MorphRenderWatcher = class {
94
+ #listeners = new ListenerSet();
95
+ #pass;
96
+ #element = null;
97
+ #onMorph = () => this.#pass.schedule();
98
+ constructor(run) {
99
+ this.#pass = new MicrotaskCoalescer(run);
100
+ }
101
+ observe(element) {
102
+ if (this.#element === element) return;
103
+ this.disconnect();
104
+ this.#element = element;
105
+ this.#pass.activate();
106
+ this.#listeners.add(element, "turbo:morph-element", this.#onMorph);
107
+ }
108
+ schedule() {
109
+ this.#pass.schedule();
110
+ }
111
+ get pending() {
112
+ return this.#pass.pending;
113
+ }
114
+ disconnect() {
115
+ this.#listeners.dispose();
116
+ this.#pass.cancel();
117
+ this.#element = null;
118
+ }
119
+ };
120
+
121
+ var MoveCounter = class {
122
+ #sequence = 0;
123
+ record() {
124
+ this.#sequence += 1;
125
+ return this.#sequence;
126
+ }
127
+ isLatest(token) {
128
+ return token === this.#sequence;
129
+ }
130
+ };
131
+
72
132
  var OwnedPointerSession = class {
73
133
  #pointerId;
74
134
  #owner;
@@ -88,7 +148,6 @@ var OwnedPointerSession = class {
88
148
  } catch {
89
149
  }
90
150
  }
91
- /** Releases capture and listeners, then reports the end exactly once. */
92
151
  end() {
93
152
  this.#finish("teardown");
94
153
  }
@@ -113,7 +172,13 @@ var OwnedPointerSession = class {
113
172
  };
114
173
  };
115
174
 
116
- // src/controllers/color_picker_controller.ts
175
+ function fillTemplate(template, values) {
176
+ return template.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g, (match, name) => {
177
+ const replacement = Object.hasOwn(values, name) ? values[name] : void 0;
178
+ return replacement === void 0 ? match : String(replacement);
179
+ });
180
+ }
181
+
117
182
  var COLOR_PROPERTY = "--stimeo--color";
118
183
  var VALUE_TEXT_ATTRIBUTE = "data-value-text";
119
184
  var CHANNEL_RANGE = {
@@ -123,6 +188,12 @@ var CHANNEL_RANGE = {
123
188
  alpha: [0, 100]
124
189
  };
125
190
  var ColorPickerController = class extends Controller {
191
+ #fieldWrites = /* @__PURE__ */ new WeakMap();
192
+ #moves = new MoveCounter();
193
+ #move = 0;
194
+ #adoptedValue = null;
195
+ #adoptedAlpha = false;
196
+ #exactHex = null;
126
197
  static targets = ["slider", "hex", "preview", "field"];
127
198
  static values = {
128
199
  value: { type: String, default: "#000000" },
@@ -131,89 +202,59 @@ var ColorPickerController = class extends Controller {
131
202
  };
132
203
  static actions = ["onHexInput", "onKeydown", "onPointerDown"];
133
204
  static events = ["change", "reconcile"];
134
- /** Whether the consumer declared a mirroring track and the direction mirrors it. */
135
- get #mirrored() {
136
- return this.logicalTrackValue && isRtl(this.element);
137
- }
138
- /** The current color in the editing model; its alpha is 100 while `alpha` is off. */
139
205
  #color = { hue: 0, saturation: 0, lightness: 0, alpha: 100 };
140
- /** The pointer that owns the live drag, with the slider whose geometry maps it. */
141
206
  #drag = null;
142
- /** Color the last repaint settled on, so a configuration-driven move is reported once. */
143
207
  #committedHex = null;
144
- /**
145
- * Whether the paint about to run was asked for by this picker's own controls.
146
- * The `value` Value is shared with the page — application code and a Turbo
147
- * morph write it too — so the form fields and the hex input take their "did
148
- * the user commit this" answer from the route, not from the Value.
149
- */
150
- #movedByUser = false;
151
- /**
152
- * The hex this picker last wrote into its hex input, or `null` before it wrote
153
- * one. A repaint the page drives compares with it rather than with the input's
154
- * text, so a color that did not move leaves what the reader is typing alone.
155
- */
156
208
  #writtenHex = null;
157
- /**
158
- * Collapses a morph that swaps render inputs into one repaint, and refuses the
159
- * pass Stimulus delivers before `connect()`.
160
- */
161
- #repaint = new MicrotaskCoalescer(() => this.#reconcileColor());
162
- /** Seeds the model from the initial hex value and renders every surface. */
209
+ #writtenHexInput = null;
210
+ #repaint = new MorphRenderWatcher(() => this.#reconcileColor());
163
211
  connect() {
164
- this.#repaint.activate();
212
+ this.#repaint.observe(this.element);
165
213
  this.#adoptValue();
166
214
  this.#render();
167
215
  }
168
- /** Cancels any active pointer drag so document listeners never leak. */
169
216
  disconnect() {
170
- this.#repaint.cancel();
217
+ this.#repaint.disconnect();
171
218
  this.#endDrag();
172
219
  }
173
- /** Repaints when application code (or a Turbo morph) changes `alpha` at runtime. */
174
220
  alphaValueChanged() {
175
221
  this.#repaint.schedule();
176
222
  }
177
- /** Adopts a color application code (or a Turbo morph) put in `value` at runtime. */
178
223
  valueValueChanged() {
179
224
  if (this.valueValue === this.#committedHex) return;
180
225
  this.#repaint.schedule();
181
226
  }
182
- /**
183
- * Hydrates a channel slider inserted or replaced at runtime through the repaint
184
- * pass, which renders every slider after the batch and reports a committed
185
- * color that moved. A slider arriving moves no color, so that pass reports
186
- * nothing.
187
- */
188
227
  sliderTargetConnected() {
189
228
  this.#repaint.schedule();
190
229
  }
191
- /** Ends a gesture whose geometry target disappeared or ceased being a target. */
192
230
  sliderTargetDisconnected(slider) {
193
231
  if (this.#drag?.slider === slider) this.#endDrag();
194
232
  }
195
- /** Fills a hex input inserted or replaced at runtime with the current color. */
196
233
  hexTargetConnected(hex) {
197
234
  this.#writeHex(hex, this.#hexString());
235
+ if (hex === this.hexTarget) this.#writtenHexInput = hex;
236
+ }
237
+ hexTargetDisconnected() {
238
+ this.#repaint.schedule();
198
239
  }
199
- /** Fills a form field inserted or replaced at runtime with the current color. */
200
240
  fieldTargetConnected(field) {
201
241
  this.#mirrorColor(field, this.#hexString());
202
242
  }
203
- /** Publishes the current color on a preview inserted or replaced at runtime. */
204
243
  previewTargetConnected(preview) {
205
244
  this.#publishColor(preview, this.#hexString());
206
245
  }
207
- /** Keyboard stepping on the focused channel slider (APG Slider model). */
208
246
  onKeydown(event) {
209
247
  if (isReservedArrowChord(event)) return;
248
+ if ((event.key === "Home" || event.key === "End" || event.key === "PageUp" || event.key === "PageDown") && hasModifierChord(event))
249
+ return;
210
250
  const slider = event.currentTarget;
211
251
  const channel = this.#editableChannel(slider);
212
252
  if (!channel) return;
253
+ this.#adoptPendingValue();
213
254
  const [min, max] = this.#rangeOf(slider, channel);
214
255
  const value = this.#color[channel];
215
256
  let next = null;
216
- switch (this.#mirrored ? logicalArrowKey(event.key, this.element) : event.key) {
257
+ switch (this.logicalTrackValue ? logicalArrowKey(event.key, slider) : event.key) {
217
258
  case "ArrowRight":
218
259
  case "ArrowUp":
219
260
  next = value + 1;
@@ -240,14 +281,13 @@ var ColorPickerController = class extends Controller {
240
281
  event.preventDefault();
241
282
  this.#setChannel(channel, next, min, max);
242
283
  }
243
- /** Begins a primary-button drag on a channel slider, owned by its own pointer. */
244
284
  onPointerDown(event) {
245
285
  if (event.button !== 0 || this.#drag) return;
246
286
  const slider = event.currentTarget;
247
287
  const channel = this.#editableChannel(slider);
248
288
  if (!channel) return;
249
289
  const [min, max] = this.#rangeOf(slider, channel);
250
- const mirrored = this.#mirrored;
290
+ const mirrored = this.logicalTrackValue && isRtl(slider);
251
291
  const update = (clientX) => {
252
292
  const rect = slider.getBoundingClientRect();
253
293
  if (rect.width === 0) return false;
@@ -271,81 +311,85 @@ var ColorPickerController = class extends Controller {
271
311
  });
272
312
  this.#drag = drag;
273
313
  }
274
- /** Parses the hex input on confirm and syncs every channel + surface. */
275
- onHexInput() {
276
- if (!this.hasHexTarget) return;
277
- const parsed = hexToHsla(this.hexTarget.value);
314
+ onHexInput(event) {
315
+ const input = this.#confirmingHexInput(event);
316
+ if (!input) return;
317
+ const parsed = hexToHsla(input.value);
278
318
  if (!parsed) {
279
- this.#writeHex(this.hexTarget, this.#hexString());
319
+ this.#writeHex(input, this.#hexString());
280
320
  return;
281
321
  }
282
- this.#color = this.#opaqueUnlessEnabled(parsed);
283
- this.#commitColor();
322
+ this.#color = this.#opaqueUnlessEnabled(parsed.color);
323
+ this.#exactHex = parsed.hex;
324
+ this.#commitColor(input);
325
+ }
326
+ #confirmingHexInput(event) {
327
+ if (event) return ownerOf(this.hexTargets, event.target);
328
+ return this.hasHexTarget ? this.hexTarget : null;
284
329
  }
285
- /** Replaces the model with the color `value` names, leaving an unparsable one alone. */
286
330
  #adoptValue() {
331
+ this.#adoptedValue = this.valueValue;
332
+ this.#adoptedAlpha = this.alphaValue;
287
333
  const parsed = hexToHsla(this.valueValue);
288
- if (parsed) this.#color = this.#opaqueUnlessEnabled(parsed);
334
+ if (parsed) {
335
+ this.#color = this.#opaqueUnlessEnabled(parsed.color);
336
+ this.#exactHex = parsed.hex;
337
+ }
338
+ }
339
+ #adoptPendingValue() {
340
+ if (this.valueValue !== this.#adoptedValue || this.alphaValue !== this.#adoptedAlpha) {
341
+ this.#adoptValue();
342
+ }
289
343
  }
290
- /**
291
- * The model a parsed color implies: alpha only survives while its channel is
292
- * enabled, because `hexString()` would otherwise emit `#RRGGBB` while `change`
293
- * reported `rgba.a < 1`.
294
- */
295
344
  #opaqueUnlessEnabled(parsed) {
296
345
  return this.alphaValue ? parsed : { ...parsed, alpha: 100 };
297
346
  }
298
- /** Clamps and snaps one channel to an integer, then re-renders + emits change. */
299
347
  #setChannel(channel, raw, min, max) {
300
- this.#color[channel] = Math.round(Math.min(max, Math.max(min, raw)));
348
+ this.#adoptPendingValue();
349
+ const next = Math.round(Math.min(max, Math.max(min, raw)));
350
+ if (next !== this.#color[channel]) this.#exactHex = null;
351
+ this.#color[channel] = next;
301
352
  this.#commitColor();
302
353
  }
303
- /**
304
- * Renders the model and reports a color the user actually moved. A key pressed
305
- * at a bound, a pointer that lands on the step already showing, and a re-confirmed
306
- * hex all leave the committed color where it was, so no `change` describes them.
307
- *
308
- * The color is written into `value` first — the one path that writes it — so a
309
- * Turbo snapshot and a morph read the color the user picked, and a listener of
310
- * the field's native `change` already finds it there.
311
- */
312
- #commitColor() {
354
+ #commitColor(source = null) {
313
355
  const previous = this.#committedHex;
314
356
  const hex = this.#hexString();
315
- if (this.valueValue !== hex) this.valueValue = hex;
316
- this.#movedByUser = true;
317
- this.#render();
318
- if (this.#committedHex !== previous) {
319
- this.dispatch("change", { detail: this.#settledDetail() });
357
+ const changed = hex !== previous;
358
+ if (changed) {
359
+ if (this.valueValue !== hex) this.valueValue = hex;
360
+ this.#adoptedValue = hex;
361
+ this.#adoptedAlpha = this.alphaValue;
362
+ this.#move = this.#moves.record();
363
+ }
364
+ const move = this.#move;
365
+ const fields = this.#render(true);
366
+ if (source) this.#writeHex(source, hex);
367
+ const detail = this.#settledDetail();
368
+ for (const [field, write] of fields) {
369
+ if (field.value === hex && this.#fieldWrites.get(field) === write) commitField(field);
320
370
  }
371
+ if (!this.#moves.isLatest(move)) return;
372
+ if (changed) this.dispatch("change", { detail });
321
373
  }
322
- /**
323
- * Reflects the model onto sliders, the hex input, preview, and form field. The
324
- * `value` Value is left as it is.
325
- *
326
- * The hex input is written for the reader's own commit, which shows the color
327
- * in its canonical form, and otherwise only when the hex it shows moved: a
328
- * repaint the page drives that leaves the color where it is keeps text the
329
- * reader has typed there and not committed.
330
- *
331
- * @stimeoRenderRoot
332
- */
333
- #render() {
334
- const byUser = this.#movedByUser;
335
- this.#movedByUser = false;
374
+ #render(byUser = false) {
375
+ const fields = [];
336
376
  for (const slider of this.sliderTargets) this.#renderSlider(slider);
337
377
  const hex = this.#hexString();
338
378
  this.#committedHex = hex;
339
- if (this.hasHexTarget && (byUser || hex !== this.#writtenHex)) {
340
- this.#writeHex(this.hexTarget, hex);
379
+ if (this.hasHexTarget) {
380
+ const input = this.hexTarget;
381
+ if (byUser || hex !== this.#writtenHex || input !== this.#writtenHexInput) {
382
+ this.#writtenHexInput = input;
383
+ this.#writeHex(input, hex);
384
+ }
341
385
  }
342
386
  for (const field of this.fieldTargets) {
343
- if (this.#mirrorColor(field, hex) && byUser) commitField(field);
387
+ if (this.#mirrorColor(field, hex)) fields.push([field, this.#fieldWrites.get(field) ?? 0]);
344
388
  }
345
389
  for (const preview of this.previewTargets) this.#publishColor(preview, hex);
346
390
  this.#publishColor(this.element, hex);
391
+ return fields;
347
392
  }
348
- /** Writes one slider's announced range, value, and value text, skipping equal ones. */
349
393
  #renderSlider(slider) {
350
394
  const channel = this.#channelOf(slider);
351
395
  if (!channel) return;
@@ -358,86 +402,72 @@ var ColorPickerController = class extends Controller {
358
402
  "aria-valuetext": this.#valueText(slider, channel, value)
359
403
  };
360
404
  for (const [name, next] of Object.entries(attributes)) {
361
- if (slider.getAttribute(name) !== next) slider.setAttribute(name, next);
405
+ setAttributeIfChanged(slider, name, next);
362
406
  }
363
407
  }
364
- /** Writes `hex` into a hex input and keeps it as the hex last written there. */
365
408
  #writeHex(input, hex) {
366
409
  this.#writtenHex = hex;
367
410
  this.#mirrorColor(input, hex);
368
411
  }
369
- /**
370
- * Mirrors the color into an input, leaving an already-equal value untouched.
371
- *
372
- * @returns Whether the input's value moved.
373
- */
374
412
  #mirrorColor(input, hex) {
375
- return writeField(input, hex);
413
+ if (!writeField(input, hex)) return false;
414
+ this.#fieldWrites.set(input, (this.#fieldWrites.get(input) ?? 0) + 1);
415
+ return true;
376
416
  }
377
- /** Publishes the color as the consumer's CSS hook, skipping an equal value. */
378
417
  #publishColor(element, hex) {
379
418
  if (element.style.getPropertyValue(COLOR_PROPERTY) !== hex) {
380
419
  element.style.setProperty(COLOR_PROPERTY, hex);
381
420
  }
382
421
  }
383
- /**
384
- * Repaints after a declarative input changed at runtime and reports a color this
385
- * controller settled on. Disabling alpha drops it from the model and an outside
386
- * `value` names another color, so the committed color can move without a user
387
- * edit; `change` stays reserved for the picker's own actions.
388
- */
389
422
  #reconcileColor() {
423
+ if (this.#drag && !this.#editableChannel(this.#drag.slider)) this.#endDrag();
390
424
  const previous = this.#committedHex;
391
- if (previous !== null && this.valueValue !== previous) this.#adoptValue();
425
+ this.#adoptPendingValue();
392
426
  if (!this.alphaValue) this.#color.alpha = 100;
393
427
  this.#render();
394
428
  if (previous !== null && this.#committedHex !== previous) {
429
+ this.#move = this.#moves.record();
395
430
  this.dispatch("reconcile", { detail: this.#settledDetail() });
396
431
  }
397
432
  }
398
- /** The settled color as event detail, shared by both report paths. */
399
433
  #settledDetail() {
400
- const rgb = hslToRgb(this.#color.hue, this.#color.saturation, this.#color.lightness);
401
- return { value: this.#hexString(), rgba: { ...rgb, a: this.#color.alpha / 100 } };
434
+ const value = this.#hexString();
435
+ return {
436
+ value,
437
+ rgba: {
438
+ r: Number.parseInt(value.slice(1, 3), 16),
439
+ g: Number.parseInt(value.slice(3, 5), 16),
440
+ b: Number.parseInt(value.slice(5, 7), 16),
441
+ a: this.alphaValue ? Number.parseInt(value.slice(7, 9), 16) / 255 : 1
442
+ }
443
+ };
402
444
  }
403
- /** The current color as `#RRGGBB`, or `#RRGGBBAA` when alpha is enabled. */
404
445
  #hexString() {
446
+ if (this.#exactHex !== null) {
447
+ return this.alphaValue ? this.#exactHex : this.#exactHex.slice(0, 7);
448
+ }
405
449
  const rgb = hslToRgb(this.#color.hue, this.#color.saturation, this.#color.lightness);
406
450
  const base = `#${hex2(rgb.r)}${hex2(rgb.g)}${hex2(rgb.b)}`;
407
451
  if (!this.alphaValue) return base;
408
452
  return `${base}${hex2(Math.round(this.#color.alpha / 100 * 255))}`;
409
453
  }
410
- /** Reads a slider's `data-channel`, if it is a known channel. */
411
454
  #channelOf(slider) {
412
455
  const channel = slider.getAttribute("data-channel");
413
456
  return channel && Object.hasOwn(CHANNEL_RANGE, channel) ? channel : null;
414
457
  }
415
- /**
416
- * The channel a slider edits, or null when this picker edits none through it. An
417
- * alpha slider authored while `alpha` is off edits nothing: moving it would leave
418
- * the model translucent behind an opaque `#RRGGBB`.
419
- */
420
458
  #editableChannel(slider) {
421
459
  const channel = this.#channelOf(slider);
422
460
  return channel === "alpha" && !this.alphaValue ? null : channel;
423
461
  }
424
- /** The channel's announced text: the slider's template, or the built-in English. */
425
462
  #valueText(slider, channel, value) {
426
463
  const template = slider.getAttribute(VALUE_TEXT_ATTRIBUTE);
427
- return template ? template.replaceAll("{value}", String(value)) : defaultValueText(channel, value);
464
+ return template ? fillTemplate(template, { value }) : defaultValueText(channel, value);
428
465
  }
429
- /** Ends the live drag so no further movement of that pointer reaches the model. */
430
466
  #endDrag() {
431
467
  const drag = this.#drag;
432
468
  this.#drag = null;
433
469
  drag?.pointer?.end();
434
470
  }
435
- /**
436
- * A slider's `[min, max]` from aria-valuemin/max, falling back per channel.
437
- * An absent or blank attribute means "not authored", not zero — coercing it to
438
- * a number would pin the channel at `0` and make the per-channel default
439
- * unreachable.
440
- */
441
471
  #rangeOf(slider, channel) {
442
472
  const [defMin, defMax] = CHANNEL_RANGE[channel];
443
473
  return [
@@ -503,9 +533,11 @@ function hexToHsla(input) {
503
533
  const b = Number.parseInt(full.slice(4, 6), 16);
504
534
  const a = full.length === 8 ? Number.parseInt(full.slice(6, 8), 16) : 255;
505
535
  const { h, s, l } = rgbToHsl(r, g, b);
506
- return { hue: h, saturation: s, lightness: l, alpha: Math.round(a / 255 * 100) };
536
+ return {
537
+ color: { hue: h, saturation: s, lightness: l, alpha: Math.round(a / 255 * 100) },
538
+ hex: `#${full.slice(0, 6).toLowerCase()}${hex2(a)}`
539
+ };
507
540
  }
508
541
 
509
542
  export { ColorPickerController };
510
- //# sourceMappingURL=color_picker_controller.js.map
511
543
  //# sourceMappingURL=color_picker_controller.js.map