stimeo-ui 0.17.0 → 0.18.1

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 (299) hide show
  1. package/CHANGELOG.md +136 -2
  2. package/README.md +19 -10
  3. package/dist/cable/index.d.ts +11 -9
  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 +290 -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 +66 -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 +200 -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.d.ts +2 -1
  97. package/dist/controllers/form_field_controller.js +52 -43
  98. package/dist/controllers/form_field_controller.js.map +1 -1
  99. package/dist/controllers/form_validation_controller.d.ts +3 -3
  100. package/dist/controllers/form_validation_controller.js +18 -11
  101. package/dist/controllers/form_validation_controller.js.map +1 -1
  102. package/dist/controllers/frame_loading_controller.d.ts +13 -12
  103. package/dist/controllers/frame_loading_controller.js +55 -48
  104. package/dist/controllers/frame_loading_controller.js.map +1 -1
  105. package/dist/controllers/highlight_controller.d.ts +5 -4
  106. package/dist/controllers/highlight_controller.js.map +1 -1
  107. package/dist/controllers/hover_card_controller.d.ts +4 -1
  108. package/dist/controllers/hover_card_controller.js +67 -61
  109. package/dist/controllers/hover_card_controller.js.map +1 -1
  110. package/dist/controllers/idle_controller.d.ts +6 -5
  111. package/dist/controllers/idle_controller.js +10 -6
  112. package/dist/controllers/idle_controller.js.map +1 -1
  113. package/dist/controllers/input_mask_controller.d.ts +31 -13
  114. package/dist/controllers/input_mask_controller.js +434 -24
  115. package/dist/controllers/input_mask_controller.js.map +1 -1
  116. package/dist/controllers/intersection_controller.js +3 -0
  117. package/dist/controllers/intersection_controller.js.map +1 -1
  118. package/dist/controllers/lazy_frame_controller.d.ts +3 -2
  119. package/dist/controllers/lazy_frame_controller.js +15 -3
  120. package/dist/controllers/lazy_frame_controller.js.map +1 -1
  121. package/dist/controllers/listbox_controller.d.ts +10 -7
  122. package/dist/controllers/listbox_controller.js +260 -79
  123. package/dist/controllers/listbox_controller.js.map +1 -1
  124. package/dist/controllers/local_time_controller.d.ts +8 -6
  125. package/dist/controllers/local_time_controller.js +48 -13
  126. package/dist/controllers/local_time_controller.js.map +1 -1
  127. package/dist/controllers/masonry_controller.js +11 -4
  128. package/dist/controllers/masonry_controller.js.map +1 -1
  129. package/dist/controllers/menu_controller.d.ts +24 -5
  130. package/dist/controllers/menu_controller.js +138 -82
  131. package/dist/controllers/menu_controller.js.map +1 -1
  132. package/dist/controllers/menubar_controller.d.ts +49 -7
  133. package/dist/controllers/menubar_controller.js +65 -19
  134. package/dist/controllers/menubar_controller.js.map +1 -1
  135. package/dist/controllers/meter_controller.d.ts +13 -20
  136. package/dist/controllers/meter_controller.js +270 -24
  137. package/dist/controllers/meter_controller.js.map +1 -1
  138. package/dist/controllers/multi_select_controller.d.ts +19 -16
  139. package/dist/controllers/multi_select_controller.js +272 -95
  140. package/dist/controllers/multi_select_controller.js.map +1 -1
  141. package/dist/controllers/navigation_menu_controller.d.ts +19 -5
  142. package/dist/controllers/navigation_menu_controller.js +67 -19
  143. package/dist/controllers/navigation_menu_controller.js.map +1 -1
  144. package/dist/controllers/nested_form_controller.js +98 -64
  145. package/dist/controllers/nested_form_controller.js.map +1 -1
  146. package/dist/controllers/network_status_controller.js +70 -52
  147. package/dist/controllers/network_status_controller.js.map +1 -1
  148. package/dist/controllers/number_input_controller.d.ts +24 -6
  149. package/dist/controllers/number_input_controller.js +344 -94
  150. package/dist/controllers/number_input_controller.js.map +1 -1
  151. package/dist/controllers/optimistic_controller.d.ts +8 -5
  152. package/dist/controllers/optimistic_controller.js +29 -11
  153. package/dist/controllers/optimistic_controller.js.map +1 -1
  154. package/dist/controllers/otp_controller.d.ts +35 -4
  155. package/dist/controllers/otp_controller.js +502 -104
  156. package/dist/controllers/otp_controller.js.map +1 -1
  157. package/dist/controllers/overflow_indicator_controller.js +6 -0
  158. package/dist/controllers/overflow_indicator_controller.js.map +1 -1
  159. package/dist/controllers/overflow_menu_controller.d.ts +10 -9
  160. package/dist/controllers/overflow_menu_controller.js +136 -21
  161. package/dist/controllers/overflow_menu_controller.js.map +1 -1
  162. package/dist/controllers/pagination_controller.d.ts +3 -2
  163. package/dist/controllers/pagination_controller.js +47 -14
  164. package/dist/controllers/pagination_controller.js.map +1 -1
  165. package/dist/controllers/password_reveal_controller.d.ts +5 -4
  166. package/dist/controllers/password_reveal_controller.js +52 -49
  167. package/dist/controllers/password_reveal_controller.js.map +1 -1
  168. package/dist/controllers/password_strength_controller.d.ts +1 -1
  169. package/dist/controllers/password_strength_controller.js +13 -6
  170. package/dist/controllers/password_strength_controller.js.map +1 -1
  171. package/dist/controllers/persist_controller.js +48 -128
  172. package/dist/controllers/persist_controller.js.map +1 -1
  173. package/dist/controllers/pointer_drag_controller.d.ts +20 -8
  174. package/dist/controllers/pointer_drag_controller.js +255 -24
  175. package/dist/controllers/pointer_drag_controller.js.map +1 -1
  176. package/dist/controllers/popover_controller.d.ts +9 -5
  177. package/dist/controllers/popover_controller.js +91 -65
  178. package/dist/controllers/popover_controller.js.map +1 -1
  179. package/dist/controllers/portal_controller.js +6 -0
  180. package/dist/controllers/portal_controller.js.map +1 -1
  181. package/dist/controllers/preview_guard_controller.js +14 -3
  182. package/dist/controllers/preview_guard_controller.js.map +1 -1
  183. package/dist/controllers/progress_controller.d.ts +9 -19
  184. package/dist/controllers/progress_controller.js +271 -27
  185. package/dist/controllers/progress_controller.js.map +1 -1
  186. package/dist/controllers/radio_group_controller.d.ts +11 -8
  187. package/dist/controllers/radio_group_controller.js +167 -80
  188. package/dist/controllers/radio_group_controller.js.map +1 -1
  189. package/dist/controllers/range_slider_controller.d.ts +4 -3
  190. package/dist/controllers/range_slider_controller.js +27 -7
  191. package/dist/controllers/range_slider_controller.js.map +1 -1
  192. package/dist/controllers/rating_controller.js +93 -57
  193. package/dist/controllers/rating_controller.js.map +1 -1
  194. package/dist/controllers/read_more_controller.js +10 -6
  195. package/dist/controllers/read_more_controller.js.map +1 -1
  196. package/dist/controllers/reading_progress_controller.js +22 -5
  197. package/dist/controllers/reading_progress_controller.js.map +1 -1
  198. package/dist/controllers/relative_time_controller.d.ts +4 -4
  199. package/dist/controllers/relative_time_controller.js +75 -11
  200. package/dist/controllers/relative_time_controller.js.map +1 -1
  201. package/dist/controllers/reset_on_restore_controller.d.ts +3 -3
  202. package/dist/controllers/reset_on_restore_controller.js +6 -0
  203. package/dist/controllers/reset_on_restore_controller.js.map +1 -1
  204. package/dist/controllers/resizable_controller.d.ts +3 -0
  205. package/dist/controllers/resizable_controller.js +55 -22
  206. package/dist/controllers/resizable_controller.js.map +1 -1
  207. package/dist/controllers/roving_controller.d.ts +3 -3
  208. package/dist/controllers/roving_controller.js +10 -4
  209. package/dist/controllers/roving_controller.js.map +1 -1
  210. package/dist/controllers/scroll_area_controller.js +129 -88
  211. package/dist/controllers/scroll_area_controller.js.map +1 -1
  212. package/dist/controllers/scroll_restore_controller.d.ts +3 -3
  213. package/dist/controllers/scroll_restore_controller.js +14 -2
  214. package/dist/controllers/scroll_restore_controller.js.map +1 -1
  215. package/dist/controllers/scroll_visibility_controller.js +93 -60
  216. package/dist/controllers/scroll_visibility_controller.js.map +1 -1
  217. package/dist/controllers/scrollspy_controller.js +11 -5
  218. package/dist/controllers/scrollspy_controller.js.map +1 -1
  219. package/dist/controllers/separator_controller.d.ts +1 -1
  220. package/dist/controllers/separator_controller.js +59 -43
  221. package/dist/controllers/separator_controller.js.map +1 -1
  222. package/dist/controllers/sidebar_controller.d.ts +1 -1
  223. package/dist/controllers/sidebar_controller.js +150 -122
  224. package/dist/controllers/sidebar_controller.js.map +1 -1
  225. package/dist/controllers/skeleton_controller.js +55 -48
  226. package/dist/controllers/skeleton_controller.js.map +1 -1
  227. package/dist/controllers/slider_controller.d.ts +2 -1
  228. package/dist/controllers/slider_controller.js +27 -6
  229. package/dist/controllers/slider_controller.js.map +1 -1
  230. package/dist/controllers/smart_sticky_header_controller.d.ts +1 -1
  231. package/dist/controllers/smart_sticky_header_controller.js +13 -5
  232. package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
  233. package/dist/controllers/sortable_controller.d.ts +4 -4
  234. package/dist/controllers/sortable_controller.js +27 -14
  235. package/dist/controllers/sortable_controller.js.map +1 -1
  236. package/dist/controllers/spinner_controller.js +55 -48
  237. package/dist/controllers/spinner_controller.js.map +1 -1
  238. package/dist/controllers/step_indicator_controller.d.ts +4 -4
  239. package/dist/controllers/step_indicator_controller.js +6 -0
  240. package/dist/controllers/step_indicator_controller.js.map +1 -1
  241. package/dist/controllers/stepper_controller.d.ts +2 -3
  242. package/dist/controllers/stepper_controller.js +6 -0
  243. package/dist/controllers/stepper_controller.js.map +1 -1
  244. package/dist/controllers/stick_to_bottom_controller.d.ts +3 -1
  245. package/dist/controllers/stick_to_bottom_controller.js +19 -8
  246. package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
  247. package/dist/controllers/sticky_observer_controller.js +49 -43
  248. package/dist/controllers/sticky_observer_controller.js.map +1 -1
  249. package/dist/controllers/submit_once_controller.d.ts +2 -1
  250. package/dist/controllers/submit_once_controller.js +145 -85
  251. package/dist/controllers/submit_once_controller.js.map +1 -1
  252. package/dist/controllers/switch_controller.d.ts +7 -4
  253. package/dist/controllers/switch_controller.js +172 -28
  254. package/dist/controllers/switch_controller.js.map +1 -1
  255. package/dist/controllers/tabs_controller.d.ts +7 -4
  256. package/dist/controllers/tabs_controller.js +6 -1
  257. package/dist/controllers/tabs_controller.js.map +1 -1
  258. package/dist/controllers/tags_input_controller.d.ts +4 -3
  259. package/dist/controllers/tags_input_controller.js +157 -28
  260. package/dist/controllers/tags_input_controller.js.map +1 -1
  261. package/dist/controllers/textarea_autosize_controller.d.ts +1 -1
  262. package/dist/controllers/textarea_autosize_controller.js +40 -19
  263. package/dist/controllers/textarea_autosize_controller.js.map +1 -1
  264. package/dist/controllers/theme_controller.d.ts +3 -2
  265. package/dist/controllers/theme_controller.js +10 -4
  266. package/dist/controllers/theme_controller.js.map +1 -1
  267. package/dist/controllers/time_picker_controller.d.ts +38 -5
  268. package/dist/controllers/time_picker_controller.js +192 -54
  269. package/dist/controllers/time_picker_controller.js.map +1 -1
  270. package/dist/controllers/toast_controller.d.ts +4 -5
  271. package/dist/controllers/toast_controller.js +58 -27
  272. package/dist/controllers/toast_controller.js.map +1 -1
  273. package/dist/controllers/toggle_group_controller.d.ts +2 -3
  274. package/dist/controllers/toggle_group_controller.js +158 -56
  275. package/dist/controllers/toggle_group_controller.js.map +1 -1
  276. package/dist/controllers/toolbar_controller.d.ts +8 -6
  277. package/dist/controllers/toolbar_controller.js +150 -21
  278. package/dist/controllers/toolbar_controller.js.map +1 -1
  279. package/dist/controllers/tooltip_controller.d.ts +4 -1
  280. package/dist/controllers/tooltip_controller.js.map +1 -1
  281. package/dist/controllers/transition_controller.js.map +1 -1
  282. package/dist/controllers/tree_view_controller.d.ts +1 -1
  283. package/dist/controllers/tree_view_controller.js +134 -25
  284. package/dist/controllers/tree_view_controller.js.map +1 -1
  285. package/dist/index.d.ts +4 -1
  286. package/dist/index.js +2515 -1315
  287. package/dist/index.js.map +1 -1
  288. package/dist/inspector/cli.d.ts +25 -12
  289. package/dist/inspector/cli.js +21 -3
  290. package/dist/inspector/cli.js.map +1 -1
  291. package/dist/inspector/cli_bin.d.ts +1 -1
  292. package/dist/inspector/cli_bin.js +62 -8
  293. package/dist/inspector/cli_bin.js.map +1 -1
  294. package/dist/inspector/examples.json +13 -13
  295. package/dist/inspector/manifest.json +19 -5
  296. package/dist/positioning/index.d.ts +9 -8
  297. package/dist/positioning/index.js +6 -0
  298. package/dist/positioning/index.js.map +1 -1
  299. package/package.json +11 -10
@@ -10,16 +10,27 @@ function announce(message, options = {}) {
10
10
  );
11
11
  }
12
12
 
13
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
14
+ if (element.getAttribute(name) === value) return false;
15
+ if (value === null) element.removeAttribute(name);
16
+ else element.setAttribute(name, value);
17
+ return true;
18
+ }
19
+
13
20
  function sharedRegistry(key, create) {
14
21
  const symbol = Symbol.for(key);
15
22
  const scope = globalThis;
16
23
  const existing = scope[symbol];
17
24
  if (existing !== void 0) return existing;
18
- const registry = create();
19
- Object.defineProperty(globalThis, symbol, { value: registry });
20
- return registry;
25
+ const registry2 = create();
26
+ Object.defineProperty(globalThis, symbol, { value: registry2 });
27
+ return registry2;
21
28
  }
22
29
 
30
+ var registry = sharedRegistry(
31
+ "stimeo-ui.attribute-lease.registry.v1",
32
+ () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
33
+ );
23
34
  function isAttributeValue(value) {
24
35
  return value === null || typeof value === "string";
25
36
  }
@@ -36,24 +47,46 @@ function readLeaseRecord(element, record) {
36
47
  return void 0;
37
48
  }
38
49
  }
39
- var AttributeLease = class _AttributeLease {
40
- static #registry = sharedRegistry(
41
- "stimeo-ui.attribute-lease.registry.v1",
42
- () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
43
- );
50
+ function attributeStack(element, attribute) {
51
+ const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
52
+ registry.stacks.set(element, byAttribute);
53
+ const known = byAttribute.get(attribute);
54
+ if (known) return known;
55
+ const found = [];
56
+ for (const record of registry.names.get(attribute) ?? []) {
57
+ const read = readLeaseRecord(element, record);
58
+ if (read) found.push({ ...read, record });
59
+ }
60
+ const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
61
+ const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
62
+ lease: null,
63
+ record,
64
+ written,
65
+ original,
66
+ linked: linked && index > 0
67
+ }));
68
+ byAttribute.set(attribute, stack);
69
+ return stack;
70
+ }
71
+ function findHold(stack, lease, record) {
72
+ return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
73
+ }
74
+ var AttributeLease = class {
44
75
  #attribute;
45
76
  #record;
46
77
  #base;
78
+ #preserveAuthor;
47
79
  #held = /* @__PURE__ */ new Set();
48
80
  constructor(attribute, owner, options = {}) {
49
81
  this.#attribute = attribute;
50
82
  this.#record = `data-${owner}-${attribute}-lease`;
51
83
  this.#base = options.base === true;
52
- const names = _AttributeLease.#registry.names;
84
+ this.#preserveAuthor = options.preserveAuthor === true;
85
+ const names = registry.names;
53
86
  names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
54
87
  }
55
88
  write(element, value) {
56
- const stack = this.#stack(element);
89
+ const stack = attributeStack(element, this.#attribute);
57
90
  const hold = this.#take(stack) ?? this.#acquire(element, stack);
58
91
  this.#held.add(element);
59
92
  const shows = !this.#covered(element, stack, hold);
@@ -63,8 +96,8 @@ var AttributeLease = class _AttributeLease {
63
96
  }
64
97
  return(element) {
65
98
  const held = this.#held.delete(element);
66
- const known = _AttributeLease.#registry.stacks.get(element)?.has(this.#attribute);
67
- const stack = held || known || element.hasAttribute(this.#record) ? this.#stack(element) : [];
99
+ const known = registry.stacks.get(element)?.has(this.#attribute);
100
+ const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
68
101
  const hold = this.#take(stack);
69
102
  if (!hold) return false;
70
103
  const carries = element.getAttribute(this.#attribute) === hold.written;
@@ -82,31 +115,8 @@ var AttributeLease = class _AttributeLease {
82
115
  returnAll() {
83
116
  for (const element of Array.from(this.#held)) this.return(element);
84
117
  }
85
- #stack(element) {
86
- const stacks = _AttributeLease.#registry.stacks;
87
- const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
88
- stacks.set(element, byAttribute);
89
- const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
90
- byAttribute.set(this.#attribute, stack);
91
- return stack;
92
- }
93
- #seed(element) {
94
- const found = [];
95
- for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
96
- const read = readLeaseRecord(element, record);
97
- if (read) found.push({ ...read, record });
98
- }
99
- const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
100
- return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
101
- lease: null,
102
- record,
103
- written,
104
- original,
105
- linked: linked && index > 0
106
- }));
107
- }
108
118
  #take(stack) {
109
- const hold = stack.find((held) => held.lease === this) ?? stack.find((held) => held.lease === null && held.record === this.#record);
119
+ const hold = findHold(stack, this, this.#record);
110
120
  if (hold) hold.lease = this;
111
121
  return hold;
112
122
  }
@@ -115,7 +125,7 @@ var AttributeLease = class _AttributeLease {
115
125
  const top = stack.at(-1);
116
126
  const bottom = stack[0];
117
127
  const over = top?.written === current ? top : void 0;
118
- const from = this.#base ? bottom : over;
128
+ const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
119
129
  const hold = {
120
130
  lease: this,
121
131
  record: this.#record,
@@ -145,15 +155,11 @@ var AttributeLease = class _AttributeLease {
145
155
  );
146
156
  });
147
157
  for (const [name, recorded] of records) {
148
- if (element.getAttribute(name) === recorded) continue;
149
- if (recorded === null) element.removeAttribute(name);
150
- else element.setAttribute(name, recorded);
158
+ setAttributeIfChanged(element, name, recorded);
151
159
  }
152
160
  }
153
161
  #reflect(element, value) {
154
- if (element.getAttribute(this.#attribute) === value) return;
155
- if (value === null) element.removeAttribute(this.#attribute);
156
- else element.setAttribute(this.#attribute, value);
162
+ setAttributeIfChanged(element, this.#attribute, value);
157
163
  }
158
164
  };
159
165
 
@@ -163,63 +169,182 @@ var COMPOSITION_INPUT_TYPES = /* @__PURE__ */ new Set([
163
169
  "deleteCompositionText",
164
170
  "deleteByComposition"
165
171
  ]);
172
+ function isCompositionInputType(inputType) {
173
+ return inputType !== void 0 && COMPOSITION_INPUT_TYPES.has(inputType);
174
+ }
175
+ var BEFORE_MORPH_ATTRIBUTE = "turbo:before-morph-attribute";
176
+ var textOf = (element) => element.value;
177
+ var holdsFocus = (element) => element instanceof Node && element.getRootNode().activeElement === element;
166
178
  var CompositionTracker = class {
167
179
  #observedTargets = /* @__PURE__ */ new Set();
168
- #activeTargets = /* @__PURE__ */ new Set();
180
+ #composition = null;
169
181
  #onStart;
170
182
  #onEnd;
183
+ #onAbandon;
171
184
  #confirmedTarget = null;
185
+ #keyComposing = false;
186
+ #connected = false;
187
+ #abandoned = null;
172
188
  constructor(options = {}) {
173
189
  this.#onStart = options.onStart;
174
190
  this.#onEnd = options.onEnd;
191
+ this.#onAbandon = options.onAbandon;
175
192
  }
176
193
  observe(target) {
194
+ this.#connected = true;
177
195
  if (this.#observedTargets.has(target)) return;
178
196
  target.addEventListener("compositionstart", this.#handleStart);
179
197
  target.addEventListener("compositionend", this.#handleEnd);
180
- target.addEventListener("keydown", this.#handleKeydown);
198
+ target.addEventListener("keydown", this.#handleKeydown, true);
199
+ target.addEventListener("beforeinput", this.#handleBeforeInput, true);
200
+ target.addEventListener("input", this.#handleInput, true);
201
+ target.addEventListener("blur", this.#handleBlur, true);
202
+ target.addEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);
181
203
  this.#observedTargets.add(target);
182
204
  }
183
205
  unobserve(target) {
184
206
  if (!this.#observedTargets.delete(target)) return;
185
- target.removeEventListener("compositionstart", this.#handleStart);
186
- target.removeEventListener("compositionend", this.#handleEnd);
187
- target.removeEventListener("keydown", this.#handleKeydown);
188
- this.#activeTargets.delete(target);
207
+ this.#release(target);
208
+ if (this.#composition?.target === target) this.#letGo();
189
209
  if (this.#confirmedTarget === target) this.#confirmedTarget = null;
190
210
  }
191
211
  disconnect() {
192
- for (const target of this.#observedTargets) {
193
- target.removeEventListener("compositionstart", this.#handleStart);
194
- target.removeEventListener("compositionend", this.#handleEnd);
195
- target.removeEventListener("keydown", this.#handleKeydown);
196
- }
212
+ this.#connected = false;
213
+ for (const target of this.#observedTargets) this.#release(target);
197
214
  this.#observedTargets.clear();
198
- this.#activeTargets.clear();
215
+ this.#letGo();
199
216
  this.#confirmedTarget = null;
217
+ this.#keyComposing = false;
218
+ this.#abandoned = null;
200
219
  }
201
220
  isComposing(event) {
202
- return this.#activeTargets.size > 0 || event?.isComposing === true;
221
+ this.#settle();
222
+ return event?.isComposing === true || this.#composition !== null;
223
+ }
224
+ composingElement() {
225
+ this.#settle();
226
+ return this.#composition?.element ?? null;
227
+ }
228
+ owns(event) {
229
+ const element = this.composingElement();
230
+ return event.isComposing === true || element !== null && element === event.target;
203
231
  }
204
232
  consumesConfirmedInput(event) {
205
233
  const confirmed = this.#confirmedTarget;
206
234
  this.#confirmedTarget = null;
207
235
  if (confirmed === null || confirmed !== event.target) return false;
208
236
  const inputType = event.inputType;
209
- return !inputType || COMPOSITION_INPUT_TYPES.has(inputType);
237
+ return !inputType || isCompositionInputType(inputType);
238
+ }
239
+ #release(target) {
240
+ target.removeEventListener("compositionstart", this.#handleStart);
241
+ target.removeEventListener("compositionend", this.#handleEnd);
242
+ target.removeEventListener("keydown", this.#handleKeydown, true);
243
+ target.removeEventListener("beforeinput", this.#handleBeforeInput, true);
244
+ target.removeEventListener("input", this.#handleInput, true);
245
+ target.removeEventListener("blur", this.#handleBlur, true);
246
+ target.removeEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);
247
+ }
248
+ #letGo() {
249
+ const composition = this.#composition;
250
+ if (composition === null) return;
251
+ if (!holdsFocus(composition.element)) {
252
+ this.#composition = null;
253
+ return;
254
+ }
255
+ queueMicrotask(() => {
256
+ if (this.#composition !== composition || this.#observedTargets.has(composition.target)) {
257
+ return;
258
+ }
259
+ this.#composition = null;
260
+ if (!this.#connected) return;
261
+ this.#abandoned = { element: composition.element, inPlace: true };
262
+ this.#runAbandon();
263
+ });
264
+ }
265
+ #settle() {
266
+ const composition = this.#composition;
267
+ if (composition === null) return;
268
+ const { target, element, text } = composition;
269
+ if (target instanceof Node && element instanceof Node && !target.contains(element)) {
270
+ this.#composition = null;
271
+ } else if (textOf(element) !== text) {
272
+ this.#abandon(false);
273
+ }
274
+ }
275
+ #abandon(inPlace) {
276
+ this.#owe(inPlace);
277
+ this.#composition = null;
278
+ queueMicrotask(this.#runAbandon);
210
279
  }
280
+ #owe(inPlace) {
281
+ const composition = this.#composition;
282
+ if (composition !== null) this.#abandoned = { element: composition.element, inPlace };
283
+ }
284
+ #runAbandon = () => {
285
+ const abandoned = this.#abandoned;
286
+ if (abandoned === null) return;
287
+ this.#abandoned = null;
288
+ this.#onAbandon?.(abandoned.element, abandoned.inPlace);
289
+ };
211
290
  #handleStart = (event) => {
212
291
  this.#confirmedTarget = null;
213
- if (event.currentTarget) this.#activeTargets.add(event.currentTarget);
292
+ this.#settle();
293
+ this.#owe(true);
294
+ const target = event.currentTarget;
295
+ const element = event.target;
296
+ this.#composition = { target, element, text: textOf(element) };
297
+ this.#runAbandon();
214
298
  this.#onStart?.(event);
215
299
  };
216
300
  #handleEnd = (event) => {
217
- if (event.currentTarget) this.#activeTargets.delete(event.currentTarget);
301
+ this.#runAbandon();
302
+ if (this.#composition?.target === event.currentTarget) this.#composition = null;
218
303
  this.#confirmedTarget = event.target;
219
304
  this.#onEnd?.(event);
220
305
  };
221
- #handleKeydown = () => {
306
+ #handleKeydown = (event) => {
307
+ this.#settle();
308
+ this.#runAbandon();
222
309
  this.#confirmedTarget = null;
310
+ this.#keyComposing = event.isComposing === true;
311
+ };
312
+ #handleBeforeInput = (event) => {
313
+ const keyComposing = this.#keyComposing;
314
+ this.#keyComposing = false;
315
+ this.#settle();
316
+ const { isComposing, inputType } = event;
317
+ if (this.#composition !== null && !keyComposing && !isComposing && inputType && !isCompositionInputType(inputType)) {
318
+ this.#abandon(true);
319
+ }
320
+ this.#runAbandon();
321
+ };
322
+ #handleInput = (event) => {
323
+ const composition = this.#composition;
324
+ const { isTrusted, isComposing, inputType } = event;
325
+ if (composition !== null && event.target === composition.element && (isTrusted || isComposing || isCompositionInputType(inputType))) {
326
+ composition.text = textOf(composition.element);
327
+ } else {
328
+ this.#settle();
329
+ }
330
+ this.#runAbandon();
331
+ };
332
+ #handleBlur = (event) => {
333
+ this.#settle();
334
+ this.#runAbandon();
335
+ const composition = this.#composition;
336
+ if (composition === null || composition.target === composition.element) return;
337
+ const { element } = composition;
338
+ if (!(element instanceof Node) || event.target !== element) return;
339
+ const root = element.getRootNode();
340
+ if (root.activeElement !== element) this.#composition = null;
341
+ };
342
+ #handleBeforeMorphAttribute = (event) => {
343
+ this.#settle();
344
+ const composition = this.#composition;
345
+ if (composition?.target !== event.currentTarget || event.target !== composition.element) return;
346
+ const detail = event.detail;
347
+ if (detail?.attributeName === "value") event.preventDefault();
223
348
  };
224
349
  };
225
350