stimeo-ui 0.15.0 → 0.16.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 (267) hide show
  1. package/CHANGELOG.md +178 -0
  2. package/README.md +120 -0
  3. package/dist/cable/index.js +63 -15
  4. package/dist/cable/index.js.map +1 -1
  5. package/dist/controllers/accordion_controller.d.ts +30 -3
  6. package/dist/controllers/accordion_controller.js +98 -9
  7. package/dist/controllers/accordion_controller.js.map +1 -1
  8. package/dist/controllers/alert_dialog_controller.d.ts +8 -7
  9. package/dist/controllers/alert_dialog_controller.js.map +1 -1
  10. package/dist/controllers/announcer_controller.d.ts +3 -2
  11. package/dist/controllers/announcer_controller.js +8 -1
  12. package/dist/controllers/announcer_controller.js.map +1 -1
  13. package/dist/controllers/auto_submit_controller.js +43 -2
  14. package/dist/controllers/auto_submit_controller.js.map +1 -1
  15. package/dist/controllers/avatar_controller.js +1 -1
  16. package/dist/controllers/avatar_controller.js.map +1 -1
  17. package/dist/controllers/breadcrumb_controller.d.ts +10 -7
  18. package/dist/controllers/breadcrumb_controller.js +9 -8
  19. package/dist/controllers/breadcrumb_controller.js.map +1 -1
  20. package/dist/controllers/bulk_select_controller.d.ts +4 -4
  21. package/dist/controllers/bulk_select_controller.js +7 -6
  22. package/dist/controllers/bulk_select_controller.js.map +1 -1
  23. package/dist/controllers/calendar_controller.d.ts +85 -23
  24. package/dist/controllers/calendar_controller.js +323 -123
  25. package/dist/controllers/calendar_controller.js.map +1 -1
  26. package/dist/controllers/carousel_controller.d.ts +67 -22
  27. package/dist/controllers/carousel_controller.js +263 -38
  28. package/dist/controllers/carousel_controller.js.map +1 -1
  29. package/dist/controllers/character_counter_controller.d.ts +1 -1
  30. package/dist/controllers/character_counter_controller.js +40 -2
  31. package/dist/controllers/character_counter_controller.js.map +1 -1
  32. package/dist/controllers/checkbox_controller.js +54 -10
  33. package/dist/controllers/checkbox_controller.js.map +1 -1
  34. package/dist/controllers/clipboard_controller.d.ts +28 -2
  35. package/dist/controllers/clipboard_controller.js +63 -5
  36. package/dist/controllers/clipboard_controller.js.map +1 -1
  37. package/dist/controllers/collapsible_controller.d.ts +25 -1
  38. package/dist/controllers/collapsible_controller.js +99 -14
  39. package/dist/controllers/collapsible_controller.js.map +1 -1
  40. package/dist/controllers/color_picker_controller.d.ts +29 -8
  41. package/dist/controllers/color_picker_controller.js +80 -34
  42. package/dist/controllers/color_picker_controller.js.map +1 -1
  43. package/dist/controllers/combobox_controller.d.ts +10 -1
  44. package/dist/controllers/combobox_controller.js +106 -16
  45. package/dist/controllers/combobox_controller.js.map +1 -1
  46. package/dist/controllers/command_palette_controller.d.ts +3 -3
  47. package/dist/controllers/command_palette_controller.js +35 -3
  48. package/dist/controllers/command_palette_controller.js.map +1 -1
  49. package/dist/controllers/conditional_fields_controller.js +56 -11
  50. package/dist/controllers/conditional_fields_controller.js.map +1 -1
  51. package/dist/controllers/confirm_controller.js +3 -0
  52. package/dist/controllers/confirm_controller.js.map +1 -1
  53. package/dist/controllers/context_menu_controller.d.ts +6 -0
  54. package/dist/controllers/context_menu_controller.js +32 -12
  55. package/dist/controllers/context_menu_controller.js.map +1 -1
  56. package/dist/controllers/countdown_controller.d.ts +30 -1
  57. package/dist/controllers/countdown_controller.js +129 -26
  58. package/dist/controllers/countdown_controller.js.map +1 -1
  59. package/dist/controllers/currency_input_controller.d.ts +74 -15
  60. package/dist/controllers/currency_input_controller.js +205 -58
  61. package/dist/controllers/currency_input_controller.js.map +1 -1
  62. package/dist/controllers/data_grid_controller.d.ts +63 -18
  63. package/dist/controllers/data_grid_controller.js +195 -29
  64. package/dist/controllers/data_grid_controller.js.map +1 -1
  65. package/dist/controllers/date_range_picker_controller.d.ts +34 -6
  66. package/dist/controllers/date_range_picker_controller.js +139 -27
  67. package/dist/controllers/date_range_picker_controller.js.map +1 -1
  68. package/dist/controllers/dialog_controller.d.ts +10 -3
  69. package/dist/controllers/dialog_controller.js +35 -8
  70. package/dist/controllers/dialog_controller.js.map +1 -1
  71. package/dist/controllers/direct_upload_controller.js +22 -4
  72. package/dist/controllers/direct_upload_controller.js.map +1 -1
  73. package/dist/controllers/dirty_form_controller.d.ts +2 -2
  74. package/dist/controllers/dirty_form_controller.js +14 -1
  75. package/dist/controllers/dirty_form_controller.js.map +1 -1
  76. package/dist/controllers/dismissible_controller.js +1 -0
  77. package/dist/controllers/dismissible_controller.js.map +1 -1
  78. package/dist/controllers/drawer_controller.d.ts +18 -10
  79. package/dist/controllers/drawer_controller.js +54 -19
  80. package/dist/controllers/drawer_controller.js.map +1 -1
  81. package/dist/controllers/dropdown_controller.d.ts +9 -3
  82. package/dist/controllers/dropdown_controller.js +36 -9
  83. package/dist/controllers/dropdown_controller.js.map +1 -1
  84. package/dist/controllers/editable_controller.js +34 -0
  85. package/dist/controllers/editable_controller.js.map +1 -1
  86. package/dist/controllers/file_dropzone_controller.js +144 -51
  87. package/dist/controllers/file_dropzone_controller.js.map +1 -1
  88. package/dist/controllers/filter_controller.d.ts +10 -4
  89. package/dist/controllers/filter_controller.js +20 -6
  90. package/dist/controllers/filter_controller.js.map +1 -1
  91. package/dist/controllers/flash_controller.d.ts +26 -6
  92. package/dist/controllers/flash_controller.js +305 -46
  93. package/dist/controllers/flash_controller.js.map +1 -1
  94. package/dist/controllers/focus_controller.js +1 -0
  95. package/dist/controllers/focus_controller.js.map +1 -1
  96. package/dist/controllers/form_field_controller.js +7 -5
  97. package/dist/controllers/form_field_controller.js.map +1 -1
  98. package/dist/controllers/form_validation_controller.js +19 -13
  99. package/dist/controllers/form_validation_controller.js.map +1 -1
  100. package/dist/controllers/frame_loading_controller.js +16 -2
  101. package/dist/controllers/frame_loading_controller.js.map +1 -1
  102. package/dist/controllers/highlight_controller.js +19 -2
  103. package/dist/controllers/highlight_controller.js.map +1 -1
  104. package/dist/controllers/hover_card_controller.d.ts +10 -2
  105. package/dist/controllers/hover_card_controller.js +40 -14
  106. package/dist/controllers/hover_card_controller.js.map +1 -1
  107. package/dist/controllers/idle_controller.d.ts +16 -3
  108. package/dist/controllers/idle_controller.js +90 -5
  109. package/dist/controllers/idle_controller.js.map +1 -1
  110. package/dist/controllers/input_mask_controller.d.ts +5 -2
  111. package/dist/controllers/input_mask_controller.js +65 -9
  112. package/dist/controllers/input_mask_controller.js.map +1 -1
  113. package/dist/controllers/intersection_controller.js +3 -0
  114. package/dist/controllers/intersection_controller.js.map +1 -1
  115. package/dist/controllers/lazy_frame_controller.js +11 -2
  116. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  117. package/dist/controllers/listbox_controller.d.ts +50 -8
  118. package/dist/controllers/listbox_controller.js +203 -45
  119. package/dist/controllers/listbox_controller.js.map +1 -1
  120. package/dist/controllers/masonry_controller.js +0 -2
  121. package/dist/controllers/masonry_controller.js.map +1 -1
  122. package/dist/controllers/menu_controller.d.ts +9 -3
  123. package/dist/controllers/menu_controller.js +45 -16
  124. package/dist/controllers/menu_controller.js.map +1 -1
  125. package/dist/controllers/menubar_controller.d.ts +11 -0
  126. package/dist/controllers/menubar_controller.js +58 -24
  127. package/dist/controllers/menubar_controller.js.map +1 -1
  128. package/dist/controllers/meter_controller.js +9 -5
  129. package/dist/controllers/meter_controller.js.map +1 -1
  130. package/dist/controllers/multi_select_controller.d.ts +18 -3
  131. package/dist/controllers/multi_select_controller.js +278 -104
  132. package/dist/controllers/multi_select_controller.js.map +1 -1
  133. package/dist/controllers/navigation_menu_controller.d.ts +11 -0
  134. package/dist/controllers/navigation_menu_controller.js +48 -15
  135. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  136. package/dist/controllers/nested_form_controller.js +37 -8
  137. package/dist/controllers/nested_form_controller.js.map +1 -1
  138. package/dist/controllers/network_status_controller.js +9 -1
  139. package/dist/controllers/network_status_controller.js.map +1 -1
  140. package/dist/controllers/number_input_controller.d.ts +36 -8
  141. package/dist/controllers/number_input_controller.js +124 -21
  142. package/dist/controllers/number_input_controller.js.map +1 -1
  143. package/dist/controllers/optimistic_controller.js +14 -1
  144. package/dist/controllers/optimistic_controller.js.map +1 -1
  145. package/dist/controllers/otp_controller.d.ts +22 -7
  146. package/dist/controllers/otp_controller.js +198 -55
  147. package/dist/controllers/otp_controller.js.map +1 -1
  148. package/dist/controllers/overflow_indicator_controller.d.ts +8 -12
  149. package/dist/controllers/overflow_indicator_controller.js +84 -13
  150. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  151. package/dist/controllers/overflow_menu_controller.d.ts +26 -6
  152. package/dist/controllers/overflow_menu_controller.js +112 -41
  153. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  154. package/dist/controllers/pagination_controller.d.ts +19 -11
  155. package/dist/controllers/pagination_controller.js +74 -28
  156. package/dist/controllers/pagination_controller.js.map +1 -1
  157. package/dist/controllers/password_reveal_controller.d.ts +15 -1
  158. package/dist/controllers/password_reveal_controller.js +59 -2
  159. package/dist/controllers/password_reveal_controller.js.map +1 -1
  160. package/dist/controllers/persist_controller.js +30 -8
  161. package/dist/controllers/persist_controller.js.map +1 -1
  162. package/dist/controllers/pointer_drag_controller.js +131 -52
  163. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  164. package/dist/controllers/popover_controller.d.ts +9 -3
  165. package/dist/controllers/popover_controller.js +45 -11
  166. package/dist/controllers/popover_controller.js.map +1 -1
  167. package/dist/controllers/portal_controller.d.ts +1 -1
  168. package/dist/controllers/portal_controller.js +6 -2
  169. package/dist/controllers/portal_controller.js.map +1 -1
  170. package/dist/controllers/preview_guard_controller.js +16 -1
  171. package/dist/controllers/preview_guard_controller.js.map +1 -1
  172. package/dist/controllers/progress_controller.js +8 -4
  173. package/dist/controllers/progress_controller.js.map +1 -1
  174. package/dist/controllers/radio_group_controller.d.ts +6 -4
  175. package/dist/controllers/radio_group_controller.js +42 -17
  176. package/dist/controllers/radio_group_controller.js.map +1 -1
  177. package/dist/controllers/range_slider_controller.d.ts +49 -1
  178. package/dist/controllers/range_slider_controller.js +88 -42
  179. package/dist/controllers/range_slider_controller.js.map +1 -1
  180. package/dist/controllers/rating_controller.d.ts +14 -3
  181. package/dist/controllers/rating_controller.js +39 -15
  182. package/dist/controllers/rating_controller.js.map +1 -1
  183. package/dist/controllers/read_more_controller.d.ts +24 -2
  184. package/dist/controllers/read_more_controller.js +69 -2
  185. package/dist/controllers/read_more_controller.js.map +1 -1
  186. package/dist/controllers/resizable_controller.d.ts +16 -2
  187. package/dist/controllers/resizable_controller.js +82 -22
  188. package/dist/controllers/resizable_controller.js.map +1 -1
  189. package/dist/controllers/scroll_area_controller.js +5 -1
  190. package/dist/controllers/scroll_area_controller.js.map +1 -1
  191. package/dist/controllers/scroll_visibility_controller.js +0 -1
  192. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  193. package/dist/controllers/scrollspy_controller.d.ts +3 -2
  194. package/dist/controllers/scrollspy_controller.js +6 -0
  195. package/dist/controllers/scrollspy_controller.js.map +1 -1
  196. package/dist/controllers/separator_controller.d.ts +41 -14
  197. package/dist/controllers/separator_controller.js +66 -37
  198. package/dist/controllers/separator_controller.js.map +1 -1
  199. package/dist/controllers/sidebar_controller.d.ts +20 -3
  200. package/dist/controllers/sidebar_controller.js +77 -18
  201. package/dist/controllers/sidebar_controller.js.map +1 -1
  202. package/dist/controllers/skeleton_controller.js +6 -1
  203. package/dist/controllers/skeleton_controller.js.map +1 -1
  204. package/dist/controllers/slider_controller.d.ts +45 -7
  205. package/dist/controllers/slider_controller.js +82 -47
  206. package/dist/controllers/slider_controller.js.map +1 -1
  207. package/dist/controllers/smart_sticky_header_controller.js +11 -1
  208. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  209. package/dist/controllers/sortable_controller.js +17 -2
  210. package/dist/controllers/sortable_controller.js.map +1 -1
  211. package/dist/controllers/spinner_controller.js +10 -2
  212. package/dist/controllers/spinner_controller.js.map +1 -1
  213. package/dist/controllers/step_indicator_controller.d.ts +19 -17
  214. package/dist/controllers/step_indicator_controller.js +18 -17
  215. package/dist/controllers/step_indicator_controller.js.map +1 -1
  216. package/dist/controllers/stepper_controller.d.ts +34 -9
  217. package/dist/controllers/stepper_controller.js +101 -19
  218. package/dist/controllers/stepper_controller.js.map +1 -1
  219. package/dist/controllers/stick_to_bottom_controller.d.ts +19 -0
  220. package/dist/controllers/stick_to_bottom_controller.js +75 -5
  221. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  222. package/dist/controllers/submit_once_controller.d.ts +3 -2
  223. package/dist/controllers/submit_once_controller.js +16 -3
  224. package/dist/controllers/submit_once_controller.js.map +1 -1
  225. package/dist/controllers/switch_controller.d.ts +29 -7
  226. package/dist/controllers/switch_controller.js +101 -10
  227. package/dist/controllers/switch_controller.js.map +1 -1
  228. package/dist/controllers/tabs_controller.d.ts +12 -0
  229. package/dist/controllers/tabs_controller.js +21 -2
  230. package/dist/controllers/tabs_controller.js.map +1 -1
  231. package/dist/controllers/tags_input_controller.d.ts +15 -3
  232. package/dist/controllers/tags_input_controller.js +209 -59
  233. package/dist/controllers/tags_input_controller.js.map +1 -1
  234. package/dist/controllers/theme_controller.d.ts +20 -3
  235. package/dist/controllers/theme_controller.js +64 -14
  236. package/dist/controllers/theme_controller.js.map +1 -1
  237. package/dist/controllers/time_picker_controller.js +23 -8
  238. package/dist/controllers/time_picker_controller.js.map +1 -1
  239. package/dist/controllers/toast_controller.d.ts +52 -15
  240. package/dist/controllers/toast_controller.js +337 -54
  241. package/dist/controllers/toast_controller.js.map +1 -1
  242. package/dist/controllers/toggle_group_controller.d.ts +49 -7
  243. package/dist/controllers/toggle_group_controller.js +159 -23
  244. package/dist/controllers/toggle_group_controller.js.map +1 -1
  245. package/dist/controllers/toolbar_controller.js +32 -0
  246. package/dist/controllers/toolbar_controller.js.map +1 -1
  247. package/dist/controllers/tooltip_controller.d.ts +8 -0
  248. package/dist/controllers/tooltip_controller.js +39 -13
  249. package/dist/controllers/tooltip_controller.js.map +1 -1
  250. package/dist/controllers/transition_controller.js +4 -0
  251. package/dist/controllers/transition_controller.js.map +1 -1
  252. package/dist/controllers/tree_view_controller.d.ts +39 -8
  253. package/dist/controllers/tree_view_controller.js +169 -16
  254. package/dist/controllers/tree_view_controller.js.map +1 -1
  255. package/dist/index.d.ts +28 -1
  256. package/dist/index.js +4588 -1535
  257. package/dist/index.js.map +1 -1
  258. package/dist/inspector/cli.d.ts +72 -6
  259. package/dist/inspector/cli.js +262 -51
  260. package/dist/inspector/cli.js.map +1 -1
  261. package/dist/inspector/cli_bin.js +309 -51
  262. package/dist/inspector/cli_bin.js.map +1 -1
  263. package/dist/inspector/examples.json +40 -40
  264. package/dist/inspector/manifest.json +525 -59
  265. package/dist/positioning/index.js +2 -0
  266. package/dist/positioning/index.js.map +1 -1
  267. package/package.json +2 -2
@@ -79,11 +79,19 @@ var BeforeCacheReset = class _BeforeCacheReset {
79
79
  };
80
80
 
81
81
  // src/utils/composition_tracker.ts
82
+ var COMPOSITION_INPUT_TYPES = /* @__PURE__ */ new Set([
83
+ "insertCompositionText",
84
+ "insertFromComposition",
85
+ "deleteCompositionText",
86
+ "deleteByComposition"
87
+ ]);
82
88
  var CompositionTracker = class {
83
89
  #observedTargets = /* @__PURE__ */ new Set();
84
90
  #activeTargets = /* @__PURE__ */ new Set();
85
91
  #onStart;
86
92
  #onEnd;
93
+ /** The field whose confirming `input` is still owed, while the window is open. */
94
+ #confirmedTarget = null;
87
95
  constructor(options = {}) {
88
96
  this.#onStart = options.onStart;
89
97
  this.#onEnd = options.onEnd;
@@ -93,6 +101,7 @@ var CompositionTracker = class {
93
101
  if (this.#observedTargets.has(target)) return;
94
102
  target.addEventListener("compositionstart", this.#handleStart);
95
103
  target.addEventListener("compositionend", this.#handleEnd);
104
+ target.addEventListener("keydown", this.#handleKeydown);
96
105
  this.#observedTargets.add(target);
97
106
  }
98
107
  /** Stops tracking one target and clears any active composition it owned. */
@@ -100,31 +109,74 @@ var CompositionTracker = class {
100
109
  if (!this.#observedTargets.delete(target)) return;
101
110
  target.removeEventListener("compositionstart", this.#handleStart);
102
111
  target.removeEventListener("compositionend", this.#handleEnd);
112
+ target.removeEventListener("keydown", this.#handleKeydown);
103
113
  this.#activeTargets.delete(target);
114
+ if (this.#confirmedTarget === target) this.#confirmedTarget = null;
104
115
  }
105
116
  /** Releases every listener and clears state so reconnect starts cleanly. */
106
117
  disconnect() {
107
118
  for (const target of this.#observedTargets) {
108
119
  target.removeEventListener("compositionstart", this.#handleStart);
109
120
  target.removeEventListener("compositionend", this.#handleEnd);
121
+ target.removeEventListener("keydown", this.#handleKeydown);
110
122
  }
111
123
  this.#observedTargets.clear();
112
124
  this.#activeTargets.clear();
125
+ this.#confirmedTarget = null;
113
126
  }
114
127
  /** True when lifecycle tracking or the current event reports composition. */
115
128
  isComposing(event) {
116
129
  return this.#activeTargets.size > 0 || event?.isComposing === true;
117
130
  }
131
+ /**
132
+ * Whether `event` is the `input` echoing the composition just confirmed.
133
+ *
134
+ * Asking closes the window either way, so one confirmation is folded at most
135
+ * once and a consumer asks once per `input`.
136
+ */
137
+ consumesConfirmedInput(event) {
138
+ const confirmed = this.#confirmedTarget;
139
+ this.#confirmedTarget = null;
140
+ if (confirmed === null || confirmed !== event.target) return false;
141
+ const inputType = event.inputType;
142
+ return !inputType || COMPOSITION_INPUT_TYPES.has(inputType);
143
+ }
118
144
  #handleStart = (event) => {
145
+ this.#confirmedTarget = null;
119
146
  if (event.currentTarget) this.#activeTargets.add(event.currentTarget);
120
147
  this.#onStart?.(event);
121
148
  };
122
149
  #handleEnd = (event) => {
123
150
  if (event.currentTarget) this.#activeTargets.delete(event.currentTarget);
151
+ this.#confirmedTarget = event.target;
124
152
  this.#onEnd?.(event);
125
153
  };
154
+ /** A key on an observed field opens an edit of its own, so no echo is owed. */
155
+ #handleKeydown = () => {
156
+ this.#confirmedTarget = null;
157
+ };
126
158
  };
127
159
 
160
+ // src/utils/field_mirror.ts
161
+ function commitEdit(control) {
162
+ control.dispatchEvent(new Event("input", { bubbles: true }));
163
+ control.dispatchEvent(new Event("change", { bubbles: true }));
164
+ }
165
+
166
+ // src/utils/half_width.ts
167
+ var FULL_WIDTH_SHIFT = 65248;
168
+ function halfWidthChar(char) {
169
+ if (char >= "\uFF01" && char <= "\uFF5E") {
170
+ return String.fromCharCode(char.charCodeAt(0) - FULL_WIDTH_SHIFT);
171
+ }
172
+ return char === "\u3000" ? " " : char;
173
+ }
174
+ function toHalfWidth(text) {
175
+ let out = "";
176
+ for (const char of text) out += halfWidthChar(char);
177
+ return out;
178
+ }
179
+
128
180
  // src/utils/microtask_coalescer.ts
129
181
  var MicrotaskCoalescer = class {
130
182
  #run;
@@ -358,15 +410,34 @@ var NumberInputController = class _NumberInputController extends Controller {
358
410
  #globalGuards = null;
359
411
  /** Per-target guards allow an old button to be released without touching its replacement. */
360
412
  #buttonGuards = /* @__PURE__ */ new Map();
361
- /** Tracks IME lifecycle on the current input, including confirming keys without a signal. */
362
- #composition = new CompositionTracker();
413
+ /**
414
+ * Tracks IME lifecycle on the current input, including confirming keys without a
415
+ * signal, and runs a reconciliation the composition held back once it ends.
416
+ */
417
+ #composition = new CompositionTracker({
418
+ onEnd: () => {
419
+ if (this.#reconcileHeld) this.#repaint.schedule();
420
+ }
421
+ });
422
+ /** A reconciliation that arrived while the input was composing. */
423
+ #reconcileHeld = false;
363
424
  /** Restores authored custom-spinbutton ARIA when a target leaves or the controller stops. */
364
425
  #beforeCache = new BeforeCacheReset(() => this.#rewindForCache());
365
426
  #ariaValueNow = new AttributeLease("aria-valuenow");
366
427
  #ariaValueMin = new AttributeLease("aria-valuemin");
367
428
  #ariaValueMax = new AttributeLease("aria-valuemax");
368
- /** Last reconciled or user-committed numeric value. */
429
+ /**
430
+ * The number shown last — reconciled or committed by the user — which the next
431
+ * move is measured from; `null` while the field is blank, and before this
432
+ * instance has shown one. A disconnect keeps it for the same instance
433
+ * connecting again.
434
+ */
369
435
  #lastValue = null;
436
+ /**
437
+ * Whether `connect()` has run and `disconnect()` has not since. The pass
438
+ * `connect()` runs takes the baseline without reporting it.
439
+ */
440
+ #connected = false;
370
441
  /** Timers for the hold delay and the suppress-reset safety net. */
371
442
  #holdTimeouts = new SafeTimeout();
372
443
  /** The running auto-repeat interval (one at a time). */
@@ -394,9 +465,16 @@ var NumberInputController = class _NumberInputController extends Controller {
394
465
  window.addEventListener("pointercancel", this.#onPointerEnd, { signal });
395
466
  window.addEventListener("blur", this.#onWindowBlur, { signal });
396
467
  this.#reconcile();
468
+ this.#connected = true;
397
469
  }
398
- /** Releases listeners, derived attributes, timers, and transient value state. */
470
+ /**
471
+ * Releases listeners, derived attributes, timers, and the hold state. The number
472
+ * shown last stays: the pass the next `connect()` runs takes a new one without a
473
+ * report from an input that is present, and with none it stays the number an
474
+ * input arriving later is compared with.
475
+ */
399
476
  disconnect() {
477
+ this.#connected = false;
400
478
  this.#repaint.cancel();
401
479
  this.#composition.disconnect();
402
480
  this.#beforeCache.deactivate();
@@ -418,7 +496,6 @@ var NumberInputController = class _NumberInputController extends Controller {
418
496
  this.#ariaValueNow.returnAll();
419
497
  this.#ariaValueMin.returnAll();
420
498
  this.#ariaValueMax.returnAll();
421
- this.#lastValue = null;
422
499
  }
423
500
  /** Reconciles the value against a minimum changed by application code or a Turbo morph. */
424
501
  minValueChanged() {
@@ -437,12 +514,15 @@ var NumberInputController = class _NumberInputController extends Controller {
437
514
  this.#composition.observe(input);
438
515
  this.#repaint.schedule();
439
516
  }
440
- /** Releases ARIA and composition state owned by an input that left the controller. */
517
+ /**
518
+ * Releases ARIA and composition state owned by an input that left the controller.
519
+ * The number it showed stays the baseline, so an input swapped in holding another
520
+ * number is reported as `reconcile`.
521
+ */
441
522
  inputTargetDisconnected(input) {
442
523
  this.#composition.unobserve(input);
443
524
  this.#releaseInputAria(input);
444
525
  this.#stopHold(false);
445
- this.#lastValue = null;
446
526
  this.#repaint.schedule();
447
527
  }
448
528
  /** Wires focus preservation and hold behavior on a runtime increment target. */
@@ -520,7 +600,7 @@ var NumberInputController = class _NumberInputController extends Controller {
520
600
  return;
521
601
  }
522
602
  event.preventDefault();
523
- this.#commit(next);
603
+ this.#commit(next, true);
524
604
  }
525
605
  /**
526
606
  * Wires a step button: `pointerdown` keeps focus on the input and arms the
@@ -624,42 +704,58 @@ var NumberInputController = class _NumberInputController extends Controller {
624
704
  *
625
705
  * @returns Whether the value changed (drives the auto-repeat's bound stop).
626
706
  */
627
- #commit(raw) {
707
+ #commit(raw, report = false) {
628
708
  const value = this.#normalize(raw);
629
709
  const changed = this.#lastValue === null || value !== this.#lastValue;
710
+ const shown = this.inputTarget.value;
630
711
  this.#write(value);
631
712
  this.#lastValue = value;
713
+ if (report && shown !== this.inputTarget.value) commitEdit(this.inputTarget);
632
714
  if (changed) this.dispatch("change", { detail: { value } });
633
715
  return changed;
634
716
  }
635
717
  /** Commits an adjacent endpoint/grid value and reports whether it moved. */
636
718
  #commitStep(count) {
637
719
  if (!this.hasInputTarget) return false;
638
- return this.#commit(stepSteppedValue(this.#currentValue(), count, this.#steppedRange));
720
+ return this.#commit(stepSteppedValue(this.#currentValue(), count, this.#steppedRange), true);
639
721
  }
640
722
  /**
641
- * Reflects the current value after a range or step morph, reporting a moved
642
- * value as `reconcile`.
723
+ * Reflects the current value after a range, step or input change, reporting a
724
+ * number that moved from the one shown last as `reconcile`. While the input is
725
+ * composing, its text is the IME's: the pass waits for the composition to end
726
+ * instead of reading and rewriting it. With no input there is nothing to show,
727
+ * and the number shown last stays the baseline for the input that comes next.
643
728
  *
644
729
  * @stimeoRenderRoot
645
730
  */
646
731
  #reconcile() {
647
- if (!this.hasInputTarget) {
648
- this.#lastValue = null;
732
+ if (!this.hasInputTarget) return;
733
+ if (this.#composition.isComposing()) {
734
+ this.#reconcileHeld = true;
649
735
  return;
650
736
  }
737
+ this.#reconcileHeld = false;
738
+ const previous = this.#lastValue;
651
739
  if (this.inputTarget.value.trim() !== "") {
652
- const previous = this.#lastValue;
653
740
  const value = this.#normalize(this.#currentValue());
654
741
  this.#write(value);
655
742
  this.#lastValue = value;
656
- if (previous !== null && value !== previous) {
657
- this.dispatch("reconcile", { detail: { value } });
658
- }
659
743
  } else {
660
744
  this.#lastValue = null;
661
745
  this.#reflectEmpty();
662
746
  }
747
+ this.#reportMove(previous);
748
+ }
749
+ /**
750
+ * Reports the number shown as `reconcile` when a change the page made moved it
751
+ * from `previous`. The page moved it, so it is reported apart from `change`,
752
+ * which stays reserved for user edits. A blank field reports nothing, the way a
753
+ * user blanking it does: both events carry a number.
754
+ */
755
+ #reportMove(previous) {
756
+ const value = this.#lastValue;
757
+ if (!this.#connected || value === null || value === previous) return;
758
+ this.dispatch("reconcile", { detail: { value } });
663
759
  }
664
760
  /** Reflects `value` on the input (and ARIA for non-native hosts) and the buttons. */
665
761
  #write(value) {
@@ -719,10 +815,17 @@ var NumberInputController = class _NumberInputController extends Controller {
719
815
  button.disabled = false;
720
816
  button.removeAttribute(OWNED_DISABLED);
721
817
  }
722
- /** The current numeric value, falling back to a finite min (else 0) when blank. */
818
+ /**
819
+ * The current numeric value, falling back to a finite min (else 0) when blank.
820
+ * Every read of the field's number comes through here, and the text is read
821
+ * through the shared half-width mapping: a text-type spinbutton holds whatever an
822
+ * IME confirmed, full-width digits and signs included (`34`, `-5`), while a
823
+ * native number field's value is already half-width or empty.
824
+ */
723
825
  #currentValue() {
724
- const parsed = Number(this.inputTarget.value);
725
- if (Number.isFinite(parsed) && this.inputTarget.value.trim() !== "") return parsed;
826
+ const text = toHalfWidth(this.inputTarget.value);
827
+ const parsed = Number(text);
828
+ if (Number.isFinite(parsed) && text.trim() !== "") return parsed;
726
829
  return Number.isFinite(this.minValue) ? this.minValue : 0;
727
830
  }
728
831
  /** Clamps to `[min, max]` and snaps to the step grid anchored at a finite min (else 0). */