stimeo-ui 0.17.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 (297) hide show
  1. package/CHANGELOG.md +106 -1
  2. package/README.md +19 -10
  3. package/dist/cable/index.d.ts +9 -8
  4. package/dist/cable/index.js +22 -14
  5. package/dist/cable/index.js.map +1 -1
  6. package/dist/coerce-JtZVNG5h.d.ts +20 -0
  7. package/dist/controllers/accordion_controller.js +14 -6
  8. package/dist/controllers/accordion_controller.js.map +1 -1
  9. package/dist/controllers/alert_dialog_controller.js +145 -118
  10. package/dist/controllers/alert_dialog_controller.js.map +1 -1
  11. package/dist/controllers/announcer_controller.d.ts +5 -3
  12. package/dist/controllers/announcer_controller.js +113 -17
  13. package/dist/controllers/announcer_controller.js.map +1 -1
  14. package/dist/controllers/auto_submit_controller.js +185 -60
  15. package/dist/controllers/auto_submit_controller.js.map +1 -1
  16. package/dist/controllers/avatar_controller.js +55 -43
  17. package/dist/controllers/avatar_controller.js.map +1 -1
  18. package/dist/controllers/breadcrumb_controller.js.map +1 -1
  19. package/dist/controllers/bulk_select_controller.d.ts +3 -3
  20. package/dist/controllers/bulk_select_controller.js +64 -50
  21. package/dist/controllers/bulk_select_controller.js.map +1 -1
  22. package/dist/controllers/calendar_controller.d.ts +15 -12
  23. package/dist/controllers/calendar_controller.js +55 -53
  24. package/dist/controllers/calendar_controller.js.map +1 -1
  25. package/dist/controllers/carousel_controller.d.ts +9 -5
  26. package/dist/controllers/carousel_controller.js +124 -86
  27. package/dist/controllers/carousel_controller.js.map +1 -1
  28. package/dist/controllers/character_counter_controller.d.ts +27 -6
  29. package/dist/controllers/character_counter_controller.js +291 -95
  30. package/dist/controllers/character_counter_controller.js.map +1 -1
  31. package/dist/controllers/checkbox_controller.js +6 -0
  32. package/dist/controllers/checkbox_controller.js.map +1 -1
  33. package/dist/controllers/clipboard_controller.js +118 -27
  34. package/dist/controllers/clipboard_controller.js.map +1 -1
  35. package/dist/controllers/collapsible_controller.d.ts +1 -1
  36. package/dist/controllers/collapsible_controller.js +52 -49
  37. package/dist/controllers/collapsible_controller.js.map +1 -1
  38. package/dist/controllers/color_picker_controller.js +29 -7
  39. package/dist/controllers/color_picker_controller.js.map +1 -1
  40. package/dist/controllers/combobox_controller.d.ts +1 -1
  41. package/dist/controllers/combobox_controller.js +210 -71
  42. package/dist/controllers/combobox_controller.js.map +1 -1
  43. package/dist/controllers/command_palette_controller.d.ts +9 -9
  44. package/dist/controllers/command_palette_controller.js +289 -140
  45. package/dist/controllers/command_palette_controller.js.map +1 -1
  46. package/dist/controllers/conditional_fields_controller.js +145 -58
  47. package/dist/controllers/conditional_fields_controller.js.map +1 -1
  48. package/dist/controllers/confirm_controller.js +145 -118
  49. package/dist/controllers/confirm_controller.js.map +1 -1
  50. package/dist/controllers/context_menu_controller.d.ts +49 -14
  51. package/dist/controllers/context_menu_controller.js +138 -73
  52. package/dist/controllers/context_menu_controller.js.map +1 -1
  53. package/dist/controllers/count_up_controller.js.map +1 -1
  54. package/dist/controllers/countdown_controller.d.ts +2 -2
  55. package/dist/controllers/countdown_controller.js +109 -21
  56. package/dist/controllers/countdown_controller.js.map +1 -1
  57. package/dist/controllers/currency_input_controller.d.ts +75 -11
  58. package/dist/controllers/currency_input_controller.js +446 -72
  59. package/dist/controllers/currency_input_controller.js.map +1 -1
  60. package/dist/controllers/data_grid_controller.d.ts +10 -8
  61. package/dist/controllers/data_grid_controller.js +134 -28
  62. package/dist/controllers/data_grid_controller.js.map +1 -1
  63. package/dist/controllers/date_range_picker_controller.d.ts +12 -9
  64. package/dist/controllers/date_range_picker_controller.js +93 -72
  65. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  66. package/dist/controllers/dialog_controller.d.ts +4 -5
  67. package/dist/controllers/dialog_controller.js +145 -118
  68. package/dist/controllers/dialog_controller.js.map +1 -1
  69. package/dist/controllers/direct_upload_controller.d.ts +1 -1
  70. package/dist/controllers/direct_upload_controller.js +24 -14
  71. package/dist/controllers/direct_upload_controller.js.map +1 -1
  72. package/dist/controllers/dirty_form_controller.d.ts +6 -1
  73. package/dist/controllers/dirty_form_controller.js +68 -31
  74. package/dist/controllers/dirty_form_controller.js.map +1 -1
  75. package/dist/controllers/dismissible_controller.js +64 -46
  76. package/dist/controllers/dismissible_controller.js.map +1 -1
  77. package/dist/controllers/drawer_controller.js +145 -118
  78. package/dist/controllers/drawer_controller.js.map +1 -1
  79. package/dist/controllers/dropdown_controller.js +76 -63
  80. package/dist/controllers/dropdown_controller.js.map +1 -1
  81. package/dist/controllers/editable_controller.js +199 -62
  82. package/dist/controllers/editable_controller.js.map +1 -1
  83. package/dist/controllers/empty_state_controller.js +13 -6
  84. package/dist/controllers/empty_state_controller.js.map +1 -1
  85. package/dist/controllers/file_dropzone_controller.d.ts +3 -0
  86. package/dist/controllers/file_dropzone_controller.js +55 -48
  87. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  88. package/dist/controllers/filter_controller.js +9 -2
  89. package/dist/controllers/filter_controller.js.map +1 -1
  90. package/dist/controllers/flash_controller.d.ts +4 -4
  91. package/dist/controllers/flash_controller.js +66 -33
  92. package/dist/controllers/flash_controller.js.map +1 -1
  93. package/dist/controllers/focus_controller.d.ts +3 -3
  94. package/dist/controllers/focus_controller.js +39 -14
  95. package/dist/controllers/focus_controller.js.map +1 -1
  96. package/dist/controllers/form_field_controller.js +52 -43
  97. package/dist/controllers/form_field_controller.js.map +1 -1
  98. package/dist/controllers/form_validation_controller.d.ts +3 -3
  99. package/dist/controllers/form_validation_controller.js +18 -11
  100. package/dist/controllers/form_validation_controller.js.map +1 -1
  101. package/dist/controllers/frame_loading_controller.d.ts +13 -12
  102. package/dist/controllers/frame_loading_controller.js +55 -48
  103. package/dist/controllers/frame_loading_controller.js.map +1 -1
  104. package/dist/controllers/highlight_controller.d.ts +5 -4
  105. package/dist/controllers/highlight_controller.js.map +1 -1
  106. package/dist/controllers/hover_card_controller.d.ts +4 -1
  107. package/dist/controllers/hover_card_controller.js +67 -61
  108. package/dist/controllers/hover_card_controller.js.map +1 -1
  109. package/dist/controllers/idle_controller.d.ts +6 -5
  110. package/dist/controllers/idle_controller.js +10 -6
  111. package/dist/controllers/idle_controller.js.map +1 -1
  112. package/dist/controllers/input_mask_controller.d.ts +30 -13
  113. package/dist/controllers/input_mask_controller.js +411 -24
  114. package/dist/controllers/input_mask_controller.js.map +1 -1
  115. package/dist/controllers/intersection_controller.js +3 -0
  116. package/dist/controllers/intersection_controller.js.map +1 -1
  117. package/dist/controllers/lazy_frame_controller.d.ts +3 -2
  118. package/dist/controllers/lazy_frame_controller.js +15 -3
  119. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  120. package/dist/controllers/listbox_controller.d.ts +10 -7
  121. package/dist/controllers/listbox_controller.js +260 -79
  122. package/dist/controllers/listbox_controller.js.map +1 -1
  123. package/dist/controllers/local_time_controller.d.ts +8 -6
  124. package/dist/controllers/local_time_controller.js +48 -13
  125. package/dist/controllers/local_time_controller.js.map +1 -1
  126. package/dist/controllers/masonry_controller.js +11 -4
  127. package/dist/controllers/masonry_controller.js.map +1 -1
  128. package/dist/controllers/menu_controller.d.ts +24 -5
  129. package/dist/controllers/menu_controller.js +138 -82
  130. package/dist/controllers/menu_controller.js.map +1 -1
  131. package/dist/controllers/menubar_controller.d.ts +49 -7
  132. package/dist/controllers/menubar_controller.js +65 -19
  133. package/dist/controllers/menubar_controller.js.map +1 -1
  134. package/dist/controllers/meter_controller.d.ts +13 -20
  135. package/dist/controllers/meter_controller.js +270 -24
  136. package/dist/controllers/meter_controller.js.map +1 -1
  137. package/dist/controllers/multi_select_controller.d.ts +17 -15
  138. package/dist/controllers/multi_select_controller.js +251 -94
  139. package/dist/controllers/multi_select_controller.js.map +1 -1
  140. package/dist/controllers/navigation_menu_controller.d.ts +19 -5
  141. package/dist/controllers/navigation_menu_controller.js +67 -19
  142. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  143. package/dist/controllers/nested_form_controller.js +98 -64
  144. package/dist/controllers/nested_form_controller.js.map +1 -1
  145. package/dist/controllers/network_status_controller.js +70 -52
  146. package/dist/controllers/network_status_controller.js.map +1 -1
  147. package/dist/controllers/number_input_controller.d.ts +24 -6
  148. package/dist/controllers/number_input_controller.js +344 -94
  149. package/dist/controllers/number_input_controller.js.map +1 -1
  150. package/dist/controllers/optimistic_controller.d.ts +8 -5
  151. package/dist/controllers/optimistic_controller.js +29 -11
  152. package/dist/controllers/optimistic_controller.js.map +1 -1
  153. package/dist/controllers/otp_controller.d.ts +35 -4
  154. package/dist/controllers/otp_controller.js +502 -104
  155. package/dist/controllers/otp_controller.js.map +1 -1
  156. package/dist/controllers/overflow_indicator_controller.js +6 -0
  157. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  158. package/dist/controllers/overflow_menu_controller.d.ts +10 -9
  159. package/dist/controllers/overflow_menu_controller.js +136 -21
  160. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  161. package/dist/controllers/pagination_controller.d.ts +3 -2
  162. package/dist/controllers/pagination_controller.js +47 -14
  163. package/dist/controllers/pagination_controller.js.map +1 -1
  164. package/dist/controllers/password_reveal_controller.d.ts +5 -4
  165. package/dist/controllers/password_reveal_controller.js +52 -49
  166. package/dist/controllers/password_reveal_controller.js.map +1 -1
  167. package/dist/controllers/password_strength_controller.d.ts +1 -1
  168. package/dist/controllers/password_strength_controller.js +13 -6
  169. package/dist/controllers/password_strength_controller.js.map +1 -1
  170. package/dist/controllers/persist_controller.js +48 -128
  171. package/dist/controllers/persist_controller.js.map +1 -1
  172. package/dist/controllers/pointer_drag_controller.d.ts +19 -8
  173. package/dist/controllers/pointer_drag_controller.js +249 -23
  174. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  175. package/dist/controllers/popover_controller.d.ts +3 -3
  176. package/dist/controllers/popover_controller.js +82 -65
  177. package/dist/controllers/popover_controller.js.map +1 -1
  178. package/dist/controllers/portal_controller.js +6 -0
  179. package/dist/controllers/portal_controller.js.map +1 -1
  180. package/dist/controllers/preview_guard_controller.js +14 -3
  181. package/dist/controllers/preview_guard_controller.js.map +1 -1
  182. package/dist/controllers/progress_controller.d.ts +9 -19
  183. package/dist/controllers/progress_controller.js +271 -27
  184. package/dist/controllers/progress_controller.js.map +1 -1
  185. package/dist/controllers/radio_group_controller.d.ts +11 -8
  186. package/dist/controllers/radio_group_controller.js +167 -80
  187. package/dist/controllers/radio_group_controller.js.map +1 -1
  188. package/dist/controllers/range_slider_controller.d.ts +4 -3
  189. package/dist/controllers/range_slider_controller.js +27 -7
  190. package/dist/controllers/range_slider_controller.js.map +1 -1
  191. package/dist/controllers/rating_controller.js +93 -57
  192. package/dist/controllers/rating_controller.js.map +1 -1
  193. package/dist/controllers/read_more_controller.js +10 -6
  194. package/dist/controllers/read_more_controller.js.map +1 -1
  195. package/dist/controllers/reading_progress_controller.js +22 -5
  196. package/dist/controllers/reading_progress_controller.js.map +1 -1
  197. package/dist/controllers/relative_time_controller.d.ts +4 -4
  198. package/dist/controllers/relative_time_controller.js +75 -11
  199. package/dist/controllers/relative_time_controller.js.map +1 -1
  200. package/dist/controllers/reset_on_restore_controller.d.ts +3 -3
  201. package/dist/controllers/reset_on_restore_controller.js +6 -0
  202. package/dist/controllers/reset_on_restore_controller.js.map +1 -1
  203. package/dist/controllers/resizable_controller.d.ts +3 -0
  204. package/dist/controllers/resizable_controller.js +55 -22
  205. package/dist/controllers/resizable_controller.js.map +1 -1
  206. package/dist/controllers/roving_controller.d.ts +3 -3
  207. package/dist/controllers/roving_controller.js +10 -4
  208. package/dist/controllers/roving_controller.js.map +1 -1
  209. package/dist/controllers/scroll_area_controller.js +129 -88
  210. package/dist/controllers/scroll_area_controller.js.map +1 -1
  211. package/dist/controllers/scroll_restore_controller.d.ts +3 -3
  212. package/dist/controllers/scroll_restore_controller.js +14 -2
  213. package/dist/controllers/scroll_restore_controller.js.map +1 -1
  214. package/dist/controllers/scroll_visibility_controller.js +93 -60
  215. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  216. package/dist/controllers/scrollspy_controller.js +11 -5
  217. package/dist/controllers/scrollspy_controller.js.map +1 -1
  218. package/dist/controllers/separator_controller.d.ts +1 -1
  219. package/dist/controllers/separator_controller.js +59 -43
  220. package/dist/controllers/separator_controller.js.map +1 -1
  221. package/dist/controllers/sidebar_controller.d.ts +1 -1
  222. package/dist/controllers/sidebar_controller.js +150 -122
  223. package/dist/controllers/sidebar_controller.js.map +1 -1
  224. package/dist/controllers/skeleton_controller.js +55 -48
  225. package/dist/controllers/skeleton_controller.js.map +1 -1
  226. package/dist/controllers/slider_controller.d.ts +2 -1
  227. package/dist/controllers/slider_controller.js +27 -6
  228. package/dist/controllers/slider_controller.js.map +1 -1
  229. package/dist/controllers/smart_sticky_header_controller.d.ts +1 -1
  230. package/dist/controllers/smart_sticky_header_controller.js +13 -5
  231. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  232. package/dist/controllers/sortable_controller.d.ts +4 -4
  233. package/dist/controllers/sortable_controller.js +27 -14
  234. package/dist/controllers/sortable_controller.js.map +1 -1
  235. package/dist/controllers/spinner_controller.js +55 -48
  236. package/dist/controllers/spinner_controller.js.map +1 -1
  237. package/dist/controllers/step_indicator_controller.d.ts +4 -4
  238. package/dist/controllers/step_indicator_controller.js +6 -0
  239. package/dist/controllers/step_indicator_controller.js.map +1 -1
  240. package/dist/controllers/stepper_controller.d.ts +2 -3
  241. package/dist/controllers/stepper_controller.js +6 -0
  242. package/dist/controllers/stepper_controller.js.map +1 -1
  243. package/dist/controllers/stick_to_bottom_controller.d.ts +3 -1
  244. package/dist/controllers/stick_to_bottom_controller.js +19 -8
  245. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  246. package/dist/controllers/sticky_observer_controller.js +49 -43
  247. package/dist/controllers/sticky_observer_controller.js.map +1 -1
  248. package/dist/controllers/submit_once_controller.d.ts +2 -1
  249. package/dist/controllers/submit_once_controller.js +145 -85
  250. package/dist/controllers/submit_once_controller.js.map +1 -1
  251. package/dist/controllers/switch_controller.d.ts +7 -4
  252. package/dist/controllers/switch_controller.js +172 -28
  253. package/dist/controllers/switch_controller.js.map +1 -1
  254. package/dist/controllers/tabs_controller.d.ts +7 -4
  255. package/dist/controllers/tabs_controller.js +6 -1
  256. package/dist/controllers/tabs_controller.js.map +1 -1
  257. package/dist/controllers/tags_input_controller.d.ts +4 -3
  258. package/dist/controllers/tags_input_controller.js +157 -28
  259. package/dist/controllers/tags_input_controller.js.map +1 -1
  260. package/dist/controllers/textarea_autosize_controller.d.ts +1 -1
  261. package/dist/controllers/textarea_autosize_controller.js +40 -19
  262. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  263. package/dist/controllers/theme_controller.d.ts +3 -2
  264. package/dist/controllers/theme_controller.js +10 -4
  265. package/dist/controllers/theme_controller.js.map +1 -1
  266. package/dist/controllers/time_picker_controller.d.ts +38 -5
  267. package/dist/controllers/time_picker_controller.js +192 -54
  268. package/dist/controllers/time_picker_controller.js.map +1 -1
  269. package/dist/controllers/toast_controller.d.ts +4 -5
  270. package/dist/controllers/toast_controller.js +58 -27
  271. package/dist/controllers/toast_controller.js.map +1 -1
  272. package/dist/controllers/toggle_group_controller.d.ts +2 -3
  273. package/dist/controllers/toggle_group_controller.js +158 -56
  274. package/dist/controllers/toggle_group_controller.js.map +1 -1
  275. package/dist/controllers/toolbar_controller.d.ts +8 -6
  276. package/dist/controllers/toolbar_controller.js +150 -21
  277. package/dist/controllers/toolbar_controller.js.map +1 -1
  278. package/dist/controllers/tooltip_controller.d.ts +4 -1
  279. package/dist/controllers/tooltip_controller.js.map +1 -1
  280. package/dist/controllers/transition_controller.js.map +1 -1
  281. package/dist/controllers/tree_view_controller.d.ts +1 -1
  282. package/dist/controllers/tree_view_controller.js +134 -25
  283. package/dist/controllers/tree_view_controller.js.map +1 -1
  284. package/dist/index.d.ts +2 -0
  285. package/dist/index.js +2451 -1312
  286. package/dist/index.js.map +1 -1
  287. package/dist/inspector/cli.d.ts +15 -11
  288. package/dist/inspector/cli.js +16 -3
  289. package/dist/inspector/cli.js.map +1 -1
  290. package/dist/inspector/cli_bin.js +53 -8
  291. package/dist/inspector/cli_bin.js.map +1 -1
  292. package/dist/inspector/examples.json +13 -13
  293. package/dist/inspector/manifest.json +19 -5
  294. package/dist/positioning/index.d.ts +7 -7
  295. package/dist/positioning/index.js +6 -0
  296. package/dist/positioning/index.js.map +1 -1
  297. package/package.json +10 -9
@@ -6,63 +6,182 @@ var COMPOSITION_INPUT_TYPES = /* @__PURE__ */ new Set([
6
6
  "deleteCompositionText",
7
7
  "deleteByComposition"
8
8
  ]);
9
+ function isCompositionInputType(inputType) {
10
+ return inputType !== void 0 && COMPOSITION_INPUT_TYPES.has(inputType);
11
+ }
12
+ var BEFORE_MORPH_ATTRIBUTE = "turbo:before-morph-attribute";
13
+ var textOf = (element) => element.value;
14
+ var holdsFocus = (element) => element instanceof Node && element.getRootNode().activeElement === element;
9
15
  var CompositionTracker = class {
10
16
  #observedTargets = /* @__PURE__ */ new Set();
11
- #activeTargets = /* @__PURE__ */ new Set();
17
+ #composition = null;
12
18
  #onStart;
13
19
  #onEnd;
20
+ #onAbandon;
14
21
  #confirmedTarget = null;
22
+ #keyComposing = false;
23
+ #connected = false;
24
+ #abandoned = null;
15
25
  constructor(options = {}) {
16
26
  this.#onStart = options.onStart;
17
27
  this.#onEnd = options.onEnd;
28
+ this.#onAbandon = options.onAbandon;
18
29
  }
19
30
  observe(target) {
31
+ this.#connected = true;
20
32
  if (this.#observedTargets.has(target)) return;
21
33
  target.addEventListener("compositionstart", this.#handleStart);
22
34
  target.addEventListener("compositionend", this.#handleEnd);
23
- target.addEventListener("keydown", this.#handleKeydown);
35
+ target.addEventListener("keydown", this.#handleKeydown, true);
36
+ target.addEventListener("beforeinput", this.#handleBeforeInput, true);
37
+ target.addEventListener("input", this.#handleInput, true);
38
+ target.addEventListener("blur", this.#handleBlur, true);
39
+ target.addEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);
24
40
  this.#observedTargets.add(target);
25
41
  }
26
42
  unobserve(target) {
27
43
  if (!this.#observedTargets.delete(target)) return;
28
- target.removeEventListener("compositionstart", this.#handleStart);
29
- target.removeEventListener("compositionend", this.#handleEnd);
30
- target.removeEventListener("keydown", this.#handleKeydown);
31
- this.#activeTargets.delete(target);
44
+ this.#release(target);
45
+ if (this.#composition?.target === target) this.#letGo();
32
46
  if (this.#confirmedTarget === target) this.#confirmedTarget = null;
33
47
  }
34
48
  disconnect() {
35
- for (const target of this.#observedTargets) {
36
- target.removeEventListener("compositionstart", this.#handleStart);
37
- target.removeEventListener("compositionend", this.#handleEnd);
38
- target.removeEventListener("keydown", this.#handleKeydown);
39
- }
49
+ this.#connected = false;
50
+ for (const target of this.#observedTargets) this.#release(target);
40
51
  this.#observedTargets.clear();
41
- this.#activeTargets.clear();
52
+ this.#letGo();
42
53
  this.#confirmedTarget = null;
54
+ this.#keyComposing = false;
55
+ this.#abandoned = null;
43
56
  }
44
57
  isComposing(event) {
45
- return this.#activeTargets.size > 0 || event?.isComposing === true;
58
+ this.#settle();
59
+ return event?.isComposing === true || this.#composition !== null;
60
+ }
61
+ composingElement() {
62
+ this.#settle();
63
+ return this.#composition?.element ?? null;
64
+ }
65
+ owns(event) {
66
+ const element = this.composingElement();
67
+ return event.isComposing === true || element !== null && element === event.target;
46
68
  }
47
69
  consumesConfirmedInput(event) {
48
70
  const confirmed = this.#confirmedTarget;
49
71
  this.#confirmedTarget = null;
50
72
  if (confirmed === null || confirmed !== event.target) return false;
51
73
  const inputType = event.inputType;
52
- return !inputType || COMPOSITION_INPUT_TYPES.has(inputType);
74
+ return !inputType || isCompositionInputType(inputType);
75
+ }
76
+ #release(target) {
77
+ target.removeEventListener("compositionstart", this.#handleStart);
78
+ target.removeEventListener("compositionend", this.#handleEnd);
79
+ target.removeEventListener("keydown", this.#handleKeydown, true);
80
+ target.removeEventListener("beforeinput", this.#handleBeforeInput, true);
81
+ target.removeEventListener("input", this.#handleInput, true);
82
+ target.removeEventListener("blur", this.#handleBlur, true);
83
+ target.removeEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);
84
+ }
85
+ #letGo() {
86
+ const composition = this.#composition;
87
+ if (composition === null) return;
88
+ if (!holdsFocus(composition.element)) {
89
+ this.#composition = null;
90
+ return;
91
+ }
92
+ queueMicrotask(() => {
93
+ if (this.#composition !== composition || this.#observedTargets.has(composition.target)) {
94
+ return;
95
+ }
96
+ this.#composition = null;
97
+ if (!this.#connected) return;
98
+ this.#abandoned = { element: composition.element, inPlace: true };
99
+ this.#runAbandon();
100
+ });
101
+ }
102
+ #settle() {
103
+ const composition = this.#composition;
104
+ if (composition === null) return;
105
+ const { target, element, text } = composition;
106
+ if (target instanceof Node && element instanceof Node && !target.contains(element)) {
107
+ this.#composition = null;
108
+ } else if (textOf(element) !== text) {
109
+ this.#abandon(false);
110
+ }
111
+ }
112
+ #abandon(inPlace) {
113
+ this.#owe(inPlace);
114
+ this.#composition = null;
115
+ queueMicrotask(this.#runAbandon);
116
+ }
117
+ #owe(inPlace) {
118
+ const composition = this.#composition;
119
+ if (composition !== null) this.#abandoned = { element: composition.element, inPlace };
53
120
  }
121
+ #runAbandon = () => {
122
+ const abandoned = this.#abandoned;
123
+ if (abandoned === null) return;
124
+ this.#abandoned = null;
125
+ this.#onAbandon?.(abandoned.element, abandoned.inPlace);
126
+ };
54
127
  #handleStart = (event) => {
55
128
  this.#confirmedTarget = null;
56
- if (event.currentTarget) this.#activeTargets.add(event.currentTarget);
129
+ this.#settle();
130
+ this.#owe(true);
131
+ const target = event.currentTarget;
132
+ const element = event.target;
133
+ this.#composition = { target, element, text: textOf(element) };
134
+ this.#runAbandon();
57
135
  this.#onStart?.(event);
58
136
  };
59
137
  #handleEnd = (event) => {
60
- if (event.currentTarget) this.#activeTargets.delete(event.currentTarget);
138
+ this.#runAbandon();
139
+ if (this.#composition?.target === event.currentTarget) this.#composition = null;
61
140
  this.#confirmedTarget = event.target;
62
141
  this.#onEnd?.(event);
63
142
  };
64
- #handleKeydown = () => {
143
+ #handleKeydown = (event) => {
144
+ this.#settle();
145
+ this.#runAbandon();
65
146
  this.#confirmedTarget = null;
147
+ this.#keyComposing = event.isComposing === true;
148
+ };
149
+ #handleBeforeInput = (event) => {
150
+ const keyComposing = this.#keyComposing;
151
+ this.#keyComposing = false;
152
+ this.#settle();
153
+ const { isComposing, inputType } = event;
154
+ if (this.#composition !== null && !keyComposing && !isComposing && inputType && !isCompositionInputType(inputType)) {
155
+ this.#abandon(true);
156
+ }
157
+ this.#runAbandon();
158
+ };
159
+ #handleInput = (event) => {
160
+ const composition = this.#composition;
161
+ const { isTrusted, isComposing, inputType } = event;
162
+ if (composition !== null && event.target === composition.element && (isTrusted || isComposing || isCompositionInputType(inputType))) {
163
+ composition.text = textOf(composition.element);
164
+ } else {
165
+ this.#settle();
166
+ }
167
+ this.#runAbandon();
168
+ };
169
+ #handleBlur = (event) => {
170
+ this.#settle();
171
+ this.#runAbandon();
172
+ const composition = this.#composition;
173
+ if (composition === null || composition.target === composition.element) return;
174
+ const { element } = composition;
175
+ if (!(element instanceof Node) || event.target !== element) return;
176
+ const root = element.getRootNode();
177
+ if (root.activeElement !== element) this.#composition = null;
178
+ };
179
+ #handleBeforeMorphAttribute = (event) => {
180
+ this.#settle();
181
+ const composition = this.#composition;
182
+ if (composition?.target !== event.currentTarget || event.target !== composition.element) return;
183
+ const detail = event.detail;
184
+ if (detail?.attributeName === "value") event.preventDefault();
66
185
  };
67
186
  };
68
187
 
@@ -89,6 +208,43 @@ function parseJsonObject(raw) {
89
208
  return parsed;
90
209
  }
91
210
 
211
+ var DetachGate = class _DetachGate {
212
+ #pending = false;
213
+ get pending() {
214
+ return this.#pending;
215
+ }
216
+ static isDetached(host) {
217
+ return !host.element.isConnected || !_DetachGate.#listed(host);
218
+ }
219
+ disconnected(host, teardown) {
220
+ const carried = _DetachGate.#carried(host);
221
+ if (!carried && _DetachGate.isDetached(host)) {
222
+ this.#pending = false;
223
+ teardown();
224
+ return;
225
+ }
226
+ this.#pending = true;
227
+ const probe = () => {
228
+ if (!this.#pending) return;
229
+ this.#pending = false;
230
+ teardown();
231
+ };
232
+ if (carried) setTimeout(probe, 0);
233
+ else queueMicrotask(probe);
234
+ }
235
+ static #carried(host) {
236
+ const element = host.element;
237
+ return !element.isConnected && element.closest("[data-turbo-permanent]") !== null && _DetachGate.#listed(host);
238
+ }
239
+ static #listed(host) {
240
+ const tokens = (host.element.getAttribute("data-controller") ?? "").split(/\s+/);
241
+ return tokens.includes(host.identifier);
242
+ }
243
+ cancel() {
244
+ this.#pending = false;
245
+ }
246
+ };
247
+
92
248
  function inheritsFieldsetDisabled(control) {
93
249
  let fieldset = control.closest("fieldset[disabled]");
94
250
  while (fieldset) {
@@ -99,6 +255,120 @@ function inheritsFieldsetDisabled(control) {
99
255
  return false;
100
256
  }
101
257
 
258
+ function sharedRegistry(key, create) {
259
+ const symbol = Symbol.for(key);
260
+ const scope = globalThis;
261
+ const existing = scope[symbol];
262
+ if (existing !== void 0) return existing;
263
+ const registry = create();
264
+ Object.defineProperty(globalThis, symbol, { value: registry });
265
+ return registry;
266
+ }
267
+
268
+ var PREFIX = "__stimeo_raw_v1_";
269
+ var documents = sharedRegistry(
270
+ "stimeo-ui.form-data-projection.registry.v1",
271
+ () => /* @__PURE__ */ new WeakMap()
272
+ );
273
+ function decodedName(key) {
274
+ if (!key.startsWith(PREFIX)) return null;
275
+ const separator = PREFIX.length + 32;
276
+ if (key[separator] !== ":") return null;
277
+ try {
278
+ const name = JSON.parse(key.slice(separator + 1));
279
+ return typeof name === "string" ? name : null;
280
+ } catch {
281
+ return null;
282
+ }
283
+ }
284
+ function projectedFieldName(name) {
285
+ return decodedName(name) ?? name;
286
+ }
287
+ function forDocument(document2) {
288
+ const existing = documents.get(document2);
289
+ if (existing) return existing;
290
+ const state = {
291
+ fields: /* @__PURE__ */ new Map(),
292
+ byField: /* @__PURE__ */ new WeakMap(),
293
+ handle: (event) => {
294
+ const data = event.formData;
295
+ if (!data) return;
296
+ const entries = [...data.entries()];
297
+ let changed = false;
298
+ const projected = entries.map(([key, value]) => {
299
+ const name = decodedName(key);
300
+ if (name === null) return [key, value];
301
+ changed = true;
302
+ const field = state.fields.get(key);
303
+ const live = field && field.field.name === key && field.field.form === event.target;
304
+ return [name, live ? field.project(value) : ""];
305
+ });
306
+ if (!changed) return;
307
+ for (const key of new Set(data.keys())) data.delete(key);
308
+ for (const [name, value] of projected) data.append(name, value);
309
+ }
310
+ };
311
+ documents.set(document2, state);
312
+ document2.addEventListener("formdata", state.handle, { capture: true });
313
+ return state;
314
+ }
315
+ function prepareFormDataProjection(form) {
316
+ const state = forDocument(form.ownerDocument);
317
+ form.addEventListener("formdata", state.handle, { capture: true });
318
+ }
319
+ var FormDataProjection = class {
320
+ #held = null;
321
+ hold(field, project) {
322
+ const held = this.#held;
323
+ if (held?.field === field && held.key === field.name && held.document === field.ownerDocument) {
324
+ if (field.form) prepareFormDataProjection(field.form);
325
+ return;
326
+ }
327
+ this.release();
328
+ const name = projectedFieldName(field.name);
329
+ if (name === "" || field.type === "hidden" && name.toLowerCase() === "_charset_") return;
330
+ const state = forDocument(field.ownerDocument);
331
+ if (field.form) prepareFormDataProjection(field.form);
332
+ const previous = state.byField.get(field);
333
+ if (previous) {
334
+ state.fields.delete(previous.key);
335
+ field.removeEventListener("turbo:morph-element", previous.restore);
336
+ }
337
+ const nonce = Array.from(
338
+ crypto.getRandomValues(new Uint8Array(16)),
339
+ (value) => value.toString(16).padStart(2, "0")
340
+ ).join("");
341
+ const key = `${PREFIX}${nonce}:${JSON.stringify(name)}`;
342
+ const projection = {
343
+ field,
344
+ key,
345
+ name,
346
+ project,
347
+ document: field.ownerDocument,
348
+ state,
349
+ restore: () => {
350
+ if (field.name === name) field.name = key;
351
+ }
352
+ };
353
+ state.fields.set(key, projection);
354
+ state.byField.set(field, projection);
355
+ this.#held = projection;
356
+ field.name = key;
357
+ field.addEventListener("turbo:morph-element", projection.restore);
358
+ }
359
+ release() {
360
+ const held = this.#held;
361
+ this.#held = null;
362
+ if (held === null) return;
363
+ held.field.removeEventListener("turbo:morph-element", held.restore);
364
+ const state = held.state;
365
+ if (state.byField.get(held.field) !== held) return;
366
+ state.fields.delete(held.key);
367
+ state.byField.delete(held.field);
368
+ if (held.field.name === held.key) held.field.name = held.name;
369
+ }
370
+ };
371
+
102
372
  var FULL_WIDTH_SHIFT = 65248;
103
373
  function halfWidthChar(char) {
104
374
  if (char >= "\uFF01" && char <= "\uFF5E") {
@@ -134,6 +404,9 @@ var MicrotaskCoalescer = class {
134
404
  this.#queued = false;
135
405
  this.#generation += 1;
136
406
  }
407
+ get pending() {
408
+ return this.#queued;
409
+ }
137
410
  schedule() {
138
411
  if (!this.#active || this.#queued) return;
139
412
  this.#queued = true;
@@ -164,6 +437,9 @@ var MorphRenderWatcher = class {
164
437
  schedule() {
165
438
  this.#pass.schedule();
166
439
  }
440
+ get pending() {
441
+ return this.#pass.pending;
442
+ }
167
443
  disconnect() {
168
444
  this.#listeners.dispose();
169
445
  this.#pass.cancel();
@@ -171,12 +447,53 @@ var MorphRenderWatcher = class {
171
447
  }
172
448
  };
173
449
 
450
+ var TimerRegistry = class {
451
+ ids = /* @__PURE__ */ new Set();
452
+ clear(id) {
453
+ if (this.ids.delete(id)) {
454
+ this.cancel(id);
455
+ }
456
+ }
457
+ clearAll() {
458
+ for (const id of this.ids) {
459
+ this.cancel(id);
460
+ }
461
+ this.ids.clear();
462
+ }
463
+ get size() {
464
+ return this.ids.size;
465
+ }
466
+ };
467
+ var SafeTimeout = class extends TimerRegistry {
468
+ set(callback, delay) {
469
+ const id = this.schedule(() => {
470
+ this.ids.delete(id);
471
+ callback();
472
+ }, delay);
473
+ this.ids.add(id);
474
+ return id;
475
+ }
476
+ schedule(callback, delay) {
477
+ return window.setTimeout(callback, delay);
478
+ }
479
+ cancel(id) {
480
+ window.clearTimeout(id);
481
+ }
482
+ };
483
+
484
+ function prepareInputMaskForm(form) {
485
+ prepareFormDataProjection(form);
486
+ }
174
487
  var DEFAULT_TOKENS = {
175
488
  "9": "\\d",
176
489
  a: "[A-Za-z]",
177
490
  "*": "[A-Za-z0-9]"
178
491
  };
179
492
  var UNMASK_ATTR = "unmask";
493
+ var rawWriters = sharedRegistry(
494
+ "stimeo-ui.input-mask-raw-writer.registry.v1",
495
+ () => /* @__PURE__ */ new WeakMap()
496
+ );
180
497
  function acceptedForm(regex, char) {
181
498
  if (regex.test(char)) return char;
182
499
  const half = halfWidthChar(char);
@@ -265,8 +582,14 @@ var InputMaskController = class extends Controller {
265
582
  static events = ["change", "reconcile"];
266
583
  #lastValue = null;
267
584
  #started = false;
585
+ #rawSink = null;
586
+ #rawValue = "";
587
+ #rawSourceForm = null;
588
+ #submission = new FormDataProjection();
268
589
  #tokens = compileTokens("");
269
590
  #textBeforeComposition = "";
591
+ #formatted = null;
592
+ #shown = { result: null, empty: true };
270
593
  #composition = new CompositionTracker({
271
594
  onStart: () => {
272
595
  this.#textBeforeComposition = this.element.value;
@@ -274,6 +597,9 @@ var InputMaskController = class extends Controller {
274
597
  onEnd: () => {
275
598
  const committedNothing = this.element.value === this.#textBeforeComposition;
276
599
  this.#reformat(committedNothing ? "reconcile" : "edit");
600
+ },
601
+ onAbandon: () => {
602
+ if (this.#formatted !== this.#declared) this.#reformat("reconcile");
277
603
  }
278
604
  });
279
605
  tokensValueChanged() {
@@ -285,34 +611,53 @@ var InputMaskController = class extends Controller {
285
611
  }
286
612
  unmaskToHiddenValueChanged() {
287
613
  if (!this.#started) return;
288
- if (!this.unmaskToHiddenValue) {
289
- const sink = this.#resolveSink();
290
- if (sink) sink.value = "";
291
- }
614
+ if (!this.unmaskToHiddenValue) this.#withdraw();
292
615
  this.#reformat("reconcile");
293
616
  }
617
+ #withdraw() {
618
+ if (this.#retractRaw() && this.#composition.isComposing()) this.#formatted = null;
619
+ }
294
620
  #morph = new MorphRenderWatcher(() => this.#reformat("reconcile"));
621
+ #gate = new DetachGate();
622
+ #adoption = new SafeTimeout();
295
623
  connect() {
624
+ this.#gate.cancel();
296
625
  this.#morph.observe(this.element);
297
626
  this.#started = true;
298
627
  this.#composition.observe(this.element);
628
+ if (!this.unmaskToHiddenValue) this.#withdraw();
629
+ if (this.#composition.isComposing()) {
630
+ this.#reformat("reconcile");
631
+ return;
632
+ }
299
633
  this.#lastValue = this.element.value;
300
634
  this.#reformat("reconcile");
635
+ if (this.unmaskToHiddenValue && this.#rawSink === null) {
636
+ this.#adoption.set(() => this.#adoptSink(), 0);
637
+ }
301
638
  }
302
639
  disconnect() {
303
640
  this.#morph.disconnect();
304
641
  this.#started = false;
305
642
  this.#composition.disconnect();
643
+ this.#adoption.clearAll();
644
+ this.#gate.disconnected(this, () => this.#retractRaw());
306
645
  }
307
646
  format(event) {
308
647
  if (this.#composition.isComposing(event)) return;
309
648
  this.#reformat("edit", deletionOf(event));
310
649
  }
311
650
  #reformat(cause, deletion = null) {
312
- if (this.#composition.isComposing()) return;
651
+ if (this.#composition.isComposing()) {
652
+ this.#showAgain();
653
+ return;
654
+ }
655
+ this.#formatted = this.#declared;
313
656
  const input = this.element;
314
657
  const raw = input.value;
315
658
  if (this.patternValue === "") {
659
+ this.#retractRaw();
660
+ this.#shown = { result: null, empty: raw.length === 0 };
316
661
  this.#flag("data-mask-complete", false);
317
662
  this.#flag("data-mask-empty", raw.length === 0);
318
663
  this.#lastValue = raw;
@@ -349,14 +694,56 @@ var InputMaskController = class extends Controller {
349
694
  if (cause === "edit") this.dispatch("change", { detail });
350
695
  else this.dispatch("reconcile", { detail });
351
696
  }
697
+ get #declared() {
698
+ return JSON.stringify([this.patternValue, this.tokensValue, this.unmaskToHiddenValue]);
699
+ }
352
700
  #publish(result, shown) {
701
+ this.#shown = { result, empty: shown.length === 0 };
353
702
  if (this.unmaskToHiddenValue) {
354
703
  const sink = this.#resolveSink();
355
- if (sink) sink.value = result.unmasked;
704
+ if (sink !== this.#rawSink) this.#retractRaw();
705
+ if (sink) {
706
+ sink.value = result.unmasked;
707
+ rawWriters.set(sink, this);
708
+ this.#rawSink = sink;
709
+ this.#rawValue = result.unmasked;
710
+ this.#rawSourceForm = this.element.form;
711
+ this.#submission.hold(sink, (value) => this.#submittedValue(sink, value));
712
+ }
356
713
  }
357
714
  this.#flag("data-mask-complete", result.complete);
358
715
  this.#flag("data-mask-empty", shown.length === 0);
359
716
  }
717
+ #showAgain() {
718
+ const shown = this.#shown;
719
+ const sink = this.#rawSink;
720
+ if (shown.result !== null && this.unmaskToHiddenValue && sink !== null && rawWriters.get(sink) === this && this.#resolveSink() === sink) {
721
+ sink.value = shown.result.unmasked;
722
+ }
723
+ this.#flag("data-mask-complete", shown.result?.complete ?? false);
724
+ this.#flag("data-mask-empty", shown.empty);
725
+ }
726
+ #retractRaw() {
727
+ const sink = this.#rawSink;
728
+ this.#rawSink = null;
729
+ this.#submission.release();
730
+ if (sink === null || rawWriters.get(sink) !== this) return false;
731
+ rawWriters.delete(sink);
732
+ if (sink.value === this.#rawValue) sink.value = "";
733
+ return true;
734
+ }
735
+ #submittedValue(sink, value) {
736
+ if (rawWriters.get(sink) !== this || sink.value !== this.#rawValue || value !== this.#rawValue)
737
+ return value;
738
+ const source = this.element;
739
+ const listed = (source.getAttribute("data-controller") ?? "").split(/\s+/).includes(this.identifier);
740
+ const associated = source.form === null ? this.#rawSourceForm === null : source.form === sink.form;
741
+ const eligible = source.isConnected && this.application.element.contains(source) && listed && this.unmaskToHiddenValue && associated;
742
+ return eligible ? value : "";
743
+ }
744
+ #adoptSink() {
745
+ if (this.#resolveSink() !== null) this.#reformat("reconcile");
746
+ }
360
747
  #significantBefore(prefix) {
361
748
  return applyMask(prefix, this.patternValue, this.#tokens).unmasked.length;
362
749
  }
@@ -413,5 +800,5 @@ var InputMaskController = class extends Controller {
413
800
  }
414
801
  };
415
802
 
416
- export { InputMaskController, applyMask };
803
+ export { InputMaskController, applyMask, prepareInputMaskForm };
417
804
  //# sourceMappingURL=input_mask_controller.js.map