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
@@ -22,13 +22,18 @@ function actionSource(source) {
22
22
  };
23
23
  }
24
24
 
25
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
26
+ if (element.getAttribute(name) === value) return false;
27
+ if (value === null) element.removeAttribute(name);
28
+ else element.setAttribute(name, value);
29
+ return true;
30
+ }
31
+
25
32
  function syncActiveOption(options, active) {
26
33
  let written = 0;
27
34
  for (const option of options) {
28
35
  const next = option === active ? "true" : "false";
29
- if (option.getAttribute("aria-selected") === next) continue;
30
- option.setAttribute("aria-selected", next);
31
- written += 1;
36
+ if (setAttributeIfChanged(option, "aria-selected", next)) written += 1;
32
37
  }
33
38
  return written;
34
39
  }
@@ -37,17 +42,24 @@ function isReservedArrowChord(event, allow = []) {
37
42
  if (!event.key.startsWith("Arrow")) return false;
38
43
  return event.altKey && !allow.includes("alt") || event.ctrlKey && !allow.includes("ctrl") || event.metaKey && !allow.includes("meta") || event.shiftKey && !allow.includes("shift");
39
44
  }
45
+ function hasModifierChord(event) {
46
+ return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
47
+ }
40
48
 
41
49
  function sharedRegistry(key, create) {
42
50
  const symbol = Symbol.for(key);
43
51
  const scope = globalThis;
44
52
  const existing = scope[symbol];
45
53
  if (existing !== void 0) return existing;
46
- const registry = create();
47
- Object.defineProperty(globalThis, symbol, { value: registry });
48
- return registry;
54
+ const registry2 = create();
55
+ Object.defineProperty(globalThis, symbol, { value: registry2 });
56
+ return registry2;
49
57
  }
50
58
 
59
+ var registry = sharedRegistry(
60
+ "stimeo-ui.attribute-lease.registry.v1",
61
+ () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
62
+ );
51
63
  function isAttributeValue(value) {
52
64
  return value === null || typeof value === "string";
53
65
  }
@@ -64,24 +76,46 @@ function readLeaseRecord(element, record) {
64
76
  return void 0;
65
77
  }
66
78
  }
67
- var AttributeLease = class _AttributeLease {
68
- static #registry = sharedRegistry(
69
- "stimeo-ui.attribute-lease.registry.v1",
70
- () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
71
- );
79
+ function attributeStack(element, attribute) {
80
+ const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
81
+ registry.stacks.set(element, byAttribute);
82
+ const known = byAttribute.get(attribute);
83
+ if (known) return known;
84
+ const found = [];
85
+ for (const record of registry.names.get(attribute) ?? []) {
86
+ const read = readLeaseRecord(element, record);
87
+ if (read) found.push({ ...read, record });
88
+ }
89
+ const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
90
+ const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
91
+ lease: null,
92
+ record,
93
+ written,
94
+ original,
95
+ linked: linked && index > 0
96
+ }));
97
+ byAttribute.set(attribute, stack);
98
+ return stack;
99
+ }
100
+ function findHold(stack, lease, record) {
101
+ return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
102
+ }
103
+ var AttributeLease = class {
72
104
  #attribute;
73
105
  #record;
74
106
  #base;
107
+ #preserveAuthor;
75
108
  #held = /* @__PURE__ */ new Set();
76
109
  constructor(attribute, owner, options = {}) {
77
110
  this.#attribute = attribute;
78
111
  this.#record = `data-${owner}-${attribute}-lease`;
79
112
  this.#base = options.base === true;
80
- const names = _AttributeLease.#registry.names;
113
+ this.#preserveAuthor = options.preserveAuthor === true;
114
+ const names = registry.names;
81
115
  names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
82
116
  }
83
117
  write(element, value) {
84
- const stack = this.#stack(element);
118
+ const stack = attributeStack(element, this.#attribute);
85
119
  const hold = this.#take(stack) ?? this.#acquire(element, stack);
86
120
  this.#held.add(element);
87
121
  const shows = !this.#covered(element, stack, hold);
@@ -91,8 +125,8 @@ var AttributeLease = class _AttributeLease {
91
125
  }
92
126
  return(element) {
93
127
  const held = this.#held.delete(element);
94
- const known = _AttributeLease.#registry.stacks.get(element)?.has(this.#attribute);
95
- const stack = held || known || element.hasAttribute(this.#record) ? this.#stack(element) : [];
128
+ const known = registry.stacks.get(element)?.has(this.#attribute);
129
+ const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
96
130
  const hold = this.#take(stack);
97
131
  if (!hold) return false;
98
132
  const carries = element.getAttribute(this.#attribute) === hold.written;
@@ -110,31 +144,8 @@ var AttributeLease = class _AttributeLease {
110
144
  returnAll() {
111
145
  for (const element of Array.from(this.#held)) this.return(element);
112
146
  }
113
- #stack(element) {
114
- const stacks = _AttributeLease.#registry.stacks;
115
- const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
116
- stacks.set(element, byAttribute);
117
- const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
118
- byAttribute.set(this.#attribute, stack);
119
- return stack;
120
- }
121
- #seed(element) {
122
- const found = [];
123
- for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
124
- const read = readLeaseRecord(element, record);
125
- if (read) found.push({ ...read, record });
126
- }
127
- const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
128
- return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
129
- lease: null,
130
- record,
131
- written,
132
- original,
133
- linked: linked && index > 0
134
- }));
135
- }
136
147
  #take(stack) {
137
- const hold = stack.find((held) => held.lease === this) ?? stack.find((held) => held.lease === null && held.record === this.#record);
148
+ const hold = findHold(stack, this, this.#record);
138
149
  if (hold) hold.lease = this;
139
150
  return hold;
140
151
  }
@@ -143,7 +154,7 @@ var AttributeLease = class _AttributeLease {
143
154
  const top = stack.at(-1);
144
155
  const bottom = stack[0];
145
156
  const over = top?.written === current ? top : void 0;
146
- const from = this.#base ? bottom : over;
157
+ const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
147
158
  const hold = {
148
159
  lease: this,
149
160
  record: this.#record,
@@ -173,15 +184,11 @@ var AttributeLease = class _AttributeLease {
173
184
  );
174
185
  });
175
186
  for (const [name, recorded] of records) {
176
- if (element.getAttribute(name) === recorded) continue;
177
- if (recorded === null) element.removeAttribute(name);
178
- else element.setAttribute(name, recorded);
187
+ setAttributeIfChanged(element, name, recorded);
179
188
  }
180
189
  }
181
190
  #reflect(element, value) {
182
- if (element.getAttribute(this.#attribute) === value) return;
183
- if (value === null) element.removeAttribute(this.#attribute);
184
- else element.setAttribute(this.#attribute, value);
191
+ setAttributeIfChanged(element, this.#attribute, value);
185
192
  }
186
193
  };
187
194
 
@@ -191,63 +198,182 @@ var COMPOSITION_INPUT_TYPES = /* @__PURE__ */ new Set([
191
198
  "deleteCompositionText",
192
199
  "deleteByComposition"
193
200
  ]);
201
+ function isCompositionInputType(inputType) {
202
+ return inputType !== void 0 && COMPOSITION_INPUT_TYPES.has(inputType);
203
+ }
204
+ var BEFORE_MORPH_ATTRIBUTE = "turbo:before-morph-attribute";
205
+ var textOf = (element) => element.value;
206
+ var holdsFocus = (element) => element instanceof Node && element.getRootNode().activeElement === element;
194
207
  var CompositionTracker = class {
195
208
  #observedTargets = /* @__PURE__ */ new Set();
196
- #activeTargets = /* @__PURE__ */ new Set();
209
+ #composition = null;
197
210
  #onStart;
198
211
  #onEnd;
212
+ #onAbandon;
199
213
  #confirmedTarget = null;
214
+ #keyComposing = false;
215
+ #connected = false;
216
+ #abandoned = null;
200
217
  constructor(options = {}) {
201
218
  this.#onStart = options.onStart;
202
219
  this.#onEnd = options.onEnd;
220
+ this.#onAbandon = options.onAbandon;
203
221
  }
204
222
  observe(target) {
223
+ this.#connected = true;
205
224
  if (this.#observedTargets.has(target)) return;
206
225
  target.addEventListener("compositionstart", this.#handleStart);
207
226
  target.addEventListener("compositionend", this.#handleEnd);
208
- target.addEventListener("keydown", this.#handleKeydown);
227
+ target.addEventListener("keydown", this.#handleKeydown, true);
228
+ target.addEventListener("beforeinput", this.#handleBeforeInput, true);
229
+ target.addEventListener("input", this.#handleInput, true);
230
+ target.addEventListener("blur", this.#handleBlur, true);
231
+ target.addEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);
209
232
  this.#observedTargets.add(target);
210
233
  }
211
234
  unobserve(target) {
212
235
  if (!this.#observedTargets.delete(target)) return;
213
- target.removeEventListener("compositionstart", this.#handleStart);
214
- target.removeEventListener("compositionend", this.#handleEnd);
215
- target.removeEventListener("keydown", this.#handleKeydown);
216
- this.#activeTargets.delete(target);
236
+ this.#release(target);
237
+ if (this.#composition?.target === target) this.#letGo();
217
238
  if (this.#confirmedTarget === target) this.#confirmedTarget = null;
218
239
  }
219
240
  disconnect() {
220
- for (const target of this.#observedTargets) {
221
- target.removeEventListener("compositionstart", this.#handleStart);
222
- target.removeEventListener("compositionend", this.#handleEnd);
223
- target.removeEventListener("keydown", this.#handleKeydown);
224
- }
241
+ this.#connected = false;
242
+ for (const target of this.#observedTargets) this.#release(target);
225
243
  this.#observedTargets.clear();
226
- this.#activeTargets.clear();
244
+ this.#letGo();
227
245
  this.#confirmedTarget = null;
246
+ this.#keyComposing = false;
247
+ this.#abandoned = null;
228
248
  }
229
249
  isComposing(event) {
230
- return this.#activeTargets.size > 0 || event?.isComposing === true;
250
+ this.#settle();
251
+ return event?.isComposing === true || this.#composition !== null;
252
+ }
253
+ composingElement() {
254
+ this.#settle();
255
+ return this.#composition?.element ?? null;
256
+ }
257
+ owns(event) {
258
+ const element = this.composingElement();
259
+ return event.isComposing === true || element !== null && element === event.target;
231
260
  }
232
261
  consumesConfirmedInput(event) {
233
262
  const confirmed = this.#confirmedTarget;
234
263
  this.#confirmedTarget = null;
235
264
  if (confirmed === null || confirmed !== event.target) return false;
236
265
  const inputType = event.inputType;
237
- return !inputType || COMPOSITION_INPUT_TYPES.has(inputType);
266
+ return !inputType || isCompositionInputType(inputType);
267
+ }
268
+ #release(target) {
269
+ target.removeEventListener("compositionstart", this.#handleStart);
270
+ target.removeEventListener("compositionend", this.#handleEnd);
271
+ target.removeEventListener("keydown", this.#handleKeydown, true);
272
+ target.removeEventListener("beforeinput", this.#handleBeforeInput, true);
273
+ target.removeEventListener("input", this.#handleInput, true);
274
+ target.removeEventListener("blur", this.#handleBlur, true);
275
+ target.removeEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);
276
+ }
277
+ #letGo() {
278
+ const composition = this.#composition;
279
+ if (composition === null) return;
280
+ if (!holdsFocus(composition.element)) {
281
+ this.#composition = null;
282
+ return;
283
+ }
284
+ queueMicrotask(() => {
285
+ if (this.#composition !== composition || this.#observedTargets.has(composition.target)) {
286
+ return;
287
+ }
288
+ this.#composition = null;
289
+ if (!this.#connected) return;
290
+ this.#abandoned = { element: composition.element, inPlace: true };
291
+ this.#runAbandon();
292
+ });
238
293
  }
294
+ #settle() {
295
+ const composition = this.#composition;
296
+ if (composition === null) return;
297
+ const { target, element, text } = composition;
298
+ if (target instanceof Node && element instanceof Node && !target.contains(element)) {
299
+ this.#composition = null;
300
+ } else if (textOf(element) !== text) {
301
+ this.#abandon(false);
302
+ }
303
+ }
304
+ #abandon(inPlace) {
305
+ this.#owe(inPlace);
306
+ this.#composition = null;
307
+ queueMicrotask(this.#runAbandon);
308
+ }
309
+ #owe(inPlace) {
310
+ const composition = this.#composition;
311
+ if (composition !== null) this.#abandoned = { element: composition.element, inPlace };
312
+ }
313
+ #runAbandon = () => {
314
+ const abandoned = this.#abandoned;
315
+ if (abandoned === null) return;
316
+ this.#abandoned = null;
317
+ this.#onAbandon?.(abandoned.element, abandoned.inPlace);
318
+ };
239
319
  #handleStart = (event) => {
240
320
  this.#confirmedTarget = null;
241
- if (event.currentTarget) this.#activeTargets.add(event.currentTarget);
321
+ this.#settle();
322
+ this.#owe(true);
323
+ const target = event.currentTarget;
324
+ const element = event.target;
325
+ this.#composition = { target, element, text: textOf(element) };
326
+ this.#runAbandon();
242
327
  this.#onStart?.(event);
243
328
  };
244
329
  #handleEnd = (event) => {
245
- if (event.currentTarget) this.#activeTargets.delete(event.currentTarget);
330
+ this.#runAbandon();
331
+ if (this.#composition?.target === event.currentTarget) this.#composition = null;
246
332
  this.#confirmedTarget = event.target;
247
333
  this.#onEnd?.(event);
248
334
  };
249
- #handleKeydown = () => {
335
+ #handleKeydown = (event) => {
336
+ this.#settle();
337
+ this.#runAbandon();
250
338
  this.#confirmedTarget = null;
339
+ this.#keyComposing = event.isComposing === true;
340
+ };
341
+ #handleBeforeInput = (event) => {
342
+ const keyComposing = this.#keyComposing;
343
+ this.#keyComposing = false;
344
+ this.#settle();
345
+ const { isComposing, inputType } = event;
346
+ if (this.#composition !== null && !keyComposing && !isComposing && inputType && !isCompositionInputType(inputType)) {
347
+ this.#abandon(true);
348
+ }
349
+ this.#runAbandon();
350
+ };
351
+ #handleInput = (event) => {
352
+ const composition = this.#composition;
353
+ const { isTrusted, isComposing, inputType } = event;
354
+ if (composition !== null && event.target === composition.element && (isTrusted || isComposing || isCompositionInputType(inputType))) {
355
+ composition.text = textOf(composition.element);
356
+ } else {
357
+ this.#settle();
358
+ }
359
+ this.#runAbandon();
360
+ };
361
+ #handleBlur = (event) => {
362
+ this.#settle();
363
+ this.#runAbandon();
364
+ const composition = this.#composition;
365
+ if (composition === null || composition.target === composition.element) return;
366
+ const { element } = composition;
367
+ if (!(element instanceof Node) || event.target !== element) return;
368
+ const root = element.getRootNode();
369
+ if (root.activeElement !== element) this.#composition = null;
370
+ };
371
+ #handleBeforeMorphAttribute = (event) => {
372
+ this.#settle();
373
+ const composition = this.#composition;
374
+ if (composition?.target !== event.currentTarget || event.target !== composition.element) return;
375
+ const detail = event.detail;
376
+ if (detail?.attributeName === "value") event.preventDefault();
251
377
  };
252
378
  };
253
379
 
@@ -296,25 +422,25 @@ var EscapeLayer = class _EscapeLayer {
296
422
  #active = null;
297
423
  activate(ownerDocument = document, options) {
298
424
  this.deactivate();
299
- let registry = _EscapeLayer.#registries.get(ownerDocument);
300
- if (!registry) {
301
- registry = _EscapeLayer.#createRegistry();
302
- _EscapeLayer.#registries.set(ownerDocument, registry);
303
- ownerDocument.addEventListener("keydown", registry.onKeydown);
425
+ let registry2 = _EscapeLayer.#registries.get(ownerDocument);
426
+ if (!registry2) {
427
+ registry2 = _EscapeLayer.#createRegistry();
428
+ _EscapeLayer.#registries.set(ownerDocument, registry2);
429
+ ownerDocument.addEventListener("keydown", registry2.onKeydown);
304
430
  }
305
431
  const entry = { onDismiss: options.onDismiss, claims: options.claims ?? null };
306
- registry.stack.push(entry);
432
+ registry2.stack.push(entry);
307
433
  this.#active = { document: ownerDocument, entry };
308
434
  }
309
435
  deactivate() {
310
436
  const active = this.#active;
311
437
  if (!active) return;
312
- const registry = _EscapeLayer.#registries.get(active.document);
313
- if (registry) {
314
- const index = registry.stack.lastIndexOf(active.entry);
315
- if (index >= 0) registry.stack.splice(index, 1);
316
- if (registry.stack.length === 0) {
317
- active.document.removeEventListener("keydown", registry.onKeydown);
438
+ const registry2 = _EscapeLayer.#registries.get(active.document);
439
+ if (registry2) {
440
+ const index = registry2.stack.lastIndexOf(active.entry);
441
+ if (index >= 0) registry2.stack.splice(index, 1);
442
+ if (registry2.stack.length === 0) {
443
+ active.document.removeEventListener("keydown", registry2.onKeydown);
318
444
  _EscapeLayer.#registries.delete(active.document);
319
445
  }
320
446
  }
@@ -323,22 +449,22 @@ var EscapeLayer = class _EscapeLayer {
323
449
  get ownsEscape() {
324
450
  const active = this.#active;
325
451
  if (!active) return false;
326
- const registry = _EscapeLayer.#registries.get(active.document);
327
- if (!registry) return false;
328
- return _EscapeLayer.#resolveOwner(registry.stack) === active.entry;
452
+ const registry2 = _EscapeLayer.#registries.get(active.document);
453
+ if (!registry2) return false;
454
+ return _EscapeLayer.#resolveOwner(registry2.stack) === active.entry;
329
455
  }
330
456
  static #createRegistry() {
331
- const registry = {
457
+ const registry2 = {
332
458
  stack: [],
333
459
  onKeydown: (event) => {
334
460
  if (event.key !== "Escape" || event.defaultPrevented || event.isComposing) return;
335
- const owner = _EscapeLayer.#resolveOwner(registry.stack);
461
+ const owner = _EscapeLayer.#resolveOwner(registry2.stack);
336
462
  if (!owner) return;
337
463
  event.preventDefault();
338
464
  owner.onDismiss();
339
465
  }
340
466
  };
341
- return registry;
467
+ return registry2;
342
468
  }
343
469
  static #resolveOwner(stack) {
344
470
  for (let index = stack.length - 1; index >= 0; index--) {
@@ -571,6 +697,9 @@ var MicrotaskCoalescer = class {
571
697
  this.#queued = false;
572
698
  this.#generation += 1;
573
699
  }
700
+ get pending() {
701
+ return this.#queued;
702
+ }
574
703
  schedule() {
575
704
  if (!this.#active || this.#queued) return;
576
705
  this.#queued = true;
@@ -599,6 +728,9 @@ function queryOpenDescendants(root, selector) {
599
728
  return matches;
600
729
  }
601
730
 
731
+ function holdsFocus2(element) {
732
+ return element.matches(":focus") || deepActiveElement(element.ownerDocument) === element;
733
+ }
602
734
  var TabindexLoan = class _TabindexLoan {
603
735
  static #registry = sharedRegistry(
604
736
  "stimeo-ui.tabindex-loan.registry.v1",
@@ -606,19 +738,22 @@ var TabindexLoan = class _TabindexLoan {
606
738
  );
607
739
  #value;
608
740
  #record;
741
+ #preserveFocus;
609
742
  #lent = /* @__PURE__ */ new Set();
610
- constructor(value, owner) {
743
+ constructor(value, owner, options = {}) {
611
744
  this.#value = value;
612
745
  this.#record = `data-${owner}-tabindex-loan`;
746
+ this.#preserveFocus = options.preserveFocus === true;
613
747
  _TabindexLoan.#registry.names.add(this.#record);
614
748
  }
615
- lend(element) {
749
+ lend(element, options = {}) {
616
750
  const stack = this.#stack(element);
617
751
  const current = element.getAttribute("tabindex");
618
752
  const held = stack.find((hold) => hold.loan === this) ?? stack.find(
619
753
  (hold) => hold.loan === null && hold.record === this.#record && hold.value === this.#value
620
754
  );
621
755
  const linked = stack.at(-1)?.value === current;
756
+ if (!held && options.onlyIfUnfocusable && (current !== null || element.tabIndex >= 0)) return;
622
757
  if (!held && current !== null && !linked) return;
623
758
  this.#lent.add(element);
624
759
  if (held) held.loan = this;
@@ -628,19 +763,28 @@ var TabindexLoan = class _TabindexLoan {
628
763
  element.setAttribute("tabindex", this.#value);
629
764
  }
630
765
  }
631
- returnAll() {
632
- for (const element of this.#lent) {
633
- const stack = this.#stack(element);
634
- const hold = stack.find((held) => held.loan === this);
635
- if (hold) this.#release(element, stack, hold);
766
+ return(element) {
767
+ const stack = this.#stack(element);
768
+ const hold = stack.find((held) => held.loan === this) ?? stack.find(
769
+ (held) => held.loan === null && held.record === this.#record && held.value === this.#value
770
+ );
771
+ if (!hold) return false;
772
+ if (!this.#release(element, stack, hold, this.#preserveFocus)) {
773
+ hold.loan = this;
774
+ this.#lent.add(element);
775
+ return false;
636
776
  }
637
- this.#lent.clear();
777
+ this.#lent.delete(element);
778
+ return true;
779
+ }
780
+ returnAll() {
781
+ for (const element of Array.from(this.#lent)) this.return(element);
638
782
  }
639
783
  reclaim(element) {
640
784
  if (element.getAttribute(this.#record) !== this.#value) return;
641
785
  const stack = this.#stack(element);
642
786
  const hold = stack.find((held) => held.loan === null && held.record === this.#record);
643
- if (hold && !element.matches(":focus")) this.#release(element, stack, hold);
787
+ if (hold && !holdsFocus2(element)) this.#release(element, stack, hold);
644
788
  }
645
789
  reclaimWithin(root) {
646
790
  for (const element of queryOpenDescendants(root, `[${this.#record}]`)) {
@@ -664,26 +808,26 @@ var TabindexLoan = class _TabindexLoan {
664
808
  for (const [index, hold] of holds.entries()) hold.linked = index > 0;
665
809
  return holds;
666
810
  }
667
- #release(element, stack, hold) {
811
+ #release(element, stack, hold, preserveFocus = false) {
668
812
  const current = element.getAttribute("tabindex");
669
813
  const index = stack.indexOf(hold);
670
814
  const owns = current === hold.value && !stack.slice(index + 1).some((above2) => above2.value === current);
815
+ if (owns && preserveFocus && holdsFocus2(element)) return false;
671
816
  stack.splice(index, 1);
672
817
  const above = stack[index];
673
818
  if (above) above.linked &&= hold.linked;
674
819
  this.#mark(element, stack);
675
- if (!owns) return;
820
+ if (!owns) return true;
676
821
  const below = hold.linked ? stack[index - 1] : void 0;
677
822
  if (!below) element.removeAttribute("tabindex");
678
823
  else if (below.value !== current) element.setAttribute("tabindex", below.value);
824
+ return true;
679
825
  }
680
826
  #mark(element, stack) {
681
827
  const records = /* @__PURE__ */ new Map([[this.#record, null]]);
682
828
  for (const hold of stack) records.set(hold.record, hold.value);
683
829
  for (const [name, recorded] of records) {
684
- if (element.getAttribute(name) === recorded) continue;
685
- if (recorded === null) element.removeAttribute(name);
686
- else element.setAttribute(name, recorded);
830
+ setAttributeIfChanged(element, name, recorded);
687
831
  }
688
832
  }
689
833
  };
@@ -786,23 +930,23 @@ var FocusTrap = class _FocusTrap {
786
930
  return typeof option === "function" ? option() : option;
787
931
  }
788
932
  #joinStack() {
789
- const registry = _FocusTrap.#registry(document);
790
- if (registry.stack.length === 0) {
791
- document.addEventListener("keydown", registry.onKeydown);
792
- document.addEventListener("turbo:morph", registry.onMorph);
793
- document.addEventListener("turbo:morph-element", registry.onMorph);
933
+ const registry2 = _FocusTrap.#registry(document);
934
+ if (registry2.stack.length === 0) {
935
+ document.addEventListener("keydown", registry2.onKeydown);
936
+ document.addEventListener("turbo:morph", registry2.onMorph);
937
+ document.addEventListener("turbo:morph-element", registry2.onMorph);
794
938
  }
795
- registry.stack.push(this.#entry);
939
+ registry2.stack.push(this.#entry);
796
940
  }
797
941
  #leaveStack() {
798
- const registry = _FocusTrap.#registry(document);
799
- const index = registry.stack.indexOf(this.#entry);
800
- const above = registry.stack.slice(index + 1);
801
- registry.stack.splice(index, 1);
802
- if (registry.stack.length === 0) {
803
- document.removeEventListener("keydown", registry.onKeydown);
804
- document.removeEventListener("turbo:morph", registry.onMorph);
805
- document.removeEventListener("turbo:morph-element", registry.onMorph);
942
+ const registry2 = _FocusTrap.#registry(document);
943
+ const index = registry2.stack.indexOf(this.#entry);
944
+ const above = registry2.stack.slice(index + 1);
945
+ registry2.stack.splice(index, 1);
946
+ if (registry2.stack.length === 0) {
947
+ document.removeEventListener("keydown", registry2.onKeydown);
948
+ document.removeEventListener("turbo:morph", registry2.onMorph);
949
+ document.removeEventListener("turbo:morph-element", registry2.onMorph);
806
950
  }
807
951
  return above;
808
952
  }
@@ -877,22 +1021,22 @@ var FocusTrap = class _FocusTrap {
877
1021
  }
878
1022
  }
879
1023
  #lockScroll() {
880
- const registry = _FocusTrap.#registry(document);
1024
+ const registry2 = _FocusTrap.#registry(document);
881
1025
  const body = document.body;
882
1026
  if (!body.hasAttribute(OVERFLOW_MARK)) body.setAttribute(OVERFLOW_MARK, body.style.overflow);
883
- registry.scrollLocks.add(this.#entry);
1027
+ registry2.scrollLocks.add(this.#entry);
884
1028
  this.#entry.lockedBody = body;
885
1029
  body.style.overflow = "hidden";
886
1030
  }
887
1031
  #unlockScroll() {
888
- const registry = _FocusTrap.#registry(document);
1032
+ const registry2 = _FocusTrap.#registry(document);
889
1033
  const body = this.#entry.lockedBody;
890
1034
  this.#entry.lockedBody = null;
891
- if (!registry.scrollLocks.delete(this.#entry) || !body) return;
892
- if (!_FocusTrap.#isLocked(registry, body)) _FocusTrap.#unlock(body);
1035
+ if (!registry2.scrollLocks.delete(this.#entry) || !body) return;
1036
+ if (!_FocusTrap.#isLocked(registry2, body)) _FocusTrap.#unlock(body);
893
1037
  }
894
- static #isLocked(registry, body) {
895
- return [...registry.scrollLocks].some((trap) => trap.lockedBody === body);
1038
+ static #isLocked(registry2, body) {
1039
+ return [...registry2.scrollLocks].some((trap) => trap.lockedBody === body);
896
1040
  }
897
1041
  static #unlock(body) {
898
1042
  const saved = body.getAttribute(OVERFLOW_MARK);
@@ -901,62 +1045,62 @@ var FocusTrap = class _FocusTrap {
901
1045
  body.style.overflow = saved;
902
1046
  }
903
1047
  static #sweep() {
904
- const registry = _FocusTrap.#registry(document);
1048
+ const registry2 = _FocusTrap.#registry(document);
905
1049
  for (const element of queryOpenDescendants(document, `[${INERT_MARK}]`)) {
906
- if (registry.inerted.has(element)) continue;
1050
+ if (registry2.inerted.has(element)) continue;
907
1051
  element.removeAttribute(INERT_MARK);
908
1052
  element.inert = false;
909
1053
  }
910
- if (!_FocusTrap.#isLocked(registry, document.body)) _FocusTrap.#unlock(document.body);
1054
+ if (!_FocusTrap.#isLocked(registry2, document.body)) _FocusTrap.#unlock(document.body);
911
1055
  }
912
1056
  static #registry(ownerDocument) {
913
1057
  const existing = _FocusTrap.#registries.get(ownerDocument);
914
1058
  if (existing) return existing;
915
- const morphs = new MicrotaskCoalescer(() => _FocusTrap.#reapply(registry));
1059
+ const morphs = new MicrotaskCoalescer(() => _FocusTrap.#reapply(registry2));
916
1060
  morphs.activate();
917
- const registry = {
1061
+ const registry2 = {
918
1062
  stack: [],
919
- onKeydown: (event) => _FocusTrap.#resolveTab(registry.stack, event),
1063
+ onKeydown: (event) => _FocusTrap.#resolveTab(registry2.stack, event),
920
1064
  onMorph: () => morphs.schedule(),
921
1065
  inerted: /* @__PURE__ */ new Set(),
922
1066
  scrollLocks: /* @__PURE__ */ new Set()
923
1067
  };
924
- _FocusTrap.#registries.set(ownerDocument, registry);
925
- return registry;
1068
+ _FocusTrap.#registries.set(ownerDocument, registry2);
1069
+ return registry2;
926
1070
  }
927
- static #reapply(registry) {
1071
+ static #reapply(registry2) {
928
1072
  _FocusTrap.#reconcileBackground(document);
929
1073
  const body = document.body;
930
- if (!_FocusTrap.#isLocked(registry, body)) return;
1074
+ if (!_FocusTrap.#isLocked(registry2, body)) return;
931
1075
  if (!body.hasAttribute(OVERFLOW_MARK)) body.setAttribute(OVERFLOW_MARK, body.style.overflow);
932
1076
  body.style.overflow = "hidden";
933
1077
  }
934
1078
  static #reconcileBackground(ownerDocument) {
935
- const registry = _FocusTrap.#registry(ownerDocument);
936
- for (const element of registry.inerted) {
937
- if (!element.hasAttribute(INERT_MARK)) registry.inerted.delete(element);
1079
+ const registry2 = _FocusTrap.#registry(ownerDocument);
1080
+ for (const element of registry2.inerted) {
1081
+ if (!element.hasAttribute(INERT_MARK)) registry2.inerted.delete(element);
938
1082
  }
939
- const background = _FocusTrap.#backgroundOf(registry);
940
- for (const element of registry.inerted) {
1083
+ const background = _FocusTrap.#backgroundOf(registry2);
1084
+ for (const element of registry2.inerted) {
941
1085
  if (background.has(element)) continue;
942
1086
  element.removeAttribute(INERT_MARK);
943
1087
  element.inert = false;
944
- registry.inerted.delete(element);
1088
+ registry2.inerted.delete(element);
945
1089
  }
946
1090
  const added = [];
947
1091
  for (const element of background) {
948
- if (registry.inerted.has(element)) continue;
1092
+ if (registry2.inerted.has(element)) continue;
949
1093
  element.setAttribute(INERT_MARK, "");
950
1094
  element.inert = true;
951
- registry.inerted.add(element);
1095
+ registry2.inerted.add(element);
952
1096
  added.push(element);
953
1097
  }
954
1098
  return added;
955
1099
  }
956
- static #backgroundOf(registry) {
957
- const containers = registry.stack.map((trap) => trap.container());
1100
+ static #backgroundOf(registry2) {
1101
+ const containers = registry2.stack.map((trap) => trap.container());
958
1102
  let top = -1;
959
- registry.stack.forEach((trap, index) => {
1103
+ registry2.stack.forEach((trap, index) => {
960
1104
  if (trap.isolated && containers[index]) top = index;
961
1105
  });
962
1106
  const background = /* @__PURE__ */ new Set();
@@ -971,7 +1115,7 @@ var FocusTrap = class _FocusTrap {
971
1115
  const parent = flatTreeParent(node);
972
1116
  for (const sibling of parent ? flatTreeChildren(parent) : []) {
973
1117
  if (!(sibling instanceof HTMLElement) || kept.has(sibling)) continue;
974
- if (sibling.inert && !registry.inerted.has(sibling)) continue;
1118
+ if (sibling.inert && !registry2.inerted.has(sibling)) continue;
975
1119
  background.add(sibling);
976
1120
  }
977
1121
  }
@@ -1079,6 +1223,9 @@ var MorphRenderWatcher = class {
1079
1223
  schedule() {
1080
1224
  this.#pass.schedule();
1081
1225
  }
1226
+ get pending() {
1227
+ return this.#pass.pending;
1228
+ }
1082
1229
  disconnect() {
1083
1230
  this.#listeners.dispose();
1084
1231
  this.#pass.cancel();
@@ -1160,10 +1307,11 @@ var CommandPaletteController = class _CommandPaletteController extends Controlle
1160
1307
  return this.inputTargets.find((input) => dialog.contains(input)) ?? null;
1161
1308
  }
1162
1309
  });
1310
+ #listeners = new ListenerSet();
1163
1311
  connect() {
1164
1312
  const connection = this.#lived.connect(this.element);
1165
1313
  this.#trap.connect();
1166
- document.addEventListener("keydown", this.#onGlobalKeydown);
1314
+ this.#listeners.add(document, "keydown", this.#onGlobalKeydown);
1167
1315
  if (this.hasInputTarget) this.#composition.observe(this.inputTarget);
1168
1316
  this.#syncOptionSemantics();
1169
1317
  if (connection === "reconnect" && this.#isOpen) {
@@ -1183,7 +1331,7 @@ var CommandPaletteController = class _CommandPaletteController extends Controlle
1183
1331
  this.#lived.disconnect();
1184
1332
  this.#morphRender.disconnect();
1185
1333
  this.#reconcile.cancel();
1186
- document.removeEventListener("keydown", this.#onGlobalKeydown);
1334
+ this.#listeners.dispose();
1187
1335
  this.#composition.disconnect();
1188
1336
  this.#trap.disconnect(this);
1189
1337
  }
@@ -1314,6 +1462,7 @@ var CommandPaletteController = class _CommandPaletteController extends Controlle
1314
1462
  onKeydown(event) {
1315
1463
  if (event.defaultPrevented) return;
1316
1464
  if (isReservedArrowChord(event)) return;
1465
+ if ((event.key === "Home" || event.key === "End") && hasModifierChord(event)) return;
1317
1466
  if (this.#composition.isComposing(event) || !this.#isOpen) return;
1318
1467
  this.#reconcileActive();
1319
1468
  switch (event.key) {