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,5 +1,12 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
+ function fillTemplate(template, values) {
4
+ return template.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g, (match, name) => {
5
+ const replacement = Object.hasOwn(values, name) ? values[name] : void 0;
6
+ return replacement === void 0 ? match : String(replacement);
7
+ });
8
+ }
9
+
3
10
  function announce(message, options = {}) {
4
11
  const text = message.trim();
5
12
  if (text.length === 0) return;
@@ -9,11 +16,12 @@ function announce(message, options = {}) {
9
16
  })
10
17
  );
11
18
  }
12
- function fillTemplate(template, values) {
13
- return template.replace(/\{([a-zA-Z][a-zA-Z0-9]*)\}/g, (match, name) => {
14
- const replacement = values[name];
15
- return replacement === void 0 ? match : String(replacement);
16
- });
19
+
20
+ function setAttributeIfChanged(element, name, value, beforeWrite) {
21
+ if (element.getAttribute(name) === value) return false;
22
+ if (value === null) element.removeAttribute(name);
23
+ else element.setAttribute(name, value);
24
+ return true;
17
25
  }
18
26
 
19
27
  function sharedRegistry(key, create) {
@@ -21,11 +29,15 @@ function sharedRegistry(key, create) {
21
29
  const scope = globalThis;
22
30
  const existing = scope[symbol];
23
31
  if (existing !== void 0) return existing;
24
- const registry = create();
25
- Object.defineProperty(globalThis, symbol, { value: registry });
26
- return registry;
32
+ const registry2 = create();
33
+ Object.defineProperty(globalThis, symbol, { value: registry2 });
34
+ return registry2;
27
35
  }
28
36
 
37
+ var registry = sharedRegistry(
38
+ "stimeo-ui.attribute-lease.registry.v1",
39
+ () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
40
+ );
29
41
  function isAttributeValue(value) {
30
42
  return value === null || typeof value === "string";
31
43
  }
@@ -42,24 +54,46 @@ function readLeaseRecord(element, record) {
42
54
  return void 0;
43
55
  }
44
56
  }
45
- var AttributeLease = class _AttributeLease {
46
- static #registry = sharedRegistry(
47
- "stimeo-ui.attribute-lease.registry.v1",
48
- () => ({ stacks: /* @__PURE__ */ new WeakMap(), names: /* @__PURE__ */ new Map() })
49
- );
57
+ function attributeStack(element, attribute) {
58
+ const byAttribute = registry.stacks.get(element) ?? /* @__PURE__ */ new Map();
59
+ registry.stacks.set(element, byAttribute);
60
+ const known = byAttribute.get(attribute);
61
+ if (known) return known;
62
+ const found = [];
63
+ for (const record of registry.names.get(attribute) ?? []) {
64
+ const read = readLeaseRecord(element, record);
65
+ if (read) found.push({ ...read, record });
66
+ }
67
+ const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
68
+ const stack = found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
69
+ lease: null,
70
+ record,
71
+ written,
72
+ original,
73
+ linked: linked && index > 0
74
+ }));
75
+ byAttribute.set(attribute, stack);
76
+ return stack;
77
+ }
78
+ function findHold(stack, lease, record) {
79
+ return stack.find((held) => held.lease === lease) ?? stack.find((held) => held.lease === null && held.record === record);
80
+ }
81
+ var AttributeLease = class {
50
82
  #attribute;
51
83
  #record;
52
84
  #base;
85
+ #preserveAuthor;
53
86
  #held = /* @__PURE__ */ new Set();
54
87
  constructor(attribute, owner, options = {}) {
55
88
  this.#attribute = attribute;
56
89
  this.#record = `data-${owner}-${attribute}-lease`;
57
90
  this.#base = options.base === true;
58
- const names = _AttributeLease.#registry.names;
91
+ this.#preserveAuthor = options.preserveAuthor === true;
92
+ const names = registry.names;
59
93
  names.set(attribute, (names.get(attribute) ?? /* @__PURE__ */ new Set()).add(this.#record));
60
94
  }
61
95
  write(element, value) {
62
- const stack = this.#stack(element);
96
+ const stack = attributeStack(element, this.#attribute);
63
97
  const hold = this.#take(stack) ?? this.#acquire(element, stack);
64
98
  this.#held.add(element);
65
99
  const shows = !this.#covered(element, stack, hold);
@@ -69,8 +103,8 @@ var AttributeLease = class _AttributeLease {
69
103
  }
70
104
  return(element) {
71
105
  const held = this.#held.delete(element);
72
- const known = _AttributeLease.#registry.stacks.get(element)?.has(this.#attribute);
73
- const stack = held || known || element.hasAttribute(this.#record) ? this.#stack(element) : [];
106
+ const known = registry.stacks.get(element)?.has(this.#attribute);
107
+ const stack = held || known || element.hasAttribute(this.#record) ? attributeStack(element, this.#attribute) : [];
74
108
  const hold = this.#take(stack);
75
109
  if (!hold) return false;
76
110
  const carries = element.getAttribute(this.#attribute) === hold.written;
@@ -88,31 +122,8 @@ var AttributeLease = class _AttributeLease {
88
122
  returnAll() {
89
123
  for (const element of Array.from(this.#held)) this.return(element);
90
124
  }
91
- #stack(element) {
92
- const stacks = _AttributeLease.#registry.stacks;
93
- const byAttribute = stacks.get(element) ?? /* @__PURE__ */ new Map();
94
- stacks.set(element, byAttribute);
95
- const stack = byAttribute.get(this.#attribute) ?? this.#seed(element);
96
- byAttribute.set(this.#attribute, stack);
97
- return stack;
98
- }
99
- #seed(element) {
100
- const found = [];
101
- for (const record of _AttributeLease.#registry.names.get(this.#attribute) ?? []) {
102
- const read = readLeaseRecord(element, record);
103
- if (read) found.push({ ...read, record });
104
- }
105
- const depth = ({ beneath }) => beneath.filter((name) => found.some((other) => other.record === name)).length;
106
- return found.sort((one, other) => depth(one) - depth(other)).map(({ record, written, original, linked }, index) => ({
107
- lease: null,
108
- record,
109
- written,
110
- original,
111
- linked: linked && index > 0
112
- }));
113
- }
114
125
  #take(stack) {
115
- const hold = stack.find((held) => held.lease === this) ?? stack.find((held) => held.lease === null && held.record === this.#record);
126
+ const hold = findHold(stack, this, this.#record);
116
127
  if (hold) hold.lease = this;
117
128
  return hold;
118
129
  }
@@ -121,7 +132,7 @@ var AttributeLease = class _AttributeLease {
121
132
  const top = stack.at(-1);
122
133
  const bottom = stack[0];
123
134
  const over = top?.written === current ? top : void 0;
124
- const from = this.#base ? bottom : over;
135
+ const from = this.#base ? this.#preserveAuthor && !stack.some((held) => held.written === current) ? void 0 : bottom : over;
125
136
  const hold = {
126
137
  lease: this,
127
138
  record: this.#record,
@@ -151,15 +162,11 @@ var AttributeLease = class _AttributeLease {
151
162
  );
152
163
  });
153
164
  for (const [name, recorded] of records) {
154
- if (element.getAttribute(name) === recorded) continue;
155
- if (recorded === null) element.removeAttribute(name);
156
- else element.setAttribute(name, recorded);
165
+ setAttributeIfChanged(element, name, recorded);
157
166
  }
158
167
  }
159
168
  #reflect(element, value) {
160
- if (element.getAttribute(this.#attribute) === value) return;
161
- if (value === null) element.removeAttribute(this.#attribute);
162
- else element.setAttribute(this.#attribute, value);
169
+ setAttributeIfChanged(element, this.#attribute, value);
163
170
  }
164
171
  };
165
172
 
@@ -247,6 +254,11 @@ function firstTabStop(root) {
247
254
  }
248
255
  return null;
249
256
  }
257
+ function deepActiveElement(ownerDocument) {
258
+ let active = ownerDocument.activeElement;
259
+ while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;
260
+ return active;
261
+ }
250
262
 
251
263
  var ListenerSet = class {
252
264
  #abort = new AbortController();
@@ -275,6 +287,9 @@ var MicrotaskCoalescer = class {
275
287
  this.#queued = false;
276
288
  this.#generation += 1;
277
289
  }
290
+ get pending() {
291
+ return this.#queued;
292
+ }
278
293
  schedule() {
279
294
  if (!this.#active || this.#queued) return;
280
295
  this.#queued = true;
@@ -305,6 +320,9 @@ var MorphRenderWatcher = class {
305
320
  schedule() {
306
321
  this.#pass.schedule();
307
322
  }
323
+ get pending() {
324
+ return this.#pass.pending;
325
+ }
308
326
  disconnect() {
309
327
  this.#listeners.dispose();
310
328
  this.#pass.cancel();
@@ -372,6 +390,9 @@ function queryOpenDescendants(root, selector) {
372
390
  return matches;
373
391
  }
374
392
 
393
+ function holdsFocus(element) {
394
+ return element.matches(":focus") || deepActiveElement(element.ownerDocument) === element;
395
+ }
375
396
  var TabindexLoan = class _TabindexLoan {
376
397
  static #registry = sharedRegistry(
377
398
  "stimeo-ui.tabindex-loan.registry.v1",
@@ -379,19 +400,22 @@ var TabindexLoan = class _TabindexLoan {
379
400
  );
380
401
  #value;
381
402
  #record;
403
+ #preserveFocus;
382
404
  #lent = /* @__PURE__ */ new Set();
383
- constructor(value, owner) {
405
+ constructor(value, owner, options = {}) {
384
406
  this.#value = value;
385
407
  this.#record = `data-${owner}-tabindex-loan`;
408
+ this.#preserveFocus = options.preserveFocus === true;
386
409
  _TabindexLoan.#registry.names.add(this.#record);
387
410
  }
388
- lend(element) {
411
+ lend(element, options = {}) {
389
412
  const stack = this.#stack(element);
390
413
  const current = element.getAttribute("tabindex");
391
414
  const held = stack.find((hold) => hold.loan === this) ?? stack.find(
392
415
  (hold) => hold.loan === null && hold.record === this.#record && hold.value === this.#value
393
416
  );
394
417
  const linked = stack.at(-1)?.value === current;
418
+ if (!held && options.onlyIfUnfocusable && (current !== null || element.tabIndex >= 0)) return;
395
419
  if (!held && current !== null && !linked) return;
396
420
  this.#lent.add(element);
397
421
  if (held) held.loan = this;
@@ -401,19 +425,28 @@ var TabindexLoan = class _TabindexLoan {
401
425
  element.setAttribute("tabindex", this.#value);
402
426
  }
403
427
  }
404
- returnAll() {
405
- for (const element of this.#lent) {
406
- const stack = this.#stack(element);
407
- const hold = stack.find((held) => held.loan === this);
408
- if (hold) this.#release(element, stack, hold);
428
+ return(element) {
429
+ const stack = this.#stack(element);
430
+ const hold = stack.find((held) => held.loan === this) ?? stack.find(
431
+ (held) => held.loan === null && held.record === this.#record && held.value === this.#value
432
+ );
433
+ if (!hold) return false;
434
+ if (!this.#release(element, stack, hold, this.#preserveFocus)) {
435
+ hold.loan = this;
436
+ this.#lent.add(element);
437
+ return false;
409
438
  }
410
- this.#lent.clear();
439
+ this.#lent.delete(element);
440
+ return true;
441
+ }
442
+ returnAll() {
443
+ for (const element of Array.from(this.#lent)) this.return(element);
411
444
  }
412
445
  reclaim(element) {
413
446
  if (element.getAttribute(this.#record) !== this.#value) return;
414
447
  const stack = this.#stack(element);
415
448
  const hold = stack.find((held) => held.loan === null && held.record === this.#record);
416
- if (hold && !element.matches(":focus")) this.#release(element, stack, hold);
449
+ if (hold && !holdsFocus(element)) this.#release(element, stack, hold);
417
450
  }
418
451
  reclaimWithin(root) {
419
452
  for (const element of queryOpenDescendants(root, `[${this.#record}]`)) {
@@ -437,26 +470,26 @@ var TabindexLoan = class _TabindexLoan {
437
470
  for (const [index, hold] of holds.entries()) hold.linked = index > 0;
438
471
  return holds;
439
472
  }
440
- #release(element, stack, hold) {
473
+ #release(element, stack, hold, preserveFocus = false) {
441
474
  const current = element.getAttribute("tabindex");
442
475
  const index = stack.indexOf(hold);
443
476
  const owns = current === hold.value && !stack.slice(index + 1).some((above2) => above2.value === current);
477
+ if (owns && preserveFocus && holdsFocus(element)) return false;
444
478
  stack.splice(index, 1);
445
479
  const above = stack[index];
446
480
  if (above) above.linked &&= hold.linked;
447
481
  this.#mark(element, stack);
448
- if (!owns) return;
482
+ if (!owns) return true;
449
483
  const below = hold.linked ? stack[index - 1] : void 0;
450
484
  if (!below) element.removeAttribute("tabindex");
451
485
  else if (below.value !== current) element.setAttribute("tabindex", below.value);
486
+ return true;
452
487
  }
453
488
  #mark(element, stack) {
454
489
  const records = /* @__PURE__ */ new Map([[this.#record, null]]);
455
490
  for (const hold of stack) records.set(hold.record, hold.value);
456
491
  for (const [name, recorded] of records) {
457
- if (element.getAttribute(name) === recorded) continue;
458
- if (recorded === null) element.removeAttribute(name);
459
- else element.setAttribute(name, recorded);
492
+ setAttributeIfChanged(element, name, recorded);
460
493
  }
461
494
  }
462
495
  };
@@ -508,17 +541,18 @@ var NestedFormController = class _NestedFormController extends Controller {
508
541
  const row = this.#rowContaining(button);
509
542
  if (row) this.#removeRow(row);
510
543
  };
544
+ #listeners = new ListenerSet();
511
545
  connect() {
512
546
  this.#tabindex.reclaim(this.element);
513
547
  this.#warnedMissing = false;
514
548
  this.#warnedTemplate = false;
515
- this.element.addEventListener("click", this.#onClick);
549
+ this.#listeners.add(this.element, "click", this.#onClick);
516
550
  this.#reconcile.observe(this.element);
517
551
  if (!this.hasListTarget || !this.hasTemplateTarget) this.#warnMissing();
518
552
  this.#refresh();
519
553
  }
520
554
  disconnect() {
521
- this.element.removeEventListener("click", this.#onClick);
555
+ this.#listeners.dispose();
522
556
  this.#observer?.disconnect();
523
557
  this.#observer = null;
524
558
  this.#reconcile.disconnect();