@editora/ui-core 0.1.22 → 0.1.24

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 (278) hide show
  1. package/README.md +292 -221
  2. package/dist/{ElementBase-YlTLMsGk.mjs → ElementBase-BeZT54Hj.mjs} +3 -2
  3. package/dist/ElementBase-DxbvhLJs.js +1 -0
  4. package/dist/ElementBase.d.ts +2 -1
  5. package/dist/ElementBase.d.ts.map +1 -1
  6. package/dist/__tests__/setup.d.ts +0 -2
  7. package/dist/__tests__/setup.d.ts.map +1 -1
  8. package/dist/accordion.cjs.js +1 -1
  9. package/dist/accordion.esm.js +1 -1
  10. package/dist/alert-dialog.cjs.js +1 -1
  11. package/dist/alert-dialog.esm.js +1 -1
  12. package/dist/alert.cjs.js +1 -1
  13. package/dist/alert.esm.js +1 -1
  14. package/dist/anchor.cjs.js +3 -3
  15. package/dist/anchor.esm.js +6 -5
  16. package/dist/animated-beam.cjs.js +1 -1
  17. package/dist/animated-beam.esm.js +1 -1
  18. package/dist/animated-list.cjs.js +1 -1
  19. package/dist/animated-list.esm.js +1 -1
  20. package/dist/animated-text.cjs.js +1 -1
  21. package/dist/animated-text.esm.js +1 -1
  22. package/dist/app-header.cjs.js +1 -1
  23. package/dist/app-header.esm.js +1 -1
  24. package/dist/aspect-ratio.cjs.js +1 -1
  25. package/dist/aspect-ratio.esm.js +1 -1
  26. package/dist/avatar.cjs.js +1 -1
  27. package/dist/avatar.esm.js +1 -1
  28. package/dist/badge.cjs.js +1 -1
  29. package/dist/badge.esm.js +1 -1
  30. package/dist/block-controls.cjs.js +1 -1
  31. package/dist/block-controls.esm.js +1 -1
  32. package/dist/box.cjs.js +1 -1
  33. package/dist/box.esm.js +1 -1
  34. package/dist/breadcrumb.cjs.js +1 -1
  35. package/dist/breadcrumb.esm.js +1 -1
  36. package/dist/button.cjs.js +1 -1
  37. package/dist/button.esm.js +1 -1
  38. package/dist/{calendar-DbxYRdlv.mjs → calendar-B3PUKHQm.mjs} +1 -1
  39. package/dist/{calendar-Qa-cFOp3.js → calendar-D-mXMgqc.js} +1 -1
  40. package/dist/calendar.cjs.js +1 -1
  41. package/dist/calendar.esm.js +1 -1
  42. package/dist/card.cjs.js +1 -1
  43. package/dist/card.esm.js +1 -1
  44. package/dist/chart.cjs.js +1 -1
  45. package/dist/chart.esm.js +1 -1
  46. package/dist/checkbox.cjs.js +1 -1
  47. package/dist/checkbox.esm.js +1 -1
  48. package/dist/collapsible.cjs.js +1 -1
  49. package/dist/collapsible.esm.js +1 -1
  50. package/dist/collection.cjs.js +1 -1
  51. package/dist/collection.esm.js +9 -8
  52. package/dist/color-picker.cjs.js +4 -4
  53. package/dist/color-picker.esm.js +3 -3
  54. package/dist/combobox.cjs.js +1 -1
  55. package/dist/combobox.esm.js +1 -1
  56. package/dist/command-palette.cjs.js +1 -1
  57. package/dist/command-palette.esm.js +1 -1
  58. package/dist/command.cjs.js +1 -1
  59. package/dist/command.esm.js +1 -1
  60. package/dist/components/ui-anchor.d.ts +2 -1
  61. package/dist/components/ui-anchor.d.ts.map +1 -1
  62. package/dist/components/ui-button.d.ts.map +1 -1
  63. package/dist/components/ui-collection.d.ts +2 -1
  64. package/dist/components/ui-collection.d.ts.map +1 -1
  65. package/dist/components/ui-form.d.ts +1 -0
  66. package/dist/components/ui-form.d.ts.map +1 -1
  67. package/dist/components/ui-roving-focus-group.d.ts +2 -1
  68. package/dist/components/ui-roving-focus-group.d.ts.map +1 -1
  69. package/dist/components/ui-sortable.d.ts +209 -12
  70. package/dist/components/ui-sortable.d.ts.map +1 -1
  71. package/dist/container.cjs.js +1 -1
  72. package/dist/container.esm.js +1 -1
  73. package/dist/context-menu.cjs.js +1 -1
  74. package/dist/context-menu.esm.js +1 -1
  75. package/dist/control-group.cjs.js +1 -1
  76. package/dist/control-group.esm.js +1 -1
  77. package/dist/data-table.cjs.js +1 -1
  78. package/dist/data-table.esm.js +1 -1
  79. package/dist/date-field.cjs.js +1 -1
  80. package/dist/date-field.esm.js +3 -3
  81. package/dist/date-picker.cjs.js +1 -1
  82. package/dist/date-picker.esm.js +3 -3
  83. package/dist/date-range-picker.cjs.js +1 -1
  84. package/dist/date-range-picker.esm.js +3 -3
  85. package/dist/date-range-time-picker.cjs.js +1 -1
  86. package/dist/date-range-time-picker.esm.js +3 -3
  87. package/dist/date-time-picker.cjs.js +1 -1
  88. package/dist/date-time-picker.esm.js +3 -3
  89. package/dist/{date-time-utils-Cps2aSu2.mjs → date-time-utils-BTlxnz5j.mjs} +1 -1
  90. package/dist/{date-time-utils-BzfTpeU-.js → date-time-utils-y3AvNvGe.js} +1 -1
  91. package/dist/description.cjs.js +1 -1
  92. package/dist/description.esm.js +1 -1
  93. package/dist/dialog.cjs.js +1 -1
  94. package/dist/dialog.esm.js +1 -1
  95. package/dist/direction-provider.cjs.js +1 -1
  96. package/dist/direction-provider.esm.js +1 -1
  97. package/dist/dismissable-layer.cjs.js +1 -1
  98. package/dist/dismissable-layer.esm.js +1 -1
  99. package/dist/dock.cjs.js +1 -1
  100. package/dist/dock.esm.js +1 -1
  101. package/dist/domElement-DazSZBjV.js +1 -0
  102. package/dist/domElement-ZlSGVP0l.mjs +5 -0
  103. package/dist/domElement.d.ts +2 -0
  104. package/dist/domElement.d.ts.map +1 -0
  105. package/dist/drawer.cjs.js +1 -1
  106. package/dist/drawer.esm.js +1 -1
  107. package/dist/dropdown.cjs.js +1 -1
  108. package/dist/dropdown.esm.js +1 -1
  109. package/dist/empty-state.cjs.js +1 -1
  110. package/dist/empty-state.esm.js +1 -1
  111. package/dist/field-error.cjs.js +1 -1
  112. package/dist/field-error.esm.js +1 -1
  113. package/dist/field.cjs.js +1 -1
  114. package/dist/field.esm.js +1 -1
  115. package/dist/fieldset.cjs.js +1 -1
  116. package/dist/fieldset.esm.js +1 -1
  117. package/dist/file-upload.cjs.js +1 -1
  118. package/dist/file-upload.esm.js +1 -1
  119. package/dist/flex.cjs.js +1 -1
  120. package/dist/flex.esm.js +1 -1
  121. package/dist/floating-toolbar.cjs.js +1 -1
  122. package/dist/floating-toolbar.esm.js +1 -1
  123. package/dist/focus-scope.cjs.js +1 -1
  124. package/dist/focus-scope.esm.js +1 -1
  125. package/dist/form.cjs.js +2 -2
  126. package/dist/form.esm.js +12 -2
  127. package/dist/gantt.cjs.js +1 -1
  128. package/dist/gantt.esm.js +1 -1
  129. package/dist/grid.cjs.js +1 -1
  130. package/dist/grid.esm.js +1 -1
  131. package/dist/hover-card.cjs.js +1 -1
  132. package/dist/hover-card.esm.js +1 -1
  133. package/dist/icon-cloud.cjs.js +1 -1
  134. package/dist/icon-cloud.esm.js +1 -1
  135. package/dist/icon.cjs.js +1 -1
  136. package/dist/icon.esm.js +1 -1
  137. package/dist/index.cjs.js +1 -1
  138. package/dist/index.esm.js +6 -6
  139. package/dist/inline-edit.cjs.js +1 -1
  140. package/dist/inline-edit.esm.js +1 -1
  141. package/dist/input.cjs.js +1 -1
  142. package/dist/input.esm.js +1 -1
  143. package/dist/label.cjs.js +1 -1
  144. package/dist/label.esm.js +1 -1
  145. package/dist/layout.cjs.js +1 -1
  146. package/dist/layout.esm.js +1 -1
  147. package/dist/marquee.cjs.js +1 -1
  148. package/dist/marquee.esm.js +1 -1
  149. package/dist/masonry-grid.cjs.js +1 -1
  150. package/dist/masonry-grid.esm.js +1 -1
  151. package/dist/menu.cjs.js +1 -1
  152. package/dist/menu.esm.js +1 -1
  153. package/dist/menubar.cjs.js +1 -1
  154. package/dist/menubar.esm.js +1 -1
  155. package/dist/meter.cjs.js +1 -1
  156. package/dist/meter.esm.js +1 -1
  157. package/dist/multi-select.cjs.js +1 -1
  158. package/dist/multi-select.esm.js +1 -1
  159. package/dist/navigation-menu.cjs.js +1 -1
  160. package/dist/navigation-menu.esm.js +1 -1
  161. package/dist/number-field.cjs.js +2 -2
  162. package/dist/number-field.esm.js +2 -2
  163. package/dist/number-ticker.cjs.js +1 -1
  164. package/dist/number-ticker.esm.js +1 -1
  165. package/dist/odometer.cjs.js +1 -1
  166. package/dist/odometer.esm.js +1 -1
  167. package/dist/orbiter.cjs.js +1 -1
  168. package/dist/orbiter.esm.js +1 -1
  169. package/dist/pagination.cjs.js +1 -1
  170. package/dist/pagination.esm.js +1 -1
  171. package/dist/{panel-group-CaD0_KQf.js → panel-group-BVHJEdfx.js} +1 -1
  172. package/dist/{panel-group-8sVNnGxg.mjs → panel-group-BxO_eNW6.mjs} +1 -1
  173. package/dist/panel-group.cjs.js +1 -1
  174. package/dist/panel-group.esm.js +1 -1
  175. package/dist/panel.cjs.js +1 -1
  176. package/dist/panel.esm.js +1 -1
  177. package/dist/password-field.cjs.js +1 -1
  178. package/dist/password-field.esm.js +1 -1
  179. package/dist/pin-input.cjs.js +1 -1
  180. package/dist/pin-input.esm.js +1 -1
  181. package/dist/placement-grid.cjs.js +1 -1
  182. package/dist/placement-grid.esm.js +1 -1
  183. package/dist/plugin-panel.cjs.js +1 -1
  184. package/dist/plugin-panel.esm.js +1 -1
  185. package/dist/popover.cjs.js +1 -1
  186. package/dist/popover.esm.js +1 -1
  187. package/dist/portal.cjs.js +1 -1
  188. package/dist/portal.esm.js +1 -1
  189. package/dist/positioner.cjs.js +1 -1
  190. package/dist/positioner.esm.js +1 -1
  191. package/dist/presence.cjs.js +1 -1
  192. package/dist/presence.esm.js +1 -1
  193. package/dist/progress.cjs.js +1 -1
  194. package/dist/progress.esm.js +1 -1
  195. package/dist/quick-actions.cjs.js +1 -1
  196. package/dist/quick-actions.esm.js +1 -1
  197. package/dist/radio-group.cjs.js +1 -1
  198. package/dist/radio-group.esm.js +1 -1
  199. package/dist/radio.cjs.js +1 -1
  200. package/dist/radio.esm.js +1 -1
  201. package/dist/rating.cjs.js +1 -1
  202. package/dist/rating.esm.js +1 -1
  203. package/dist/roving-focus-group.cjs.js +1 -1
  204. package/dist/roving-focus-group.esm.js +11 -10
  205. package/dist/scroll-area.cjs.js +1 -1
  206. package/dist/scroll-area.esm.js +1 -1
  207. package/dist/section.cjs.js +1 -1
  208. package/dist/section.esm.js +1 -1
  209. package/dist/select.cjs.js +1 -1
  210. package/dist/select.esm.js +1 -1
  211. package/dist/selection-popup.cjs.js +1 -1
  212. package/dist/selection-popup.esm.js +1 -1
  213. package/dist/separator.cjs.js +1 -1
  214. package/dist/separator.esm.js +1 -1
  215. package/dist/sidebar.cjs.js +2 -2
  216. package/dist/sidebar.esm.js +9 -9
  217. package/dist/skeleton.cjs.js +1 -1
  218. package/dist/skeleton.esm.js +1 -1
  219. package/dist/slider.cjs.js +1 -1
  220. package/dist/slider.esm.js +1 -1
  221. package/dist/slot.cjs.js +1 -1
  222. package/dist/slot.esm.js +1 -1
  223. package/dist/sortable.cjs.js +504 -369
  224. package/dist/sortable.d.ts +1 -1
  225. package/dist/sortable.d.ts.map +1 -1
  226. package/dist/sortable.esm.js +1758 -1168
  227. package/dist/spinning-text.cjs.js +1 -1
  228. package/dist/spinning-text.esm.js +1 -1
  229. package/dist/split-button.cjs.js +1 -1
  230. package/dist/split-button.esm.js +1 -1
  231. package/dist/splitter.cjs.js +1 -1
  232. package/dist/splitter.esm.js +1 -1
  233. package/dist/stepper.cjs.js +1 -1
  234. package/dist/stepper.esm.js +1 -1
  235. package/dist/switch.cjs.js +1 -1
  236. package/dist/switch.esm.js +1 -1
  237. package/dist/table.cjs.js +1 -1
  238. package/dist/table.esm.js +1 -1
  239. package/dist/tabs.cjs.js +1 -1
  240. package/dist/tabs.esm.js +1 -1
  241. package/dist/tags-input.cjs.js +1 -1
  242. package/dist/tags-input.esm.js +1 -1
  243. package/dist/textarea.cjs.js +1 -1
  244. package/dist/textarea.esm.js +1 -1
  245. package/dist/time-field.cjs.js +1 -1
  246. package/dist/time-field.esm.js +2 -2
  247. package/dist/time-picker.cjs.js +1 -1
  248. package/dist/time-picker.esm.js +3 -3
  249. package/dist/timeline.cjs.js +1 -1
  250. package/dist/timeline.esm.js +1 -1
  251. package/dist/toast.cjs.js +1 -1
  252. package/dist/toast.esm.js +1 -1
  253. package/dist/toggle-group.cjs.js +1 -1
  254. package/dist/toggle-group.esm.js +1 -1
  255. package/dist/toggle.cjs.js +1 -1
  256. package/dist/toggle.esm.js +1 -1
  257. package/dist/toolbar.cjs.js +1 -1
  258. package/dist/toolbar.esm.js +1 -1
  259. package/dist/tooltip.cjs.js +1 -1
  260. package/dist/tooltip.esm.js +1 -1
  261. package/dist/transfer-list.cjs.js +1 -1
  262. package/dist/transfer-list.esm.js +1 -1
  263. package/dist/{tree-Deoft-kO.mjs → tree-B_oQput6.mjs} +1 -1
  264. package/dist/{tree-7qbVnpGp.js → tree-SivHxcAy.js} +1 -1
  265. package/dist/tree-item.cjs.js +1 -1
  266. package/dist/tree-item.esm.js +1 -1
  267. package/dist/tree.cjs.js +1 -1
  268. package/dist/tree.esm.js +1 -1
  269. package/dist/{ui-button-BInsgSbr.js → ui-button-BPrzJScZ.js} +5 -5
  270. package/dist/{ui-button-rfiuUnUD.mjs → ui-button-Co8Sid6t.mjs} +11 -7
  271. package/dist/{ui-icon-Bvt9oIIR.js → ui-icon-D3avtxX_.js} +1 -1
  272. package/dist/{ui-icon-BSi_GtqO.mjs → ui-icon-DLhB08Fo.mjs} +1 -1
  273. package/dist/visually-hidden.cjs.js +1 -1
  274. package/dist/visually-hidden.esm.js +1 -1
  275. package/dist/wizard.cjs.js +1 -1
  276. package/dist/wizard.esm.js +1 -1
  277. package/package.json +2 -2
  278. package/dist/ElementBase-EV6mVBUV.js +0 -1
@@ -1,43 +1,106 @@
1
- import { E as ee } from "./ElementBase-YlTLMsGk.mjs";
2
- function te(l, e, t, r = 56, i = 18) {
3
- if (!Number.isFinite(l) || !(t > e)) return 0;
4
- const s = Math.min(r, (t - e) / 2);
5
- return s <= 0 ? 0 : l < e + s ? -Math.ceil(i * Math.min(1, (e + s - l) / s)) : l > t - s ? Math.ceil(i * Math.min(1, (l - (t - s)) / s)) : 0;
1
+ import { E as dt } from "./ElementBase-BeZT54Hj.mjs";
2
+ function K(u, t, e, i = 56, r = 18) {
3
+ if (!Number.isFinite(u) || !(e > t)) return 0;
4
+ const s = Math.min(i, (e - t) / 2);
5
+ return s <= 0 ? 0 : u < t + s ? -Math.ceil(r * Math.min(1, (t + s - u) / s)) : u > e - s ? Math.ceil(r * Math.min(1, (u - (e - s)) / s)) : 0;
6
6
  }
7
- const re = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
8
- function ie(l) {
9
- let e = l;
10
- for (; e; ) {
11
- if (e = e.parentNode instanceof ShadowRoot ? e.parentNode.host : e.parentNode, !(e instanceof HTMLElement)) continue;
12
- if (e === e.ownerDocument.body || e === e.ownerDocument.documentElement) return null;
13
- const { overflowY: t } = e.ownerDocument.defaultView?.getComputedStyle(e) ?? { overflowY: "" };
14
- if (re.has(t) && e.scrollHeight > e.clientHeight) return e;
7
+ const ct = /* @__PURE__ */ new Set(["auto", "scroll", "overlay"]);
8
+ function ut(u) {
9
+ let t = u;
10
+ for (; t; ) {
11
+ if (t = t.parentNode instanceof ShadowRoot ? t.parentNode.host : t.parentNode, !(t instanceof HTMLElement)) continue;
12
+ if (t === t.ownerDocument.body || t === t.ownerDocument.documentElement) return null;
13
+ const { overflowY: e } = t.ownerDocument.defaultView?.getComputedStyle(t) ?? { overflowY: "" };
14
+ if (ct.has(e) && t.scrollHeight > t.clientHeight) return t;
15
15
  }
16
16
  return null;
17
17
  }
18
- const se = 1, oe = 44, ne = 72, ae = `
18
+ const ht = 1, Y = {
19
+ hintHandle: "Use the handle to drag, or press Space on a focused item to start keyboard reordering.",
20
+ hintItem: "Drag from anywhere on an item, or press Space on a focused item to start keyboard reordering.",
21
+ hintCustom: "Use your custom drag handle element, or press Space on a focused item to start keyboard reordering.",
22
+ hintKeyboard: "Keyboard drag active. Use arrow keys to choose a drop target, Space or Enter to drop, and Escape to cancel.",
23
+ hintNestGutter: "To nest an item, hold Alt or drop it on the far side of another.",
24
+ hintNestModifier: "To nest an item, hold Alt while you drop it on another.",
25
+ hintNestArea: "To nest an item, drop it on the middle of another.",
26
+ hintPausedSort: "Dragging is paused while alphabetical sorting is active.",
27
+ hintPausedFilter: "Dragging is paused while the list is filtered.",
28
+ hintDisabled: "Dragging is currently disabled.",
29
+ selectedOne: "item selected",
30
+ selectedMany: "items selected",
31
+ listReadOnly: "This list is read-only.",
32
+ listClone: "Dragging from this list creates a copy.",
33
+ listAccepts: "Accepts drops from: {lists}",
34
+ listFull: "This list is full ({max} items).",
35
+ emptyList: "Drop items here.",
36
+ dropHere: "Drop here",
37
+ nestHere: "Nest here",
38
+ badgeSelected: "Selected",
39
+ badgeClone: "Clone on drag",
40
+ badgePinned: "Pinned",
41
+ dropPreview: "Drop preview",
42
+ copyPreview: "Copy preview",
43
+ releaseMove: "Release to place this item here.",
44
+ releaseMoveMany: "Release to place this selection here.",
45
+ releaseCopy: "Release to add a copy here.",
46
+ movingOne: "Moving item",
47
+ movingMany: "Moving {count} items",
48
+ copyingOne: "Copying item",
49
+ copyingMany: "Copying {count} items",
50
+ announceSelectedMany: "{count} items selected.",
51
+ announceDragDisabled: "Dragging is disabled right now.",
52
+ announceDragging: "Dragging {label}.",
53
+ announceDraggingMany: "Dragging {count} items.",
54
+ announceDraggingCopy: "Dragging {label} as a copy.",
55
+ announceDraggingCopyMany: "Dragging {count} items as a copy.",
56
+ announceCancelled: "Drag cancelled.",
57
+ announceRejected: "That move is not allowed.",
58
+ announceLifted: "Lifted {label}.",
59
+ announceLiftedMany: "Lifted {count} items.",
60
+ announceLiftedHelp: "Use arrow keys to choose a destination.",
61
+ announceCopiedOne: "Item copied into {list}.",
62
+ announceCopiedMany: "{count} items copied into {list}.",
63
+ announceNestedOne: "Item nested in {list}.",
64
+ announceNestedMany: "{count} items nested in {list}.",
65
+ announceMovedOne: "Item moved to {list}.",
66
+ announceMovedMany: "{count} items moved to {list}.",
67
+ announceReorderedOne: "Item reordered in {list}.",
68
+ announceReorderedMany: "{count} items reordered in {list}.",
69
+ targetBefore: "Before {label}",
70
+ targetInside: "Nest inside {label}",
71
+ targetEnd: "End of {list}",
72
+ targetAfterChildren: "After children"
73
+ }, W = 44, Q = 72, Z = 350, pt = 10, gt = `
19
74
  :host {
20
75
  --ui-sortable-accent: var(--ui-color-primary, #2563eb);
21
76
  --ui-sortable-surface: var(--ui-color-surface, #ffffff);
22
- --ui-sortable-surface-muted: color-mix(in srgb, var(--ui-sortable-surface) 92%, #eff6ff);
23
- --ui-sortable-border: color-mix(in srgb, var(--ui-color-border, #cbd5e1) 76%, transparent);
24
77
  --ui-sortable-text: var(--ui-color-text, #0f172a);
25
- --ui-sortable-muted: var(--ui-color-muted, #526175);
26
- --ui-sortable-shadow:
27
- 0 1px 3px rgba(15, 23, 42, 0.06),
28
- 0 16px 34px rgba(15, 23, 42, 0.08);
29
- --ui-sortable-radius: 24px;
30
- --ui-sortable-panel-radius: 18px;
31
- --ui-sortable-item-radius: 16px;
32
- --ui-sortable-handle-radius: 12px;
33
- --ui-sortable-gap: 16px;
34
- --ui-sortable-list-gap: 8px;
35
- --ui-sortable-item-gap: 12px;
36
- --ui-sortable-dropzone-size: 10px;
37
- --ui-sortable-dropzone-inside-size: 16px;
38
- --ui-sortable-dropzone-container-min-block-size: 76px;
78
+ --ui-sortable-muted: var(--ui-color-muted, #5b6778);
79
+ --ui-sortable-lane: color-mix(in srgb, var(--ui-sortable-text) 3.5%, var(--ui-sortable-surface));
80
+ --ui-sortable-card: var(--ui-sortable-surface);
81
+ --ui-sortable-surface-muted: var(--ui-sortable-lane);
82
+ --ui-sortable-border: color-mix(in srgb, var(--ui-color-border, #cbd5e1) 62%, transparent);
83
+ --ui-sortable-border-strong: color-mix(in srgb, var(--ui-sortable-text) 24%, var(--ui-sortable-surface));
84
+ --ui-sortable-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
85
+ --ui-sortable-card-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
86
+ --ui-sortable-card-shadow-hover: 0 3px 10px rgba(15, 23, 42, 0.1);
87
+ --ui-sortable-lift-shadow:
88
+ 0 22px 44px -10px rgba(15, 23, 42, 0.32),
89
+ 0 8px 16px rgba(15, 23, 42, 0.14);
90
+ --ui-sortable-radius: 14px;
91
+ --ui-sortable-panel-radius: 14px;
92
+ --ui-sortable-item-radius: 10px;
93
+ --ui-sortable-handle-radius: 6px;
94
+ --ui-sortable-gap: 12px;
95
+ --ui-sortable-list-gap: 6px;
96
+ --ui-sortable-item-gap: 6px;
97
+ --ui-sortable-list-min-size: 260px;
98
+ --ui-sortable-dropzone-size: 0px;
99
+ --ui-sortable-dropzone-hit-size: 7px;
100
+ --ui-sortable-dropzone-inside-size: 0px;
101
+ --ui-sortable-dropzone-container-min-block-size: 56px;
39
102
  --ui-sortable-dropzone-container-min-inline-size: 180px;
40
- --ui-sortable-indent: 22px;
103
+ --ui-sortable-indent: 16px;
41
104
  display: block;
42
105
  min-inline-size: 0;
43
106
  color: var(--ui-sortable-text);
@@ -52,7 +115,7 @@ const se = 1, oe = 44, ne = 72, ae = `
52
115
 
53
116
  .root {
54
117
  display: grid;
55
- gap: 14px;
118
+ gap: 10px;
56
119
  min-inline-size: 0;
57
120
  }
58
121
 
@@ -61,13 +124,25 @@ const se = 1, oe = 44, ne = 72, ae = `
61
124
  flex-wrap: wrap;
62
125
  align-items: center;
63
126
  justify-content: space-between;
64
- gap: 10px 16px;
127
+ gap: 6px 16px;
65
128
  padding: 0 2px;
66
129
  color: var(--ui-sortable-muted);
67
- font-size: 13px;
130
+ font-size: 12px;
68
131
  line-height: 1.5;
69
132
  }
70
133
 
134
+ /* hide-toolbar: the hint is still what the lists are described by, so it is hidden from sight only. */
135
+ .toolbar[data-hidden="true"] {
136
+ position: absolute;
137
+ inline-size: 1px;
138
+ block-size: 1px;
139
+ margin: -1px;
140
+ padding: 0;
141
+ overflow: hidden;
142
+ clip: rect(0, 0, 0, 0);
143
+ white-space: nowrap;
144
+ }
145
+
71
146
  .helper {
72
147
  display: inline-flex;
73
148
  align-items: center;
@@ -75,40 +150,54 @@ const se = 1, oe = 44, ne = 72, ae = `
75
150
  min-inline-size: 0;
76
151
  }
77
152
 
153
+ .selection-summary[data-count="0"] {
154
+ display: none;
155
+ }
156
+
78
157
  .selection-pill {
79
158
  display: inline-flex;
80
159
  align-items: center;
81
160
  justify-content: center;
82
- min-inline-size: 28px;
83
- min-block-size: 24px;
84
- padding-inline: 8px;
161
+ min-inline-size: 22px;
162
+ min-block-size: 20px;
163
+ padding-inline: 7px;
85
164
  border-radius: 999px;
86
165
  background: color-mix(in srgb, var(--ui-sortable-accent) 14%, transparent);
87
166
  color: color-mix(in srgb, var(--ui-sortable-accent) 84%, var(--ui-sortable-text));
167
+ font-size: 11.5px;
88
168
  font-weight: 700;
89
169
  }
90
170
 
171
+ /* Lists sit side by side and scroll sideways when they do not fit (a board), instead of wrapping onto
172
+ rows. One list fills the width. The padding gives card shadows and focus rings room inside the
173
+ scroller; the negative margin hands that room back to the layout. */
91
174
  .lists {
92
175
  display: grid;
176
+ grid-auto-flow: column;
177
+ grid-auto-columns: minmax(min(var(--ui-sortable-list-min-size), 100%), 1fr);
93
178
  gap: var(--ui-sortable-gap);
94
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
95
179
  min-inline-size: 0;
180
+ padding: 4px;
181
+ margin: -4px;
182
+ overflow: auto hidden;
183
+ overscroll-behavior-x: contain;
184
+ }
185
+
186
+ .lists,
187
+ .items {
188
+ scrollbar-width: thin;
189
+ scrollbar-color: color-mix(in srgb, var(--ui-sortable-text) 28%, transparent) transparent;
96
190
  }
97
191
 
98
192
  .list {
99
193
  display: grid;
100
194
  grid-template-rows: auto 1fr;
101
- gap: 12px;
195
+ gap: 10px;
102
196
  min-inline-size: 0;
103
- padding: 16px;
197
+ padding: 12px;
104
198
  border: 1px solid var(--ui-sortable-border);
105
199
  border-radius: var(--ui-sortable-radius);
106
- background:
107
- linear-gradient(
108
- 180deg,
109
- color-mix(in srgb, var(--ui-sortable-surface) 96%, transparent),
110
- color-mix(in srgb, var(--ui-sortable-accent) 4%, var(--ui-sortable-surface))
111
- );
200
+ background: var(--ui-sortable-lane);
112
201
  box-shadow: var(--ui-sortable-shadow);
113
202
  }
114
203
 
@@ -117,6 +206,7 @@ const se = 1, oe = 44, ne = 72, ae = `
117
206
  flex-wrap: nowrap;
118
207
  overflow: auto hidden;
119
208
  align-items: stretch;
209
+ min-block-size: 0;
120
210
  }
121
211
 
122
212
  /* The cards live inside one root .tree wrapper, which is a vertical grid. Without this the
@@ -126,20 +216,26 @@ const se = 1, oe = 44, ne = 72, ae = `
126
216
  flex-wrap: nowrap;
127
217
  align-items: stretch;
128
218
  min-inline-size: min-content;
219
+ margin-block: 0;
220
+ margin-inline: calc(var(--ui-sortable-list-gap) / -2);
129
221
  }
130
222
 
131
223
  .list[data-orientation="horizontal"] .items > .tree > .item-shell {
132
224
  flex: 0 0 auto;
133
225
  min-inline-size: min(220px, 70vw);
226
+ align-content: start;
227
+ padding-block: 0;
228
+ padding-inline: calc(var(--ui-sortable-list-gap) / 2);
134
229
  }
135
230
 
136
231
  .list[data-disabled="true"] {
137
- opacity: 0.68;
232
+ opacity: 0.62;
138
233
  }
139
234
 
140
235
  .list-header {
141
236
  display: grid;
142
- gap: 4px;
237
+ gap: 2px;
238
+ padding: 2px 4px 0;
143
239
  }
144
240
 
145
241
  .list-custom-header:empty {
@@ -162,9 +258,10 @@ const se = 1, oe = 44, ne = 72, ae = `
162
258
  }
163
259
 
164
260
  .list-label {
165
- font-size: 14px;
261
+ font-size: 13px;
166
262
  line-height: 1.4;
167
- font-weight: 700;
263
+ font-weight: 650;
264
+ letter-spacing: 0.005em;
168
265
  color: var(--ui-sortable-text);
169
266
  }
170
267
 
@@ -172,36 +269,85 @@ const se = 1, oe = 44, ne = 72, ae = `
172
269
  display: inline-flex;
173
270
  align-items: center;
174
271
  justify-content: center;
175
- min-inline-size: 28px;
176
- min-block-size: 24px;
177
- padding-inline: 8px;
272
+ min-inline-size: 22px;
273
+ min-block-size: 20px;
274
+ padding-inline: 7px;
178
275
  border-radius: 999px;
179
- background: color-mix(in srgb, var(--ui-sortable-accent) 10%, transparent);
276
+ background: color-mix(in srgb, var(--ui-sortable-text) 7%, transparent);
180
277
  color: var(--ui-sortable-muted);
181
- font-size: 12px;
182
- font-weight: 700;
278
+ font-size: 11.5px;
279
+ font-weight: 650;
280
+ font-variant-numeric: tabular-nums;
281
+ }
282
+
283
+ /* A list at its maxItems takes nothing more: the count turns to a warning colour. */
284
+ .list[data-full="true"] .list-count {
285
+ background: color-mix(in srgb, var(--ui-sortable-warning, #d97706) 16%, transparent);
286
+ color: color-mix(in srgb, var(--ui-sortable-warning, #d97706) 80%, var(--ui-sortable-text));
183
287
  }
184
288
 
185
289
  .list-description,
186
- .list-helper,
187
- .empty {
290
+ .list-helper {
188
291
  color: var(--ui-sortable-muted);
189
292
  font-size: 12px;
190
- line-height: 1.55;
293
+ line-height: 1.5;
294
+ }
295
+
296
+ .list-helper {
297
+ font-size: 11.5px;
298
+ opacity: 0.85;
299
+ }
300
+
301
+ .empty {
302
+ display: grid;
303
+ place-items: center;
304
+ min-block-size: 64px;
305
+ margin-block: calc(var(--ui-sortable-list-gap) / 2);
306
+ padding: 14px;
307
+ border: 1px dashed var(--ui-sortable-border-strong);
308
+ border-radius: var(--ui-sortable-item-radius);
309
+ color: var(--ui-sortable-muted);
310
+ font-size: 12.5px;
311
+ line-height: 1.5;
312
+ text-align: center;
313
+ transition: border-color 140ms ease, background 140ms ease, color 140ms ease;
314
+ }
315
+
316
+ .empty:has(+ .dropzone[data-active="true"]) {
317
+ border-color: var(--ui-sortable-accent);
318
+ background: color-mix(in srgb, var(--ui-sortable-accent) 7%, transparent);
319
+ color: color-mix(in srgb, var(--ui-sortable-accent) 80%, var(--ui-sortable-text));
191
320
  }
192
321
 
193
322
  .items {
194
323
  display: grid;
195
324
  align-content: start;
196
- gap: var(--ui-sortable-list-gap);
197
- min-block-size: 140px;
325
+ gap: 0;
326
+ min-block-size: 88px;
198
327
  min-inline-size: 0;
199
328
  }
200
329
 
330
+ /* A list with a height of its own scrolls by itself. The padding (and the cards' own spacing) gives shadows and
331
+ focus rings room inside the scroller; the negative margin hands that room back to the layout. The wrapper's
332
+ negative margin is dropped here: inside a scroller it would count as overflow, and a list whose cards all fit
333
+ would still scroll by a few pixels. */
334
+ .items[data-scroll="true"] {
335
+ max-block-size: var(--ui-sortable-list-max-block-size);
336
+ overflow-y: auto;
337
+ overscroll-behavior: contain;
338
+ padding: 1px 4px;
339
+ margin: -4px;
340
+ }
341
+
342
+ .items[data-scroll="true"] > .tree {
343
+ margin-block: 0;
344
+ }
345
+
201
346
  .tree {
202
347
  display: grid;
203
- gap: var(--ui-sortable-list-gap);
348
+ gap: 0;
204
349
  min-inline-size: 0;
350
+ margin-block: calc(var(--ui-sortable-list-gap) / -2);
205
351
  }
206
352
 
207
353
  .list-custom-empty:empty {
@@ -216,169 +362,235 @@ const se = 1, oe = 44, ne = 72, ae = `
216
362
  display: none;
217
363
  }
218
364
 
365
+ /* The cards are spaced by the shell's padding, not by a grid gap: the drop rails between them take
366
+ no height, so the list is as tall as its cards. */
219
367
  .item-shell {
220
368
  display: grid;
221
- gap: 8px;
369
+ gap: 0;
222
370
  min-inline-size: 0;
371
+ padding-block: calc(var(--ui-sortable-list-gap) / 2);
223
372
  }
224
373
 
225
374
  .item {
226
375
  display: grid;
227
376
  grid-template-columns: auto minmax(0, 1fr);
228
- align-items: start;
377
+ align-items: center;
229
378
  gap: var(--ui-sortable-item-gap);
230
379
  min-inline-size: 0;
231
- padding: 12px;
232
- border: 1px solid color-mix(in srgb, var(--ui-sortable-border) 82%, transparent);
380
+ padding: 9px 12px 9px 6px;
381
+ border: 1px solid var(--ui-sortable-border);
233
382
  border-radius: var(--ui-sortable-item-radius);
234
- background: var(--ui-sortable-surface-muted);
235
- box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
236
- will-change: transform, opacity, box-shadow, border-color, background;
383
+ background: var(--ui-sortable-card);
384
+ box-shadow: var(--ui-sortable-card-shadow);
237
385
  transition:
238
- transform 180ms ease,
239
- opacity 180ms ease,
240
- box-shadow 180ms ease,
241
- border-color 180ms ease,
242
- background 180ms ease;
386
+ opacity 160ms ease,
387
+ box-shadow 160ms ease,
388
+ border-color 160ms ease,
389
+ background 160ms ease;
390
+ }
391
+
392
+ .item:hover {
393
+ border-color: var(--ui-sortable-border-strong);
394
+ box-shadow: var(--ui-sortable-card-shadow-hover);
395
+ }
396
+
397
+ .item:focus {
398
+ outline: none;
399
+ }
400
+
401
+ .item:focus-visible {
402
+ outline: 2px solid var(--ui-sortable-accent);
403
+ outline-offset: 2px;
243
404
  }
244
405
 
245
406
  .item[data-drag-handle-mode="item"],
246
407
  .item[data-drag-handle-mode="custom"] {
247
408
  grid-template-columns: minmax(0, 1fr);
409
+ padding-inline-start: 12px;
248
410
  }
249
411
 
250
412
  .item[data-drag-handle-mode="item"] {
251
413
  cursor: grab;
252
414
  }
253
415
 
416
+ /* A card that is dragged by its body is held to lift on touch: no text selection or callout while holding. */
417
+ .item[data-drag-handle-mode="item"],
418
+ .item[data-drag-handle-mode="custom"] {
419
+ -webkit-user-select: none;
420
+ user-select: none;
421
+ -webkit-touch-callout: none;
422
+ }
423
+
254
424
  .item[data-drag-handle-mode="item"][data-dragging="true"] {
255
425
  cursor: grabbing;
256
426
  }
257
427
 
258
428
  .item[data-selected="true"] {
259
- border-color: color-mix(in srgb, var(--ui-sortable-accent) 32%, var(--ui-sortable-border));
260
- background: color-mix(in srgb, var(--ui-sortable-accent) 11%, var(--ui-sortable-surface));
429
+ border-color: color-mix(in srgb, var(--ui-sortable-accent) 60%, var(--ui-sortable-border));
430
+ background: color-mix(in srgb, var(--ui-sortable-accent) 7%, var(--ui-sortable-card));
261
431
  box-shadow:
262
- 0 0 0 1px color-mix(in srgb, var(--ui-sortable-accent) 10%, transparent),
263
- 0 10px 24px rgba(15, 23, 42, 0.08);
264
- }
265
-
266
- .item[data-focused="true"] {
267
- border-color: color-mix(in srgb, var(--ui-sortable-accent) 42%, var(--ui-sortable-border));
268
- box-shadow:
269
- 0 0 0 3px color-mix(in srgb, var(--ui-sortable-accent) 12%, transparent),
270
- 0 10px 24px rgba(15, 23, 42, 0.08);
432
+ 0 0 0 1px color-mix(in srgb, var(--ui-sortable-accent) 28%, transparent),
433
+ var(--ui-sortable-card-shadow);
271
434
  }
272
435
 
273
436
  .item[data-drop-inside-active="true"] {
274
- border-color: color-mix(in srgb, var(--ui-sortable-accent) 48%, var(--ui-sortable-border));
275
- background:
276
- linear-gradient(
277
- 180deg,
278
- color-mix(in srgb, var(--ui-sortable-accent) 14%, var(--ui-sortable-surface)),
279
- color-mix(in srgb, var(--ui-sortable-accent) 10%, var(--ui-sortable-surface-muted))
280
- );
437
+ border-color: var(--ui-sortable-accent);
438
+ background: color-mix(in srgb, var(--ui-sortable-accent) 10%, var(--ui-sortable-card));
281
439
  box-shadow:
282
- 0 0 0 3px color-mix(in srgb, var(--ui-sortable-accent) 12%, transparent),
283
- 0 14px 30px rgba(15, 23, 42, 0.1);
440
+ 0 0 0 3px color-mix(in srgb, var(--ui-sortable-accent) 20%, transparent),
441
+ var(--ui-sortable-card-shadow);
284
442
  }
285
443
 
444
+ /* While a card is being dragged its place in the list stays as an empty slot, so the list does not
445
+ jump; the card itself is the ghost that follows the pointer. */
286
446
  .item[data-dragging="true"] {
287
- opacity: 0.48;
288
- transform: scale(0.985);
289
- transition-duration: 0ms, 180ms, 180ms, 180ms, 180ms;
447
+ border-style: dashed;
448
+ border-color: color-mix(in srgb, var(--ui-sortable-accent) 45%, var(--ui-sortable-border));
449
+ background: color-mix(in srgb, var(--ui-sortable-accent) 5%, var(--ui-sortable-card));
450
+ box-shadow: none;
451
+ }
452
+
453
+ .item[data-dragging="true"] > * {
454
+ visibility: hidden;
290
455
  }
291
456
 
457
+ /* The keyboard drag shows the card at its destination as a quiet dashed card. */
292
458
  .item.item-placeholder {
293
459
  grid-template-columns: 1fr;
460
+ padding-inline-start: 12px;
294
461
  border-style: dashed;
295
- border-color: color-mix(in srgb, var(--ui-sortable-accent) 50%, var(--ui-sortable-border));
296
- background:
297
- linear-gradient(
298
- 180deg,
299
- color-mix(in srgb, var(--ui-sortable-accent) 10%, var(--ui-sortable-surface)),
300
- color-mix(in srgb, var(--ui-sortable-accent) 6%, var(--ui-sortable-surface-muted))
301
- );
302
- box-shadow:
303
- inset 0 0 0 1px color-mix(in srgb, var(--ui-sortable-accent) 18%, transparent),
304
- 0 12px 26px rgba(15, 23, 42, 0.08);
462
+ border-color: color-mix(in srgb, var(--ui-sortable-accent) 55%, var(--ui-sortable-border));
463
+ background: color-mix(in srgb, var(--ui-sortable-accent) 7%, var(--ui-sortable-card));
464
+ box-shadow: none;
305
465
  }
306
466
 
307
467
  .placeholder-content {
308
468
  display: grid;
309
- gap: 6px;
469
+ gap: 3px;
310
470
  min-inline-size: 0;
311
471
  }
312
472
 
313
473
  .placeholder-kicker {
314
- font-size: 11px;
474
+ font-size: 10.5px;
315
475
  line-height: 1.4;
316
476
  font-weight: 700;
317
477
  letter-spacing: 0.08em;
318
478
  text-transform: uppercase;
319
- color: color-mix(in srgb, var(--ui-sortable-accent) 72%, var(--ui-sortable-text));
479
+ color: color-mix(in srgb, var(--ui-sortable-accent) 78%, var(--ui-sortable-text));
320
480
  }
321
481
 
322
482
  .placeholder-title {
323
- font-size: 14px;
483
+ font-size: 13.5px;
324
484
  line-height: 1.4;
325
- font-weight: 700;
485
+ font-weight: 600;
326
486
  color: var(--ui-sortable-text);
327
487
  }
328
488
 
329
489
  .placeholder-description {
330
490
  color: var(--ui-sortable-muted);
331
491
  font-size: 12px;
332
- line-height: 1.55;
492
+ line-height: 1.5;
333
493
  }
334
494
 
335
- .drag-preview-overlay {
495
+ /* The card that follows the pointer: a copy of the real card, lifted. */
496
+ .item.item-ghost {
336
497
  position: fixed;
337
- inset: auto auto auto auto;
338
- top: -9999px;
339
- left: -9999px;
340
- z-index: 2147483646;
498
+ inset: 0 auto auto 0;
499
+ z-index: 2147483647;
341
500
  box-sizing: border-box;
342
- inline-size: min(320px, calc(100vw - 32px));
343
- padding: 12px;
344
- border: 1px dashed color-mix(in srgb, var(--ui-sortable-accent) 50%, var(--ui-sortable-border));
345
- border-radius: var(--ui-sortable-item-radius);
346
- background:
347
- linear-gradient(
348
- 180deg,
349
- color-mix(in srgb, var(--ui-sortable-accent) 10%, var(--ui-sortable-surface)),
350
- color-mix(in srgb, var(--ui-sortable-accent) 6%, var(--ui-sortable-surface-muted))
351
- );
352
- box-shadow:
353
- inset 0 0 0 1px color-mix(in srgb, var(--ui-sortable-accent) 18%, transparent),
354
- 0 18px 40px rgba(15, 23, 42, 0.12);
501
+ max-inline-size: calc(100vw - 16px);
502
+ margin: 0;
355
503
  pointer-events: none;
356
- opacity: 0;
357
- transition: opacity 120ms ease;
504
+ cursor: grabbing;
505
+ border-color: color-mix(in srgb, var(--ui-sortable-accent) 55%, var(--ui-sortable-border));
506
+ background: var(--ui-sortable-card);
507
+ box-shadow: var(--ui-sortable-lift-shadow);
508
+ rotate: 1.2deg;
509
+ scale: 1.025;
510
+ transition: none;
511
+ will-change: transform;
512
+ animation: ui-sortable-lift 150ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
358
513
  }
359
514
 
360
- .drag-preview-overlay[data-visible="true"] {
515
+ .item.item-ghost[data-count="stack"] {
516
+ box-shadow:
517
+ 5px 5px 0 -1px var(--ui-sortable-card),
518
+ 5px 5px 0 0 var(--ui-sortable-border-strong),
519
+ 10px 10px 0 -2px var(--ui-sortable-card),
520
+ 10px 10px 0 -1px var(--ui-sortable-border-strong),
521
+ var(--ui-sortable-lift-shadow);
522
+ }
523
+
524
+ .item.item-ghost[data-refused] {
525
+ border-color: var(--ui-sortable-danger, #dc2626);
526
+ box-shadow:
527
+ 0 0 0 3px color-mix(in srgb, var(--ui-sortable-danger, #dc2626) 22%, transparent),
528
+ var(--ui-sortable-lift-shadow);
529
+ }
530
+
531
+ .item.item-ghost[data-refused] .handle {
532
+ color: var(--ui-sortable-danger, #dc2626);
533
+ }
534
+
535
+ .item.item-ghost .handle {
361
536
  opacity: 1;
537
+ color: var(--ui-sortable-accent);
538
+ cursor: grabbing;
362
539
  }
363
540
 
364
- .drag-preview-overlay .placeholder-description {
365
- display: inline-block;
366
- max-inline-size: 190px;
367
- padding: 4px 8px;
368
- border-radius: 10px;
369
- background: color-mix(in srgb, var(--ui-sortable-surface) 94%, white 6%);
370
- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-sortable-border) 72%, transparent);
371
- color: color-mix(in srgb, var(--ui-sortable-text) 84%, var(--ui-sortable-accent));
372
- font-weight: 500;
541
+ .item.item-ghost[data-compact="true"] .item-description,
542
+ .item.item-ghost[data-compact="true"] .item-meta {
543
+ display: none;
544
+ }
545
+
546
+ .ghost-badge {
547
+ position: absolute;
548
+ inset-block-start: -9px;
549
+ inset-inline-end: -9px;
550
+ min-inline-size: 22px;
551
+ block-size: 22px;
552
+ padding-inline: 6px;
553
+ box-sizing: border-box;
554
+ border-radius: 999px;
555
+ background: var(--ui-sortable-accent);
556
+ color: var(--ui-sortable-accent-contrast, #ffffff);
557
+ font-size: 11px;
558
+ font-weight: 700;
559
+ line-height: 22px;
560
+ text-align: center;
561
+ box-shadow: 0 0 0 2px var(--ui-sortable-card);
562
+ }
563
+
564
+ /* Fallback when the dragged card cannot be copied. */
565
+ .drag-pill {
566
+ position: fixed;
567
+ inset: 0 auto auto 0;
568
+ z-index: 2147483647;
569
+ padding: 8px 12px;
570
+ border-radius: 999px;
571
+ background: var(--ui-sortable-text);
572
+ color: var(--ui-sortable-surface);
573
+ font-size: 12px;
574
+ font-weight: 600;
575
+ line-height: 1;
576
+ pointer-events: none;
577
+ box-shadow: var(--ui-sortable-lift-shadow);
578
+ }
579
+
580
+ @keyframes ui-sortable-lift {
581
+ from {
582
+ rotate: 0deg;
583
+ scale: 1;
584
+ }
373
585
  }
374
586
 
375
587
  .item[data-disabled="true"] {
376
- opacity: 0.58;
588
+ opacity: 0.55;
377
589
  }
378
590
 
379
591
  .item-content {
380
592
  display: grid;
381
- gap: 4px;
593
+ gap: 2px;
382
594
  min-inline-size: 0;
383
595
  }
384
596
 
@@ -409,9 +621,9 @@ const se = 1, oe = 44, ne = 72, ae = `
409
621
  }
410
622
 
411
623
  .item-title {
412
- font-size: 14px;
624
+ font-size: 13.5px;
413
625
  line-height: 1.4;
414
- font-weight: 700;
626
+ font-weight: 600;
415
627
  color: var(--ui-sortable-text);
416
628
  overflow-wrap: anywhere;
417
629
  }
@@ -419,35 +631,41 @@ const se = 1, oe = 44, ne = 72, ae = `
419
631
  .item-description {
420
632
  color: var(--ui-sortable-muted);
421
633
  font-size: 12px;
422
- line-height: 1.55;
634
+ line-height: 1.5;
423
635
  overflow-wrap: anywhere;
424
636
  }
425
637
 
426
638
  .item-meta {
427
639
  display: flex;
428
640
  flex-wrap: wrap;
429
- gap: 6px;
641
+ gap: 4px;
642
+ }
643
+
644
+ .item-meta:has(.item-badge:not([hidden]):not(.drop-badge)),
645
+ .item[data-drop-inside-active="true"] .item-meta {
646
+ margin-block-start: 4px;
430
647
  }
431
648
 
432
649
  .item-badge {
433
650
  display: inline-flex;
434
651
  align-items: center;
435
652
  gap: 6px;
436
- padding: 4px 8px;
653
+ padding: 1px 7px;
437
654
  border-radius: 999px;
438
- background: color-mix(in srgb, var(--ui-sortable-accent) 10%, transparent);
655
+ background: color-mix(in srgb, var(--ui-sortable-text) 6%, transparent);
439
656
  color: var(--ui-sortable-muted);
440
- font-size: 11px;
657
+ font-size: 10.5px;
441
658
  font-weight: 600;
659
+ line-height: 1.6;
442
660
  }
443
661
 
444
- .item-badge[hidden] {
445
- display: none;
662
+ .item-badge.selection-badge {
663
+ background: color-mix(in srgb, var(--ui-sortable-accent) 14%, transparent);
664
+ color: color-mix(in srgb, var(--ui-sortable-accent) 82%, var(--ui-sortable-text));
446
665
  }
447
666
 
448
- .item[data-drop-inside-active="true"] .item-badge.drop-badge {
449
- background: color-mix(in srgb, var(--ui-sortable-accent) 18%, var(--ui-sortable-surface));
450
- color: color-mix(in srgb, var(--ui-sortable-accent) 78%, var(--ui-sortable-text));
667
+ .item-badge[hidden] {
668
+ display: none;
451
669
  }
452
670
 
453
671
  .item-badge.drop-badge {
@@ -456,263 +674,220 @@ const se = 1, oe = 44, ne = 72, ae = `
456
674
 
457
675
  .item[data-drop-inside-active="true"] .item-badge.drop-badge {
458
676
  display: inline-flex;
677
+ background: color-mix(in srgb, var(--ui-sortable-accent) 18%, var(--ui-sortable-card));
678
+ color: color-mix(in srgb, var(--ui-sortable-accent) 80%, var(--ui-sortable-text));
459
679
  }
460
680
 
681
+ /* A quiet grip: faint until the card is hovered, focused, selected or dragged. */
461
682
  .handle {
462
683
  display: inline-grid;
463
684
  place-items: center;
464
- inline-size: 34px;
465
- block-size: 34px;
685
+ inline-size: 22px;
686
+ block-size: 28px;
466
687
  margin: 0;
467
688
  padding: 0;
468
- border: 1px solid color-mix(in srgb, var(--ui-sortable-border) 86%, transparent);
689
+ border: 0;
469
690
  border-radius: var(--ui-sortable-handle-radius);
470
- background: color-mix(in srgb, var(--ui-sortable-surface) 92%, transparent);
691
+ background: transparent;
471
692
  color: var(--ui-sortable-muted);
693
+ opacity: 0.4;
472
694
  cursor: grab;
473
695
  touch-action: none;
474
696
  user-select: none;
475
697
  -webkit-user-select: none;
476
698
  transition:
477
- transform 160ms ease,
478
- color 160ms ease,
479
- border-color 160ms ease,
480
- background 160ms ease;
699
+ opacity 140ms ease,
700
+ color 140ms ease,
701
+ background 140ms ease;
702
+ }
703
+
704
+ .item:hover .handle,
705
+ .item:focus-visible .handle,
706
+ .item[data-selected="true"] .handle {
707
+ opacity: 1;
481
708
  }
482
709
 
483
710
  .handle:hover {
484
- color: color-mix(in srgb, var(--ui-sortable-accent) 80%, var(--ui-sortable-text));
485
- border-color: color-mix(in srgb, var(--ui-sortable-accent) 26%, var(--ui-sortable-border));
486
- background: color-mix(in srgb, var(--ui-sortable-accent) 8%, var(--ui-sortable-surface));
711
+ color: var(--ui-sortable-text);
712
+ background: color-mix(in srgb, var(--ui-sortable-text) 8%, transparent);
487
713
  }
488
714
 
489
715
  .handle:active {
490
716
  cursor: grabbing;
491
- transform: scale(0.96);
492
717
  }
493
718
 
494
719
  .handle[disabled] {
495
720
  cursor: not-allowed;
496
- opacity: 0.48;
721
+ opacity: 0.25;
497
722
  }
498
723
 
499
724
  .handle svg {
500
- inline-size: 16px;
501
- block-size: 16px;
725
+ inline-size: 14px;
726
+ block-size: 14px;
727
+ fill: currentColor;
502
728
  }
503
729
 
730
+ /* Nested cards hang off a guide line under their parent. */
504
731
  .children {
505
732
  display: grid;
506
- gap: var(--ui-sortable-list-gap);
507
- padding-inline-start: var(--ui-sortable-indent);
733
+ gap: 0;
508
734
  min-inline-size: 0;
735
+ margin-inline-start: 11px;
736
+ padding-block-start: calc(var(--ui-sortable-list-gap) / 2);
737
+ padding-inline-start: var(--ui-sortable-indent);
738
+ border-inline-start: 1px solid var(--ui-sortable-border-strong);
509
739
  }
510
740
 
741
+ /* Drop rails take no height: they are the thin lines between cards, with an invisible hit area
742
+ around them. The line shows only on the rail the pointer is over. */
511
743
  .dropzone {
512
744
  position: relative;
513
745
  display: block;
746
+ block-size: var(--ui-sortable-dropzone-size);
514
747
  min-block-size: var(--ui-sortable-dropzone-size);
515
748
  min-inline-size: 0;
516
- border-radius: 999px;
517
- will-change: opacity, background;
518
- transition: opacity 140ms ease, background 140ms ease;
519
- }
520
-
521
- .root[data-dropzone-style="container"] .dropzone {
522
- display: grid;
523
- place-items: center;
524
- min-block-size: var(--ui-sortable-dropzone-match-block-size, var(--ui-sortable-dropzone-container-min-block-size));
525
- inline-size: min(100%, var(--ui-sortable-dropzone-match-inline-size, 100%));
526
- max-inline-size: var(--ui-sortable-dropzone-container-max-inline-size, none);
527
- padding: 12px;
528
- border: 1px dashed color-mix(in srgb, var(--ui-sortable-accent) 40%, var(--ui-sortable-border));
529
- border-radius: var(--ui-sortable-item-radius);
530
- background:
531
- linear-gradient(
532
- 180deg,
533
- color-mix(in srgb, var(--ui-sortable-accent) 9%, var(--ui-sortable-surface)),
534
- color-mix(in srgb, var(--ui-sortable-accent) 5%, var(--ui-sortable-surface-muted))
535
- );
536
- box-shadow:
537
- inset 0 0 0 1px color-mix(in srgb, var(--ui-sortable-accent) 12%, transparent),
538
- 0 8px 18px rgba(15, 23, 42, 0.05);
539
- opacity: 0.82;
540
- overflow: hidden;
541
- }
542
-
543
- .list[data-orientation="horizontal"] .dropzone {
544
- min-block-size: auto;
545
- min-inline-size: 16px;
546
- align-self: stretch;
547
- }
548
-
549
- .root[data-dropzone-style="container"] .list[data-orientation="horizontal"] .dropzone {
550
- min-block-size: var(--ui-sortable-dropzone-match-block-size, var(--ui-sortable-dropzone-container-min-block-size));
551
- min-inline-size: var(--ui-sortable-dropzone-match-inline-size, var(--ui-sortable-dropzone-container-min-inline-size));
552
- inline-size: auto;
553
- align-self: stretch;
554
749
  }
555
750
 
556
751
  .dropzone::before {
557
752
  content: '';
558
753
  position: absolute;
559
- inset-block-start: 50%;
754
+ inset-block-start: 0;
560
755
  inset-inline: 0;
561
756
  block-size: 2px;
562
- transform: translateY(-50%) scaleX(0.42);
563
- transform-origin: center;
757
+ margin-block-start: -1px;
564
758
  border-radius: 999px;
565
- background: color-mix(in srgb, var(--ui-sortable-accent) 22%, transparent);
566
- transition: transform 160ms ease, background 160ms ease;
759
+ background: var(--ui-sortable-accent);
760
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--ui-sortable-accent) 20%, transparent);
761
+ opacity: 0;
762
+ transform: scaleX(0.35);
763
+ transform-origin: center;
764
+ transition: opacity 120ms ease, transform 160ms cubic-bezier(0.2, 0.8, 0.2, 1);
567
765
  }
568
766
 
569
- .list[data-orientation="horizontal"] .dropzone::before {
570
- inset-block: 0;
571
- inset-inline-start: 50%;
572
- inset-inline-end: auto;
573
- inline-size: 2px;
574
- block-size: 100%;
575
- transform: translateX(-50%) scaleY(0.24);
767
+ .dropzone::after {
768
+ content: '';
769
+ position: absolute;
770
+ inset-inline: 0;
771
+ inset-block: calc(var(--ui-sortable-dropzone-hit-size) * -1);
576
772
  }
577
773
 
578
- .dropzone[data-active="true"] {
579
- opacity: 1;
774
+ /* The last rail of a group only reaches up: below the last card the list body is already a drop area, and a
775
+ hit area hanging out of the bottom would count as overflow in a list that scrolls. */
776
+ .dropzone:last-child::after {
777
+ inset-block-end: 0;
580
778
  }
581
779
 
582
- .root[data-dropzone-style="container"] .dropzone[data-active="true"] {
583
- border-color: color-mix(in srgb, var(--ui-sortable-accent) 56%, var(--ui-sortable-border));
584
- background:
585
- linear-gradient(
586
- 180deg,
587
- color-mix(in srgb, var(--ui-sortable-accent) 14%, var(--ui-sortable-surface)),
588
- color-mix(in srgb, var(--ui-sortable-accent) 10%, var(--ui-sortable-surface-muted))
589
- );
590
- box-shadow:
591
- inset 0 0 0 1px color-mix(in srgb, var(--ui-sortable-accent) 16%, transparent),
592
- 0 12px 24px rgba(15, 23, 42, 0.08);
780
+ .dropzone[data-active="true"]::before {
781
+ opacity: 1;
782
+ transform: scaleX(1);
593
783
  }
594
784
 
595
- .list[data-orientation="horizontal"] .dropzone[data-active="true"] {
785
+ .root[data-drop-indicator-visibility="always"] .dropzone::before {
596
786
  opacity: 1;
787
+ transform: scaleX(1);
788
+ background: color-mix(in srgb, var(--ui-sortable-accent) 22%, transparent);
789
+ box-shadow: none;
597
790
  }
598
791
 
599
- .dropzone[data-active="true"]::before {
600
- transform: translateY(-50%) scaleX(1);
601
- background: color-mix(in srgb, var(--ui-sortable-accent) 86%, var(--ui-sortable-text));
792
+ .root[data-drop-indicator-visibility="always"] .dropzone[data-active="true"]::before {
793
+ background: var(--ui-sortable-accent);
794
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--ui-sortable-accent) 20%, transparent);
602
795
  }
603
796
 
604
- .list[data-orientation="horizontal"] .dropzone[data-active="true"]::before {
605
- transform: translateX(-50%) scaleY(1);
797
+ /* A card shows "drop inside" by highlighting itself, so its inside rail draws nothing. */
798
+ .root[data-dropzone-style="indicator"] .dropzone[data-mode="inside"]::before,
799
+ .root[data-dropzone-style="indicator"] .dropzone[data-mode="inside"]::after {
800
+ display: none;
606
801
  }
607
802
 
608
- .dropzone[data-mode="inside"] {
609
- min-block-size: var(--ui-sortable-dropzone-inside-size);
610
- margin-block-start: -2px;
611
- padding-inline-start: 6px;
803
+ .list[data-orientation="horizontal"] .dropzone {
804
+ align-self: stretch;
805
+ block-size: auto;
806
+ min-block-size: 0;
807
+ inline-size: var(--ui-sortable-dropzone-size);
808
+ min-inline-size: var(--ui-sortable-dropzone-size);
612
809
  }
613
810
 
614
- .root[data-dropzone-style="container"] .dropzone[data-mode="inside"] {
615
- min-block-size: max(
616
- calc(var(--ui-sortable-dropzone-match-block-size, var(--ui-sortable-dropzone-container-min-block-size)) * 0.78),
617
- var(--ui-sortable-dropzone-container-min-block-size)
618
- );
811
+ .list[data-orientation="horizontal"] .dropzone::before {
812
+ inset-block: 0;
813
+ inset-inline: auto;
814
+ inset-inline-start: 0;
815
+ inline-size: 2px;
816
+ block-size: auto;
619
817
  margin-block-start: 0;
620
- padding-inline-start: 12px;
818
+ margin-inline-start: -1px;
819
+ transform: scaleY(0.35);
621
820
  }
622
821
 
623
- .dropzone[data-mode="inside"]::before {
624
- inset-inline-start: 8px;
625
- inset-inline-end: auto;
626
- inline-size: 42px;
822
+ .list[data-orientation="horizontal"] .dropzone::after {
823
+ inset-block: 0;
824
+ inset-inline: calc(var(--ui-sortable-dropzone-hit-size) * -1);
627
825
  }
628
826
 
629
- .dropzone-label {
630
- position: absolute;
631
- inset-block-start: 50%;
632
- inset-inline-start: 50%;
633
- inset-inline-end: auto;
634
- transform: translate(-50%, -50%) scale(0.98);
635
- padding: 2px 8px;
636
- border-radius: 999px;
637
- background: color-mix(in srgb, var(--ui-sortable-surface) 84%, transparent);
638
- color: var(--ui-sortable-muted);
639
- font-size: 11px;
640
- opacity: 0;
641
- transition: opacity 120ms ease, transform 120ms ease;
642
- pointer-events: none;
827
+ .list[data-orientation="horizontal"] .dropzone[data-active="true"]::before,
828
+ .root[data-drop-indicator-visibility="always"] .list[data-orientation="horizontal"] .dropzone::before {
829
+ transform: scaleY(1);
643
830
  }
644
831
 
645
- .root[data-dropzone-style="container"] .dropzone::before {
832
+ .dropzone-label {
646
833
  display: none;
647
834
  }
648
835
 
649
- .root[data-dropzone-style="container"] .dropzone-label {
650
- position: static;
651
- inset: auto;
652
- transform: none;
653
- padding: 0;
654
- border-radius: 0;
655
- background: transparent;
656
- color: color-mix(in srgb, var(--ui-sortable-accent) 76%, var(--ui-sortable-text));
657
- font-size: 12px;
658
- font-weight: 700;
659
- letter-spacing: 0.02em;
660
- opacity: 1;
661
- white-space: nowrap;
836
+ /* dropzone-style="container": the target is drawn as a whole dashed card in place. */
837
+ .root[data-dropzone-style="container"] .dropzone {
838
+ display: grid;
839
+ place-items: center;
840
+ block-size: auto;
841
+ min-block-size: var(--ui-sortable-dropzone-match-block-size, var(--ui-sortable-dropzone-container-min-block-size));
842
+ inline-size: min(100%, var(--ui-sortable-dropzone-match-inline-size, 100%));
843
+ max-inline-size: var(--ui-sortable-dropzone-container-max-inline-size, none);
844
+ padding: 10px;
845
+ border: 1px dashed color-mix(in srgb, var(--ui-sortable-accent) 45%, var(--ui-sortable-border));
846
+ border-radius: var(--ui-sortable-item-radius);
847
+ background: color-mix(in srgb, var(--ui-sortable-accent) 5%, var(--ui-sortable-card));
848
+ opacity: 0.85;
849
+ overflow: hidden;
662
850
  }
663
851
 
664
- .dropzone[data-active="true"] .dropzone-label {
665
- opacity: 1;
666
- transform: translate(-50%, -50%) scale(1);
852
+ .root[data-dropzone-style="container"] .list[data-orientation="horizontal"] .dropzone {
853
+ min-block-size: var(--ui-sortable-dropzone-match-block-size, var(--ui-sortable-dropzone-container-min-block-size));
854
+ min-inline-size: var(--ui-sortable-dropzone-match-inline-size, var(--ui-sortable-dropzone-container-min-inline-size));
855
+ inline-size: auto;
667
856
  }
668
857
 
669
- .root[data-drag-preview="true"] .dropzone-label {
670
- opacity: 0;
858
+ .root[data-dropzone-style="container"] .dropzone::before,
859
+ .root[data-dropzone-style="container"] .dropzone::after {
860
+ display: none;
671
861
  }
672
862
 
673
- .root[data-dropzone-style="container"][data-drag-preview="true"] .dropzone-label {
863
+ .root[data-dropzone-style="container"] .dropzone[data-active="true"] {
674
864
  opacity: 1;
865
+ border-color: var(--ui-sortable-accent);
866
+ background: color-mix(in srgb, var(--ui-sortable-accent) 10%, var(--ui-sortable-card));
675
867
  }
676
868
 
677
- .root[data-drop-indicator-visibility="active"] .dropzone {
678
- opacity: 0;
869
+ .root[data-dropzone-style="container"] .dropzone[data-mode="inside"] {
870
+ min-block-size: max(
871
+ calc(var(--ui-sortable-dropzone-match-block-size, var(--ui-sortable-dropzone-container-min-block-size)) * 0.78),
872
+ var(--ui-sortable-dropzone-container-min-block-size)
873
+ );
874
+ }
875
+
876
+ .root[data-dropzone-style="container"] .dropzone-label {
877
+ display: block;
878
+ color: color-mix(in srgb, var(--ui-sortable-accent) 80%, var(--ui-sortable-text));
879
+ font-size: 12px;
880
+ font-weight: 650;
881
+ letter-spacing: 0.02em;
882
+ white-space: nowrap;
679
883
  }
680
884
 
681
885
  .root[data-dropzone-style="container"][data-drop-indicator-visibility="active"] .dropzone {
682
886
  display: none;
683
- opacity: 0;
684
887
  }
685
888
 
686
889
  .root[data-dropzone-style="container"][data-drop-indicator-visibility="active"] .dropzone[data-active="true"] {
687
890
  display: grid;
688
- opacity: 1;
689
- }
690
-
691
- .root[data-drop-indicator-visibility="active"] .dropzone::before {
692
- background: transparent;
693
- transform: translateY(-50%) scaleX(0.16);
694
- }
695
-
696
- .root[data-drop-indicator-visibility="active"] .list[data-orientation="horizontal"] .dropzone::before {
697
- transform: translateX(-50%) scaleY(0.16);
698
- }
699
-
700
- .root[data-drop-indicator-visibility="active"] .dropzone[data-active="true"] {
701
- opacity: 1;
702
- }
703
-
704
- .root[data-drop-indicator-visibility="active"] .dropzone[data-active="true"]::before {
705
- transform: translateY(-50%) scaleX(1);
706
- background: color-mix(in srgb, var(--ui-sortable-accent) 86%, var(--ui-sortable-text));
707
- }
708
-
709
- .root[data-drop-indicator-visibility="active"] .list[data-orientation="horizontal"] .dropzone[data-active="true"]::before {
710
- transform: translateX(-50%) scaleY(1);
711
- }
712
-
713
- .root[data-drop-indicator-visibility="active"] .dropzone[data-active="true"] .dropzone-label {
714
- opacity: 1;
715
- transform: translate(-50%, -50%) scale(1);
716
891
  }
717
892
 
718
893
  .sr-only {
@@ -727,14 +902,26 @@ const se = 1, oe = 44, ne = 72, ae = `
727
902
  border: 0;
728
903
  }
729
904
 
905
+ /* Touch screens have no hover: keep the grip clearly visible. */
906
+ @media (hover: none) {
907
+ .handle {
908
+ opacity: 1;
909
+ }
910
+ }
911
+
730
912
  @media (prefers-reduced-motion: reduce) {
731
913
  .item,
732
914
  .handle,
733
- .dropzone,
734
- .dropzone::before,
735
- .dropzone-label {
915
+ .empty,
916
+ .dropzone::before {
736
917
  transition: none;
737
918
  }
919
+
920
+ .item.item-ghost {
921
+ animation: none;
922
+ rotate: 0deg;
923
+ scale: 1;
924
+ }
738
925
  }
739
926
 
740
927
  @media (forced-colors: active) {
@@ -747,257 +934,294 @@ const se = 1, oe = 44, ne = 72, ae = `
747
934
  border-color: CanvasText;
748
935
  }
749
936
 
937
+ .item[data-selected="true"],
938
+ .item:focus-visible {
939
+ outline: 2px solid Highlight;
940
+ }
941
+
750
942
  .dropzone::before {
751
943
  background: Highlight;
944
+ box-shadow: none;
752
945
  }
753
946
  }
754
947
  `;
755
- function K(l) {
756
- if (!l) return [];
948
+ function V(u) {
949
+ if (!u) return [];
757
950
  try {
758
- const e = JSON.parse(l);
759
- return Array.isArray(e) ? e : [];
951
+ const t = JSON.parse(u);
952
+ return Array.isArray(t) ? t : [];
760
953
  } catch {
761
954
  return [];
762
955
  }
763
956
  }
764
- function I(l) {
765
- return l.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
957
+ function tt(u) {
958
+ if (u === void 0) return "";
959
+ let t;
960
+ try {
961
+ t = JSON.stringify(u) ?? "";
962
+ } catch {
963
+ return "";
964
+ }
965
+ let e = 5381;
966
+ for (let i = 0; i < t.length; i += 1) e = (e << 5) + e + t.charCodeAt(i) | 0;
967
+ return (e >>> 0).toString(36);
766
968
  }
767
- function k(l, e) {
768
- return `${l}::${e ?? "__root__"}`;
969
+ function mt(u) {
970
+ if (!u) return {};
971
+ try {
972
+ const t = JSON.parse(u);
973
+ if (!t || typeof t != "object" || Array.isArray(t)) return {};
974
+ const e = {};
975
+ return Object.keys(Y).forEach((i) => {
976
+ typeof t[i] == "string" && (e[i] = t[i]);
977
+ }), e;
978
+ } catch {
979
+ return {};
980
+ }
769
981
  }
770
- function j(l) {
771
- return l ? [l.listId, l.parentId ?? "", l.beforeId ?? "", l.mode].join("::") : "";
982
+ function ot(u) {
983
+ if (typeof u == "number") return Number.isFinite(u) && u > 0 ? `${u}px` : void 0;
984
+ if (typeof u != "string") return;
985
+ const t = u.trim();
986
+ return /^(?:\d+\.?\d*|\.\d+)(?:px|rem|em|ch|vh|svh|dvh|vw|%)$/.test(t) ? t : void 0;
772
987
  }
773
- function B(l, e) {
774
- return j(l) === j(e);
988
+ function v(u) {
989
+ return u.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
775
990
  }
776
- function le(l) {
777
- if (!l || l === "none")
778
- return { x: 1, y: 1 };
779
- const e = l.match(/^matrix3d\((.+)\)$/);
780
- if (e) {
781
- const r = e[1].split(",").map((i) => Number.parseFloat(i.trim()));
782
- if (r.length === 16 && r.every((i) => Number.isFinite(i)))
783
- return {
784
- x: r[0] || 1,
785
- y: r[5] || 1
786
- };
787
- }
788
- const t = l.match(/^matrix\((.+)\)$/);
789
- if (t) {
790
- const r = t[1].split(",").map((i) => Number.parseFloat(i.trim()));
791
- if (r.length === 6 && r.every((i) => Number.isFinite(i))) {
792
- const [i, s, n, a] = r;
793
- return {
794
- x: Math.sqrt(i * i + s * s) || 1,
795
- y: Math.sqrt(n * n + a * a) || 1
796
- };
797
- }
991
+ function w(u, t) {
992
+ return `${u}::${t ?? "__root__"}`;
993
+ }
994
+ function et(u) {
995
+ return u ? [u.listId, u.parentId ?? "", u.beforeId ?? "", u.mode].join("::") : "";
996
+ }
997
+ function H(u, t) {
998
+ return et(u) === et(t);
999
+ }
1000
+ function ft(u) {
1001
+ return u === "item" ? "item" : "handle";
1002
+ }
1003
+ function A(u) {
1004
+ return { ...u };
1005
+ }
1006
+ function B(u) {
1007
+ if (u == null || typeof u != "object") return u;
1008
+ try {
1009
+ return JSON.parse(JSON.stringify(u));
1010
+ } catch {
1011
+ return u;
798
1012
  }
799
- return { x: 1, y: 1 };
800
1013
  }
801
- function de(l) {
802
- return l === "item" ? "item" : "handle";
1014
+ function q(u) {
1015
+ const t = { ...u };
1016
+ return u.data !== void 0 && (t.data = B(u.data)), t;
803
1017
  }
804
- function P(l) {
805
- return { ...l };
1018
+ function G(u) {
1019
+ const t = { ...u };
1020
+ return u.data !== void 0 && (t.data = B(u.data)), t;
806
1021
  }
807
- function ce(l, e, t, r, i, s) {
808
- const n = T(l), a = E(l), d = /* @__PURE__ */ new Set(), o = [], u = (g) => {
809
- const x = n.get(g);
810
- !x || d.has(g) || (d.add(g), o.push(g), (a.get(k(x.listId, g)) || []).forEach(u));
1022
+ function j(u, t, e, i, r, s) {
1023
+ const n = T(u), a = M(u), d = /* @__PURE__ */ new Set(), o = [], c = (m) => {
1024
+ const S = n.get(m);
1025
+ !S || d.has(m) || (d.add(m), o.push(m), (a.get(w(S.listId, m)) || []).forEach(c));
811
1026
  };
812
- r.forEach(u);
813
- const c = l.map(P), h = c.filter((g) => d.has(g.id)), _ = i ? c.map(P) : c.filter((g) => !d.has(g.id)), b = i ? h.map((g) => s(g, o)) : h.map(P), S = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map();
814
- i && h.forEach((g, x) => {
815
- S.set(g.id, b[x].id), m.set(b[x].id, g.id);
816
- }), b.forEach((g) => {
817
- const x = i ? m.get(g.id) : g.id, M = x ? n.get(x) : null;
818
- M && (i && (g.parentId = M.parentId && S.has(M.parentId) && S.get(M.parentId) || null), g.listId = t.listId);
1027
+ i.forEach(c);
1028
+ const l = u.map(A), p = l.filter((m) => d.has(m.id)), g = r ? l.map(A) : l.filter((m) => !d.has(m.id)), b = r ? p.map((m) => s(m, o)) : p.map(A), y = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map();
1029
+ r && p.forEach((m, S) => {
1030
+ y.set(m.id, b[S].id), h.set(b[S].id, m.id);
1031
+ }), b.forEach((m) => {
1032
+ const S = r ? h.get(m.id) : m.id, L = S ? n.get(S) : null;
1033
+ L && (r && (m.parentId = L.parentId && y.has(L.parentId) && y.get(L.parentId) || null), m.listId = e.listId);
819
1034
  });
820
- const v = r.map((g) => S.get(g) || g), D = [..._, ...b], A = E(_), z = k(t.listId, t.parentId), f = [...A.get(z) || []], y = t.beforeId ? f.indexOf(t.beforeId) : f.length, R = y >= 0 ? y : f.length;
821
- f.splice(R, 0, ...v), A.set(z, f), E(b).forEach((g, x) => {
822
- const [, M] = x.split("::");
823
- (M || "") !== "__root__" && A.set(x, [...g]);
1035
+ const f = i.map((m) => y.get(m) || m), x = [...g, ...b], D = M(g), C = w(e.listId, e.parentId), z = [...D.get(C) || []], E = e.beforeId ? z.indexOf(e.beforeId) : z.length, F = E >= 0 ? E : z.length;
1036
+ z.splice(F, 0, ...f), D.set(C, z), M(b).forEach((m, S) => {
1037
+ const [, L] = S.split("::");
1038
+ (L || "") !== "__root__" && D.set(S, [...m]);
824
1039
  });
825
- const O = T(D);
826
- v.forEach((g) => {
827
- const x = O.get(g);
828
- x && (x.parentId = t.parentId, x.listId = t.listId);
1040
+ const I = T(x);
1041
+ f.forEach((m) => {
1042
+ const S = I.get(m);
1043
+ S && (S.parentId = e.parentId, S.listId = e.listId);
829
1044
  });
830
- const L = [], q = /* @__PURE__ */ new Set(), H = (g, x) => {
831
- (A.get(k(g, x)) || []).forEach((C, G) => {
832
- const p = O.get(C);
833
- !p || q.has(C) || (q.add(C), p.listId = g, p.parentId = x, p.order = G, L.push(p), H(g, C));
1045
+ const P = [], k = /* @__PURE__ */ new Set(), R = (m, S) => {
1046
+ (D.get(w(m, S)) || []).forEach((N, lt) => {
1047
+ const O = I.get(N);
1048
+ !O || k.has(N) || (k.add(N), O.listId = m, O.parentId = S, O.order = lt, P.push(O), R(m, N));
834
1049
  });
835
1050
  };
836
- return e.forEach((g) => H(g.id, null)), D.forEach((g) => {
837
- q.has(g.id) || (g.parentId = null, L.push(g));
1051
+ return t.forEach((m) => R(m.id, null)), x.forEach((m) => {
1052
+ k.has(m.id) || (m.parentId = null, P.push(m));
838
1053
  }), {
839
- items: L.map(P),
840
- insertedRootIds: v
1054
+ items: P.map(A),
1055
+ insertedRootIds: f
841
1056
  };
842
1057
  }
843
- function E(l) {
844
- const e = /* @__PURE__ */ new Map();
845
- return l.forEach((t) => {
846
- const r = k(t.listId, t.parentId), i = e.get(r);
847
- i ? i.push(t.id) : e.set(r, [t.id]);
848
- }), e;
1058
+ function M(u) {
1059
+ const t = /* @__PURE__ */ new Map();
1060
+ return u.forEach((e) => {
1061
+ const i = w(e.listId, e.parentId), r = t.get(i);
1062
+ r ? r.push(e.id) : t.set(i, [e.id]);
1063
+ }), t;
849
1064
  }
850
- function T(l) {
851
- return new Map(l.map((e) => [e.id, e]));
1065
+ function T(u) {
1066
+ return new Map(u.map((t) => [t.id, t]));
852
1067
  }
853
- function Y(l) {
854
- const e = /* @__PURE__ */ new Set(), t = [];
855
- return l.forEach((r, i) => {
856
- const s = typeof r?.id == "string" && r.id.trim() ? r.id.trim() : `list-${i + 1}`;
857
- e.has(s) || (e.add(s), t.push({
1068
+ function it(u) {
1069
+ const t = /* @__PURE__ */ new Set(), e = [];
1070
+ return u.forEach((i, r) => {
1071
+ const s = typeof i?.id == "string" && i.id.trim() ? i.id.trim() : `list-${r + 1}`;
1072
+ t.has(s) || (t.add(s), e.push({
858
1073
  id: s,
859
- label: typeof r?.label == "string" && r.label.trim() ? r.label.trim() : `List ${i + 1}`,
860
- description: typeof r?.description == "string" ? r.description : "",
861
- emptyLabel: typeof r?.emptyLabel == "string" && r.emptyLabel.trim() ? r.emptyLabel.trim() : "Drop items here.",
862
- orientation: r?.orientation === "horizontal" ? "horizontal" : "vertical",
863
- disabled: !!r?.disabled,
864
- cloneOnDrag: !!r?.cloneOnDrag,
865
- accepts: Array.isArray(r?.accepts) ? r.accepts.filter((n) => typeof n == "string" && n.trim().length > 0) : void 0
1074
+ label: typeof i?.label == "string" && i.label.trim() ? i.label.trim() : `List ${r + 1}`,
1075
+ description: typeof i?.description == "string" ? i.description : "",
1076
+ emptyLabel: typeof i?.emptyLabel == "string" && i.emptyLabel.trim() ? i.emptyLabel.trim() : "",
1077
+ orientation: i?.orientation === "horizontal" ? "horizontal" : "vertical",
1078
+ disabled: !!i?.disabled,
1079
+ cloneOnDrag: !!i?.cloneOnDrag,
1080
+ accepts: Array.isArray(i?.accepts) ? i.accepts.filter((n) => typeof n == "string" && n.trim().length > 0) : void 0,
1081
+ maxItems: Number.isFinite(i?.maxItems) && Number(i.maxItems) >= 0 ? Math.floor(Number(i.maxItems)) : void 0,
1082
+ maxHeight: ot(i?.maxHeight),
1083
+ ...i?.data !== void 0 ? { data: i.data } : {}
866
1084
  }));
867
- }), t.length ? t : [{
1085
+ }), e.length ? e : [{
868
1086
  id: "default",
869
1087
  label: "Items",
870
1088
  description: "",
871
- emptyLabel: "Drop items here.",
1089
+ emptyLabel: "",
872
1090
  orientation: "vertical",
873
1091
  disabled: !1,
874
1092
  cloneOnDrag: !1
875
1093
  }];
876
1094
  }
877
- function U(l, e) {
878
- const t = new Set(l.map((o) => o.id)), r = [];
879
- e.forEach((o, u) => {
880
- const c = typeof o?.id == "string" && o.id.trim() ? o.id.trim() : "", h = typeof o?.label == "string" && o.label.trim() ? o.label.trim() : "";
881
- if (!c || !h) return;
882
- const _ = typeof o?.listId == "string" && t.has(o.listId) ? o.listId : l[0].id;
883
- r.push({
884
- id: c,
885
- label: h,
886
- listId: _,
1095
+ function U(u, t) {
1096
+ const e = new Set(u.map((o) => o.id)), i = [];
1097
+ t.forEach((o, c) => {
1098
+ const l = typeof o?.id == "string" && o.id.trim() ? o.id.trim() : "", p = typeof o?.label == "string" && o.label.trim() ? o.label.trim() : "";
1099
+ if (!l || !p) return;
1100
+ const g = typeof o?.listId == "string" && e.has(o.listId) ? o.listId : u[0].id;
1101
+ i.push({
1102
+ id: l,
1103
+ label: p,
1104
+ listId: g,
887
1105
  parentId: typeof o?.parentId == "string" && o.parentId.trim() ? o.parentId.trim() : null,
888
1106
  description: typeof o?.description == "string" ? o.description : "",
889
- order: Number.isFinite(o?.order) ? Number(o.order) : u,
1107
+ order: Number.isFinite(o?.order) ? Number(o.order) : c,
890
1108
  disabled: !!o?.disabled,
891
1109
  dragDisabled: !!o?.dragDisabled,
892
1110
  cloneOnDrag: !!o?.cloneOnDrag,
893
- hidden: !!o?.hidden
1111
+ hidden: !!o?.hidden,
1112
+ ...o?.data !== void 0 ? { data: o.data } : {}
894
1113
  });
895
1114
  });
896
- const i = new Map(r.map((o) => [o.id, o]));
897
- r.forEach((o) => {
1115
+ const r = new Map(i.map((o) => [o.id, o]));
1116
+ i.forEach((o) => {
898
1117
  if (!o.parentId) return;
899
- const u = i.get(o.parentId);
900
- (!u || u.id === o.id || u.listId !== o.listId) && (o.parentId = null);
1118
+ const c = r.get(o.parentId);
1119
+ (!c || c.id === o.id || c.listId !== o.listId) && (o.parentId = null);
901
1120
  });
902
1121
  const s = /* @__PURE__ */ new Map();
903
- r.forEach((o) => {
904
- const u = k(o.listId, o.parentId), c = s.get(u);
905
- c ? c.push(o) : s.set(u, [o]);
906
- }), s.forEach((o) => o.sort((u, c) => u.order - c.order || u.label.localeCompare(c.label)));
907
- const n = [], a = /* @__PURE__ */ new Set(), d = (o, u) => {
908
- (s.get(k(o, u)) || []).forEach((h, _) => {
909
- a.has(h.id) || (a.add(h.id), h.order = _, n.push(h), d(o, h.id));
1122
+ i.forEach((o) => {
1123
+ const c = w(o.listId, o.parentId), l = s.get(c);
1124
+ l ? l.push(o) : s.set(c, [o]);
1125
+ }), s.forEach((o) => o.sort((c, l) => c.order - l.order || c.label.localeCompare(l.label)));
1126
+ const n = [], a = /* @__PURE__ */ new Set(), d = (o, c) => {
1127
+ (s.get(w(o, c)) || []).forEach((p, g) => {
1128
+ a.has(p.id) || (a.add(p.id), p.order = g, n.push(p), d(o, p.id));
910
1129
  });
911
1130
  };
912
- return l.forEach((o) => d(o.id, null)), r.forEach((o) => {
1131
+ return u.forEach((o) => d(o.id, null)), i.forEach((o) => {
913
1132
  a.has(o.id) || (o.parentId = null, n.push(o));
914
- }), n.map(P);
1133
+ }), n.map(A);
915
1134
  }
916
- function ue(l) {
917
- return JSON.stringify(l.map((e) => ({
918
- id: e.id,
919
- label: e.label,
920
- listId: e.listId,
921
- parentId: e.parentId,
922
- description: e.description,
923
- order: e.order,
924
- disabled: e.disabled,
925
- dragDisabled: e.dragDisabled,
926
- cloneOnDrag: e.cloneOnDrag,
927
- hidden: e.hidden
1135
+ function bt(u) {
1136
+ return JSON.stringify(u.map((t) => ({
1137
+ id: t.id,
1138
+ label: t.label,
1139
+ listId: t.listId,
1140
+ parentId: t.parentId,
1141
+ description: t.description,
1142
+ order: t.order,
1143
+ disabled: t.disabled,
1144
+ dragDisabled: t.dragDisabled,
1145
+ cloneOnDrag: t.cloneOnDrag,
1146
+ hidden: t.hidden,
1147
+ data: t.data
928
1148
  })));
929
1149
  }
930
- function pe(l) {
931
- return JSON.stringify(l.map((e) => ({
932
- id: e.id,
933
- label: e.label,
934
- description: e.description,
935
- emptyLabel: e.emptyLabel,
936
- orientation: e.orientation,
937
- disabled: e.disabled,
938
- cloneOnDrag: e.cloneOnDrag,
939
- accepts: e.accepts
1150
+ function _t(u) {
1151
+ return JSON.stringify(u.map((t) => ({
1152
+ id: t.id,
1153
+ label: t.label,
1154
+ description: t.description,
1155
+ emptyLabel: t.emptyLabel,
1156
+ orientation: t.orientation,
1157
+ disabled: t.disabled,
1158
+ cloneOnDrag: t.cloneOnDrag,
1159
+ accepts: t.accepts,
1160
+ maxItems: t.maxItems,
1161
+ maxHeight: t.maxHeight,
1162
+ data: t.data
940
1163
  })));
941
1164
  }
942
- function X(l) {
943
- return JSON.stringify(l);
1165
+ function rt(u) {
1166
+ return JSON.stringify(u);
944
1167
  }
945
- function J(l) {
946
- const e = /* @__PURE__ */ new Map(), t = l.map((r) => {
947
- const i = k(r.listId, r.parentId), s = e.get(i) ?? 0;
948
- return e.set(i, s + 1), {
949
- id: r.id,
950
- listId: r.listId,
951
- parentId: r.parentId,
1168
+ function J(u) {
1169
+ const t = /* @__PURE__ */ new Map(), e = u.map((i) => {
1170
+ const r = w(i.listId, i.parentId), s = t.get(r) ?? 0;
1171
+ return t.set(r, s + 1), {
1172
+ id: i.id,
1173
+ listId: i.listId,
1174
+ parentId: i.parentId,
952
1175
  index: s
953
1176
  };
954
1177
  });
955
1178
  return {
956
- version: se,
957
- records: t
1179
+ version: ht,
1180
+ records: e
958
1181
  };
959
1182
  }
960
- function W(l, e) {
961
- return e ? `${l.label} ${l.description}`.toLowerCase().includes(e.toLowerCase()) : !0;
1183
+ function st(u) {
1184
+ return /class="item[\s"]/.test(u);
962
1185
  }
963
- function Q(l, e, t, r, i) {
964
- const s = T(l), n = E(l), a = /* @__PURE__ */ new Map(), d = (c, h) => {
965
- const _ = [...n.get(k(c, h)) || []];
966
- return i === "label" && _.sort((b, S) => {
967
- const m = s.get(b), v = s.get(S);
968
- return !m || !v ? 0 : m.label.localeCompare(v.label);
969
- }), _;
970
- }, o = (c, h, _) => {
1186
+ function at(u, t) {
1187
+ return t ? `${u.label} ${u.description}`.toLowerCase().includes(t.toLowerCase()) : !0;
1188
+ }
1189
+ function nt(u, t, e, i, r) {
1190
+ const s = T(u), n = M(u), a = /* @__PURE__ */ new Map(), d = (l, p) => {
1191
+ const g = [...n.get(w(l, p)) || []];
1192
+ return r === "label" && g.sort((b, y) => {
1193
+ const h = s.get(b), f = s.get(y);
1194
+ return !h || !f ? 0 : h.label.localeCompare(f.label);
1195
+ }), g;
1196
+ }, o = (l, p, g) => {
971
1197
  const b = [];
972
- return d(c, h).forEach((S) => {
973
- const m = s.get(S);
974
- if (!m || m.hidden) return;
975
- const v = o(c, m.id);
976
- !W(m, r) && v.length === 0 || (b.push({
977
- id: m.id,
978
- disabled: m.disabled
979
- }), v.length && b.push(...v));
1198
+ return d(l, p).forEach((y) => {
1199
+ const h = s.get(y);
1200
+ if (!h || h.hidden) return;
1201
+ const f = o(l, h.id);
1202
+ !at(h, i) && f.length === 0 || (b.push({
1203
+ id: h.id,
1204
+ disabled: h.disabled
1205
+ }), f.length && b.push(...f));
980
1206
  }), b;
981
1207
  };
982
- return Array.from(new Set(l.map((c) => c.listId))).forEach((c) => {
983
- a.set(c, o(c, null));
1208
+ return Array.from(new Set(u.map((l) => l.listId))).forEach((l) => {
1209
+ a.set(l, o(l, null));
984
1210
  }), a;
985
1211
  }
986
- class he extends ee {
1212
+ const $ = class $ extends dt {
987
1213
  constructor() {
988
- super(), this._lists = Y([]), this._items = [], this._selection = [], this._focusedId = null, this._rangeAnchorId = null, this._dragState = null, this._liveMessage = "Sortable list ready.", this._lastListsAttr = null, this._lastItemsAttr = null, this._lastSelectionAttr = null, this._hydratedPersistKey = null, this._cloneSeed = 1, this._dragImage = null, this._dragPreviewOverlay = null, this._pendingFocusId = null, this._pointerGesture = null, this._pendingDropTarget = null, this._suppressAttributeRender = !1, this._autoScrollFrame = 0, this._autoScrollPoint = null, this._autoScrollTick = () => {
1214
+ super(), this._lists = it([]), this._items = [], this._selection = [], this._focusedId = null, this._rangeAnchorId = null, this._dragState = null, this._liveMessage = "Sortable list ready.", this._lastListsAttr = null, this._lastItemsAttr = null, this._lastSelectionAttr = null, this._lastLabelsAttr = null, this._canDropCallback = null, this._renderItemFn = null, this._renderListHeaderFn = null, this._renderEmptyStateFn = null, this._labels = {}, this._hydratedPersistKey = null, this._cloneSeed = 1, this._dragImage = null, this._dragImageOffset = { x: -14, y: -14 }, this._pendingFocusId = null, this._pointerGesture = null, this._pendingDropTarget = null, this._pendingTimer = null, this._focusWasInside = !1, this._revealPending = !1, this._externalTarget = null, this._nestModifier = !1, this._lastPointer = null, this._suppressAttributeRender = !1, this._autoScrollFrame = 0, this._autoScrollPoint = null, this._autoScrollTick = () => {
989
1215
  this._autoScrollFrame = 0;
990
- const e = this._autoScrollPoint;
991
- if (!e || !this._dragState || this._dragState.keyboard) return;
992
- const t = this.ownerDocument?.defaultView, r = ie(this), i = r ? r.getBoundingClientRect() : null, s = Math.max(0, i ? i.top : 0), n = Math.min(t?.innerHeight ?? 0, i ? i.bottom : 1 / 0), a = te(e.y, s, n);
993
- if (a) {
994
- if (r ? r.scrollTop += a : t?.scrollBy(0, a), !this._dragState.committed) {
995
- const d = this._dropTargetFromPoint(e.x, e.y), o = d && this._canDrop(d, this._dragState.movedRootIds) ? d : null;
996
- this._queueDropTarget(o, performance.now());
997
- }
998
- this._autoScrollFrame = requestAnimationFrame(this._autoScrollTick);
999
- }
1000
- }, this._onClick = this._onClick.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDragStart = this._onDragStart.bind(this), this._onDragOver = this._onDragOver.bind(this), this._onDrop = this._onDrop.bind(this), this._onDragEnd = this._onDragEnd.bind(this), this._onPointerDown = this._onPointerDown.bind(this), this._onPointerMove = this._onPointerMove.bind(this), this._onPointerUp = this._onPointerUp.bind(this), this._onPointerCancel = this._onPointerCancel.bind(this), this._onFocusIn = this._onFocusIn.bind(this), this._onDocumentKeyDown = this._onDocumentKeyDown.bind(this);
1216
+ const t = this._autoScrollPoint;
1217
+ if (!t || !this._dragState || this._dragState.keyboard) return;
1218
+ const e = this.ownerDocument?.defaultView;
1219
+ let i = this._scrollOwn(t.x, t.y);
1220
+ const r = this._peerUnder(t.x, t.y);
1221
+ r && r._scrollOwn(t.x, t.y) && (i = !0);
1222
+ const s = ut(this), n = s ? s.getBoundingClientRect() : null, a = Math.max(0, n ? n.top : 0), d = Math.min(e?.innerHeight ?? 0, n ? n.bottom : 1 / 0), o = K(t.y, a, d);
1223
+ o && (s ? s.scrollTop += o : e?.scrollBy(0, o), i = !0), i && (this._retarget(t.x, t.y, { timestamp: performance.now() }), this._autoScrollFrame = requestAnimationFrame(this._autoScrollTick));
1224
+ }, this._onClick = this._onClick.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDragStart = this._onDragStart.bind(this), this._onPointerDown = this._onPointerDown.bind(this), this._onPointerMove = this._onPointerMove.bind(this), this._onPointerUp = this._onPointerUp.bind(this), this._onPointerCancel = this._onPointerCancel.bind(this), this._onFocusIn = this._onFocusIn.bind(this), this._onTouchMove = this._onTouchMove.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this._onDocumentKeyDown = this._onDocumentKeyDown.bind(this), this._onDocumentKeyUp = this._onDocumentKeyUp.bind(this);
1001
1225
  }
1002
1226
  static get observedAttributes() {
1003
1227
  return [
@@ -1016,63 +1240,128 @@ class he extends ee {
1016
1240
  "drag-handle-selector",
1017
1241
  "custom-item-rendering",
1018
1242
  "show-selection-badge",
1243
+ "nest-trigger",
1244
+ "touch-hold-delay",
1245
+ "list-max-height",
1246
+ "group",
1247
+ "labels",
1248
+ "hide-toolbar",
1019
1249
  "disabled"
1020
1250
  ];
1021
1251
  }
1022
- shouldRenderOnAttributeChange(e, t, r) {
1023
- return this._suppressAttributeRender ? !["lists", "items", "selection"].includes(e) : !0;
1252
+ shouldRenderOnAttributeChange(t, e, i) {
1253
+ return this._suppressAttributeRender ? !["lists", "items", "selection"].includes(t) : !0;
1024
1254
  }
1025
- attributeChangedCallback(e, t, r) {
1026
- if (t !== r && this.isConnected) {
1027
- if (e === "selection" && !this._suppressAttributeRender && this._canSyncInteractiveStateInPlace()) {
1028
- this._syncSelectionFromAttribute(r ?? null), this._syncSelectionVisualState();
1255
+ attributeChangedCallback(t, e, i) {
1256
+ if (e !== i && this.isConnected) {
1257
+ if (t === "selection" && !this._suppressAttributeRender && this._canSyncInteractiveStateInPlace()) {
1258
+ this._syncSelectionFromAttribute(i ?? null), this._syncSelectionVisualState();
1029
1259
  return;
1030
1260
  }
1031
- if (e === "show-selection-badge" && this._canSyncInteractiveStateInPlace()) {
1261
+ if (t === "show-selection-badge" && this._canSyncInteractiveStateInPlace()) {
1032
1262
  this._syncSelectionVisualState();
1033
1263
  return;
1034
1264
  }
1035
- super.attributeChangedCallback(e, t, r);
1265
+ super.attributeChangedCallback(t, e, i);
1036
1266
  }
1037
1267
  }
1038
1268
  connectedCallback() {
1039
- super.connectedCallback(), this.root.addEventListener("click", this._onClick), this.root.addEventListener("keydown", this._onKeyDown), this.root.addEventListener("dragstart", this._onDragStart), this.root.addEventListener("dragover", this._onDragOver), this.root.addEventListener("drop", this._onDrop), this.root.addEventListener("dragend", this._onDragEnd), this.root.addEventListener("pointerdown", this._onPointerDown), this.root.addEventListener("focusin", this._onFocusIn), this.ownerDocument?.addEventListener("keydown", this._onDocumentKeyDown, !0), this.ownerDocument?.addEventListener("pointermove", this._onPointerMove, !0), this.ownerDocument?.addEventListener("pointerup", this._onPointerUp, !0), this.ownerDocument?.addEventListener("pointercancel", this._onPointerCancel, !0);
1269
+ super.connectedCallback(), $._instances.add(this), this.root.addEventListener("click", this._onClick), this.root.addEventListener("keydown", this._onKeyDown), this.root.addEventListener("dragstart", this._onDragStart), this.root.addEventListener("pointerdown", this._onPointerDown), this.root.addEventListener("focusin", this._onFocusIn), this.root.addEventListener("touchmove", this._onTouchMove, { passive: !1 }), this.root.addEventListener("contextmenu", this._onContextMenu), this.ownerDocument?.addEventListener("keydown", this._onDocumentKeyDown, !0), this.ownerDocument?.addEventListener("keyup", this._onDocumentKeyUp, !0), this.ownerDocument?.addEventListener("pointermove", this._onPointerMove, !0), this.ownerDocument?.addEventListener("pointerup", this._onPointerUp, !0), this.ownerDocument?.addEventListener("pointercancel", this._onPointerCancel, !0);
1040
1270
  }
1041
1271
  disconnectedCallback() {
1042
- this.root.removeEventListener("click", this._onClick), this.root.removeEventListener("keydown", this._onKeyDown), this.root.removeEventListener("dragstart", this._onDragStart), this.root.removeEventListener("dragover", this._onDragOver), this.root.removeEventListener("drop", this._onDrop), this.root.removeEventListener("dragend", this._onDragEnd), this.root.removeEventListener("pointerdown", this._onPointerDown), this.root.removeEventListener("focusin", this._onFocusIn), this.ownerDocument?.removeEventListener("keydown", this._onDocumentKeyDown, !0), this.ownerDocument?.removeEventListener("pointermove", this._onPointerMove, !0), this.ownerDocument?.removeEventListener("pointerup", this._onPointerUp, !0), this.ownerDocument?.removeEventListener("pointercancel", this._onPointerCancel, !0), this._stopAutoScroll(), this._removeDragPreviewOverlay(), this._removeDragImage(), super.disconnectedCallback();
1272
+ this.root.removeEventListener("click", this._onClick), this.root.removeEventListener("keydown", this._onKeyDown), this.root.removeEventListener("dragstart", this._onDragStart), this.root.removeEventListener("pointerdown", this._onPointerDown), this.root.removeEventListener("focusin", this._onFocusIn), this.root.removeEventListener("touchmove", this._onTouchMove), this.root.removeEventListener("contextmenu", this._onContextMenu), this._clearHoldTimer(), this.ownerDocument?.removeEventListener("keydown", this._onDocumentKeyDown, !0), this.ownerDocument?.removeEventListener("keyup", this._onDocumentKeyUp, !0), this.ownerDocument?.removeEventListener("pointermove", this._onPointerMove, !0), this.ownerDocument?.removeEventListener("pointerup", this._onPointerUp, !0), this.ownerDocument?.removeEventListener("pointercancel", this._onPointerCancel, !0), this._stopAutoScroll(), this._removeDragImage(), this._pendingTimer && clearTimeout(this._pendingTimer), this._pendingTimer = null, $._instances.delete(this), this._setExternal(null), this._showExternalTarget(null), super.disconnectedCallback();
1043
1273
  }
1044
1274
  get lists() {
1045
- return this._lists.map((e) => ({ ...e }));
1275
+ return this._lists.map(G);
1046
1276
  }
1047
- set lists(e) {
1048
- this.setAttribute("lists", JSON.stringify(e ?? []));
1277
+ set lists(t) {
1278
+ this.setAttribute("lists", JSON.stringify(t ?? []));
1049
1279
  }
1050
1280
  get items() {
1051
- return this._items.map((e) => ({ ...e }));
1281
+ return this._items.map(q);
1282
+ }
1283
+ set items(t) {
1284
+ this.setAttribute("items", JSON.stringify(t ?? []));
1285
+ }
1286
+ /**
1287
+ * Decides whether items may go somewhere. It is asked wherever a place is considered: a refused place is not
1288
+ * highlighted, the keyboard skips it, a drop on it does nothing, and `moveSelection` returns false. Return
1289
+ * true to allow. It runs on every pointer move: keep it quick.
1290
+ */
1291
+ get canDrop() {
1292
+ return this._canDropCallback;
1052
1293
  }
1053
- set items(e) {
1054
- this.setAttribute("items", JSON.stringify(e ?? []));
1294
+ set canDrop(t) {
1295
+ this._canDropCallback = typeof t == "function" ? t : null;
1296
+ }
1297
+ /**
1298
+ * Draws the inside of a card yourself, in plain JavaScript (React has `renderItem` on the wrapper). Return a
1299
+ * fresh DOM node, or a string of HTML; return nothing to keep the built-in card. It is called again whenever
1300
+ * the card is drawn anew, when its `data` changes, and when it is selected or deselected.
1301
+ */
1302
+ get renderItem() {
1303
+ return this._renderItemFn;
1304
+ }
1305
+ set renderItem(t) {
1306
+ this._renderItemFn = typeof t == "function" ? t : null, this.requestRender();
1307
+ }
1308
+ /** Draws a list's header yourself. Return a fresh DOM node or a string of HTML; nothing keeps the built-in header. */
1309
+ get renderListHeader() {
1310
+ return this._renderListHeaderFn;
1311
+ }
1312
+ set renderListHeader(t) {
1313
+ this._renderListHeaderFn = typeof t == "function" ? t : null, this.requestRender();
1314
+ }
1315
+ /** Draws what an empty list shows. Return a fresh DOM node or a string of HTML; nothing keeps the built-in message. */
1316
+ get renderEmptyState() {
1317
+ return this._renderEmptyStateFn;
1318
+ }
1319
+ set renderEmptyState(t) {
1320
+ this._renderEmptyStateFn = typeof t == "function" ? t : null, this.requestRender();
1321
+ }
1322
+ /**
1323
+ * Elements with the same non-empty `group` can exchange items: a card held over another of them can be
1324
+ * dropped there, and both report it (`change`, with `external`). Ids must be unique across the group.
1325
+ */
1326
+ get group() {
1327
+ return this._group();
1328
+ }
1329
+ set group(t) {
1330
+ t ? this.setAttribute("group", t) : this.removeAttribute("group");
1331
+ }
1332
+ _group() {
1333
+ return this.getAttribute("group")?.trim() || "";
1334
+ }
1335
+ /** The text the component shows, with any `labels` you set applied over the English defaults. */
1336
+ get labels() {
1337
+ return { ...Y, ...this._labels };
1338
+ }
1339
+ set labels(t) {
1340
+ !t || !Object.keys(t).length ? this.removeAttribute("labels") : this.setAttribute("labels", JSON.stringify(t));
1341
+ }
1342
+ _t(t, e) {
1343
+ return (this._labels[t] ?? Y[t]).replace(/\{(\w+)\}/g, (r, s) => String(e?.[s] ?? ""));
1055
1344
  }
1056
1345
  get selection() {
1057
1346
  return [...this._selection];
1058
1347
  }
1059
- set selection(e) {
1060
- this.setAttribute("selection", JSON.stringify(e ?? []));
1348
+ set selection(t) {
1349
+ this.setAttribute("selection", JSON.stringify(t ?? []));
1061
1350
  }
1062
1351
  get sort() {
1063
1352
  return this.getAttribute("sort") === "label" ? "label" : "manual";
1064
1353
  }
1065
- set sort(e) {
1066
- !e || e === "manual" ? this.removeAttribute("sort") : this.setAttribute("sort", e);
1354
+ set sort(t) {
1355
+ !t || t === "manual" ? this.removeAttribute("sort") : this.setAttribute("sort", t);
1067
1356
  }
1068
1357
  get filterQuery() {
1069
1358
  return this.getAttribute("filter-query") || "";
1070
1359
  }
1071
- set filterQuery(e) {
1072
- e ? this.setAttribute("filter-query", e) : this.removeAttribute("filter-query");
1360
+ set filterQuery(t) {
1361
+ t ? this.setAttribute("filter-query", t) : this.removeAttribute("filter-query");
1073
1362
  }
1074
- select(e) {
1075
- this._setSelection(e, "api");
1363
+ select(t) {
1364
+ this._setSelection(t, "api");
1076
1365
  }
1077
1366
  clearSelection() {
1078
1367
  this._setSelection([], "api");
@@ -1080,140 +1369,192 @@ class he extends ee {
1080
1369
  cancelDrag() {
1081
1370
  this._cancelDrag(!0);
1082
1371
  }
1083
- focusItem(e) {
1084
- this._items.some((t) => t.id === e) && (this._focusedId = e, this._pendingFocusId = e, !this._applyInteractiveStateInPlace({ restoreFocus: !0 }) && this.requestRender());
1372
+ focusItem(t) {
1373
+ this._items.some((e) => e.id === t) && (this._focusedId = t, this._pendingFocusId = t, this._revealPending = !0, !this._applyInteractiveStateInPlace({ restoreFocus: !0 }) && this.requestRender());
1085
1374
  }
1086
- moveSelection(e) {
1375
+ /** Moves (or copies) the selected items. Returns false when nothing moved: no selection, a place that is not allowed, or `before-change` cancelled. */
1376
+ moveSelection(t) {
1087
1377
  this._syncSelectionFromAttribute(this.getAttribute("selection"));
1088
- const t = this._selectedRootIds();
1089
- t.length && this._commitMove({
1378
+ const e = this._selectedRootIds();
1379
+ return e.length ? this._commitMove({
1380
+ listId: t.targetListId,
1381
+ parentId: t.parentId ?? null,
1382
+ beforeId: t.beforeId ?? null,
1383
+ mode: t.mode ?? (t.parentId ? "inside" : "before")
1384
+ }, e, !!t.clone, t.source ?? "api") : !1;
1385
+ }
1386
+ /**
1387
+ * Moves (or, with `clone`, copies) the selected items into another `<ui-sortable>`: the same as dragging them
1388
+ * there, for code and for keyboard users. `options` is the place in `peer`. Returns false when nothing moved.
1389
+ */
1390
+ moveSelectionTo(t, e) {
1391
+ if (!t || !(t instanceof $)) return !1;
1392
+ if (t === this) return this.moveSelection(e);
1393
+ this._syncSelectionFromAttribute(this.getAttribute("selection"));
1394
+ const i = this._selectedRootIds();
1395
+ return i.length ? this._transferTo(t, {
1090
1396
  listId: e.targetListId,
1091
1397
  parentId: e.parentId ?? null,
1092
1398
  beforeId: e.beforeId ?? null,
1093
1399
  mode: e.mode ?? (e.parentId ? "inside" : "before")
1094
- }, t, !!e.clone, e.source ?? "api");
1400
+ }, i, !!e.clone, e.source ?? "api") : !1;
1095
1401
  }
1096
1402
  getPersistenceSnapshot() {
1097
1403
  return J(this._items);
1098
1404
  }
1099
1405
  render() {
1100
1406
  this._syncStateFromAttributes();
1101
- const e = this._measureItemShellRects(), t = new Set(this._draggingIds()), r = new Set(this._selection), s = !!this._dragState?.keyboard ? this._projectedMoveResult() : null, n = s?.items || this._items, a = new Set(s?.insertedRootIds || []), d = !!this._dragState && !this._dragState.keyboard && !!this._dragState.dropTarget, o = Q(n, r, t, this.filterQuery, this.sort), u = this._resolvedFocusedId(o), c = this._isDragLocked(), h = this._selection.length, _ = this.getAttribute("allow-nesting") !== "false", b = this.getAttribute("drop-indicator-visibility") === "always" ? "always" : "active", S = this._dropzoneStyle(), m = this.getAttribute("show-selection-badge") !== "false", v = this._dragHandleMode(), D = this._usesCustomHandleSelector(), A = c ? this.sort === "label" ? "Dragging is paused while alphabetical sorting is active." : this.filterQuery && !this.hasAttribute("allow-filtered-drag") ? "Dragging is paused while the list is filtered." : "Dragging is currently disabled." : this._dragState?.keyboard ? "Keyboard drag active. Use arrow keys to choose a drop target, Space or Enter to drop, and Escape to cancel." : v === "item" ? "Drag from anywhere on an item, or press Space on a focused item to start keyboard reordering." : D ? "Use your custom drag handle element, or press Space on a focused item to start keyboard reordering." : "Use the handle to drag, or press Space on a focused item to start keyboard reordering.", z = `
1102
- <style>${ae}</style>
1407
+ const t = this._measureItemShellRects(), e = new Set(this._draggingIds()), i = new Set(this._selection), s = !!this._dragState?.keyboard ? this._projectedMoveResult() : null, n = s?.items || this._items, a = new Set(s?.insertedRootIds || []), d = !!this._dragState && !this._dragState.keyboard && !!this._dragState.dropTarget, o = nt(n, i, e, this.filterQuery, this.sort), c = this._resolvedFocusedId(o), l = this._isDragLocked(), p = this._selection.length, g = this.getAttribute("allow-nesting") !== "false", b = this.getAttribute("drop-indicator-visibility") === "always" ? "always" : "active", y = this._dropzoneStyle(), h = this.getAttribute("show-selection-badge") !== "false", f = this._dragHandleMode(), x = this._usesCustomHandleSelector(), D = l ? this.sort === "label" ? this._t("hintPausedSort") : this.filterQuery && !this.hasAttribute("allow-filtered-drag") ? this._t("hintPausedFilter") : this._t("hintDisabled") : this._dragState?.keyboard ? this._t("hintKeyboard") : f === "item" ? this._t("hintItem") : x ? this._t("hintCustom") : this._t("hintHandle"), C = this.hasAttribute("hide-toolbar"), z = g && !l && !this._dragState?.keyboard ? this._t(this._nestTrigger() === "area" ? "hintNestArea" : this._nestTrigger() === "modifier" ? "hintNestModifier" : "hintNestGutter") : "", E = `
1408
+ <style>${gt}</style>
1103
1409
  <div
1104
1410
  class="root"
1105
1411
  part="root"
1106
- data-drag-locked="${c}"
1412
+ data-drag-locked="${l}"
1107
1413
  data-drag-preview="${a.size || d ? "true" : "false"}"
1108
1414
  data-drop-indicator-visibility="${b}"
1109
- data-dropzone-style="${S}"
1415
+ data-dropzone-style="${y}"
1110
1416
  >
1111
- <div class="toolbar" part="toolbar">
1112
- <div class="helper" id="ui-sortable-helper">${I(A)}</div>
1113
- <div class="helper selection-summary">
1114
- <span class="selection-pill" part="selection-count">${h}</span>
1115
- <span class="selection-text">${h === 1 ? "item selected" : "items selected"}</span>
1417
+ <div class="toolbar" part="toolbar"${C ? ' data-hidden="true"' : ""}>
1418
+ <div class="helper" id="ui-sortable-helper">${v(z ? `${D} ${z}` : D)}</div>
1419
+ <div class="helper selection-summary" data-count="${p}">
1420
+ <span class="selection-pill" part="selection-count">${p}</span>
1421
+ <span class="selection-text">${v(p === 1 ? this._t("selectedOne") : this._t("selectedMany"))}</span>
1116
1422
  </div>
1117
1423
  </div>
1118
1424
  <div class="lists" part="lists">
1119
- ${this._lists.map((f) => {
1120
- const y = o.get(f.id) || [], R = y.length ? this._renderListTree(n, f, u, t, _, a, m) : "", $ = f.disabled ? "This list is read-only." : f.cloneOnDrag ? "Dragging from this list creates a copy." : f.accepts?.length ? `Accepts drops from: ${f.accepts.join(", ")}` : "";
1425
+ ${this._lists.map((_) => {
1426
+ const I = o.get(_.id) || [], P = I.length ? this._renderListTree(n, _, c, e, g, a, h) : "", k = _.orientation === "horizontal" ? void 0 : _.maxHeight ?? ot(this.getAttribute("list-max-height")), R = this._items.filter((L) => L.listId === _.id).length, m = _.maxItems !== void 0 && R >= _.maxItems, S = _.disabled ? this._t("listReadOnly") : m ? this._t("listFull", { max: _.maxItems ?? 0 }) : _.cloneOnDrag ? this._t("listClone") : _.accepts?.length ? this._t("listAccepts", { lists: _.accepts.join(", ") }) : "";
1121
1427
  return `
1122
1428
  <section
1123
1429
  class="list"
1124
1430
  part="list"
1125
- data-list-id="${I(f.id)}"
1126
- data-orientation="${f.orientation}"
1127
- data-disabled="${f.disabled}"
1128
- aria-label="${I(f.label)}"
1431
+ data-list-id="${v(_.id)}"
1432
+ data-orientation="${_.orientation}"
1433
+ data-disabled="${_.disabled}"
1434
+ data-full="${m}"
1435
+ ${this._renderListHeaderFn || this._renderEmptyStateFn ? `data-rev="${tt(_.data)}"` : ""}
1436
+ aria-label="${v(_.label)}"
1129
1437
  >
1130
1438
  <header class="list-header">
1131
- <div class="list-custom-header" part="list-custom-header" data-list-header-target="${I(f.id)}"></div>
1439
+ <div class="list-custom-header" part="list-custom-header" data-list-header-target="${v(_.id)}"></div>
1132
1440
  <div class="list-default-header">
1133
1441
  <div class="list-topline">
1134
- <div class="list-label">${I(f.label)}</div>
1135
- <span class="list-count">${y.length}</span>
1442
+ <div class="list-label">${v(_.label)}</div>
1443
+ <span class="list-count">${_.maxItems !== void 0 ? `${R}/${_.maxItems}` : I.length}</span>
1136
1444
  </div>
1137
- ${f.description ? `<div class="list-description">${I(f.description)}</div>` : ""}
1138
- ${$ ? `<div class="list-helper">${I($)}</div>` : ""}
1445
+ ${_.description ? `<div class="list-description">${v(_.description)}</div>` : ""}
1446
+ ${S ? `<div class="list-helper">${v(S)}</div>` : ""}
1139
1447
  </div>
1140
1448
  </header>
1141
- <div class="items" role="${y.length ? "listbox" : "group"}" ${y.length ? 'aria-multiselectable="true"' : ""} aria-label="${I(f.label)}" aria-describedby="ui-sortable-helper">
1142
- ${R || `<div class="list-custom-empty" part="list-custom-empty" data-list-empty-target="${I(f.id)}"></div><div class="empty">${I(f.emptyLabel)}</div>${this._renderDropzone({
1143
- listId: f.id,
1449
+ <div class="items" part="items"${k ? ` data-scroll="true" style="--ui-sortable-list-max-block-size: ${k}"` : ""} role="${I.length ? "listbox" : "group"}" ${I.length ? 'aria-multiselectable="true"' : ""} aria-label="${v(_.label)}" aria-describedby="ui-sortable-helper">
1450
+ ${P || `<div class="list-custom-empty" part="list-custom-empty" data-list-empty-target="${v(_.id)}"></div><div class="empty">${v(_.emptyLabel || this._t("emptyList"))}</div>${this._renderDropzone({
1451
+ listId: _.id,
1144
1452
  parentId: null,
1145
1453
  beforeId: null,
1146
1454
  mode: "before"
1147
- }, "Drop here")}`}
1455
+ }, this._t("dropHere"))}`}
1148
1456
  </div>
1149
1457
  </section>
1150
1458
  `;
1151
1459
  }).join("")}
1152
1460
  </div>
1153
- <div class="sr-only" aria-live="polite" aria-atomic="true">${I(this._liveMessage)}</div>
1461
+ <div class="sr-only" aria-live="polite" aria-atomic="true">${v(this._liveMessage)}</div>
1154
1462
  </div>
1155
- `;
1156
- this.setContent(z), queueMicrotask(() => {
1157
- this._restorePendingFocus(), this._applyCurrentDropTargetVisualState(), this._applyLiveMessage(), this._updatePointerDragPreview(), this._animateItemShellReflow(e);
1463
+ `, F = this._captureScroll();
1464
+ this._focusWasInside = !!this.root.activeElement, this.setContent(E), this._restoreScroll(F), this._fillCustomTargets(), queueMicrotask(() => {
1465
+ this._restorePendingFocus(), this._dragState?.keyboard && this.root.querySelector(".item-placeholder")?.scrollIntoView?.({ block: "nearest", inline: "nearest" }), this._applyCurrentDropTargetVisualState(), this._applyLiveMessage(), this._animateItemShellReflow(t);
1158
1466
  });
1159
1467
  }
1160
1468
  _syncStateFromAttributes() {
1161
- const e = this.getAttribute("lists");
1162
- e !== this._lastListsAttr && (this._lastListsAttr = e, this._lists = Y(K(e)));
1163
- const t = this.getAttribute("items");
1164
- if (t !== this._lastItemsAttr) {
1165
- this._lastItemsAttr = t, this._items = U(this._lists, K(t));
1166
- const i = this.getAttribute("persist-key");
1167
- i && this._hydratedPersistKey !== i && (this._items = this._restorePersistedItems(i, this._items), this._hydratedPersistKey = i);
1469
+ const t = this.getAttribute("lists");
1470
+ t !== this._lastListsAttr && (this._lastListsAttr = t, this._lists = it(V(t)));
1471
+ const e = this.getAttribute("items");
1472
+ if (e !== this._lastItemsAttr) {
1473
+ this._lastItemsAttr = e, this._items = U(this._lists, V(e)), this._lastSelectionAttr = null;
1474
+ const s = this.getAttribute("persist-key");
1475
+ s && this._hydratedPersistKey !== s && (this._items = this._restorePersistedItems(s, this._items), this._hydratedPersistKey = s);
1168
1476
  }
1169
- const r = this.getAttribute("selection");
1170
- r !== this._lastSelectionAttr && this._syncSelectionFromAttribute(r), this._focusedId || (this._focusedId = this._items.find((i) => !i.hidden)?.id || null);
1477
+ const i = this.getAttribute("selection");
1478
+ i !== this._lastSelectionAttr && this._syncSelectionFromAttribute(i);
1479
+ const r = this.getAttribute("labels");
1480
+ r !== this._lastLabelsAttr && (this._lastLabelsAttr = r, this._labels = mt(r)), this._focusedId || (this._focusedId = this._items.find((s) => !s.hidden)?.id || null);
1171
1481
  }
1172
- _restorePersistedItems(e, t) {
1482
+ _restorePersistedItems(t, e) {
1173
1483
  try {
1174
- const r = window.localStorage.getItem(e);
1175
- if (!r) return t;
1176
- const i = JSON.parse(r);
1177
- if (!i || typeof i != "object" || !Array.isArray(i.records)) return t;
1178
- const s = new Map(i.records.map((a) => [a.id, a])), n = t.map((a, d) => {
1484
+ const i = window.localStorage.getItem(t);
1485
+ if (!i) return e;
1486
+ const r = JSON.parse(i);
1487
+ if (!r || typeof r != "object" || !Array.isArray(r.records)) return e;
1488
+ const s = new Map(r.records.map((a) => [a.id, a])), n = e.map((a, d) => {
1179
1489
  const o = s.get(a.id);
1180
1490
  return o ? {
1181
1491
  ...a,
1182
- listId: this._lists.some((u) => u.id === o.listId) ? o.listId : a.listId,
1492
+ listId: this._lists.some((c) => c.id === o.listId) ? o.listId : a.listId,
1183
1493
  parentId: typeof o.parentId == "string" ? o.parentId : null,
1184
1494
  order: Number.isFinite(o.index) ? o.index : d
1185
1495
  } : { ...a, order: d };
1186
1496
  });
1187
1497
  return U(this._lists, n);
1188
1498
  } catch {
1189
- return t;
1499
+ return e;
1190
1500
  }
1191
1501
  }
1192
- _resolvedFocusedId(e) {
1193
- const t = new Set(Array.from(e.values()).flat().map((i) => i.id));
1194
- return this._focusedId && t.has(this._focusedId) ? this._focusedId : Array.from(e.values()).flat().find((i) => !i.disabled)?.id || null;
1502
+ _resolvedFocusedId(t) {
1503
+ const e = new Set(Array.from(t.values()).flat().map((r) => r.id));
1504
+ return this._focusedId && e.has(this._focusedId) ? this._focusedId : Array.from(t.values()).flat().find((r) => !r.disabled)?.id || null;
1195
1505
  }
1196
1506
  _restorePendingFocus() {
1197
- const e = this._pendingFocusId || this._focusedId;
1198
- if (!e) return;
1199
- const t = typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(e) : e.replace(/"/g, '\\"'), r = this.root.querySelector(`.item[data-id="${t}"]`);
1200
- r && (document.activeElement !== r && r.focus({ preventScroll: !0 }), this._pendingFocusId = null);
1507
+ const t = this._pendingFocusId || (this._focusWasInside ? this._focusedId : null);
1508
+ if (this._focusWasInside = !1, !t) return;
1509
+ const e = typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(t) : t.replace(/"/g, '\\"'), i = this.root.querySelector(`.item[data-id="${e}"]`);
1510
+ i && (document.activeElement !== i && i.focus({ preventScroll: !0 }), this._revealPending ? (this._revealPending = !1, i.scrollIntoView?.({ block: "nearest", inline: "nearest" })) : this._revealInBoard(i), this._pendingFocusId = null);
1511
+ }
1512
+ // Every render replaces the shadow content, which would send the board (and any list with its own
1513
+ // scrollbar) back to the start.
1514
+ _captureScroll() {
1515
+ const t = this.root.querySelector(".lists");
1516
+ if (!t) return null;
1517
+ const e = /* @__PURE__ */ new Map();
1518
+ return this.root.querySelectorAll(".list[data-list-id]").forEach((i) => {
1519
+ const r = i.querySelector(".items"), s = i.getAttribute("data-list-id");
1520
+ r && s && (r.scrollLeft || r.scrollTop) && e.set(s, { left: r.scrollLeft, top: r.scrollTop });
1521
+ }), { board: t.scrollLeft, lists: e };
1522
+ }
1523
+ _restoreScroll(t) {
1524
+ if (!t) return;
1525
+ const e = this.root.querySelector(".lists");
1526
+ e && t.board && (e.scrollLeft = t.board), t.lists.size && this.root.querySelectorAll(".list[data-list-id]").forEach((i) => {
1527
+ const r = t.lists.get(i.getAttribute("data-list-id") || ""), s = i.querySelector(".items");
1528
+ !r || !s || (s.scrollLeft = r.left, s.scrollTop = r.top);
1529
+ });
1530
+ }
1531
+ // A board that scrolls sideways can hold the focused card off screen (after a drop into a far list,
1532
+ // or when the keyboard moves into one): bring that list into view.
1533
+ _revealInBoard(t) {
1534
+ const e = this.root.querySelector(".lists"), i = t.closest(".list");
1535
+ if (!e || !i || e.scrollWidth <= e.clientWidth + 1) return;
1536
+ const r = e.getBoundingClientRect(), s = i.getBoundingClientRect();
1537
+ s.left < r.left ? e.scrollLeft -= r.left - s.left + 4 : s.right > r.right && (e.scrollLeft += Math.min(s.right - r.right + 4, s.left - r.left));
1201
1538
  }
1202
- _escapeSelectorValue(e) {
1203
- return typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(e) : e.replace(/"/g, '\\"');
1539
+ _escapeSelectorValue(t) {
1540
+ return typeof CSS < "u" && typeof CSS.escape == "function" ? CSS.escape(t) : t.replace(/"/g, '\\"');
1204
1541
  }
1205
- _findDropzone(e) {
1206
- const t = this._escapeSelectorValue(e.listId), r = this._escapeSelectorValue(e.parentId ?? ""), i = this._escapeSelectorValue(e.beforeId ?? ""), s = this._escapeSelectorValue(e.mode);
1542
+ _findDropzone(t) {
1543
+ const e = this._escapeSelectorValue(t.listId), i = this._escapeSelectorValue(t.parentId ?? ""), r = this._escapeSelectorValue(t.beforeId ?? ""), s = this._escapeSelectorValue(t.mode);
1207
1544
  return this.root.querySelector(
1208
- `.dropzone[data-list-id="${t}"][data-parent-id="${r}"][data-before-id="${i}"][data-mode="${s}"]`
1545
+ `.dropzone[data-list-id="${e}"][data-parent-id="${i}"][data-before-id="${r}"][data-mode="${s}"]`
1209
1546
  );
1210
1547
  }
1211
- _findItemElement(e) {
1212
- const t = this._escapeSelectorValue(e);
1213
- return this.root.querySelector(`.item[data-id="${t}"]`);
1548
+ _findItemElement(t) {
1549
+ const e = this._escapeSelectorValue(t);
1550
+ return this.root.querySelector(`.item[data-id="${e}"]`);
1214
1551
  }
1215
1552
  _dragHandleMode() {
1216
- return de(this.getAttribute("drag-handle-mode"));
1553
+ return ft(this.getAttribute("drag-handle-mode"));
1554
+ }
1555
+ _nestTrigger() {
1556
+ const t = this.getAttribute("nest-trigger");
1557
+ return t === "modifier" || t === "area" ? t : "gutter";
1217
1558
  }
1218
1559
  _dropzoneStyle() {
1219
1560
  return this.getAttribute("dropzone-style") === "container" ? "container" : "indicator";
@@ -1221,331 +1562,343 @@ class he extends ee {
1221
1562
  _usesCustomHandleSelector() {
1222
1563
  return !!this.getAttribute("drag-handle-selector")?.trim();
1223
1564
  }
1224
- _dragActivatorFromPath(e) {
1225
- const t = e.find((n) => n instanceof HTMLElement && !!n.getAttribute("data-drag-trigger"));
1226
- if (!t) return null;
1227
- const r = t.getAttribute("data-drag-trigger"), i = r === "item" ? "item" : r === "custom" ? "custom" : "handle", s = t.getAttribute("data-id") || t.closest(".item[data-id]")?.getAttribute("data-id");
1228
- return s ? { element: t, id: s, kind: i } : null;
1565
+ _dragActivatorFromPath(t) {
1566
+ const e = t.find((n) => n instanceof HTMLElement && !!n.getAttribute("data-drag-trigger"));
1567
+ if (!e) return null;
1568
+ const i = e.getAttribute("data-drag-trigger"), r = i === "item" ? "item" : i === "custom" ? "custom" : "handle", s = e.getAttribute("data-id") || e.closest(".item[data-id]")?.getAttribute("data-id");
1569
+ return s ? { element: e, id: s, kind: r } : null;
1229
1570
  }
1230
- _setDropTargetVisualState(e, t) {
1231
- if (!e) return;
1232
- const r = this._findDropzone(e);
1233
- r && (r.setAttribute("data-active", t ? "true" : "false"), t ? this._syncDropzoneContainerSize(r, e) : this._clearDropzoneContainerSize(r)), e.mode === "inside" && e.parentId && this._findItemElement(e.parentId)?.setAttribute("data-drop-inside-active", t ? "true" : "false");
1571
+ _setDropTargetVisualState(t, e) {
1572
+ if (!t) return;
1573
+ const i = this._findDropzone(t);
1574
+ i && (i.setAttribute("data-active", e ? "true" : "false"), e ? this._syncDropzoneContainerSize(i, t) : this._clearDropzoneContainerSize(i)), t.mode === "inside" && t.parentId && this._findItemElement(t.parentId)?.setAttribute("data-drop-inside-active", e ? "true" : "false");
1234
1575
  }
1235
- _applyCurrentDropTargetVisualState(e) {
1236
- this._setDropTargetVisualState(e ?? null, !1), this._setDropTargetVisualState(this._dragState?.dropTarget ?? null, !0);
1576
+ _applyCurrentDropTargetVisualState(t) {
1577
+ this._setDropTargetVisualState(t ?? null, !1), this._setDropTargetVisualState(this._dragState?.dropTarget ?? null, !0);
1237
1578
  }
1238
1579
  _applyLiveMessage() {
1239
- const e = this.root.querySelector(".sr-only[aria-live]");
1240
- e && (e.textContent = this._liveMessage);
1580
+ const t = this.root.querySelector(".sr-only[aria-live]");
1581
+ t && (t.textContent = this._liveMessage);
1241
1582
  }
1242
1583
  _canSyncInteractiveStateInPlace() {
1243
1584
  return !!this.root.querySelector(".root") && !this._dragState;
1244
1585
  }
1245
- _applyInteractiveStateInPlace(e) {
1246
- return this._canSyncInteractiveStateInPlace() ? (this._syncSelectionVisualState(), e?.restoreFocus && this._restorePendingFocus(), this._applyLiveMessage(), !0) : !1;
1586
+ _applyInteractiveStateInPlace(t) {
1587
+ return this._canSyncInteractiveStateInPlace() ? (this._syncSelectionVisualState(), t?.restoreFocus && this._restorePendingFocus(), this._applyLiveMessage(), !0) : !1;
1588
+ }
1589
+ // Fills the places the markup leaves for custom content (the inside of a card, a list header, an empty state)
1590
+ // from the render functions. Fresh markup has them empty; `itemIds` redraws just those cards.
1591
+ _fillCustomTargets(t) {
1592
+ if (!this._renderItemFn && !this._renderListHeaderFn && !this._renderEmptyStateFn) return;
1593
+ const e = this._isDragLocked(), i = new Map(this._lists.map((d) => [d.id, d])), r = (d, o) => {
1594
+ let c;
1595
+ try {
1596
+ c = o();
1597
+ } catch (l) {
1598
+ console.error("ui-sortable: a render function threw; the built-in markup is shown.", l);
1599
+ return;
1600
+ }
1601
+ typeof c == "string" ? d.innerHTML = c : c && typeof c.nodeType == "number" && d.replaceChildren(c);
1602
+ }, s = this._renderItemFn;
1603
+ if (s) {
1604
+ const d = new Map(this._items.map((l) => [l.id, l])), o = new Set(this._selection), c = this.getAttribute("drag-handle-selector")?.trim() || "";
1605
+ this.root.querySelectorAll(".item-custom-content[data-item-content-target]").forEach((l) => {
1606
+ const p = l.getAttribute("data-item-content-target") || "";
1607
+ if (t ? !t.itemIds.has(p) : l.hasChildNodes()) return;
1608
+ const g = d.get(p);
1609
+ if (!g) return;
1610
+ t && l.replaceChildren();
1611
+ const b = i.get(g.listId);
1612
+ r(l, () => s(q(g), {
1613
+ selected: o.has(p),
1614
+ disabled: g.disabled,
1615
+ dragDisabled: g.dragDisabled,
1616
+ cloneOnDrag: g.cloneOnDrag || !!b?.cloneOnDrag,
1617
+ list: b ? G(b) : void 0
1618
+ })), c && this._markCustomHandles(l, p, c);
1619
+ });
1620
+ }
1621
+ if (t) return;
1622
+ const n = this._renderListHeaderFn;
1623
+ n && this.root.querySelectorAll(".list-custom-header[data-list-header-target]").forEach((d) => {
1624
+ if (d.hasChildNodes()) return;
1625
+ const o = i.get(d.getAttribute("data-list-header-target") || "");
1626
+ if (!o) return;
1627
+ const c = this._items.filter((l) => l.listId === o.id).length;
1628
+ r(d, () => n(G(o), { itemCount: c, dragLocked: e }));
1629
+ });
1630
+ const a = this._renderEmptyStateFn;
1631
+ a && this.root.querySelectorAll(".list-custom-empty[data-list-empty-target]").forEach((d) => {
1632
+ if (d.hasChildNodes()) return;
1633
+ const o = i.get(d.getAttribute("data-list-empty-target") || "");
1634
+ if (!o) return;
1635
+ const c = this._items.filter((l) => l.listId === o.id).length;
1636
+ r(d, () => a(G(o), { itemCount: c, dragLocked: e, filterQuery: this.filterQuery }));
1637
+ });
1638
+ }
1639
+ // The parts of a custom card that match `drag-handle-selector` start a drag, the way the built-in grip does.
1640
+ _markCustomHandles(t, e, i) {
1641
+ let r;
1642
+ try {
1643
+ r = t.querySelectorAll(i);
1644
+ } catch {
1645
+ return;
1646
+ }
1647
+ r.forEach((s) => {
1648
+ s.setAttribute("data-sortable-custom-handle", ""), s.setAttribute("data-drag-trigger", "custom"), s.setAttribute("data-id", e), s.hasAttribute("tabindex") || s.setAttribute("tabindex", "-1");
1649
+ });
1247
1650
  }
1248
1651
  _hasCustomItemRendering() {
1249
- return this.hasAttribute("custom-item-rendering");
1652
+ return this.hasAttribute("custom-item-rendering") || !!this._renderItemFn;
1250
1653
  }
1251
- _syncSelectionFromAttribute(e) {
1252
- this._lastSelectionAttr = e;
1253
- const t = new Set(this._items.map((r) => r.id));
1254
- this._selection = K(e).filter((r) => t.has(r)), !this._selection.length && this._focusedId && !t.has(this._focusedId) && (this._focusedId = null);
1654
+ _syncSelectionFromAttribute(t) {
1655
+ this._lastSelectionAttr = t;
1656
+ const e = new Set(this._items.map((i) => i.id));
1657
+ this._selection = V(t).filter((i) => e.has(i)), !this._selection.length && this._focusedId && !e.has(this._focusedId) && (this._focusedId = null);
1255
1658
  }
1256
1659
  _syncSelectionVisualState() {
1257
- const e = new Set(this._selection), t = this.getAttribute("show-selection-badge") !== "false";
1258
- this.root.querySelectorAll(".item[data-id]").forEach((s) => {
1259
- const n = s.getAttribute("data-id");
1260
- if (!n) return;
1261
- const a = e.has(n), d = this._focusedId === n;
1262
- s.setAttribute("data-selected", a ? "true" : "false"), s.setAttribute("aria-selected", a ? "true" : "false"), s.setAttribute("data-focused", d ? "true" : "false"), s.setAttribute("tabindex", d ? "0" : "-1");
1263
- const o = s.querySelector('[data-selection-badge="true"]');
1264
- if (o) {
1265
- const u = a && t;
1266
- o.hidden = !u, o.textContent = u ? "Selected" : "";
1660
+ const t = new Set(this._selection), e = this.getAttribute("show-selection-badge") !== "false", i = /* @__PURE__ */ new Set();
1661
+ this.root.querySelectorAll(".item[data-id]").forEach((n) => {
1662
+ const a = n.getAttribute("data-id");
1663
+ if (!a) return;
1664
+ const d = t.has(a);
1665
+ n.getAttribute("data-selected") === "true" !== d && i.add(a);
1666
+ const o = this._focusedId === a;
1667
+ n.setAttribute("data-selected", d ? "true" : "false"), n.setAttribute("aria-selected", d ? "true" : "false"), n.setAttribute("data-focused", o ? "true" : "false"), n.setAttribute("tabindex", o ? "0" : "-1");
1668
+ const c = n.querySelector('[data-selection-badge="true"]');
1669
+ if (c) {
1670
+ const l = d && e;
1671
+ c.hidden = !l, c.textContent = l ? this._t("badgeSelected") : "";
1267
1672
  }
1268
- });
1673
+ }), i.size && this._renderItemFn && this._fillCustomTargets({ itemIds: i }), this.root.querySelector(".selection-summary")?.setAttribute("data-count", String(this._selection.length));
1269
1674
  const r = this.root.querySelector(".selection-pill");
1270
1675
  r && (r.textContent = String(this._selection.length));
1271
- const i = this.root.querySelector(".selection-text");
1272
- i && (i.textContent = this._selection.length === 1 ? "item selected" : "items selected");
1676
+ const s = this.root.querySelector(".selection-text");
1677
+ s && (s.textContent = this._selection.length === 1 ? this._t("selectedOne") : this._t("selectedMany"));
1273
1678
  }
1274
- _clearDropzoneContainerSize(e) {
1275
- e.style.removeProperty("--ui-sortable-dropzone-match-block-size"), e.style.removeProperty("--ui-sortable-dropzone-match-inline-size");
1679
+ _clearDropzoneContainerSize(t) {
1680
+ t.style.removeProperty("--ui-sortable-dropzone-match-block-size"), t.style.removeProperty("--ui-sortable-dropzone-match-inline-size");
1276
1681
  }
1277
- _dropzoneReferenceElement(e, t) {
1278
- if (e.mode === "inside" && e.parentId) return this._findItemElement(e.parentId);
1279
- let r = t.nextElementSibling;
1280
- for (; r; ) {
1281
- if (r instanceof HTMLElement && r.classList.contains("item-shell"))
1282
- return r.querySelector(".item[data-id]");
1283
- r = r.nextElementSibling;
1284
- }
1285
- let i = t.previousElementSibling;
1682
+ _dropzoneReferenceElement(t, e) {
1683
+ if (t.mode === "inside" && t.parentId) return this._findItemElement(t.parentId);
1684
+ let i = e.nextElementSibling;
1286
1685
  for (; i; ) {
1287
1686
  if (i instanceof HTMLElement && i.classList.contains("item-shell"))
1288
1687
  return i.querySelector(".item[data-id]");
1289
- i = i.previousElementSibling;
1688
+ i = i.nextElementSibling;
1290
1689
  }
1291
- const s = this._escapeSelectorValue(e.listId), n = this.root.querySelector(`.list[data-list-id="${s}"] .items`), a = n?.querySelector(".item[data-id]");
1690
+ let r = e.previousElementSibling;
1691
+ for (; r; ) {
1692
+ if (r instanceof HTMLElement && r.classList.contains("item-shell"))
1693
+ return r.querySelector(".item[data-id]");
1694
+ r = r.previousElementSibling;
1695
+ }
1696
+ const s = this._escapeSelectorValue(t.listId), n = this.root.querySelector(`.list[data-list-id="${s}"] .items`), a = n?.querySelector(".item[data-id]");
1292
1697
  return a || n || null;
1293
1698
  }
1294
- _syncDropzoneContainerSize(e, t) {
1295
- if (this._clearDropzoneContainerSize(e), this._dropzoneStyle() !== "container") return;
1296
- const r = this._dropzoneReferenceElement(t, e);
1297
- if (!r) return;
1298
- const i = r.getBoundingClientRect();
1299
- e.style.setProperty("--ui-sortable-dropzone-match-block-size", `${Math.max(76, Math.round(i.height))}px`), e.style.setProperty("--ui-sortable-dropzone-match-inline-size", `${Math.max(180, Math.round(i.width))}px`);
1300
- }
1301
- _ensureDragPreviewOverlay() {
1302
- if (this._dragPreviewOverlay && this._dragPreviewOverlay.isConnected) return this._dragPreviewOverlay;
1303
- const e = document.createElement("div");
1304
- return e.className = "drag-preview-overlay", e.setAttribute("data-visible", "false"), this.root.appendChild(e), this._dragPreviewOverlay = e, e;
1699
+ _syncDropzoneContainerSize(t, e) {
1700
+ if (this._clearDropzoneContainerSize(t), this._dropzoneStyle() !== "container") return;
1701
+ const i = this._dropzoneReferenceElement(e, t);
1702
+ if (!i) return;
1703
+ const r = i.getBoundingClientRect();
1704
+ t.style.setProperty("--ui-sortable-dropzone-match-block-size", `${Math.max(76, Math.round(r.height))}px`), t.style.setProperty("--ui-sortable-dropzone-match-inline-size", `${Math.max(180, Math.round(r.width))}px`);
1305
1705
  }
1306
1706
  _clearPointerDragPreview() {
1307
- this._dragPreviewOverlay?.setAttribute("data-visible", "false"), this._dragPreviewOverlay?.style.setProperty("left", "-9999px"), this._dragPreviewOverlay?.style.setProperty("top", "-9999px");
1308
- const e = this.root.querySelector(".root");
1309
- e && !this._dragState?.keyboard && e.setAttribute("data-drag-preview", "false");
1310
- }
1311
- _pointerPreviewContent() {
1312
- if (!this._dragState || this._dragState.keyboard) return null;
1313
- const e = this._dragState.movedRootIds[0], t = this._items.find((r) => r.id === e);
1314
- return t ? {
1315
- kicker: this._dragState.clone ? "Copy preview" : "Drop preview",
1316
- title: this._dragState.clone ? `${t.label} copy` : t.label,
1317
- description: this._dragState.clone ? "Release to add a copy here." : this._dragState.movedRootIds.length > 1 ? "Release to place this selection here." : "Release to place this item here."
1318
- } : null;
1319
- }
1320
- _pointerPreviewSize() {
1321
- if (this.getAttribute("drag-preview-size") === "compact" || !this._dragState || this._dragState.keyboard) return null;
1322
- const e = this._dragState.movedRootIds[0], t = e ? this._findItemElement(e) : null;
1323
- if (!t) return null;
1324
- const r = window.getComputedStyle(t), i = le(r.transform);
1325
- return {
1326
- width: t.offsetWidth * i.x,
1327
- height: t.offsetHeight * i.y
1328
- };
1707
+ const t = this.root.querySelector(".root");
1708
+ t && !this._dragState?.keyboard && t.setAttribute("data-drag-preview", "false");
1329
1709
  }
1330
- _updatePointerDragPreview() {
1331
- if (!this._dragState || this._dragState.keyboard) {
1332
- this._clearPointerDragPreview();
1333
- return;
1334
- }
1335
- const e = this._pointerPreviewContent();
1336
- if (!e) {
1337
- this._clearPointerDragPreview();
1338
- return;
1339
- }
1340
- const t = this.root.querySelector(".root"), i = this._dragPreviewOverlay?.getAttribute("data-visible") === "true", s = this._pointerPreviewSize();
1341
- if (!this._dragState.dropTarget) {
1342
- i && t && t.setAttribute("data-drag-preview", "true");
1343
- return;
1344
- }
1345
- const n = this._findDropzone(this._dragState.dropTarget);
1346
- if (!n) {
1347
- i && t && t.setAttribute("data-drag-preview", "true");
1348
- return;
1349
- }
1350
- const a = this._ensureDragPreviewOverlay();
1351
- a.innerHTML = `
1352
- <div class="placeholder-content">
1353
- <div class="placeholder-kicker">${I(e.kicker)}</div>
1354
- <div class="placeholder-title">${I(e.title)}</div>
1355
- <div class="placeholder-description">${I(e.description)}</div>
1356
- </div>
1357
- `;
1358
- const d = n.getBoundingClientRect();
1359
- t && t.setAttribute("data-drag-preview", "true"), a.style.setProperty("left", "-9999px"), a.style.setProperty("top", "-9999px"), s ? (a.style.setProperty("inline-size", `${s.width}px`), a.style.setProperty("block-size", `${s.height}px`)) : (a.style.removeProperty("inline-size"), a.style.removeProperty("block-size")), a.setAttribute("data-visible", "true");
1360
- const o = a.getBoundingClientRect(), u = s?.width ?? o.width, c = s?.height ?? o.height, h = Math.max(16, Math.min(d.left, window.innerWidth - u - 16)), _ = Math.max(
1361
- 16,
1362
- Math.min(
1363
- d.top + (d.height - c) / 2,
1364
- window.innerHeight - c - 16
1365
- )
1366
- );
1367
- a.style.setProperty("left", `${Math.round(h)}px`), a.style.setProperty("top", `${Math.round(_)}px`);
1368
- }
1369
- _setDraggingVisualState(e, t) {
1370
- e.forEach((r) => {
1371
- const i = this._findItemElement(r);
1372
- i && (i.setAttribute("data-dragging", t ? "true" : "false"), t && i.getBoundingClientRect());
1710
+ _setDraggingVisualState(t, e) {
1711
+ e && this._dragState?.clone && !this._dragState.keyboard || t.forEach((i) => {
1712
+ const r = this._findItemElement(i);
1713
+ r && (r.setAttribute("data-dragging", e ? "true" : "false"), e && r.getBoundingClientRect());
1373
1714
  });
1374
1715
  }
1375
- _setDropTarget(e, t) {
1376
- const r = this._dragState?.dropTarget ?? null;
1377
- if (!(!this._dragState || B(r, e))) {
1378
- if (this._pendingDropTarget = null, this._dragState.dropTarget = e, this._applyCurrentDropTargetVisualState(r), t?.announceLabel && this._announce(t.announceLabel), this._dragState.keyboard) {
1716
+ _setDropTarget(t, e) {
1717
+ const i = this._dragState?.dropTarget ?? null;
1718
+ if (!(!this._dragState || H(i, t))) {
1719
+ if (this._pendingDropTarget = null, this._dragState.dropTarget = t, this._applyCurrentDropTargetVisualState(i), e?.announceLabel && this._announce(e.announceLabel), this._dragState.keyboard) {
1379
1720
  this.requestRender();
1380
1721
  return;
1381
1722
  }
1382
- this._updatePointerDragPreview();
1723
+ this.root.querySelector(".root")?.setAttribute("data-drag-preview", t ? "true" : "false");
1383
1724
  }
1384
1725
  }
1385
- _queueDropTarget(e, t, r) {
1726
+ _queueDropTarget(t, e, i) {
1386
1727
  if (!this._dragState) return;
1387
- const i = this._dragState.dropTarget ?? null;
1388
- if (B(i, e)) {
1728
+ const r = this._dragState.dropTarget ?? null;
1729
+ if (H(r, t)) {
1389
1730
  this._pendingDropTarget = null;
1390
1731
  return;
1391
1732
  }
1392
- if (!i && e) {
1393
- this._setDropTarget(e, r);
1733
+ if (!r && t) {
1734
+ this._setDropTarget(t, i);
1394
1735
  return;
1395
1736
  }
1396
- const s = typeof t == "number" && Number.isFinite(t) ? t : performance.now(), n = this._pendingDropTarget;
1397
- if (n && B(n.target, e)) {
1398
- const a = e ? oe : ne;
1399
- s - n.startedAt >= a && this._setDropTarget(e, n.announceLabel ? { announceLabel: n.announceLabel } : r);
1737
+ const s = typeof e == "number" && Number.isFinite(e) ? e : performance.now(), n = this._pendingDropTarget;
1738
+ if (n && H(n.target, t)) {
1739
+ const a = t ? W : Q;
1740
+ s - n.startedAt >= a && this._setDropTarget(t, n.announceLabel ? { announceLabel: n.announceLabel } : i);
1400
1741
  return;
1401
1742
  }
1402
1743
  this._pendingDropTarget = {
1403
- target: e,
1744
+ target: t,
1404
1745
  startedAt: s,
1405
- announceLabel: r?.announceLabel
1406
- };
1407
- }
1408
- _releaseDropTarget(e, t) {
1746
+ announceLabel: i?.announceLabel
1747
+ }, this._schedulePendingFlush(t ? W : Q);
1748
+ }
1749
+ // The settle delay is judged on the next pointer event, so a pointer that has stopped (over a place that
1750
+ // refuses the drop, say) would leave the old highlight on. This applies the change once the delay is up.
1751
+ _schedulePendingFlush(t) {
1752
+ this._pendingTimer && clearTimeout(this._pendingTimer), this._pendingTimer = setTimeout(() => {
1753
+ this._pendingTimer = null;
1754
+ const e = this._pendingDropTarget;
1755
+ !e || !this._dragState || this._dragState.committed || this._dragState.keyboard || this._setDropTarget(e.target, e.announceLabel ? { announceLabel: e.announceLabel } : void 0);
1756
+ }, t + 8);
1757
+ }
1758
+ _releaseDropTarget(t, e) {
1409
1759
  if (!this._dragState) return null;
1410
- if (Number.isFinite(e) && Number.isFinite(t)) {
1411
- const n = this._dropTargetFromPoint(e, t);
1760
+ if (Number.isFinite(t) && Number.isFinite(e)) {
1761
+ const n = this._dropTargetFromPoint(t, e);
1412
1762
  if (n && this._canDrop(n, this._dragState.movedRootIds))
1413
1763
  return this._pendingDropTarget = null, n;
1414
1764
  }
1415
- const r = this._pendingDropTarget?.target ?? null;
1765
+ const i = this._pendingDropTarget?.target ?? null;
1416
1766
  this._pendingDropTarget = null;
1417
- const i = (n) => this._pointerIsOverList(n.listId, e, t);
1418
- if (r && this._canDrop(r, this._dragState.movedRootIds) && i(r)) return r;
1767
+ const r = (n) => this._pointerIsOverList(n.listId, t, e);
1768
+ if (i && this._canDrop(i, this._dragState.movedRootIds) && r(i)) return i;
1419
1769
  const s = this._dragState.dropTarget ?? null;
1420
- return s && this._canDrop(s, this._dragState.movedRootIds) && i(s) ? s : null;
1770
+ return s && this._canDrop(s, this._dragState.movedRootIds) && r(s) ? s : null;
1421
1771
  }
1422
- _pointerIsOverList(e, t, r) {
1423
- if (!Number.isFinite(t) || !Number.isFinite(r)) return !0;
1424
- const s = Array.from(this.root.querySelectorAll(".list[data-list-id]")).find((a) => a.getAttribute("data-list-id") === e);
1772
+ _pointerIsOverList(t, e, i) {
1773
+ if (!Number.isFinite(e) || !Number.isFinite(i)) return !0;
1774
+ const s = Array.from(this.root.querySelectorAll(".list[data-list-id]")).find((a) => a.getAttribute("data-list-id") === t);
1425
1775
  if (!s) return !0;
1426
1776
  const n = s.getBoundingClientRect();
1427
- return t >= n.left && t <= n.right && r >= n.top && r <= n.bottom;
1777
+ return e >= n.left && e <= n.right && i >= n.top && i <= n.bottom;
1428
1778
  }
1429
- _pathFromPoint(e, t) {
1430
- const r = [], i = this.root;
1431
- let s = typeof i.elementFromPoint == "function" ? i.elementFromPoint(e, t) : this.ownerDocument?.elementFromPoint(e, t) ?? null;
1432
- for (; s && (s instanceof HTMLElement && r.push(s), s !== this); ) {
1779
+ _pathFromPoint(t, e) {
1780
+ const i = [], r = this.root;
1781
+ let s = typeof r.elementFromPoint == "function" ? r.elementFromPoint(t, e) : this.ownerDocument?.elementFromPoint?.(t, e) ?? null;
1782
+ for (; s && (s instanceof HTMLElement && i.push(s), s !== this); ) {
1433
1783
  if (s instanceof ShadowRoot) {
1434
1784
  s = s.host;
1435
1785
  continue;
1436
1786
  }
1437
- s = s.parentNode, !s && r[r.length - 1]?.getRootNode() instanceof ShadowRoot && (s = r[r.length - 1].getRootNode().host);
1787
+ s = s.parentNode, !s && i[i.length - 1]?.getRootNode() instanceof ShadowRoot && (s = i[i.length - 1].getRootNode().host);
1438
1788
  }
1439
- return r;
1789
+ return i;
1440
1790
  }
1441
1791
  _measureItemShellRects() {
1442
- const e = /* @__PURE__ */ new Map();
1443
- return this.root.querySelectorAll(".item-shell[data-item-shell]").forEach((t) => {
1444
- const r = t.getAttribute("data-item-shell");
1445
- if (!r) return;
1446
- const i = t.getBoundingClientRect();
1447
- e.set(r, { top: i.top, left: i.left });
1448
- }), e;
1449
- }
1450
- _animateItemShellReflow(e) {
1451
- if (!e.size) return;
1452
- const t = new Set(this._draggingIds());
1453
- this.root.querySelectorAll(".item-shell[data-item-shell]").forEach((r) => {
1454
- const i = r.getAttribute("data-item-shell");
1455
- if (!i || t.has(i)) return;
1456
- const s = e.get(i);
1792
+ const t = /* @__PURE__ */ new Map();
1793
+ return this.root.querySelectorAll(".item-shell[data-item-shell]").forEach((e) => {
1794
+ const i = e.getAttribute("data-item-shell");
1795
+ if (!i) return;
1796
+ const r = e.getBoundingClientRect();
1797
+ t.set(i, { top: r.top, left: r.left });
1798
+ }), t;
1799
+ }
1800
+ _animateItemShellReflow(t) {
1801
+ if (!t.size) return;
1802
+ const e = new Set(this._draggingIds());
1803
+ this.root.querySelectorAll(".item-shell[data-item-shell]").forEach((i) => {
1804
+ const r = i.getAttribute("data-item-shell");
1805
+ if (!r || e.has(r)) return;
1806
+ const s = t.get(r);
1457
1807
  if (!s) return;
1458
- const n = r.getBoundingClientRect(), a = s.left - n.left, d = s.top - n.top;
1459
- Math.abs(a) < 0.5 && Math.abs(d) < 0.5 || (r.style.transition = "none", r.style.transform = `translate(${a}px, ${d}px)`, r.style.willChange = "transform", r.getBoundingClientRect(), requestAnimationFrame(() => {
1460
- r.style.transition = "transform 180ms ease", r.style.transform = "";
1808
+ const n = i.getBoundingClientRect(), a = s.left - n.left, d = s.top - n.top;
1809
+ Math.abs(a) < 0.5 && Math.abs(d) < 0.5 || (i.style.transition = "none", i.style.transform = `translate(${a}px, ${d}px)`, i.style.willChange = "transform", i.getBoundingClientRect(), requestAnimationFrame(() => {
1810
+ i.style.transition = "transform 180ms ease", i.style.transform = "";
1461
1811
  const o = () => {
1462
- r.style.transition = "", r.style.willChange = "", r.removeEventListener("transitionend", o);
1812
+ i.style.transition = "", i.style.willChange = "", i.removeEventListener("transitionend", o);
1463
1813
  };
1464
- r.addEventListener("transitionend", o), window.setTimeout(o, 220);
1814
+ i.addEventListener("transitionend", o), window.setTimeout(o, 220);
1465
1815
  }));
1466
1816
  });
1467
1817
  }
1468
- _previewCloneSubtreeItem(e, t) {
1469
- const r = e.id.includes("--copy-") ? e.id.split("--copy-")[0] : e.id;
1818
+ _previewCloneSubtreeItem(t, e) {
1819
+ const i = t.id.includes("--copy-") ? t.id.split("--copy-")[0] : t.id;
1470
1820
  return {
1471
- ...e,
1472
- id: `${r}--preview`,
1473
- label: t[0] === e.id ? `${e.label} copy` : e.label
1821
+ ...t,
1822
+ id: `${i}--preview`,
1823
+ label: e[0] === t.id ? `${t.label} copy` : t.label
1474
1824
  };
1475
1825
  }
1476
1826
  _projectedMoveResult() {
1477
- return !this._dragState?.dropTarget || !this._canDrop(this._dragState.dropTarget, this._dragState.movedRootIds) ? null : ce(
1827
+ return !this._dragState?.dropTarget || !this._canDrop(this._dragState.dropTarget, this._dragState.movedRootIds) ? null : j(
1478
1828
  this._items,
1479
1829
  this._lists,
1480
1830
  this._dragState.dropTarget,
1481
1831
  this._dragState.movedRootIds,
1482
1832
  this._dragState.clone,
1483
- (e, t) => this._previewCloneSubtreeItem(e, t)
1833
+ (t, e) => this._previewCloneSubtreeItem(t, e)
1484
1834
  );
1485
1835
  }
1486
- _renderListTree(e, t, r, i, s, n, a) {
1487
- const d = T(e), o = E(e), u = (c) => {
1488
- const h = o.get(k(t.id, c)) || [], _ = this.sort === "label" ? [...h].sort((S, m) => {
1489
- const v = d.get(S), D = d.get(m);
1490
- return !v || !D ? 0 : v.label.localeCompare(D.label);
1491
- }) : h;
1836
+ _renderListTree(t, e, i, r, s, n, a) {
1837
+ const d = T(t), o = M(t), c = (l) => {
1838
+ const p = o.get(w(e.id, l)) || [], g = this.sort === "label" ? [...p].sort((y, h) => {
1839
+ const f = d.get(y), x = d.get(h);
1840
+ return !f || !x ? 0 : f.label.localeCompare(x.label);
1841
+ }) : p;
1492
1842
  let b = "";
1493
- return _.forEach((S) => {
1494
- const m = d.get(S);
1495
- if (!m || m.hidden) return;
1496
- const v = this._renderChildBranch(
1497
- m,
1498
- r,
1843
+ return g.forEach((y) => {
1844
+ const h = d.get(y);
1845
+ if (!h || h.hidden) return;
1846
+ const f = this._renderChildBranch(
1847
+ h,
1499
1848
  i,
1500
- u,
1849
+ r,
1850
+ c,
1501
1851
  s,
1502
1852
  n,
1503
1853
  a
1504
1854
  );
1505
- !W(m, this.filterQuery) && !v.includes('class="item"') || (b += this._renderDropzone({
1506
- listId: t.id,
1507
- parentId: c,
1508
- beforeId: S,
1855
+ !at(h, this.filterQuery) && !st(f) || (b += this._renderDropzone({
1856
+ listId: e.id,
1857
+ parentId: l,
1858
+ beforeId: y,
1509
1859
  mode: "before"
1510
- }, "Drop here"), b += v);
1860
+ }, this._t("dropHere")), b += f);
1511
1861
  }), b += this._renderDropzone({
1512
- listId: t.id,
1513
- parentId: c,
1862
+ listId: e.id,
1863
+ parentId: l,
1514
1864
  beforeId: null,
1515
1865
  mode: "before"
1516
- }, "Drop here"), b;
1866
+ }, this._t("dropHere")), b;
1517
1867
  };
1518
- return `<div class="tree">${u(null)}</div>`;
1868
+ return `<div class="tree">${c(null)}</div>`;
1519
1869
  }
1520
- _renderChildBranch(e, t, r, i, s, n, a) {
1521
- const d = I(e.id), o = n.has(e.id), u = o ? "" : i(e.id), c = u.includes('class="item"'), h = o ? !1 : this._selection.includes(e.id), _ = o ? !1 : r.has(e.id), b = e.disabled, S = b || e.dragDisabled || this._isDragLocked(), m = this._dragState?.dropTarget?.mode === "inside" && this._dragState.dropTarget.parentId === e.id, v = this._dragState?.clone ? "Copy preview" : "Drop preview", D = this._dragState?.clone ? "Release to add a copy here." : this._dragState && this._dragState.movedRootIds.length > 1 ? "Release to place this selection here." : "Release to place this item here.", A = this._dragHandleMode(), z = this._usesCustomHandleSelector(), f = z ? "custom" : A, y = !z && A === "handle";
1870
+ _renderChildBranch(t, e, i, r, s, n, a) {
1871
+ const d = v(t.id), o = n.has(t.id), c = o ? "" : r(t.id), l = st(c), p = o ? !1 : this._selection.includes(t.id), g = o ? !1 : i.has(t.id), b = t.disabled, y = b || t.dragDisabled || this._isDragLocked(), h = this._dragState?.dropTarget?.mode === "inside" && this._dragState.dropTarget.parentId === t.id, f = this._t(this._dragState?.clone ? "copyPreview" : "dropPreview"), x = this._t(
1872
+ this._dragState?.clone ? "releaseCopy" : this._dragState && this._dragState.movedRootIds.length > 1 ? "releaseMoveMany" : "releaseMove"
1873
+ ), D = this._dragHandleMode(), C = this._usesCustomHandleSelector(), z = C ? "custom" : D, E = !C && D === "handle";
1522
1874
  return `
1523
1875
  <div class="item-shell" data-item-shell="${d}">
1524
1876
  <div
1525
1877
  class="item${o ? " item-placeholder" : ""}"
1526
1878
  part="item"
1527
1879
  data-id="${d}"
1528
- data-drag-handle-mode="${f}"
1529
- ${!o && f === "item" ? 'data-drag-trigger="item"' : ""}
1530
- data-selected="${h}"
1531
- data-focused="${o ? "false" : t === e.id}"
1532
- data-dragging="${_}"
1880
+ data-drag-handle-mode="${z}"
1881
+ ${!o && z === "item" ? 'data-drag-trigger="item"' : ""}
1882
+ data-selected="${p}"
1883
+ data-focused="${o ? "false" : e === t.id}"
1884
+ data-dragging="${g}"
1533
1885
  data-disabled="${b}"
1534
- data-drop-inside-active="${m ? "true" : "false"}"
1886
+ data-drop-inside-active="${h ? "true" : "false"}"
1887
+ ${this._renderItemFn && !o ? `data-rev="${tt(t.data)}"` : ""}
1535
1888
  role="${o ? "presentation" : "option"}"
1536
- aria-selected="${o ? "false" : h}"
1889
+ aria-selected="${o ? "false" : p}"
1537
1890
  aria-disabled="${b}"
1538
1891
  aria-hidden="${o ? "true" : "false"}"
1539
- tabindex="${o ? "-1" : t === e.id ? "0" : "-1"}"
1892
+ tabindex="${o ? "-1" : e === t.id ? "0" : "-1"}"
1540
1893
  >
1541
1894
  ${o ? `
1542
1895
  <div class="placeholder-content">
1543
- <div class="placeholder-kicker">${I(v)}</div>
1544
- <div class="placeholder-title">${I(e.label)}</div>
1545
- <div class="placeholder-description">${I(D)}</div>
1896
+ <div class="placeholder-kicker">${v(f)}</div>
1897
+ <div class="placeholder-title">${v(t.label)}</div>
1898
+ <div class="placeholder-description">${v(x)}</div>
1546
1899
  </div>
1547
1900
  ` : `
1548
- ${y ? `
1901
+ ${E ? `
1549
1902
  <span
1550
1903
  class="handle"
1551
1904
  part="handle"
@@ -1555,7 +1908,7 @@ class he extends ee {
1555
1908
  data-drag-trigger="handle"
1556
1909
  data-id="${d}"
1557
1910
  draggable="false"
1558
- ${S ? "disabled" : ""}
1911
+ ${y ? "disabled" : ""}
1559
1912
  >
1560
1913
  <svg viewBox="0 0 16 16" aria-hidden="true" focusable="false">
1561
1914
  <circle cx="5" cy="4" r="1.25"></circle>
@@ -1570,252 +1923,367 @@ class he extends ee {
1570
1923
  <div class="item-content" data-action="select" data-id="${d}">
1571
1924
  <div class="item-custom-content" part="item-custom-content" data-item-content-target="${d}"></div>
1572
1925
  <div class="item-default-content">
1573
- <div class="item-title">${I(e.label)}</div>
1574
- ${e.description ? `<div class="item-description">${I(e.description)}</div>` : ""}
1926
+ <div class="item-title">${v(t.label)}</div>
1927
+ ${t.description ? `<div class="item-description">${v(t.description)}</div>` : ""}
1575
1928
  <div class="item-meta">
1576
- <span class="item-badge selection-badge" data-selection-badge="true" ${h && a ? "" : "hidden"}>${h && a ? "Selected" : ""}</span>
1577
- ${e.cloneOnDrag ? '<span class="item-badge">Clone on drag</span>' : ""}
1578
- ${e.dragDisabled ? '<span class="item-badge">Pinned</span>' : ""}
1579
- ${s ? '<span class="item-badge drop-badge">Nest here</span>' : ""}
1929
+ <span class="item-badge selection-badge" data-selection-badge="true" ${p && a ? "" : "hidden"}>${p && a ? v(this._t("badgeSelected")) : ""}</span>
1930
+ ${t.cloneOnDrag ? `<span class="item-badge">${v(this._t("badgeClone"))}</span>` : ""}
1931
+ ${t.dragDisabled ? `<span class="item-badge">${v(this._t("badgePinned"))}</span>` : ""}
1932
+ ${s ? `<span class="item-badge drop-badge">${v(this._t("nestHere"))}</span>` : ""}
1580
1933
  </div>
1581
1934
  </div>
1582
1935
  </div>
1583
1936
  `}
1584
1937
  </div>
1585
1938
  ${s && !o ? this._renderDropzone({
1586
- listId: e.listId,
1587
- parentId: e.id,
1939
+ listId: t.listId,
1940
+ parentId: t.id,
1588
1941
  beforeId: null,
1589
1942
  mode: "inside"
1590
- }, "Nest here") : ""}
1591
- ${c ? `<div class="children">${u}</div>` : ""}
1943
+ }, this._t("nestHere")) : ""}
1944
+ ${l ? `<div class="children">${c}</div>` : ""}
1592
1945
  </div>
1593
1946
  `;
1594
1947
  }
1595
- _renderDropzone(e, t) {
1596
- const r = this._dragState?.dropTarget && this._dragState.dropTarget.listId === e.listId && this._dragState.dropTarget.parentId === e.parentId && this._dragState.dropTarget.beforeId === e.beforeId && this._dragState.dropTarget.mode === e.mode;
1948
+ _renderDropzone(t, e) {
1949
+ const i = this._dragState?.dropTarget ?? this._externalTarget, r = i && i.listId === t.listId && i.parentId === t.parentId && i.beforeId === t.beforeId && i.mode === t.mode;
1597
1950
  return `
1598
1951
  <div
1599
1952
  class="dropzone"
1600
1953
  part="dropzone"
1601
- data-list-id="${I(e.listId)}"
1602
- data-parent-id="${I(e.parentId ?? "")}"
1603
- data-before-id="${I(e.beforeId ?? "")}"
1604
- data-mode="${e.mode}"
1954
+ data-list-id="${v(t.listId)}"
1955
+ data-parent-id="${v(t.parentId ?? "")}"
1956
+ data-before-id="${v(t.beforeId ?? "")}"
1957
+ data-mode="${t.mode}"
1605
1958
  data-active="${r ? "true" : "false"}"
1606
1959
  aria-hidden="true"
1607
1960
  >
1608
- <span class="dropzone-label">${I(t)}</span>
1961
+ <span class="dropzone-label">${v(e)}</span>
1609
1962
  </div>
1610
1963
  `;
1611
1964
  }
1612
- _onClick(e) {
1613
- const t = e.composedPath(), r = t.find((o) => o instanceof HTMLElement && o.classList?.contains("toolbar")), i = this._dragActivatorFromPath(t), s = t.find((o) => o instanceof HTMLElement && o.classList.contains("item"));
1614
- if (i && i.kind !== "item") return;
1965
+ _onClick(t) {
1966
+ const e = t.composedPath(), i = e.find((o) => o instanceof HTMLElement && o.classList?.contains("toolbar")), r = this._dragActivatorFromPath(e), s = e.find((o) => o instanceof HTMLElement && o.classList.contains("item"));
1967
+ if (r && r.kind !== "item") return;
1615
1968
  if (!s)
1616
- return r && !(e.target instanceof HTMLButtonElement), void 0;
1969
+ return i && !(t.target instanceof HTMLButtonElement), void 0;
1617
1970
  const n = s.getAttribute("data-id");
1618
1971
  if (!n) return;
1619
1972
  const a = this._items.find((o) => o.id === n);
1620
1973
  if (!a || a.disabled) return;
1621
- const d = e;
1974
+ const d = t;
1622
1975
  if (d.shiftKey ? this._selectRangeTo(n) : d.metaKey || d.ctrlKey ? this._toggleSelection(n) : this._setSelection([n], "pointer"), this._focusedId = n, this._rangeAnchorId = n, this._pendingFocusId = n, this._hasCustomItemRendering()) {
1623
1976
  this._syncSelectionVisualState(), this._restorePendingFocus();
1624
1977
  return;
1625
1978
  }
1626
1979
  this.requestRender();
1627
1980
  }
1628
- _onFocusIn(e) {
1629
- const r = e.composedPath().find((i) => i instanceof HTMLElement && i.classList.contains("item"))?.getAttribute("data-id");
1630
- r && (this._focusedId = r, this._syncSelectionVisualState());
1981
+ _onFocusIn(t) {
1982
+ const i = t.composedPath().find((r) => r instanceof HTMLElement && r.classList.contains("item"))?.getAttribute("data-id");
1983
+ i && (this._focusedId = i, this._syncSelectionVisualState());
1631
1984
  }
1632
1985
  // Keys typed into a control that lives inside an item (an <input> or <button> in a custom card)
1633
1986
  // belong to that control: swallowing Space/Enter/arrows there made it impossible to type a space
1634
1987
  // or press the button from the keyboard. The drag handle is part of the item, not a foreign control.
1635
- _isForeignControl(e) {
1636
- const t = e.composedPath()[0];
1637
- return !(t instanceof HTMLElement) || t.classList.contains("handle") || t.classList.contains("item") ? !1 : t.isContentEditable || t.matches('input, textarea, select, button, summary, a[href], [role="button"], [role="textbox"], [role="combobox"]');
1638
- }
1639
- _onKeyDown(e) {
1640
- if (this._isForeignControl(e)) return;
1641
- const t = this._visibleItemIds();
1642
- if (!t.length) return;
1643
- const r = this._focusedId && t.includes(this._focusedId) ? this._focusedId : t[0], i = t.indexOf(r), s = this._items.find((c) => c.id === r), a = (s ? this._lists.find((c) => c.id === s.listId) : null)?.orientation === "horizontal", d = this._isRtl(), o = a ? d ? "ArrowLeft" : "ArrowRight" : "ArrowDown", u = a ? d ? "ArrowRight" : "ArrowLeft" : "ArrowUp";
1988
+ _isForeignControl(t) {
1989
+ const e = t.composedPath()[0];
1990
+ return !(e instanceof HTMLElement) || e.classList.contains("handle") || e.classList.contains("item") ? !1 : e.isContentEditable || e.matches('input, textarea, select, button, summary, a[href], [role="button"], [role="textbox"], [role="combobox"]');
1991
+ }
1992
+ _onKeyDown(t) {
1993
+ if (this._isForeignControl(t)) return;
1994
+ const e = this._visibleItemIds();
1995
+ if (!e.length) return;
1996
+ const i = this._focusedId && e.includes(this._focusedId) ? this._focusedId : e[0], r = e.indexOf(i), s = this._items.find((l) => l.id === i), a = (s ? this._lists.find((l) => l.id === s.listId) : null)?.orientation === "horizontal", d = this._isRtl(), o = a ? d ? "ArrowLeft" : "ArrowRight" : "ArrowDown", c = a ? d ? "ArrowRight" : "ArrowLeft" : "ArrowUp";
1644
1997
  if (!this._dragState?.keyboard) {
1645
- if (e.key === o) {
1646
- e.preventDefault(), this._moveFocusBy(t, i, 1);
1998
+ if (t.key === o) {
1999
+ t.preventDefault(), this._moveFocusBy(e, r, 1);
1647
2000
  return;
1648
2001
  }
1649
- if (e.key === u) {
1650
- e.preventDefault(), this._moveFocusBy(t, i, -1);
2002
+ if (t.key === c) {
2003
+ t.preventDefault(), this._moveFocusBy(e, r, -1);
1651
2004
  return;
1652
2005
  }
1653
- if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a") {
1654
- e.preventDefault(), this._setSelection(t, "keyboard"), this._announce(`${t.length} items selected.`);
2006
+ if ((t.ctrlKey || t.metaKey) && t.key.toLowerCase() === "a") {
2007
+ t.preventDefault(), this._setSelection(e, "keyboard"), this._announce(this._t("announceSelectedMany", { count: e.length }));
1655
2008
  return;
1656
2009
  }
1657
- if (e.key === "Enter") {
1658
- e.preventDefault(), this._setSelection([r], "keyboard");
2010
+ if (t.key === "Enter") {
2011
+ t.preventDefault(), this._setSelection([i], "keyboard");
1659
2012
  return;
1660
2013
  }
1661
- if (e.key === " " || e.code === "Space") {
1662
- if (e.preventDefault(), this._isDragLocked()) {
1663
- this._announce("Dragging is disabled right now.");
2014
+ if (t.key === " " || t.code === "Space") {
2015
+ if (t.preventDefault(), this._isDragLocked()) {
2016
+ this._announce(this._t("announceDragDisabled"));
1664
2017
  return;
1665
2018
  }
1666
- const c = this._selectedRootIds(r);
1667
- if (!c.length) return;
1668
- const h = this._itemClonesOnDrag(r);
2019
+ const l = this._selectedRootIds(i);
2020
+ if (!l.length) return;
2021
+ const p = this._itemClonesOnDrag(i);
1669
2022
  this._dragState = {
1670
- snapshot: this._items.map(P),
1671
- movedRootIds: c,
1672
- originId: r,
1673
- clone: h,
2023
+ snapshot: this._items.map(A),
2024
+ movedRootIds: l,
2025
+ originId: i,
2026
+ clone: p,
1674
2027
  keyboard: !0,
1675
- dropTarget: this._initialKeyboardDropTarget(r),
2028
+ dropTarget: this._initialKeyboardDropTarget(i),
1676
2029
  committed: !1
1677
2030
  };
1678
- const _ = c.length === 1 ? `Lifted ${s?.label || "item"}.` : `Lifted ${c.length} items.`;
1679
- this._announce(`${_} Use arrow keys to choose a destination.`), this.requestRender();
2031
+ const g = l.length === 1 ? this._t("announceLifted", { label: s?.label || "item" }) : this._t("announceLiftedMany", { count: l.length });
2032
+ this._announce(`${g} ${this._t("announceLiftedHelp")}`), this.requestRender();
1680
2033
  return;
1681
2034
  }
1682
- if (e.key === "Escape") {
2035
+ if (t.key === "Escape") {
1683
2036
  this._setSelection([], "keyboard");
1684
2037
  return;
1685
2038
  }
1686
2039
  return;
1687
2040
  }
1688
- if (e.key === "Escape") {
1689
- e.preventDefault(), this._cancelDrag(!0);
2041
+ if (t.key === "Escape") {
2042
+ t.preventDefault(), this._cancelDrag(!0);
1690
2043
  return;
1691
2044
  }
1692
- if (e.key === "Enter" || e.key === " " || e.code === "Space") {
1693
- e.preventDefault();
1694
- const c = this._dragState.dropTarget;
1695
- if (!c) return;
1696
- this._commitMove(c, this._dragState.movedRootIds, this._dragState.clone, "keyboard");
2045
+ if (t.key === "Enter" || t.key === " " || t.code === "Space") {
2046
+ t.preventDefault();
2047
+ const l = this._dragState.dropTarget;
2048
+ if (!l) return;
2049
+ this._commitMove(l, this._dragState.movedRootIds, this._dragState.clone, "keyboard");
1697
2050
  return;
1698
2051
  }
1699
- if (["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight"].includes(e.key)) {
1700
- e.preventDefault();
1701
- const c = d ? "ArrowLeft" : "ArrowRight", h = e.key === "ArrowDown" || e.key === c ? 1 : -1;
1702
- this._moveKeyboardDropTarget(h);
2052
+ if (["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight"].includes(t.key)) {
2053
+ t.preventDefault();
2054
+ const l = d ? "ArrowLeft" : "ArrowRight", p = t.key === "ArrowDown" || t.key === l ? 1 : -1;
2055
+ this._moveKeyboardDropTarget(p);
1703
2056
  }
1704
2057
  }
1705
2058
  _isRtl() {
1706
- const e = this.ownerDocument?.defaultView?.getComputedStyle(this).direction;
1707
- return e ? e === "rtl" : this.closest("[dir]")?.getAttribute("dir") === "rtl";
2059
+ const t = this.ownerDocument?.defaultView?.getComputedStyle(this).direction;
2060
+ return t ? t === "rtl" : this.closest("[dir]")?.getAttribute("dir") === "rtl";
1708
2061
  }
1709
- _moveFocusBy(e, t, r) {
1710
- const i = Math.max(0, Math.min(e.length - 1, t + r)), s = e[i];
1711
- this._focusedId = s, this._pendingFocusId = s, !this._applyInteractiveStateInPlace({ restoreFocus: !0 }) && this.requestRender();
2062
+ _moveFocusBy(t, e, i) {
2063
+ const r = Math.max(0, Math.min(t.length - 1, e + i)), s = t[r];
2064
+ this._focusedId = s, this._pendingFocusId = s, this._revealPending = !0, !this._applyInteractiveStateInPlace({ restoreFocus: !0 }) && this.requestRender();
1712
2065
  }
1713
- _onDragStart(e) {
1714
- const t = this._dragActivatorFromPath(e.composedPath()), r = t?.id;
1715
- if (!t || !r) {
1716
- e.preventDefault();
1717
- return;
1718
- }
1719
- if (this._isDragLocked()) {
1720
- e.preventDefault(), this._announce("Dragging is disabled right now.");
1721
- return;
1722
- }
1723
- const i = this._items.find((a) => a.id === r);
1724
- if (!i || i.disabled || i.dragDisabled) {
1725
- e.preventDefault();
2066
+ // The browser must not start a native drag while a card is being dragged with the pointer (an image or a
2067
+ // link inside a card would): the pointer drag is the only drag.
2068
+ _onDragStart(t) {
2069
+ (this._pointerGesture || this._dragState && !this._dragState.keyboard) && t.preventDefault();
2070
+ }
2071
+ _onDocumentKeyDown(t) {
2072
+ if (t.key === "Alt") {
2073
+ this._setNestModifier(!0);
1726
2074
  return;
1727
2075
  }
1728
- const s = this._selection.includes(r) ? this._selectedRootIds(r) : [r];
1729
- this._selection.includes(r) || this._setSelection([r], "pointer");
1730
- const n = this._itemClonesOnDrag(r);
1731
- this._dragState = {
1732
- snapshot: this._items.map(P),
1733
- movedRootIds: s,
1734
- originId: r,
1735
- clone: n,
1736
- keyboard: !1,
1737
- dropTarget: null,
1738
- committed: !1
1739
- }, e.dataTransfer && (e.dataTransfer.effectAllowed = n ? "copyMove" : "move", e.dataTransfer.setData("text/plain", s.join(",")), this._applyDragImage(e.dataTransfer, s.length)), this._announce(
1740
- n ? `Dragging ${s.length === 1 ? i.label : `${s.length} items`} as a copy.` : `Dragging ${s.length === 1 ? i.label : `${s.length} items`}.`
1741
- ), this.requestRender();
1742
- }
1743
- _onDragOver(e) {
1744
- if (!this._dragState || this._dragState.keyboard) return;
1745
- const t = this._dropTargetFromEvent(e);
1746
- if (!t || !this._canDrop(t, this._dragState.movedRootIds)) {
1747
- this._queueDropTarget(null, e.timeStamp);
2076
+ t.key === "Escape" && (!this._dragState || this._dragState.keyboard || (t.preventDefault(), this._cancelDrag(!0)));
2077
+ }
2078
+ _onDocumentKeyUp(t) {
2079
+ t.key === "Alt" && this._setNestModifier(!1);
2080
+ }
2081
+ // Pressing or releasing Alt changes where a card would land without the pointer moving, so the target is
2082
+ // worked out again straight away.
2083
+ _setNestModifier(t) {
2084
+ this._nestModifier !== t && (this._nestModifier = t, !(!this._dragState || this._dragState.keyboard || this._dragState.committed || !this._lastPointer) && this._retarget(this._lastPointer.x, this._lastPointer.y, { immediate: !0 }));
2085
+ }
2086
+ // Works out where the held card would land at (x, y): in this element, or, when it is over another element of the
2087
+ // same group, in that one. `immediate` skips the short delay that stops the highlight flickering.
2088
+ _retarget(t, e, i) {
2089
+ const r = this._dragState;
2090
+ if (!r || r.keyboard || r.committed) return;
2091
+ const s = this._externalAt(t, e);
2092
+ if (s) {
2093
+ r.dropTarget && this._setDropTarget(null), this._pendingDropTarget = null, this._noteRefusal(!!s.target && !s.usable), this._setExternal(s.usable && s.target ? { peer: s.peer, target: s.target } : null);
1748
2094
  return;
1749
2095
  }
1750
- e.preventDefault(), this._queueDropTarget(t, e.timeStamp), e.dataTransfer && (e.dataTransfer.dropEffect = this._dragState.clone ? "copy" : "move");
1751
- }
1752
- _onDrop(e) {
1753
- if (!this._dragState || this._dragState.keyboard) return;
1754
- const t = this._dropTargetFromEvent(e);
1755
- !t || !this._canDrop(t, this._dragState.movedRootIds) || (e.preventDefault(), this._commitMove(t, this._dragState.movedRootIds, this._dragState.clone, "pointer"));
1756
- }
1757
- _onDocumentKeyDown(e) {
1758
- e.key === "Escape" && (!this._dragState || this._dragState.keyboard || (e.preventDefault(), this._cancelDrag(!0)));
1759
- }
1760
- _onDragEnd() {
1761
- !this._dragState || this._dragState.keyboard || this._dragState.committed || (this._setDraggingVisualState(this._draggingIds(), !1), this._pendingDropTarget = null, this._setDropTargetVisualState(this._dragState.dropTarget, !1), this._clearPointerDragPreview(), this._dragState = null, this._removeDragImage(), this._announce("Drag cancelled."), this.requestRender());
2096
+ this._setExternal(null);
2097
+ const n = this._dropTargetFromPoint(t, e), a = n && this._canDrop(n, r.movedRootIds) ? n : null;
2098
+ this._noteRefusal(!!n && !a), i.immediate ? this._setDropTarget(a) : this._queueDropTarget(a, i.timestamp ?? performance.now());
2099
+ }
2100
+ // The other element of the same group under the pointer (this one wins where they overlap), and whether it
2101
+ // takes the held items at the place it found.
2102
+ _peerUnder(t, e) {
2103
+ const i = this._group();
2104
+ if (!i) return null;
2105
+ const r = (s) => {
2106
+ const n = s.getBoundingClientRect();
2107
+ return t >= n.left && t <= n.right && e >= n.top && e <= n.bottom && n.width > 0 && n.height > 0;
2108
+ };
2109
+ if (r(this)) return null;
2110
+ for (const s of $._instances)
2111
+ if (!(s === this || s._group() !== i || !s.isConnected || s.ownerDocument !== this.ownerDocument) && r(s))
2112
+ return s;
2113
+ return null;
1762
2114
  }
1763
- _dropTargetFromEvent(e) {
1764
- return this._dropTargetFromPath(e.composedPath(), e.clientX, e.clientY);
2115
+ _externalAt(t, e) {
2116
+ if (!this._dragState || this._dragState.keyboard) return null;
2117
+ const i = this._peerUnder(t, e);
2118
+ if (!i) return null;
2119
+ const r = this._sessionFor(this._dragState.movedRootIds, this._dragState.clone);
2120
+ i._nestModifier = this._nestModifier;
2121
+ const s = i._dropTargetFromPoint(t, e), n = !!s && i._canDrop(s, r.rootIds, r.clone, r);
2122
+ return { peer: i, target: s, usable: n };
2123
+ }
2124
+ _setExternal(t) {
2125
+ const e = this._dragState;
2126
+ if (!e) return;
2127
+ const i = e.external ?? null;
2128
+ if (!(i && t && i.peer === t.peer && H(i.target, t.target))) {
2129
+ if (!i && !t) {
2130
+ e.external = null;
2131
+ return;
2132
+ }
2133
+ i?.peer._showExternalTarget(null), e.external = t, t?.peer._showExternalTarget(t.target);
2134
+ }
1765
2135
  }
1766
- _dropTargetFromPath(e, t, r) {
1767
- const i = e.find((y) => y instanceof HTMLElement && y.classList.contains("dropzone"));
1768
- if (i) {
1769
- const y = {
1770
- listId: i.getAttribute("data-list-id") || "",
1771
- parentId: i.getAttribute("data-parent-id") || null,
1772
- beforeId: i.getAttribute("data-before-id") || null,
1773
- mode: i.getAttribute("data-mode") === "inside" ? "inside" : "before"
2136
+ // Marks the place in this element where a card held over it from another element would land.
2137
+ _showExternalTarget(t) {
2138
+ H(this._externalTarget, t) || (this._setDropTargetVisualState(this._externalTarget, !1), this._externalTarget = t, this._setDropTargetVisualState(t, !0));
2139
+ }
2140
+ // The held items, with all their children, as they leave this element.
2141
+ _sessionFor(t, e) {
2142
+ const i = this._dragState?.session;
2143
+ if (i && i.clone === e && i.rootIds.join() === t.join()) return i;
2144
+ const r = T(this._items), s = M(this._items), n = /* @__PURE__ */ new Set(), a = [], d = (c) => {
2145
+ const l = r.get(c);
2146
+ !l || n.has(c) || (n.add(c), a.push(A(l)), (s.get(w(l.listId, c)) || []).forEach(d));
2147
+ };
2148
+ t.forEach(d);
2149
+ const o = {
2150
+ source: this,
2151
+ rootIds: [...t],
2152
+ items: a,
2153
+ clone: e,
2154
+ sourceListIds: Array.from(new Set(t.map((c) => r.get(c)?.listId).filter((c) => !!c)))
2155
+ };
2156
+ return this._dragState && (this._dragState.session = o), o;
2157
+ }
2158
+ // Moves (or copies) items into another element: both report it, and either can cancel it first.
2159
+ _transferTo(t, e, i, r, s) {
2160
+ const n = () => (this._dragState && this._cancelDrag(!1), this._announce(this._t("announceRejected")), !1), a = this._sessionFor(i, r);
2161
+ if (!t._canDrop(e, a.rootIds, a.clone, a)) return n();
2162
+ const d = new Set(t._items.map((h) => h.id)), o = /* @__PURE__ */ new Map();
2163
+ a.items.forEach((h) => {
2164
+ if (!r) {
2165
+ o.set(h.id, h.id);
2166
+ return;
2167
+ }
2168
+ const f = h.id.includes("--copy-") ? h.id.split("--copy-")[0] : h.id;
2169
+ let x = "";
2170
+ do
2171
+ x = `${f}--copy-${this._cloneSeed++}`;
2172
+ while (d.has(x));
2173
+ d.add(x), o.set(h.id, x);
2174
+ });
2175
+ const c = a.items.map((h) => {
2176
+ const f = a.rootIds.indexOf(h.id);
2177
+ return {
2178
+ ...A(h),
2179
+ id: o.get(h.id) || h.id,
2180
+ parentId: h.parentId && o.has(h.parentId) && o.get(h.parentId) || null,
2181
+ listId: e.listId,
2182
+ label: r && f === 0 ? `${h.label} copy` : h.label,
2183
+ ...h.data !== void 0 ? { data: B(h.data) } : {}
1774
2184
  };
1775
- if (y.listId) return y;
2185
+ }), l = a.rootIds.map((h) => o.get(h) || h), p = j(
2186
+ [...t._items, ...c],
2187
+ t._lists,
2188
+ e,
2189
+ l,
2190
+ !1,
2191
+ (h) => h
2192
+ ), g = t._lists.find((h) => h.id === e.listId), b = {
2193
+ items: p.items,
2194
+ movedIds: l,
2195
+ nextSelection: [...l],
2196
+ operation: r ? "clone" : e.mode === "inside" ? "nest" : "transfer",
2197
+ target: e,
2198
+ clone: r,
2199
+ source: s,
2200
+ external: { direction: "in", peer: this }
2201
+ };
2202
+ let y = null;
2203
+ if (!r) {
2204
+ const h = new Set(a.items.map((f) => f.id));
2205
+ y = {
2206
+ items: U(this._lists, this._items.filter((f) => !h.has(f.id)).map(A)),
2207
+ movedIds: [...a.rootIds],
2208
+ nextSelection: this._selection.filter((f) => !h.has(f)),
2209
+ operation: "transfer",
2210
+ target: e,
2211
+ clone: !1,
2212
+ source: s,
2213
+ external: { direction: "out", peer: t },
2214
+ destination: g?.label || e.listId
2215
+ };
2216
+ }
2217
+ return !t._askBeforeChange(b) || y && !this._askBeforeChange(y) ? n() : (this._setExternal(null), t._showExternalTarget(null), y ? this._applyPlan(y) : (this._dragState && (this._dragState.committed = !0), this._stopAutoScroll(), this._clearPointerDragPreview(), this._dragState = null, this._removeDragImage(), this.requestRender()), t._applyPlan(b), !0);
2218
+ }
2219
+ // Over a place that exists but will not take the drop (a full list, a read-only one, canDrop said no) the
2220
+ // lifted card says so.
2221
+ _noteRefusal(t) {
2222
+ this._dragImage?.toggleAttribute && this._dragImage.toggleAttribute("data-refused", t);
2223
+ }
2224
+ _dropTargetFromPath(t, e, i) {
2225
+ const r = t.find((I) => I instanceof HTMLElement && I.classList.contains("dropzone"));
2226
+ if (r) {
2227
+ const I = {
2228
+ listId: r.getAttribute("data-list-id") || "",
2229
+ parentId: r.getAttribute("data-parent-id") || null,
2230
+ beforeId: r.getAttribute("data-before-id") || null,
2231
+ mode: r.getAttribute("data-mode") === "inside" ? "inside" : "before"
2232
+ };
2233
+ if (I.listId) return I;
1776
2234
  }
1777
- const s = e.find((y) => y instanceof HTMLElement && y.classList.contains("item"));
2235
+ const s = t.find((I) => I instanceof HTMLElement && I.classList.contains("item"));
1778
2236
  if (!s) {
1779
- const R = e.find(
1780
- ($) => $ instanceof HTMLElement && $.classList.contains("list") && $.hasAttribute("data-list-id")
2237
+ const P = t.find(
2238
+ (k) => k instanceof HTMLElement && k.classList.contains("list") && k.hasAttribute("data-list-id")
1781
2239
  )?.getAttribute("data-list-id");
1782
- return R ? { listId: R, parentId: null, beforeId: null, mode: "before" } : null;
2240
+ return P ? { listId: P, parentId: null, beforeId: null, mode: "before" } : null;
1783
2241
  }
1784
2242
  const n = s.getAttribute("data-id");
1785
2243
  if (!n) return null;
1786
- const a = this._items.find((y) => y.id === n);
2244
+ const a = this._items.find((I) => I.id === n);
1787
2245
  if (!a) return null;
1788
- const d = this._lists.find((y) => y.id === a.listId), o = s.getBoundingClientRect(), u = d?.orientation === "horizontal", c = u ? o.left : o.top, h = u ? o.right : o.bottom, _ = u ? t : r, b = Math.max(1, h - c), S = (_ - c) / b, m = u && this._isRtl() ? 1 - S : S, v = this.getAttribute("allow-nesting") !== "false" && !a.disabled;
1789
- if (m <= 0.34)
1790
- return {
1791
- listId: a.listId,
1792
- parentId: a.parentId,
1793
- beforeId: a.id,
1794
- mode: "before"
1795
- };
1796
- if (v && m >= 0.34 && m <= 0.74)
2246
+ const d = this._lists.find((I) => I.id === a.listId), o = s.getBoundingClientRect(), c = d?.orientation === "horizontal", l = c ? o.left : o.top, p = c ? o.right : o.bottom, g = c ? e : i, b = Math.max(1, p - l), y = (g - l) / b, h = c && this._isRtl() ? 1 - y : y, f = this.getAttribute("allow-nesting") !== "false" && !a.disabled, x = this._nestTrigger(), D = f && (x === "area" ? h > 0.34 && h <= 0.74 : h >= 0.25 && h <= 0.75 && (this._nestModifier || x === "gutter" && this._inNestGutter(o, e, i, c))), C = x === "area" ? h <= 0.34 : h < 0.5;
2247
+ if (D)
1797
2248
  return {
1798
2249
  listId: a.listId,
1799
2250
  parentId: a.id,
1800
2251
  beforeId: null,
1801
2252
  mode: "inside"
1802
2253
  };
1803
- const A = E(this._items).get(k(a.listId, a.parentId)) || [], z = A.indexOf(a.id), f = z >= 0 && A[z + 1] || null;
2254
+ if (C)
2255
+ return {
2256
+ listId: a.listId,
2257
+ parentId: a.parentId,
2258
+ beforeId: a.id,
2259
+ mode: "before"
2260
+ };
2261
+ const E = M(this._items).get(w(a.listId, a.parentId)) || [], F = E.indexOf(a.id), _ = F >= 0 && E[F + 1] || null;
1804
2262
  return {
1805
2263
  listId: a.listId,
1806
2264
  parentId: a.parentId,
1807
- beforeId: f,
2265
+ beforeId: _,
1808
2266
  mode: "before"
1809
2267
  };
1810
2268
  }
1811
- _dropTargetFromPoint(e, t) {
1812
- return this._dropTargetFromPath(this._pathFromPoint(e, t), e, t);
2269
+ // The far side of a card (its right in a left-to-right list, the bottom of a card in a horizontal lane):
2270
+ // somewhere a pointer only goes on purpose, and the only way to nest without a keyboard.
2271
+ _inNestGutter(t, e, i, r) {
2272
+ if (r) {
2273
+ const a = t.bottom - t.top;
2274
+ return i >= t.bottom - Math.max(24, Math.min(70, a * 0.3));
2275
+ }
2276
+ const s = t.right - t.left, n = Math.max(48, Math.min(140, s * 0.3));
2277
+ return this._isRtl() ? e <= t.left + n : e >= t.right - n;
2278
+ }
2279
+ _dropTargetFromPoint(t, e) {
2280
+ return this._dropTargetFromPath(this._pathFromPoint(t, e), t, e);
1813
2281
  }
1814
- _beginPointerDrag(e, t) {
2282
+ _beginPointerDrag(t, e) {
1815
2283
  if (!this._pointerGesture || this._dragState) return;
1816
- const r = this._items.find((i) => i.id === this._pointerGesture?.originId);
1817
- r && (this._dragState = {
1818
- snapshot: this._items.map(P),
2284
+ const i = this._items.find((r) => r.id === this._pointerGesture?.originId);
2285
+ i && (this._dragState = {
2286
+ snapshot: this._items.map(A),
1819
2287
  movedRootIds: [...this._pointerGesture.movedRootIds],
1820
2288
  originId: this._pointerGesture.originId,
1821
2289
  clone: this._pointerGesture.clone,
@@ -1823,336 +2291,458 @@ class he extends ee {
1823
2291
  dropTarget: null,
1824
2292
  committed: !1
1825
2293
  }, this._pendingDropTarget = null, this._applyPointerPreview(
1826
- e,
1827
2294
  t,
2295
+ e,
1828
2296
  this._dragState.movedRootIds.length,
1829
- this._dragState.clone
1830
- ), this._setDraggingVisualState(this._draggingIds(), !0), this._announce(
1831
- this._dragState.clone ? `Dragging ${this._dragState.movedRootIds.length === 1 ? r.label : `${this._dragState.movedRootIds.length} items`} as a copy.` : `Dragging ${this._dragState.movedRootIds.length === 1 ? r.label : `${this._dragState.movedRootIds.length} items`}.`
1832
- ));
1833
- }
1834
- _onPointerDown(e) {
1835
- const t = this._dragActivatorFromPath(e.composedPath()), r = t?.id;
1836
- if (!t || !r) return;
2297
+ this._dragState.clone,
2298
+ { x: this._pointerGesture.startX, y: this._pointerGesture.startY }
2299
+ ), this._setDraggingVisualState(this._draggingIds(), !0), this._announceDragging(i.label, this._dragState.movedRootIds.length, this._dragState.clone));
2300
+ }
2301
+ _onPointerDown(t) {
2302
+ const e = this._dragActivatorFromPath(t.composedPath()), i = e?.id;
2303
+ if (!e || !i) return;
1837
2304
  if (this._isDragLocked()) {
1838
- e.preventDefault(), this._announce("Dragging is disabled right now.");
2305
+ t.preventDefault(), this._announce(this._t("announceDragDisabled"));
1839
2306
  return;
1840
2307
  }
1841
- const i = this._items.find((n) => n.id === r);
1842
- if (!i || i.disabled || i.dragDisabled) {
1843
- e.preventDefault();
2308
+ const r = this._items.find((a) => a.id === i);
2309
+ if (!r || r.disabled || r.dragDisabled) {
2310
+ t.preventDefault();
1844
2311
  return;
1845
2312
  }
1846
- e.preventDefault();
2313
+ const s = t.pointerType === "touch" && e.kind !== "handle" && this._touchHoldDelay() > 0;
2314
+ s || t.preventDefault();
1847
2315
  try {
1848
- t.element.setPointerCapture?.(e.pointerId);
2316
+ e.element.setPointerCapture?.(t.pointerId);
1849
2317
  } catch {
1850
2318
  }
1851
- const s = this._selection.includes(r) ? this._selectedRootIds(r) : [r];
1852
- this._pointerGesture = {
1853
- pointerId: e.pointerId,
1854
- pointerType: e.pointerType,
1855
- originId: r,
1856
- movedRootIds: s,
1857
- clone: this._itemClonesOnDrag(r),
1858
- startX: e.clientX,
1859
- startY: e.clientY,
2319
+ this._clearHoldTimer();
2320
+ const n = this._selection.includes(i) ? this._selectedRootIds(i) : [i];
2321
+ if (this._pointerGesture = {
2322
+ pointerId: t.pointerId,
2323
+ pointerType: t.pointerType,
2324
+ originId: i,
2325
+ movedRootIds: n,
2326
+ clone: this._itemClonesOnDrag(i),
2327
+ startX: t.clientX,
2328
+ startY: t.clientY,
1860
2329
  moved: !1,
1861
- captureTarget: t.element
1862
- };
2330
+ captureTarget: e.element,
2331
+ hold: s,
2332
+ holdTimer: null
2333
+ }, s) {
2334
+ const a = this._pointerGesture;
2335
+ a.holdTimer = setTimeout(() => {
2336
+ if (a.holdTimer = null, !(this._pointerGesture !== a || a.moved)) {
2337
+ a.hold = !1, a.moved = !0, this._beginPointerDrag(a.startX, a.startY), this._lastPointer = { x: a.startX, y: a.startY };
2338
+ try {
2339
+ this.ownerDocument?.defaultView?.navigator?.vibrate?.(8);
2340
+ } catch {
2341
+ }
2342
+ }
2343
+ }, this._touchHoldDelay());
2344
+ }
2345
+ }
2346
+ _touchHoldDelay() {
2347
+ const t = this.getAttribute("touch-hold-delay");
2348
+ if (t === null || t.trim() === "") return Z;
2349
+ const e = Number(t);
2350
+ return Number.isFinite(e) ? Math.min(2e3, Math.max(0, e)) : Z;
2351
+ }
2352
+ _clearHoldTimer() {
2353
+ this._pointerGesture?.holdTimer && clearTimeout(this._pointerGesture.holdTimer), this._pointerGesture && (this._pointerGesture.holdTimer = null);
2354
+ }
2355
+ // While a card is lifted (or about to be) the finger must drag it, not scroll the page.
2356
+ _onTouchMove(t) {
2357
+ this._dragState && !this._dragState.keyboard && t.cancelable && t.preventDefault();
2358
+ }
2359
+ // A long press raises the system's context menu (copy, save image): not while a card is held.
2360
+ _onContextMenu(t) {
2361
+ (this._pointerGesture?.pointerType === "touch" || this._dragState && !this._dragState.keyboard) && t.preventDefault();
1863
2362
  }
1864
- _onPointerMove(e) {
1865
- if (!(!this._pointerGesture || e.pointerId !== this._pointerGesture.pointerId)) {
1866
- if (e.preventDefault(), !this._pointerGesture.moved) {
1867
- if (Math.hypot(e.clientX - this._pointerGesture.startX, e.clientY - this._pointerGesture.startY) < 6) return;
1868
- this._pointerGesture.moved = !0, this._beginPointerDrag(e.clientX, e.clientY);
2363
+ _onPointerMove(t) {
2364
+ if (!(!this._pointerGesture || t.pointerId !== this._pointerGesture.pointerId)) {
2365
+ if (this._pointerGesture.hold) {
2366
+ Math.hypot(t.clientX - this._pointerGesture.startX, t.clientY - this._pointerGesture.startY) > pt && (this._clearHoldTimer(), this._pointerGesture = null);
2367
+ return;
1869
2368
  }
1870
- if (!(!this._dragState || this._dragState.keyboard) && (this._movePointerPreview(e.clientX, e.clientY), this._updateAutoScroll(e.clientX, e.clientY), !this._dragState.committed)) {
1871
- const t = this._dropTargetFromPoint(e.clientX, e.clientY);
1872
- if (!t || !this._canDrop(t, this._dragState.movedRootIds)) {
1873
- this._queueDropTarget(null, e.timeStamp);
1874
- return;
1875
- }
1876
- this._queueDropTarget(t, e.timeStamp);
2369
+ if (t.preventDefault(), !this._pointerGesture.moved) {
2370
+ if (Math.hypot(t.clientX - this._pointerGesture.startX, t.clientY - this._pointerGesture.startY) < 6) return;
2371
+ this._pointerGesture.moved = !0, this._beginPointerDrag(t.clientX, t.clientY);
1877
2372
  }
2373
+ !this._dragState || this._dragState.keyboard || (this._nestModifier = !!t.altKey, this._lastPointer = { x: t.clientX, y: t.clientY }, this._movePointerPreview(t.clientX, t.clientY), this._updateAutoScroll(t.clientX, t.clientY), this._retarget(t.clientX, t.clientY, { timestamp: t.timeStamp }));
1878
2374
  }
1879
2375
  }
1880
- // Holding a dragged card near the top or bottom edge scrolls the page (or the nearest scrolling
1881
- // container), so lists and positions that are off screen can be reached with the pointer.
1882
- _updateAutoScroll(e, t) {
1883
- this._autoScrollPoint = { x: e, y: t }, !this._autoScrollFrame && typeof requestAnimationFrame == "function" && (this._autoScrollFrame = requestAnimationFrame(this._autoScrollTick));
2376
+ // Holding a dragged card near an edge scrolls what is under it: the board sideways, the list under
2377
+ // the pointer when it has its own scrollbar, and the page (or the nearest scrolling container) up
2378
+ // and down, so lists and positions that are off screen can be reached with the pointer.
2379
+ _updateAutoScroll(t, e) {
2380
+ this._autoScrollPoint = { x: t, y: e }, !this._autoScrollFrame && typeof requestAnimationFrame == "function" && (this._autoScrollFrame = requestAnimationFrame(this._autoScrollTick));
1884
2381
  }
1885
2382
  _stopAutoScroll() {
1886
2383
  this._autoScrollFrame && typeof cancelAnimationFrame == "function" && cancelAnimationFrame(this._autoScrollFrame), this._autoScrollFrame = 0, this._autoScrollPoint = null;
1887
2384
  }
1888
- _onPointerUp(e) {
1889
- if (!this._pointerGesture || e.pointerId !== this._pointerGesture.pointerId) return;
1890
- e.preventDefault();
2385
+ // Scrolls this element's own board sideways, and the list under (x, y) when it has a scrollbar of its own, if the
2386
+ // pointer is at their edge. True when something moved.
2387
+ _scrollOwn(t, e) {
2388
+ const i = this.ownerDocument?.defaultView;
2389
+ let r = !1;
2390
+ const s = this.root.querySelector(".lists");
2391
+ if (s && s.scrollWidth > s.clientWidth + 1) {
2392
+ const a = s.getBoundingClientRect(), d = K(t, Math.max(0, a.left), Math.min(i?.innerWidth ?? 1 / 0, a.right));
2393
+ d && (s.scrollLeft += d, r = !0);
2394
+ }
2395
+ const n = this._pathFromPoint(t, e).find((a) => a.classList?.contains("items"));
2396
+ if (n && n.scrollHeight > n.clientHeight + 1 && i?.getComputedStyle(n).overflowY !== "visible") {
2397
+ const a = n.getBoundingClientRect(), d = K(e, a.top, a.bottom);
2398
+ d && (n.scrollTop += d, r = !0);
2399
+ }
2400
+ return r;
2401
+ }
2402
+ _onPointerUp(t) {
2403
+ if (!this._pointerGesture || t.pointerId !== this._pointerGesture.pointerId) return;
2404
+ t.preventDefault();
1891
2405
  try {
1892
- this._pointerGesture.captureTarget?.releasePointerCapture?.(e.pointerId);
2406
+ this._pointerGesture.captureTarget?.releasePointerCapture?.(t.pointerId);
1893
2407
  } catch {
1894
2408
  }
1895
- const t = this._pointerGesture;
1896
- if (this._pointerGesture = null, this._stopAutoScroll(), !this._dragState || this._dragState.keyboard) return;
1897
- const r = t.moved ? this._releaseDropTarget(e.clientX, e.clientY) : null;
1898
- if (t.moved && r) {
2409
+ const e = this._pointerGesture;
2410
+ if (this._clearHoldTimer(), this._pointerGesture = null, this._stopAutoScroll(), !this._dragState || this._dragState.keyboard) return;
2411
+ this._nestModifier = !!t.altKey;
2412
+ const i = e.moved ? this._externalAt(t.clientX, t.clientY) : null;
2413
+ if (i) {
2414
+ i.usable && i.target ? this._transferTo(i.peer, i.target, this._dragState.movedRootIds, this._dragState.clone, "pointer") : this._cancelDrag(!0);
2415
+ return;
2416
+ }
2417
+ const r = e.moved ? this._releaseDropTarget(t.clientX, t.clientY) : null;
2418
+ if (e.moved && r) {
1899
2419
  this._commitMove(r, this._dragState.movedRootIds, this._dragState.clone, "pointer");
1900
2420
  return;
1901
2421
  }
1902
- t.moved ? this._cancelDrag(!0) : (this._setDropTargetVisualState(this._dragState.dropTarget, !1), this._clearPointerDragPreview(), this._dragState = null, this._removeDragImage(), this.requestRender());
2422
+ e.moved ? this._cancelDrag(!0) : (this._setDropTargetVisualState(this._dragState.dropTarget, !1), this._clearPointerDragPreview(), this._dragState = null, this._removeDragImage(), this.requestRender());
1903
2423
  }
1904
- _onPointerCancel(e) {
1905
- !this._pointerGesture || e.pointerId !== this._pointerGesture.pointerId || (this._pointerGesture = null, this._stopAutoScroll(), this._dragState && this._cancelDrag(!0));
2424
+ _onPointerCancel(t) {
2425
+ !this._pointerGesture || t.pointerId !== this._pointerGesture.pointerId || (this._clearHoldTimer(), this._pointerGesture = null, this._stopAutoScroll(), this._dragState && this._cancelDrag(!0));
1906
2426
  }
1907
- _setSelection(e, t) {
1908
- const r = new Set(this._items.map((a) => a.id)), i = Array.from(new Set(e.filter((a) => r.has(a)))), s = [...this._selection];
1909
- this._selection = i, this._rangeAnchorId = i[i.length - 1] || null, this._focusedId = i[i.length - 1] || this._focusedId;
1910
- const n = X(i);
2427
+ _setSelection(t, e) {
2428
+ const i = new Set(this._items.map((a) => a.id)), r = Array.from(new Set(t.filter((a) => i.has(a)))), s = [...this._selection];
2429
+ this._selection = r, this._rangeAnchorId = r[r.length - 1] || null, this._focusedId = r[r.length - 1] || this._focusedId;
2430
+ const n = rt(r);
1911
2431
  if (this.getAttribute("selection") !== n) {
1912
2432
  this._lastSelectionAttr = n, this._suppressAttributeRender = !0;
1913
2433
  try {
1914
- i.length ? this.setAttribute("selection", n) : this.removeAttribute("selection");
2434
+ r.length ? this.setAttribute("selection", n) : this.removeAttribute("selection");
1915
2435
  } finally {
1916
2436
  this._suppressAttributeRender = !1;
1917
2437
  }
1918
2438
  }
1919
2439
  if (this.dispatchEvent(new CustomEvent("selection-change", {
1920
2440
  detail: {
1921
- selection: [...i],
2441
+ selection: [...r],
1922
2442
  previousSelection: s
1923
2443
  },
1924
2444
  bubbles: !0,
1925
2445
  composed: !0
1926
- })), t !== "restore") {
2446
+ })), e !== "restore") {
1927
2447
  if (this._applyInteractiveStateInPlace({ restoreFocus: !0 })) return;
1928
2448
  this.requestRender();
1929
2449
  }
1930
2450
  }
1931
- _toggleSelection(e) {
1932
- const t = this._selection.includes(e) ? this._selection.filter((r) => r !== e) : [...this._selection, e];
1933
- this._setSelection(t, "pointer"), this._announce(`${t.length} items selected.`);
2451
+ _toggleSelection(t) {
2452
+ const e = this._selection.includes(t) ? this._selection.filter((i) => i !== t) : [...this._selection, t];
2453
+ this._setSelection(e, "pointer"), this._announce(this._t("announceSelectedMany", { count: e.length }));
1934
2454
  }
1935
- _selectRangeTo(e) {
1936
- const t = this._visibleItemIds(), r = this._rangeAnchorId || this._focusedId || e, i = t.indexOf(r), s = t.indexOf(e);
1937
- if (i < 0 || s < 0) {
1938
- this._setSelection([e], "pointer");
2455
+ _selectRangeTo(t) {
2456
+ const e = this._visibleItemIds(), i = this._rangeAnchorId || this._focusedId || t, r = e.indexOf(i), s = e.indexOf(t);
2457
+ if (r < 0 || s < 0) {
2458
+ this._setSelection([t], "pointer");
1939
2459
  return;
1940
2460
  }
1941
- const [n, a] = i <= s ? [i, s] : [s, i];
1942
- this._setSelection(t.slice(n, a + 1), "pointer"), this._announce(`${a - n + 1} items selected.`);
2461
+ const [n, a] = r <= s ? [r, s] : [s, r];
2462
+ this._setSelection(e.slice(n, a + 1), "pointer"), this._announce(this._t("announceSelectedMany", { count: a - n + 1 }));
1943
2463
  }
1944
2464
  _visibleItemIds() {
1945
- const e = Q(this._items, new Set(this._selection), new Set(this._draggingIds()), this.filterQuery, this.sort);
1946
- return Array.from(e.values()).flat().filter((t) => !t.disabled).map((t) => t.id);
2465
+ const t = nt(this._items, new Set(this._selection), new Set(this._draggingIds()), this.filterQuery, this.sort);
2466
+ return Array.from(t.values()).flat().filter((e) => !e.disabled).map((e) => e.id);
1947
2467
  }
1948
- _selectedRootIds(e) {
1949
- const t = this._selection.length ? [...this._selection] : e ? [e] : [], r = T(this._items), i = new Set(t);
1950
- return t.filter((s) => {
1951
- const n = r.get(s);
2468
+ _selectedRootIds(t) {
2469
+ const e = this._selection.length ? [...this._selection] : t ? [t] : [], i = T(this._items), r = new Set(e);
2470
+ return e.filter((s) => {
2471
+ const n = i.get(s);
1952
2472
  if (!n) return !1;
1953
2473
  let a = n.parentId;
1954
2474
  for (; a; ) {
1955
- if (i.has(a)) return !1;
1956
- a = r.get(a)?.parentId ?? null;
2475
+ if (r.has(a)) return !1;
2476
+ a = i.get(a)?.parentId ?? null;
1957
2477
  }
1958
2478
  return !n.disabled;
1959
2479
  });
1960
2480
  }
1961
2481
  _draggingIds() {
1962
2482
  if (!this._dragState) return [];
1963
- const e = T(this._items), t = E(this._items), r = [], i = (s) => {
1964
- r.push(s);
1965
- const n = e.get(s);
2483
+ const t = T(this._items), e = M(this._items), i = [], r = (s) => {
2484
+ i.push(s);
2485
+ const n = t.get(s);
1966
2486
  if (!n) return;
1967
- (t.get(k(n.listId, s)) || []).forEach(i);
2487
+ (e.get(w(n.listId, s)) || []).forEach(r);
1968
2488
  };
1969
- return this._dragState.movedRootIds.forEach(i), r;
2489
+ return this._dragState.movedRootIds.forEach(r), i;
1970
2490
  }
1971
- _itemClonesOnDrag(e) {
1972
- const t = this._items.find((i) => i.id === e);
1973
- return t ? t.cloneOnDrag ? !0 : !!this._lists.find((i) => i.id === t.listId)?.cloneOnDrag : !1;
2491
+ _itemClonesOnDrag(t) {
2492
+ const e = this._items.find((r) => r.id === t);
2493
+ return e ? e.cloneOnDrag ? !0 : !!this._lists.find((r) => r.id === e.listId)?.cloneOnDrag : !1;
1974
2494
  }
1975
2495
  _isDragLocked() {
1976
2496
  return !!(this.hasAttribute("disabled") || this.sort !== "manual" || this.filterQuery && !this.hasAttribute("allow-filtered-drag"));
1977
2497
  }
1978
- _canDrop(e, t) {
2498
+ // `incoming` is set when the items come from another element: they are not in this one yet, so the checks
2499
+ // that refer to them (they cannot be dropped inside themselves) are replaced by the ones that matter for
2500
+ // newcomers (their ids must be free here).
2501
+ _canDrop(t, e, i = this._dragState?.clone ?? !1, r) {
1979
2502
  if (this._isDragLocked()) return !1;
1980
- const r = this._lists.find((o) => o.id === e.listId);
1981
- if (!r || r.disabled) return !1;
1982
- const i = T(this._items), s = /* @__PURE__ */ new Set(), n = E(this._items), a = (o) => {
1983
- s.add(o);
1984
- const u = i.get(o);
1985
- u && (n.get(k(u.listId, o)) || []).forEach(a);
1986
- };
1987
- if (t.forEach(a), e.parentId && s.has(e.parentId) || e.beforeId && s.has(e.beforeId)) return !1;
1988
- const d = Array.from(new Set(t.map((o) => i.get(o)?.listId).filter(Boolean)));
1989
- return !(r.accepts?.length && d.some((o) => !r.accepts?.includes(o)) || e.mode === "inside" && this.getAttribute("allow-nesting") === "false");
1990
- }
1991
- _commitMove(e, t, r, i) {
1992
- if (!this._canDrop(e, t)) return;
1993
- const s = T(this._items), n = E(this._items), a = /* @__PURE__ */ new Set(), d = [], o = (p) => {
1994
- const w = s.get(p);
1995
- !w || a.has(p) || (a.add(p), d.push(p), (n.get(k(w.listId, p)) || []).forEach(o));
1996
- };
1997
- t.forEach(o);
1998
- const u = this._items.map(P), c = u.filter((p) => a.has(p.id)), h = r ? u.map(P) : u.filter((p) => !a.has(p.id)), _ = r ? c.map((p) => this._cloneSubtreeItem(p, d)) : c.map(P), b = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map();
1999
- r && c.forEach((p, w) => {
2000
- b.set(p.id, _[w].id), S.set(_[w].id, p.id);
2001
- }), _.forEach((p) => {
2002
- const w = r ? S.get(p.id) : p.id, F = w ? s.get(w) : null;
2003
- F && (r && (p.parentId = F.parentId && b.has(F.parentId) && b.get(F.parentId) || null), p.listId = e.listId);
2004
- });
2005
- const m = t.map((p) => b.get(p) || p), v = [...h, ..._], D = E(h), A = k(e.listId, e.parentId), z = [...D.get(A) || []], f = e.beforeId ? z.indexOf(e.beforeId) : z.length, y = f >= 0 ? f : z.length;
2006
- z.splice(y, 0, ...m), D.set(A, z), E(_).forEach((p, w) => {
2007
- const [, F] = w.split("::");
2008
- (F || "") !== "__root__" && D.set(w, [...p]);
2009
- });
2010
- const $ = T(v);
2011
- m.forEach((p) => {
2012
- const w = $.get(p);
2013
- w && (w.parentId = e.parentId, w.listId = e.listId);
2014
- });
2015
- const O = [], L = /* @__PURE__ */ new Set(), q = (p, w) => {
2016
- (D.get(k(p, w)) || []).forEach((V, Z) => {
2017
- const N = $.get(V);
2018
- !N || L.has(V) || (L.add(V), N.listId = p, N.parentId = w, N.order = Z, O.push(N), q(p, V));
2019
- });
2503
+ const s = this._lists.find((l) => l.id === t.listId);
2504
+ if (!s || s.disabled) return !1;
2505
+ const n = T(this._items), a = /* @__PURE__ */ new Set(), d = M(this._items);
2506
+ if (r)
2507
+ r.items.forEach((l) => a.add(l.id));
2508
+ else {
2509
+ const l = (p) => {
2510
+ a.add(p);
2511
+ const g = n.get(p);
2512
+ g && (d.get(w(g.listId, p)) || []).forEach(l);
2513
+ };
2514
+ if (e.forEach(l), t.parentId && a.has(t.parentId) || t.beforeId && a.has(t.beforeId)) return !1;
2515
+ }
2516
+ if (r && !r.clone && r.items.some((l) => n.has(l.id))) return !1;
2517
+ const o = r ? r.sourceListIds : Array.from(new Set(e.map((l) => n.get(l)?.listId).filter(Boolean)));
2518
+ if (s.accepts?.length && o.some((l) => !s.accepts?.includes(l)) || t.mode === "inside" && this.getAttribute("allow-nesting") === "false") return !1;
2519
+ if (s.maxItems !== void 0) {
2520
+ const l = this._items.filter((g) => g.listId === t.listId), p = r ? r.items.length : i ? a.size : Array.from(a).filter((g) => n.get(g)?.listId !== t.listId).length;
2521
+ if (p > 0 && l.length + p > s.maxItems) return !1;
2522
+ }
2523
+ const c = this._canDropCallback;
2524
+ if (c)
2525
+ try {
2526
+ const l = r ? r.items.filter((g) => r.rootIds.includes(g.id)) : e.map((g) => n.get(g)).filter((g) => !!g);
2527
+ if (!c({
2528
+ items: l.map(q),
2529
+ movedIds: [...e],
2530
+ targetListId: t.listId,
2531
+ parentId: t.parentId,
2532
+ beforeId: t.beforeId,
2533
+ mode: t.mode,
2534
+ clone: i,
2535
+ ...r ? { from: r.source } : {}
2536
+ })) return !1;
2537
+ } catch (l) {
2538
+ return console.error("ui-sortable: canDrop threw; the drop is refused.", l), !1;
2539
+ }
2540
+ return !0;
2541
+ }
2542
+ _commitMove(t, e, i, r) {
2543
+ if (!this._canDrop(t, e, i)) return !1;
2544
+ const s = T(this._items), n = j(
2545
+ this._items,
2546
+ this._lists,
2547
+ t,
2548
+ e,
2549
+ i,
2550
+ (c, l) => this._cloneSubtreeItem(c, l)
2551
+ ), a = e.map((c) => s.get(c)).filter((c) => !!c), d = i ? "clone" : t.mode === "inside" ? "nest" : a.some((c) => c.listId !== t.listId) ? "transfer" : "reorder", o = {
2552
+ items: n.items,
2553
+ movedIds: n.insertedRootIds,
2554
+ nextSelection: [...n.insertedRootIds],
2555
+ operation: d,
2556
+ target: t,
2557
+ clone: i,
2558
+ source: r
2020
2559
  };
2021
- this._lists.forEach((p) => q(p.id, null)), v.forEach((p) => {
2022
- L.has(p.id) || (p.parentId = null, O.push(p));
2023
- }), this._dragState && (this._dragState.committed = !0), this._items = O.map(P), this._clearPointerDragPreview(), this._dragState = null, this._removeDragImage();
2024
- const H = [...m], g = [...this._selection];
2025
- this._selection = H, this._focusedId = H[0] || null, this._pendingFocusId = this._focusedId, this._syncAttributesFromState();
2026
- const x = J(this._items);
2027
- this._persistSnapshot(x);
2028
- const M = t.map((p) => s.get(p)).filter((p) => !!p), C = r ? "clone" : e.mode === "inside" ? "nest" : M.some((p) => p.listId !== e.listId) ? "transfer" : "reorder", G = {
2560
+ return this._askBeforeChange(o) ? (this._applyPlan(o), !0) : (this._dragState && this._cancelDrag(!1), this._announce(this._t("announceRejected")), !1);
2561
+ }
2562
+ // The last word before anything changes: a listener of `before-change` can cancel the move.
2563
+ _askBeforeChange(t) {
2564
+ return this.dispatchEvent(new CustomEvent("before-change", {
2565
+ detail: {
2566
+ items: t.items.map(q),
2567
+ lists: this.lists,
2568
+ selection: [...t.nextSelection],
2569
+ previousSelection: [...this._selection],
2570
+ movedIds: [...t.movedIds],
2571
+ source: t.source,
2572
+ operation: t.operation,
2573
+ persistence: J(t.items),
2574
+ target: { listId: t.target.listId, parentId: t.target.parentId, beforeId: t.target.beforeId, mode: t.target.mode },
2575
+ clone: t.clone,
2576
+ ...t.external ? { external: t.external } : {}
2577
+ },
2578
+ bubbles: !0,
2579
+ composed: !0,
2580
+ cancelable: !0
2581
+ }));
2582
+ }
2583
+ // Makes a move that was accepted real: the items, the selection, the attributes, the saved positions, the
2584
+ // events and the announcement.
2585
+ _applyPlan(t) {
2586
+ const e = [...this._selection];
2587
+ this._dragState && (this._dragState.committed = !0), this._items = t.items.map(A), this._clearPointerDragPreview(), this._dragState = null, this._removeDragImage(), this._selection = [...t.nextSelection], this._focusedId = t.nextSelection[0] || null, this._pendingFocusId = this._focusedId, this._syncAttributesFromState();
2588
+ const i = J(this._items);
2589
+ this._persistSnapshot(i);
2590
+ const r = {
2029
2591
  items: this.items,
2030
2592
  lists: this.lists,
2031
- selection: [...H],
2032
- previousSelection: g,
2033
- movedIds: [...m],
2034
- source: i,
2035
- operation: C,
2036
- persistence: x
2593
+ selection: [...t.nextSelection],
2594
+ previousSelection: e,
2595
+ movedIds: [...t.movedIds],
2596
+ source: t.source,
2597
+ operation: t.operation,
2598
+ persistence: i,
2599
+ ...t.external ? { external: t.external } : {}
2037
2600
  };
2038
2601
  this.dispatchEvent(new CustomEvent("change", {
2039
- detail: G,
2602
+ detail: r,
2040
2603
  bubbles: !0,
2041
2604
  composed: !0
2042
2605
  })), this.dispatchEvent(new CustomEvent("persist-request", {
2043
- detail: G,
2606
+ detail: r,
2044
2607
  bubbles: !0,
2045
2608
  composed: !0
2046
- })), this._announce(this._messageForMove(C, m.length, e)), this.requestRender();
2609
+ })), this._announce(this._messageForMove(t.operation, t.movedIds.length, t.target, t.destination)), this.requestRender();
2047
2610
  }
2048
2611
  _syncAttributesFromState() {
2049
- const e = pe(this._lists), t = ue(this._items), r = X(this._selection);
2050
- this._lastListsAttr = e, this._lastItemsAttr = t, this._lastSelectionAttr = r, this._suppressAttributeRender = !0;
2612
+ const t = _t(this._lists), e = bt(this._items), i = rt(this._selection);
2613
+ this._lastListsAttr = t, this._lastItemsAttr = e, this._lastSelectionAttr = i, this._suppressAttributeRender = !0;
2051
2614
  try {
2052
- this.setAttribute("lists", e), this.setAttribute("items", t), this._selection.length ? this.setAttribute("selection", r) : this.removeAttribute("selection");
2615
+ this.setAttribute("lists", t), this.setAttribute("items", e), this._selection.length ? this.setAttribute("selection", i) : this.removeAttribute("selection");
2053
2616
  } finally {
2054
2617
  this._suppressAttributeRender = !1;
2055
2618
  }
2056
2619
  }
2057
- _cloneSubtreeItem(e, t) {
2058
- const i = `copy-${this._cloneSeed++}`, n = `${e.id.includes("--copy-") ? e.id.split("--copy-")[0] : e.id}--${i}`;
2620
+ _cloneSubtreeItem(t, e) {
2621
+ const r = `copy-${this._cloneSeed++}`, n = `${t.id.includes("--copy-") ? t.id.split("--copy-")[0] : t.id}--${r}`;
2059
2622
  return {
2060
- ...e,
2623
+ ...t,
2061
2624
  id: n,
2062
- label: t[0] === e.id ? `${e.label} copy` : e.label
2625
+ label: e[0] === t.id ? `${t.label} copy` : t.label,
2626
+ data: B(t.data)
2063
2627
  };
2064
2628
  }
2065
- _messageForMove(e, t, r) {
2066
- const s = this._lists.find((n) => n.id === r.listId)?.label || r.listId;
2067
- return e === "clone" ? `${t === 1 ? "Item copied" : `${t} items copied`} into ${s}.` : e === "nest" ? `${t === 1 ? "Item nested" : `${t} items nested`} in ${s}.` : e === "transfer" ? `${t === 1 ? "Item moved" : `${t} items moved`} to ${s}.` : `${t === 1 ? "Item reordered" : `${t} items reordered`} in ${s}.`;
2629
+ _messageForMove(t, e, i, r) {
2630
+ const s = this._lists.find((d) => d.id === i.listId), n = r || s?.label || i.listId, a = { count: e, list: n };
2631
+ return t === "clone" ? this._t(e === 1 ? "announceCopiedOne" : "announceCopiedMany", a) : t === "nest" ? this._t(e === 1 ? "announceNestedOne" : "announceNestedMany", a) : t === "transfer" ? this._t(e === 1 ? "announceMovedOne" : "announceMovedMany", a) : this._t(e === 1 ? "announceReorderedOne" : "announceReorderedMany", a);
2632
+ }
2633
+ _announceDragging(t, e, i) {
2634
+ e === 1 ? this._announce(this._t(i ? "announceDraggingCopy" : "announceDragging", { label: t })) : this._announce(this._t(i ? "announceDraggingCopyMany" : "announceDraggingMany", { count: e }));
2068
2635
  }
2069
- _persistSnapshot(e) {
2070
- const t = this.getAttribute("persist-key");
2071
- if (t)
2636
+ _persistSnapshot(t) {
2637
+ const e = this.getAttribute("persist-key");
2638
+ if (e)
2072
2639
  try {
2073
- window.localStorage.setItem(t, JSON.stringify(e));
2640
+ window.localStorage.setItem(e, JSON.stringify(t));
2074
2641
  } catch {
2075
2642
  }
2076
2643
  }
2077
- _announce(e) {
2078
- this._liveMessage = e, this._applyLiveMessage();
2644
+ _announce(t) {
2645
+ this._liveMessage = t, this._applyLiveMessage();
2079
2646
  }
2080
- _cancelDrag(e) {
2081
- this._stopAutoScroll(), this._dragState && (this._setDraggingVisualState(this._draggingIds(), !1), this._pendingDropTarget = null, this._setDropTargetVisualState(this._dragState.dropTarget, !1), this._clearPointerDragPreview(), this._items = this._dragState.snapshot.map(P), this._dragState = null, this._pointerGesture = null, this._removeDragImage(), e && this._announce("Drag cancelled."), this._syncAttributesFromState(), this.requestRender());
2082
- }
2083
- _applyDragImage(e, t) {
2084
- this._removeDragImage();
2085
- const r = document.createElement("div");
2086
- r.textContent = t === 1 ? "Dragging item" : `Dragging ${t} items`, r.style.position = "fixed", r.style.top = "-999px", r.style.left = "-999px", r.style.padding = "8px 12px", r.style.borderRadius = "999px", r.style.background = "rgba(15, 23, 42, 0.92)", r.style.color = "#f8fafc", r.style.font = "600 12px/1 Inter, sans-serif", r.style.pointerEvents = "none", document.body.appendChild(r), e.setDragImage(r, 12, 12), this._dragImage = r;
2647
+ _cancelDrag(t) {
2648
+ this._stopAutoScroll(), this._dragState && (this._setDraggingVisualState(this._draggingIds(), !1), this._pendingDropTarget = null, this._setExternal(null), this._setDropTargetVisualState(this._dragState.dropTarget, !1), this._clearPointerDragPreview(), this._items = this._dragState.snapshot.map(A), this._dragState = null, this._clearHoldTimer(), this._pointerGesture = null, this._removeDragImage(), t && this._announce(this._t("announceCancelled")), this._syncAttributesFromState(), this.requestRender());
2087
2649
  }
2088
2650
  _removeDragImage() {
2089
2651
  this._dragImage?.remove(), this._dragImage = null;
2090
2652
  }
2091
- _removeDragPreviewOverlay() {
2092
- this._dragPreviewOverlay?.remove(), this._dragPreviewOverlay = null;
2093
- }
2094
- _applyPointerPreview(e, t, r, i) {
2653
+ _applyPointerPreview(t, e, i, r, s) {
2095
2654
  this._removeDragImage();
2096
- const s = document.createElement("div");
2097
- s.textContent = i ? r === 1 ? "Copying item" : `Copying ${r} items` : r === 1 ? "Moving item" : `Moving ${r} items`, s.style.position = "fixed", s.style.top = "0", s.style.left = "0", s.style.zIndex = "2147483647", s.style.padding = "8px 12px", s.style.borderRadius = "999px", s.style.background = "rgba(15, 23, 42, 0.92)", s.style.color = "#f8fafc", s.style.font = "600 12px/1 Inter, sans-serif", s.style.pointerEvents = "none", s.style.boxShadow = "0 12px 28px rgba(15, 23, 42, 0.22)", document.body.appendChild(s), this._dragImage = s, this._movePointerPreview(e, t);
2098
- }
2099
- _movePointerPreview(e, t) {
2100
- this._dragImage && (this._dragImage.style.transform = `translate(${Math.round(e + 14)}px, ${Math.round(t + 14)}px)`);
2655
+ const n = this._dragState ? this._findItemElement(this._dragState.originId) : null, a = n ? this._buildDragGhost(n, i, r, s) : null;
2656
+ if (a)
2657
+ this.root.appendChild(a), this._dragImage = a;
2658
+ else {
2659
+ const d = document.createElement("div");
2660
+ d.className = "drag-pill", d.textContent = r ? i === 1 ? this._t("copyingOne") : this._t("copyingMany", { count: i }) : i === 1 ? this._t("movingOne") : this._t("movingMany", { count: i }), this.root.appendChild(d), this._dragImage = d, this._dragImageOffset = { x: -14, y: -14 };
2661
+ }
2662
+ this._movePointerPreview(t, e);
2663
+ }
2664
+ // The ghost is a copy of the card being dragged, so it looks like the thing you picked up. It is
2665
+ // inert and carries no ids, so nothing that looks cards up by id can find it.
2666
+ _buildDragGhost(t, e, i, r) {
2667
+ const s = t.getBoundingClientRect(), n = t.cloneNode(!0);
2668
+ if (n.classList.add("item-ghost"), ["id", "data-id", "data-drag-trigger", "tabindex", "role", "aria-selected", "aria-disabled"].forEach((c) => {
2669
+ n.removeAttribute(c);
2670
+ }), n.querySelectorAll("[id], [data-id], [data-drag-trigger], [tabindex]").forEach((c) => {
2671
+ ["id", "data-id", "data-drag-trigger", "tabindex"].forEach((l) => c.removeAttribute(l));
2672
+ }), n.setAttribute("part", "drag-ghost"), n.setAttribute("aria-hidden", "true"), n.setAttribute("inert", ""), n.setAttribute("data-dragging", "false"), n.setAttribute("data-focused", "false"), n.setAttribute("data-drop-inside-active", "false"), e > 1 && n.setAttribute("data-count", "stack"), e > 1 || i) {
2673
+ const c = document.createElement("span");
2674
+ c.className = "ghost-badge", c.textContent = e > 1 ? String(e) : "+", n.appendChild(c);
2675
+ }
2676
+ const a = this.getAttribute("drag-preview-size") === "compact";
2677
+ a && n.setAttribute("data-compact", "true");
2678
+ const d = a ? Math.min(s.width, 240) : s.width;
2679
+ n.style.inlineSize = `${Math.round(d)}px`;
2680
+ const o = !!r && Number.isFinite(r.x) && Number.isFinite(r.y);
2681
+ return this._dragImageOffset = {
2682
+ x: o ? Math.min(Math.max(r.x - s.left, 0), d) : d / 2,
2683
+ y: o ? Math.min(Math.max(r.y - s.top, 0), s.height) : s.height / 2
2684
+ }, n;
2685
+ }
2686
+ _movePointerPreview(t, e) {
2687
+ const i = this._dragImage;
2688
+ i && (i.isConnected || this.root.appendChild(i), i.style.transform = `translate(${Math.round(t - this._dragImageOffset.x)}px, ${Math.round(e - this._dragImageOffset.y)}px)`);
2101
2689
  }
2102
2690
  _keyboardDropTargets() {
2103
- const e = T(this._items), t = E(this._items), r = [], i = this.getAttribute("allow-nesting") !== "false", s = (n, a) => {
2104
- const d = t.get(k(n, a)) || [];
2691
+ const t = T(this._items), e = M(this._items), i = [], r = this.getAttribute("allow-nesting") !== "false", s = (n, a) => {
2692
+ const d = e.get(w(n, a)) || [];
2105
2693
  d.forEach((o) => {
2106
- const u = e.get(o);
2107
- !u || u.hidden || (r.push({
2694
+ const c = t.get(o);
2695
+ !c || c.hidden || (i.push({
2108
2696
  listId: n,
2109
2697
  parentId: a,
2110
2698
  beforeId: o,
2111
2699
  mode: "before",
2112
- label: `Before ${u.label}`
2113
- }), i && r.push({
2700
+ label: this._t("targetBefore", { label: c.label })
2701
+ }), r && i.push({
2114
2702
  listId: n,
2115
2703
  parentId: o,
2116
2704
  beforeId: null,
2117
2705
  mode: "inside",
2118
- label: `Nest inside ${u.label}`
2706
+ label: this._t("targetInside", { label: c.label })
2119
2707
  }), s(n, o));
2120
- }), a ? i && d.length > 0 && r.push({
2708
+ }), a ? r && d.length > 0 && i.push({
2121
2709
  listId: n,
2122
2710
  parentId: a,
2123
2711
  beforeId: null,
2124
2712
  mode: "before",
2125
- label: "After children"
2126
- }) : r.push({
2713
+ label: this._t("targetAfterChildren")
2714
+ }) : i.push({
2127
2715
  listId: n,
2128
2716
  parentId: a,
2129
2717
  beforeId: null,
2130
2718
  mode: "before",
2131
- label: `End of ${this._lists.find((o) => o.id === n)?.label || n}`
2719
+ label: this._t("targetEnd", { list: this._lists.find((o) => o.id === n)?.label || n })
2132
2720
  });
2133
2721
  };
2134
- return this._lists.forEach((n) => s(n.id, null)), r.filter((n) => this._canDrop(n, this._dragState?.movedRootIds || []));
2722
+ return this._lists.forEach((n) => s(n.id, null)), i.filter((n) => this._canDrop(n, this._dragState?.movedRootIds || []));
2135
2723
  }
2136
- _initialKeyboardDropTarget(e) {
2137
- const t = this._items.find((r) => r.id === e);
2138
- return t ? {
2139
- listId: t.listId,
2140
- parentId: t.parentId,
2141
- beforeId: e,
2724
+ _initialKeyboardDropTarget(t) {
2725
+ const e = this._items.find((i) => i.id === t);
2726
+ return e ? {
2727
+ listId: e.listId,
2728
+ parentId: e.parentId,
2729
+ beforeId: t,
2142
2730
  mode: "before"
2143
2731
  } : null;
2144
2732
  }
2145
- _moveKeyboardDropTarget(e) {
2733
+ _moveKeyboardDropTarget(t) {
2146
2734
  if (!this._dragState) return;
2147
- const t = this._keyboardDropTargets();
2148
- if (!t.length) return;
2149
- const r = Math.max(0, t.findIndex(
2735
+ const e = this._keyboardDropTargets();
2736
+ if (!e.length) return;
2737
+ const i = Math.max(0, e.findIndex(
2150
2738
  (s) => s.listId === this._dragState?.dropTarget?.listId && s.parentId === this._dragState?.dropTarget?.parentId && s.beforeId === this._dragState?.dropTarget?.beforeId && s.mode === this._dragState?.dropTarget?.mode
2151
- )), i = Math.max(0, Math.min(t.length - 1, r + e));
2152
- this._setDropTarget(t[i], { announceLabel: t[i].label });
2739
+ )), r = Math.max(0, Math.min(e.length - 1, i + t));
2740
+ this._setDropTarget(e[r], { announceLabel: e[r].label });
2153
2741
  }
2154
- }
2155
- typeof customElements < "u" && !customElements.get("ui-sortable") && customElements.define("ui-sortable", he);
2742
+ };
2743
+ $._instances = /* @__PURE__ */ new Set();
2744
+ let X = $;
2745
+ typeof customElements < "u" && !customElements.get("ui-sortable") && customElements.define("ui-sortable", X);
2156
2746
  export {
2157
- he as UISortable
2747
+ X as UISortable
2158
2748
  };