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
@@ -1,20 +1,41 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
+ function isAriaDisabled(element) {
4
+ for (let current = element; current; current = current.parentElement) {
5
+ if (current.getAttribute("aria-disabled") === "true") return true;
6
+ }
7
+ return false;
8
+ }
9
+
3
10
  function isReservedArrowChord(event, allow = []) {
4
11
  if (!event.key.startsWith("Arrow")) return false;
5
12
  return event.altKey && !allow.includes("alt") || event.ctrlKey && !allow.includes("ctrl") || event.metaKey && !allow.includes("meta") || event.shiftKey && !allow.includes("shift");
6
13
  }
14
+ function hasModifierChord(event) {
15
+ return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
16
+ }
17
+
18
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
19
+ if (element.getAttribute(name) === value) return false;
20
+ if (value === null) element.removeAttribute(name);
21
+ else element.setAttribute(name, value);
22
+ return true;
23
+ }
7
24
 
8
25
  function sharedRegistry(key, create) {
9
26
  const symbol = Symbol.for(key);
10
27
  const scope = globalThis;
11
28
  const existing = scope[symbol];
12
29
  if (existing !== void 0) return existing;
13
- const registry = create();
14
- Object.defineProperty(globalThis, symbol, { value: registry });
15
- return registry;
30
+ const registry2 = create();
31
+ Object.defineProperty(globalThis, symbol, { value: registry2 });
32
+ return registry2;
16
33
  }
17
34
 
35
+ var registry = sharedRegistry(
36
+ "stimeo-ui.attribute-lease.registry.v1",
37
+ () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
38
+ );
18
39
  function isAttributeValue(value) {
19
40
  return value === null || typeof value === "string";
20
41
  }
@@ -31,24 +52,46 @@ function readLeaseRecord(element, record) {
31
52
  return void 0;
32
53
  }
33
54
  }
34
- var AttributeLease = class _AttributeLease {
35
- static #registry = sharedRegistry(
36
- "stimeo-ui.attribute-lease.registry.v1",
37
- () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
38
- );
55
+ function attributeStack(element, attribute) {
56
+ const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
57
+ registry.stacks.set(element, byAttribute);
58
+ const known = byAttribute.get(attribute);
59
+ if (known) return known;
60
+ const found = [];
61
+ for (const record of registry.names.get(attribute) ?? []) {
62
+ const read = readLeaseRecord(element, record);
63
+ if (read) found.push({ ...read, record });
64
+ }
65
+ const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
66
+ const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
67
+ lease: null,
68
+ record,
69
+ written,
70
+ original,
71
+ linked: linked && index > 0
72
+ }));
73
+ byAttribute.set(attribute, stack);
74
+ return stack;
75
+ }
76
+ function findHold(stack, lease, record) {
77
+ return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
78
+ }
79
+ var AttributeLease = class {
39
80
  #attribute;
40
81
  #record;
41
82
  #base;
83
+ #preserveAuthor;
42
84
  #held = /* @__PURE__ */ new Set();
43
85
  constructor(attribute, owner, options = {}) {
44
86
  this.#attribute = attribute;
45
87
  this.#record = `data-${owner}-${attribute}-lease`;
46
88
  this.#base = options.base === true;
47
- const names = _AttributeLease.#registry.names;
89
+ this.#preserveAuthor = options.preserveAuthor === true;
90
+ const names = registry.names;
48
91
  names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
49
92
  }
50
93
  write(element, value) {
51
- const stack = this.#stack(element);
94
+ const stack = attributeStack(element, this.#attribute);
52
95
  const hold = this.#take(stack) ?? this.#acquire(element, stack);
53
96
  this.#held.add(element);
54
97
  const shows = !this.#covered(element, stack, hold);
@@ -58,8 +101,8 @@ var AttributeLease = class _AttributeLease {
58
101
  }
59
102
  return(element) {
60
103
  const held = this.#held.delete(element);
61
- const known = _AttributeLease.#registry.stacks.get(element)?.has(this.#attribute);
62
- const stack = held || known || element.hasAttribute(this.#record) ? this.#stack(element) : [];
104
+ const known = registry.stacks.get(element)?.has(this.#attribute);
105
+ const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
63
106
  const hold = this.#take(stack);
64
107
  if (!hold) return false;
65
108
  const carries = element.getAttribute(this.#attribute) === hold.written;
@@ -77,31 +120,8 @@ var AttributeLease = class _AttributeLease {
77
120
  returnAll() {
78
121
  for (const element of Array.from(this.#held)) this.return(element);
79
122
  }
80
- #stack(element) {
81
- const stacks = _AttributeLease.#registry.stacks;
82
- const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
83
- stacks.set(element, byAttribute);
84
- const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
85
- byAttribute.set(this.#attribute, stack);
86
- return stack;
87
- }
88
- #seed(element) {
89
- const found = [];
90
- for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
91
- const read = readLeaseRecord(element, record);
92
- if (read) found.push({ ...read, record });
93
- }
94
- const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
95
- return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
96
- lease: null,
97
- record,
98
- written,
99
- original,
100
- linked: linked && index > 0
101
- }));
102
- }
103
123
  #take(stack) {
104
- const hold = stack.find((held) => held.lease === this) ?? stack.find((held) => held.lease === null && held.record === this.#record);
124
+ const hold = findHold(stack, this, this.#record);
105
125
  if (hold) hold.lease = this;
106
126
  return hold;
107
127
  }
@@ -110,7 +130,7 @@ var AttributeLease = class _AttributeLease {
110
130
  const top = stack.at(-1);
111
131
  const bottom = stack[0];
112
132
  const over = top?.written === current ? top : void 0;
113
- const from = this.#base ? bottom : over;
133
+ const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
114
134
  const hold = {
115
135
  lease: this,
116
136
  record: this.#record,
@@ -140,15 +160,23 @@ var AttributeLease = class _AttributeLease {
140
160
  );
141
161
  });
142
162
  for (const [name, recorded] of records) {
143
- if (element.getAttribute(name) === recorded) continue;
144
- if (recorded === null) element.removeAttribute(name);
145
- else element.setAttribute(name, recorded);
163
+ setAttributeIfChanged(element, name, recorded);
146
164
  }
147
165
  }
148
166
  #reflect(element, value) {
149
- if (element.getAttribute(this.#attribute) === value) return;
150
- if (value === null) element.removeAttribute(this.#attribute);
151
- else element.setAttribute(this.#attribute, value);
167
+ setAttributeIfChanged(element, this.#attribute, value);
168
+ }
169
+ };
170
+
171
+ var ClickVerdicts = class {
172
+ #verdicts = /* @__PURE__ */ new WeakMap();
173
+ record(event, entries, refused) {
174
+ this.#verdicts.set(event, { entries, refused });
175
+ }
176
+ for(event, entry) {
177
+ const verdict = event && this.#verdicts.get(event);
178
+ if (!verdict?.entries.includes(entry)) return void 0;
179
+ return verdict.refused;
152
180
  }
153
181
  };
154
182
 
@@ -166,25 +194,25 @@ var EscapeLayer = class _EscapeLayer {
166
194
  #active = null;
167
195
  activate(ownerDocument = document, options) {
168
196
  this.deactivate();
169
- let registry = _EscapeLayer.#registries.get(ownerDocument);
170
- if (!registry) {
171
- registry = _EscapeLayer.#createRegistry();
172
- _EscapeLayer.#registries.set(ownerDocument, registry);
173
- ownerDocument.addEventListener("keydown", registry.onKeydown);
197
+ let registry2 = _EscapeLayer.#registries.get(ownerDocument);
198
+ if (!registry2) {
199
+ registry2 = _EscapeLayer.#createRegistry();
200
+ _EscapeLayer.#registries.set(ownerDocument, registry2);
201
+ ownerDocument.addEventListener("keydown", registry2.onKeydown);
174
202
  }
175
203
  const entry = { onDismiss: options.onDismiss, claims: options.claims ?? null };
176
- registry.stack.push(entry);
204
+ registry2.stack.push(entry);
177
205
  this.#active = { document: ownerDocument, entry };
178
206
  }
179
207
  deactivate() {
180
208
  const active = this.#active;
181
209
  if (!active) return;
182
- const registry = _EscapeLayer.#registries.get(active.document);
183
- if (registry) {
184
- const index = registry.stack.lastIndexOf(active.entry);
185
- if (index >= 0) registry.stack.splice(index, 1);
186
- if (registry.stack.length === 0) {
187
- active.document.removeEventListener("keydown", registry.onKeydown);
210
+ const registry2 = _EscapeLayer.#registries.get(active.document);
211
+ if (registry2) {
212
+ const index = registry2.stack.lastIndexOf(active.entry);
213
+ if (index >= 0) registry2.stack.splice(index, 1);
214
+ if (registry2.stack.length === 0) {
215
+ active.document.removeEventListener("keydown", registry2.onKeydown);
188
216
  _EscapeLayer.#registries.delete(active.document);
189
217
  }
190
218
  }
@@ -193,22 +221,22 @@ var EscapeLayer = class _EscapeLayer {
193
221
  get ownsEscape() {
194
222
  const active = this.#active;
195
223
  if (!active) return false;
196
- const registry = _EscapeLayer.#registries.get(active.document);
197
- if (!registry) return false;
198
- return _EscapeLayer.#resolveOwner(registry.stack) === active.entry;
224
+ const registry2 = _EscapeLayer.#registries.get(active.document);
225
+ if (!registry2) return false;
226
+ return _EscapeLayer.#resolveOwner(registry2.stack) === active.entry;
199
227
  }
200
228
  static #createRegistry() {
201
- const registry = {
229
+ const registry2 = {
202
230
  stack: [],
203
231
  onKeydown: (event) => {
204
232
  if (event.key !== "Escape" || event.defaultPrevented || event.isComposing) return;
205
- const owner = _EscapeLayer.#resolveOwner(registry.stack);
233
+ const owner = _EscapeLayer.#resolveOwner(registry2.stack);
206
234
  if (!owner) return;
207
235
  event.preventDefault();
208
236
  owner.onDismiss();
209
237
  }
210
238
  };
211
- return registry;
239
+ return registry2;
212
240
  }
213
241
  static #resolveOwner(stack) {
214
242
  for (let index = stack.length - 1; index >= 0; index--) {
@@ -228,6 +256,21 @@ function ownerIndex(candidates, node) {
228
256
  function ownerOf(candidates, node) {
229
257
  return candidates[ownerIndex(candidates, node)] ?? null;
230
258
  }
259
+ function ownersOf(candidates, node) {
260
+ if (!(node instanceof Node)) return [];
261
+ return candidates.filter((candidate) => candidate.contains(node));
262
+ }
263
+
264
+ var ListenerSet = class {
265
+ #abort = new AbortController();
266
+ add(target, type, handler, options) {
267
+ target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });
268
+ }
269
+ dispose() {
270
+ this.#abort.abort();
271
+ this.#abort = new AbortController();
272
+ }
273
+ };
231
274
 
232
275
  var TimerRegistry = class {
233
276
  ids = /* @__PURE__ */ new Set();
@@ -289,15 +332,17 @@ var MenuController = class extends Controller {
289
332
  #expanded = new AttributeLease("aria-expanded", this.identifier);
290
333
  #menu = null;
291
334
  #clickOwner = null;
335
+ #clickVerdicts = new ClickVerdicts();
292
336
  #activated = /* @__PURE__ */ new WeakSet();
293
337
  #connected = false;
294
338
  #reporting = false;
339
+ #listeners = new ListenerSet();
295
340
  connect() {
296
341
  this.#close("api");
297
- this.element.addEventListener("click", this.#onItemClickCapture, true);
298
- this.element.addEventListener("click", this.#onDelegatedItemClick);
299
- this.element.addEventListener("keydown", this.#onDelegatedItemKeydown);
300
- document.addEventListener("click", this.#onOutsideClick, true);
342
+ this.#listeners.add(this.element, "click", this.#onItemClickCapture, { capture: true });
343
+ this.#listeners.add(this.element, "click", this.#onDelegatedItemClick);
344
+ this.#listeners.add(this.element, "keydown", this.#onDelegatedItemKeydown);
345
+ this.#listeners.add(document, "click", this.#onOutsideClick, { capture: true });
301
346
  this.#connected = true;
302
347
  this.#reporting = true;
303
348
  }
@@ -306,10 +351,7 @@ var MenuController = class extends Controller {
306
351
  this.#reporting = false;
307
352
  this.#timers.clearAll();
308
353
  this.#escapeLayer.deactivate();
309
- this.element.removeEventListener("click", this.#onItemClickCapture, true);
310
- this.element.removeEventListener("click", this.#onDelegatedItemClick);
311
- this.element.removeEventListener("keydown", this.#onDelegatedItemKeydown);
312
- document.removeEventListener("click", this.#onOutsideClick, true);
354
+ this.#listeners.dispose();
313
355
  }
314
356
  triggerTargetConnected() {
315
357
  if (this.#connected) this.#reflectTrigger();
@@ -398,6 +440,7 @@ var MenuController = class extends Controller {
398
440
  #handleItemKeydown(event, from) {
399
441
  if (event.defaultPrevented) return;
400
442
  if (isReservedArrowChord(event)) return;
443
+ if ((event.key === "Home" || event.key === "End") && hasModifierChord(event)) return;
401
444
  const items = this.#navigableItems;
402
445
  const currentIndex = items.indexOf(from);
403
446
  switch (event.key) {
@@ -424,12 +467,22 @@ var MenuController = class extends Controller {
424
467
  }
425
468
  }
426
469
  activate(event) {
427
- if (event !== void 0) {
428
- if (this.#activated.has(event)) return;
429
- this.#activated.add(event);
430
- }
470
+ if (event === void 0) this.#closeAndRestore("select");
471
+ else this.#activateItem(this.#itemFrom(event.target), event);
472
+ }
473
+ #activateItem(item, event) {
474
+ if (item !== null && this.#refuses(item, event)) return;
475
+ if (this.#activated.has(event)) return;
476
+ this.#activated.add(event);
431
477
  this.#closeAndRestore("select");
432
478
  }
479
+ #refuses(item, event) {
480
+ const recorded = this.#clickVerdicts.for(event, item);
481
+ if (recorded !== void 0) return recorded;
482
+ return ownersOf(this.itemTargets, event.target).some(
483
+ (owner) => this.#isActivationDisabled(owner)
484
+ );
485
+ }
433
486
  #closeAndRestore(reason) {
434
487
  this.#close(reason);
435
488
  if (this.hasTriggerTarget) this.triggerTarget.focus();
@@ -446,20 +499,20 @@ var MenuController = class extends Controller {
446
499
  const item = this.#clickOwner;
447
500
  this.#clickOwner = null;
448
501
  if (item === null) return;
449
- this.activate(event);
502
+ this.#activateItem(item, event);
450
503
  };
451
504
  #itemFrom(node) {
452
505
  return ownerOf(this.itemTargets, node);
453
506
  }
454
507
  #onItemClickCapture = (event) => {
455
- const target = event.target;
456
- if (!(target instanceof Node)) {
457
- this.#clickOwner = null;
458
- return;
459
- }
460
- const item = this.#itemFrom(target);
461
- this.#clickOwner = item;
462
- if (item === null || item.getAttribute("aria-disabled") !== "true") return;
508
+ const items = ownersOf(this.itemTargets, event.target);
509
+ this.#clickOwner = items[0] ?? null;
510
+ this.#clickVerdicts.record(
511
+ event,
512
+ items,
513
+ items.some((item) => this.#isActivationDisabled(item))
514
+ );
515
+ if (!items.some((item) => isAriaDisabled(item))) return;
463
516
  this.#clickOwner = null;
464
517
  event.preventDefault();
465
518
  event.stopImmediatePropagation();
@@ -480,6 +533,9 @@ var MenuController = class extends Controller {
480
533
  if (item.hasAttribute("hidden")) return false;
481
534
  return !item.disabled;
482
535
  }
536
+ #isActivationDisabled(item) {
537
+ return !this.#isNavigable(item) || isAriaDisabled(item);
538
+ }
483
539
  get #isOpen() {
484
540
  return this.hasMenuTarget && !this.menuTarget.hidden;
485
541
  }