@plexui/ui 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,26 +8,42 @@ import { GripVertical } from "../Icon/index.js";
8
8
  import s from "@plexui/styles/components/Sortable/Sortable.module.css";
9
9
  const preventNativeDrag = (event) => event.preventDefault();
10
10
  /** Reorders its direct children by dragging, from anywhere but a control, or by a `Sortable.Handle` where grips are shown. */
11
- export function Sortable({ value, onChange, layout = "list", as: Tag = "div", disabled = false, handles, className, children, onPointerDown, onKeyDown, ...rest }) {
12
- const latest = useLatestValue({ value, onChange });
11
+ export function Sortable({ value, onChange, layout = "list", as: Tag = "div", disabled = false, handles, group, name, onMove, onHold, className, children, onPointerDown, onKeyDown, ...rest }) {
12
+ const latest = useLatestValue({ value, onChange, onMove, onHold, name });
13
13
  const commit = (from, to) => {
14
- flushSync(() => latest.current.onChange?.(moveItem(latest.current.value, from, to)));
14
+ const { value: items, onChange: change, onMove: move, name: list } = latest.current;
15
+ flushSync(() => {
16
+ change?.(moveItem(items, from, to));
17
+ move?.({ item: items[from], from: list, fromIndex: from, to: list, toIndex: to });
18
+ });
19
+ };
20
+ const link = {
21
+ move: (fromIndex, to, toIndex) => {
22
+ const { value: items, onMove: move, name: from } = latest.current;
23
+ flushSync(() => move?.({ item: items[fromIndex], from: from, fromIndex, to, toIndex }));
24
+ },
25
+ hold: (target) => latest.current.onHold?.(target),
15
26
  };
16
27
  const handlePointerDown = (event) => {
17
28
  onPointerDown?.(event);
18
29
  if (!disabled)
19
- sortablePointerDown(event.nativeEvent, event.currentTarget, layout, commit);
30
+ sortablePointerDown(event.nativeEvent, event.currentTarget, layout, commit, link);
20
31
  };
21
32
  const handleKeyDown = (event) => {
22
33
  onKeyDown?.(event);
23
34
  if (!disabled)
24
- void sortableKeyDown(event.nativeEvent, event.currentTarget, commit);
35
+ void sortableKeyDown(event.nativeEvent, event.currentTarget, commit, link);
25
36
  };
26
- return (_jsx(Tag, { ...rest, className: clsx(s.Sortable, className), "data-sortable": "", "data-layout": layout, "data-disabled": disabled ? "" : undefined, "data-handles": handles?.toString(), onPointerDown: handlePointerDown, onKeyDown: handleKeyDown, onDragStart: preventNativeDrag, children: children }));
37
+ return (_jsx(Tag, { ...rest, className: clsx(s.Sortable, className), "data-sortable": "", "data-layout": layout, "data-disabled": disabled ? "" : undefined, "data-handles": handles?.toString(), "data-group": group, "data-name": name, onPointerDown: handlePointerDown, onKeyDown: handleKeyDown, onDragStart: preventNativeDrag, children: children }));
27
38
  }
28
39
  /** The grip of an item. Arrow keys move the item while the handle has focus. */
29
40
  function SortableHandle({ "aria-label": ariaLabel = "Reorder", className, children, ...rest }) {
30
41
  return (_jsx("button", { ...rest, type: "button", className: clsx(s.Handle, className), "data-sortable-handle": "", "aria-label": ariaLabel, children: children ?? _jsx(GripVertical, { "aria-hidden": true }) }));
31
42
  }
43
+ /** A place outside the lists that takes an item whole: a folder, a category in a side list. */
44
+ function SortableTarget({ group, name, as: Tag = "div", className, ...rest }) {
45
+ return _jsx(Tag, { ...rest, className: clsx(s.Target, className), "data-sortable-target": group, "data-name": name });
46
+ }
32
47
  Sortable.Handle = SortableHandle;
48
+ Sortable.Target = SortableTarget;
33
49
  //# sourceMappingURL=Sortable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Sortable.js","sourceRoot":"","sources":["../../../../src/components/Sortable/Sortable.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAuB,MAAM,oBAAoB,CAAA;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,CAAC,MAAM,wDAAwD,CAAA;AAqCtE,MAAM,iBAAiB,GAAG,CAAC,KAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;AAEtE,8HAA8H;AAC9H,MAAM,UAAU,QAAQ,CAAI,EAC1B,KAAK,EACL,QAAQ,EACR,MAAM,GAAG,MAAM,EACf,EAAE,EAAE,GAAG,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,OAAO,EACP,SAAS,EACT,QAAQ,EACR,aAAa,EACb,SAAS,EACT,GAAG,IAAI,EACU;IACjB,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;IAElD,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAU,EAAE,EAAE;QAC1C,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IACtF,CAAC,CAAA;IAED,MAAM,iBAAiB,GAAG,CAAC,KAAmC,EAAE,EAAE;QAChE,aAAa,EAAE,CAAC,KAAK,CAAC,CAAA;QACtB,IAAI,CAAC,QAAQ;YAAE,mBAAmB,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5F,CAAC,CAAA;IAED,MAAM,aAAa,GAAG,CAAC,KAAoC,EAAE,EAAE;QAC7D,SAAS,EAAE,CAAC,KAAK,CAAC,CAAA;QAClB,IAAI,CAAC,QAAQ;YAAE,KAAK,eAAe,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACrF,CAAC,CAAA;IAED,OAAO,CACL,KAAC,GAAG,OACE,IAAI,EACR,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,mBACxB,EAAE,iBACH,MAAM,mBACJ,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,kBAC1B,OAAO,EAAE,QAAQ,EAAE,EACjC,aAAa,EAAE,iBAAiB,EAChC,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,iBAAiB,YAE7B,QAAQ,GACL,CACP,CAAA;AACH,CAAC;AAUD,gFAAgF;AAChF,SAAS,cAAc,CAAC,EAAE,YAAY,EAAE,SAAS,GAAG,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAuB;IAChH,OAAO,CACL,oBAAY,IAAI,EAAE,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,0BAAuB,EAAE,gBAAa,SAAS,YAChH,QAAQ,IAAI,KAAC,YAAY,0BAAe,GAClC,CACV,CAAA;AACH,CAAC;AAED,QAAQ,CAAC,MAAM,GAAG,cAAc,CAAA","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport type { ComponentProps, DragEvent, ElementType, KeyboardEvent, PointerEvent, ReactNode } from \"react\"\nimport { flushSync } from \"react-dom\"\n\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { moveItem, sortableKeyDown, sortablePointerDown, type SortableLayout } from \"../../lib/sortable\"\nimport { GripVertical } from \"../Icon\"\n\nimport s from \"@plexui/styles/components/Sortable/Sortable.module.css\"\n\nexport type SortableProps<T> = {\n /**\n * The list, in the order of the children\n */\n value: readonly T[]\n /**\n * Called with the new order after a drop\n */\n onChange?: (value: T[]) => void\n /**\n * `list` for rows one under another, `grid` for items that stand side by side\n * @default list\n */\n layout?: SortableLayout\n /**\n * Element to render, such as `TableBody` for table rows\n * @default div\n */\n as?: ElementType\n /**\n * Turns dragging off\n * @default false\n */\n disabled?: boolean\n /**\n * Shows the grips of `Sortable.Handle`. A hidden grip still takes the keyboard, and the item drags from anywhere but a control.\n * @default true in a table, otherwise false\n */\n handles?: boolean\n /**\n * The items, one direct child per entry of `value`, keyed by the entry and not by its index\n */\n children?: ReactNode\n} & Omit<ComponentProps<\"div\">, \"children\" | \"onChange\">\n\nconst preventNativeDrag = (event: DragEvent) => event.preventDefault()\n\n/** Reorders its direct children by dragging, from anywhere but a control, or by a `Sortable.Handle` where grips are shown. */\nexport function Sortable<T>({\n value,\n onChange,\n layout = \"list\",\n as: Tag = \"div\",\n disabled = false,\n handles,\n className,\n children,\n onPointerDown,\n onKeyDown,\n ...rest\n}: SortableProps<T>) {\n const latest = useLatestValue({ value, onChange })\n\n const commit = (from: number, to: number) => {\n flushSync(() => latest.current.onChange?.(moveItem(latest.current.value, from, to)))\n }\n\n const handlePointerDown = (event: PointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event)\n if (!disabled) sortablePointerDown(event.nativeEvent, event.currentTarget, layout, commit)\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event)\n if (!disabled) void sortableKeyDown(event.nativeEvent, event.currentTarget, commit)\n }\n\n return (\n <Tag\n {...rest}\n className={clsx(s.Sortable, className)}\n data-sortable=\"\"\n data-layout={layout}\n data-disabled={disabled ? \"\" : undefined}\n data-handles={handles?.toString()}\n onPointerDown={handlePointerDown}\n onKeyDown={handleKeyDown}\n onDragStart={preventNativeDrag}\n >\n {children}\n </Tag>\n )\n}\n\nexport type SortableHandleProps = {\n /**\n * Name of the handle for assistive technology\n * @default Reorder\n */\n \"aria-label\"?: string\n} & ComponentProps<\"button\">\n\n/** The grip of an item. Arrow keys move the item while the handle has focus. */\nfunction SortableHandle({ \"aria-label\": ariaLabel = \"Reorder\", className, children, ...rest }: SortableHandleProps) {\n return (\n <button {...rest} type=\"button\" className={clsx(s.Handle, className)} data-sortable-handle=\"\" aria-label={ariaLabel}>\n {children ?? <GripVertical aria-hidden />}\n </button>\n )\n}\n\nSortable.Handle = SortableHandle\n"]}
1
+ {"version":3,"file":"Sortable.js","sourceRoot":"","sources":["../../../../src/components/Sortable/Sortable.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport type { ComponentProps, DragEvent, ElementType, KeyboardEvent, PointerEvent, ReactNode } from \"react\"\nimport { flushSync } from \"react-dom\"\n\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { moveItem, sortableKeyDown, sortablePointerDown, type SortableLayout, type SortableMove } from \"../../lib/sortable\"\nimport { GripVertical } from \"../Icon\"\n\nimport s from \"@plexui/styles/components/Sortable/Sortable.module.css\"\n\nexport type SortableProps<T> = {\n /**\n * The list, in the order of the children\n */\n value: readonly T[]\n /**\n * Called with the new order after a drop\n */\n onChange?: (value: T[]) => void\n /**\n * `list` for rows one under another, `grid` for items that stand side by side\n * @default list\n */\n layout?: SortableLayout\n /**\n * Element to render, such as `TableBody` for table rows\n * @default div\n */\n as?: ElementType\n /**\n * Turns dragging off\n * @default false\n */\n disabled?: boolean\n /**\n * Shows the grips of `Sortable.Handle`. A hidden grip still takes the keyboard, and the item drags from anywhere but a control.\n * @default true in a table, otherwise false\n */\n handles?: boolean\n /**\n * Lists of one group trade items, and a `Sortable.Target` of that group takes them. Give each list a `name`.\n */\n group?: string\n /**\n * Names the list in `onMove`\n */\n name?: string\n /**\n * An item moved, inside this list or out of it. Out of it the app updates both lists: `onChange` is for a move inside one.\n */\n onMove?: (move: SortableMove<T>) => void\n /**\n * A drag rests on a `Sortable.Target` of the group: open what it stands for or go there\n */\n onHold?: (name: string) => void\n /**\n * The items, one direct child per entry of `value`, keyed by the entry and not by its index\n */\n children?: ReactNode\n} & Omit<ComponentProps<\"div\">, \"children\" | \"onChange\">\n\nconst preventNativeDrag = (event: DragEvent) => event.preventDefault()\n\n/** Reorders its direct children by dragging, from anywhere but a control, or by a `Sortable.Handle` where grips are shown. */\nexport function Sortable<T>({\n value,\n onChange,\n layout = \"list\",\n as: Tag = \"div\",\n disabled = false,\n handles,\n group,\n name,\n onMove,\n onHold,\n className,\n children,\n onPointerDown,\n onKeyDown,\n ...rest\n}: SortableProps<T>) {\n const latest = useLatestValue({ value, onChange, onMove, onHold, name })\n\n const commit = (from: number, to: number) => {\n const { value: items, onChange: change, onMove: move, name: list } = latest.current\n flushSync(() => {\n change?.(moveItem(items, from, to))\n move?.({ item: items[from], from: list as string, fromIndex: from, to: list as string, toIndex: to })\n })\n }\n\n const link = {\n move: (fromIndex: number, to: string, toIndex?: number) => {\n const { value: items, onMove: move, name: from } = latest.current\n flushSync(() => move?.({ item: items[fromIndex], from: from as string, fromIndex, to, toIndex }))\n },\n hold: (target: string) => latest.current.onHold?.(target),\n }\n\n const handlePointerDown = (event: PointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event)\n if (!disabled) sortablePointerDown(event.nativeEvent, event.currentTarget, layout, commit, link)\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event)\n if (!disabled) void sortableKeyDown(event.nativeEvent, event.currentTarget, commit, link)\n }\n\n return (\n <Tag\n {...rest}\n className={clsx(s.Sortable, className)}\n data-sortable=\"\"\n data-layout={layout}\n data-disabled={disabled ? \"\" : undefined}\n data-handles={handles?.toString()}\n data-group={group}\n data-name={name}\n onPointerDown={handlePointerDown}\n onKeyDown={handleKeyDown}\n onDragStart={preventNativeDrag}\n >\n {children}\n </Tag>\n )\n}\n\nexport type SortableHandleProps = {\n /**\n * Name of the handle for assistive technology\n * @default Reorder\n */\n \"aria-label\"?: string\n} & ComponentProps<\"button\">\n\n/** The grip of an item. Arrow keys move the item while the handle has focus. */\nfunction SortableHandle({ \"aria-label\": ariaLabel = \"Reorder\", className, children, ...rest }: SortableHandleProps) {\n return (\n <button {...rest} type=\"button\" className={clsx(s.Handle, className)} data-sortable-handle=\"\" aria-label={ariaLabel}>\n {children ?? <GripVertical aria-hidden />}\n </button>\n )\n}\n\nexport type SortableTargetProps = {\n /**\n * The `group` of the lists whose items it takes\n */\n group: string\n /**\n * Names the target in `onMove` and `onHold` on the list\n */\n name: string\n /**\n * Element to render\n * @default div\n */\n as?: ElementType\n} & ComponentProps<\"div\">\n\n/** A place outside the lists that takes an item whole: a folder, a category in a side list. */\nfunction SortableTarget({ group, name, as: Tag = \"div\", className, ...rest }: SortableTargetProps) {\n return <Tag {...rest} className={clsx(s.Target, className)} data-sortable-target={group} data-name={name} />\n}\n\nSortable.Handle = SortableHandle\nSortable.Target = SortableTarget\n"]}
@@ -1,2 +1,2 @@
1
- export { Sortable } from "./Sortable.js";
1
+ export { Sortable, } from "./Sortable.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Sortable/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAgD,MAAM,YAAY,CAAA","sourcesContent":["export { Sortable, type SortableHandleProps, type SortableProps } from \"./Sortable\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Sortable/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,GAIT,MAAM,YAAY,CAAA","sourcesContent":["export {\n Sortable,\n type SortableHandleProps,\n type SortableProps,\n type SortableTargetProps,\n} from \"./Sortable\"\nexport type { SortableMove } from \"../../lib/sortable\"\n"]}
@@ -1,6 +1,8 @@
1
1
  import s from "@plexui/styles/components/Sortable/Sortable.module.css";
2
2
  const START_DISTANCE = 4;
3
3
  const TOUCH_HOLD = 200;
4
+ // Long enough to pass over a target on the way to another
5
+ const TARGET_HOLD = 500;
4
6
  const SCROLL_EDGE = 80;
5
7
  const SCROLL_SLOW = 4;
6
8
  const SCROLL_FAST = 30;
@@ -10,6 +12,8 @@ const PART = 4;
10
12
  // --cubic-enter: an animation here cannot read a CSS variable
11
13
  const EASING = "cubic-bezier(.19,1,.22,1)";
12
14
  const HANDLE = "[data-sortable-handle]";
15
+ const GRAB = "[data-sortable-grab]";
16
+ const STATIC = "data-sortable-static";
13
17
  const INTERACTIVE = [
14
18
  "a[href]",
15
19
  "button",
@@ -29,7 +33,20 @@ const INTERACTIVE = [
29
33
  ].join(",");
30
34
  // Read at the moment of use: the setting can change while the page is open
31
35
  const reduced = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
32
- const itemsOf = (list) => [...list.children];
36
+ /** How far the line stands in from the sides of the list */
37
+ const lineInset = (list) => {
38
+ const inset = parseFloat(getComputedStyle(list).getPropertyValue("--sortable-line-inset"));
39
+ return Number.isNaN(inset) ? LINE_INSET : inset;
40
+ };
41
+ /** A head row or an empty message stands among the items and is not one of them */
42
+ const itemsOf = (list) => [...list.children].filter((item) => !item.hasAttribute(STATIC));
43
+ /** The lists a drag from this one can reach, in the order of the page */
44
+ const listsOf = (list) => {
45
+ const { group } = list.dataset;
46
+ if (!group)
47
+ return [list];
48
+ return [...document.querySelectorAll(`[data-sortable][data-group="${CSS.escape(group)}"]:not([data-disabled])`)];
49
+ };
33
50
  /** Grips stand in a table, elsewhere only when the list asks for them */
34
51
  const showsHandles = (list) => (list.dataset.handles ?? String(list.tagName === "TBODY")) === "true";
35
52
  /** The direct child of the list that holds `target` */
@@ -62,14 +79,21 @@ const nameOf = (item) => labelOf(item) || item.querySelector("img")?.alt || "";
62
79
  function makeChip(item) {
63
80
  const chip = document.createElement("div");
64
81
  chip.className = s.Chip;
65
- const image = item.querySelector("img");
66
- if (image) {
82
+ const image = item.querySelector("[data-sortable-image], img");
83
+ if (image instanceof HTMLImageElement) {
67
84
  const picture = document.createElement("img");
68
85
  picture.className = s.ChipImage;
69
86
  picture.src = image.currentSrc || image.src;
70
87
  picture.alt = "";
71
88
  chip.append(picture);
72
89
  }
90
+ else if (image) {
91
+ // A cropped background: the chip takes the element as it stands, at the chip's size
92
+ const picture = image.cloneNode(false);
93
+ picture.className = s.ChipImage;
94
+ picture.hidden = false;
95
+ chip.append(picture);
96
+ }
73
97
  const text = labelOf(item);
74
98
  if (text) {
75
99
  const label = document.createElement("span");
@@ -91,8 +115,8 @@ function announce(text) {
91
115
  }
92
116
  region.textContent = text;
93
117
  }
94
- const scrollParent = (list) => {
95
- for (let node = list.parentElement; node && node !== document.body; node = node.parentElement) {
118
+ const scrollParent = (start) => {
119
+ for (let node = start; node && node !== document.body; node = node.parentElement) {
96
120
  if (/auto|scroll/.test(getComputedStyle(node).overflowY) && node.scrollHeight > node.clientHeight)
97
121
  return node;
98
122
  }
@@ -102,6 +126,12 @@ const scrollParent = (list) => {
102
126
  const scrollStep = (depth) => SCROLL_SLOW + (SCROLL_FAST - SCROLL_SLOW) * Math.min(depth / SCROLL_EDGE, 1);
103
127
  function listSlots(list, items) {
104
128
  const box = list.getBoundingClientRect();
129
+ const inset = lineInset(list);
130
+ if (!items.length) {
131
+ // Above a message or an empty row: the line must not cross its text
132
+ const rest = (list.lastElementChild ?? list).getBoundingClientRect();
133
+ return [{ gap: 0, x: inset, y: rest.top - box.top, length: box.width - inset * 2 }];
134
+ }
105
135
  const rects = items.map((item) => item.getBoundingClientRect());
106
136
  return Array.from({ length: items.length + 1 }, (_, gap) => {
107
137
  const above = rects[gap - 1];
@@ -109,9 +139,9 @@ function listSlots(list, items) {
109
139
  const y = above && below ? (above.bottom + below.top) / 2 : (below?.top ?? above.bottom);
110
140
  return {
111
141
  gap,
112
- x: LINE_INSET,
142
+ x: inset,
113
143
  y: y - box.top,
114
- length: box.width - LINE_INSET * 2,
144
+ length: box.width - inset * 2,
115
145
  before: items[gap - 1],
116
146
  after: items[gap],
117
147
  };
@@ -120,6 +150,8 @@ function listSlots(list, items) {
120
150
  // One slot per gap, and two where a line wraps: the end of one line and the start of the next
121
151
  function gridSlots(list, items) {
122
152
  const box = list.getBoundingClientRect();
153
+ if (!items.length)
154
+ return [{ gap: 0, x: 0, y: 0, length: box.height }];
123
155
  const half = (parseFloat(getComputedStyle(list).columnGap) || 8) / 2;
124
156
  const rects = items.map((item) => item.getBoundingClientRect());
125
157
  const slots = [];
@@ -153,9 +185,9 @@ function flyChip(chip, to, layout) {
153
185
  ], { duration: 200, easing: EASING, fill: "forwards" }).onfinish = () => chip.remove();
154
186
  }
155
187
  /** The items that changed place slide there from where they stood */
156
- async function commitWithFlip(items, from, to, commit, skip) {
188
+ async function flip(items, work, skip) {
157
189
  const before = new Map(items.map((item) => [item, item.getBoundingClientRect()]));
158
- await commit(from, to);
190
+ await work();
159
191
  if (reduced())
160
192
  return;
161
193
  items
@@ -173,7 +205,7 @@ const swallow = (event) => {
173
205
  event.stopPropagation();
174
206
  event.preventDefault();
175
207
  };
176
- function startDrag(event, list, source, layout, immediate, commit) {
208
+ function startDrag(event, list, source, layout, immediate, commit, link) {
177
209
  const touch = event.pointerType === "touch" && !immediate;
178
210
  const origin = { x: event.clientX, y: event.clientY };
179
211
  const pointer = { ...origin };
@@ -181,6 +213,8 @@ function startDrag(event, list, source, layout, immediate, commit) {
181
213
  const style = getComputedStyle(list);
182
214
  const part = parseFloat(layout === "grid" ? style.columnGap : style.rowGap) ? PART : 0;
183
215
  const scroller = scrollParent(list);
216
+ const { group } = list.dataset;
217
+ const targets = group ? `[data-sortable-target="${CSS.escape(group)}"]` : undefined;
184
218
  let drag;
185
219
  window.addEventListener("pointermove", onMove);
186
220
  window.addEventListener("pointerup", onUp);
@@ -219,12 +253,17 @@ function startDrag(event, list, source, layout, immediate, commit) {
219
253
  window.removeEventListener("keydown", onKey, true);
220
254
  window.removeEventListener("touchmove", blockScroll);
221
255
  }
256
+ function measure() {
257
+ return listsOf(list).map((entry) => {
258
+ const items = itemsOf(entry);
259
+ entry.setAttribute("data-dragging", "");
260
+ return { list: entry, items, slots: layout === "grid" ? gridSlots(entry, items) : listSlots(entry, items) };
261
+ });
262
+ }
222
263
  function begin() {
223
- const items = itemsOf(list);
224
- const slots = layout === "grid" ? gridSlots(list, items) : listSlots(list, items);
264
+ const areas = measure();
225
265
  window.getSelection()?.removeAllRanges();
226
266
  document.documentElement.classList.add(s.Dragging);
227
- list.setAttribute("data-dragging", "");
228
267
  source.setAttribute("data-sortable-source", "");
229
268
  window.addEventListener("keydown", onKey, true);
230
269
  window.addEventListener("touchmove", blockScroll, { passive: false });
@@ -234,25 +273,32 @@ function startDrag(event, list, source, layout, immediate, commit) {
234
273
  line.hidden = true;
235
274
  document.body.append(line);
236
275
  const { width, height } = chip.getBoundingClientRect();
237
- drag = { chip, line, width, height, items, slots };
276
+ drag = { chip, line, width, height, areas };
238
277
  tick();
239
278
  }
240
279
  function tick() {
241
280
  if (!drag)
242
281
  return;
282
+ drag.under = targets ? document.elementFromPoint(pointer.x, pointer.y) : undefined;
243
283
  autoScroll();
244
284
  update();
245
285
  drag.frame = requestAnimationFrame(tick);
246
286
  }
287
+ /** A column of targets with a scroll of its own scrolls alone, the page stays */
288
+ function panelUnder() {
289
+ const panel = targets && drag?.under ? scrollParent(drag.under) : undefined;
290
+ return panel && panel !== scroller && panel.querySelector(targets) ? panel : undefined;
291
+ }
247
292
  function autoScroll() {
248
- const box = scroller?.getBoundingClientRect() ?? { top: 0, bottom: window.innerHeight };
293
+ const area = panelUnder() ?? scroller;
294
+ const box = area?.getBoundingClientRect() ?? { top: 0, bottom: window.innerHeight };
249
295
  const above = box.top + SCROLL_EDGE - pointer.y;
250
296
  const below = pointer.y - box.bottom + SCROLL_EDGE;
251
297
  const step = above > 0 ? -scrollStep(above) : below > 0 ? scrollStep(below) : 0;
252
298
  if (!step)
253
299
  return;
254
- if (scroller)
255
- scroller.scrollTop += step;
300
+ if (area)
301
+ area.scrollTop += step;
256
302
  else
257
303
  window.scrollBy(0, step);
258
304
  }
@@ -260,93 +306,145 @@ function startDrag(event, list, source, layout, immediate, commit) {
260
306
  if (!drag)
261
307
  return;
262
308
  drag.chip.style.transform = `translate(${pointer.x - drag.width / 2}px, ${pointer.y - drag.height / 2}px)`;
309
+ const target = (targets && drag.under?.closest(targets)) || undefined;
310
+ if (target !== drag.target)
311
+ pointAt(target);
263
312
  const box = source.getBoundingClientRect();
264
313
  const overSource = pointer.x >= box.left && pointer.x <= box.right && pointer.y >= box.top && pointer.y <= box.bottom;
265
314
  source.toggleAttribute("data-sortable-away", !overSource);
266
- showGap(overSource ? undefined : nearestSlot());
315
+ showGap(target || overSource ? undefined : nearestSlot());
316
+ }
317
+ function pointAt(target) {
318
+ if (!drag)
319
+ return;
320
+ clearTimeout(drag.rest);
321
+ drag.target?.removeAttribute("data-over");
322
+ drag.target = target;
323
+ if (!target)
324
+ return;
325
+ target.setAttribute("data-over", "");
326
+ drag.rest = setTimeout(() => {
327
+ link?.hold?.(target.dataset.name);
328
+ // What the hold changed is drawn two frames on: a list opened, the page jumped
329
+ requestAnimationFrame(() => requestAnimationFrame(() => drag && (drag.areas = measure())));
330
+ }, TARGET_HOLD);
331
+ }
332
+ function distance(slot, box) {
333
+ if (layout === "list")
334
+ return Math.abs(pointer.y - (box.top + slot.y));
335
+ const top = box.top + slot.y;
336
+ return Math.hypot(pointer.x - (box.left + slot.x), Math.max(top - pointer.y, 0, pointer.y - top - slot.length));
267
337
  }
268
338
  function nearestSlot() {
269
339
  if (!drag)
270
340
  return undefined;
271
- const box = list.getBoundingClientRect();
272
- const near = pointer.x >= box.left - NEAR_LIST &&
273
- pointer.x <= box.right + NEAR_LIST &&
274
- pointer.y >= box.top - NEAR_LIST &&
275
- pointer.y <= box.bottom + NEAR_LIST;
276
- if (!near)
341
+ let best;
342
+ let closest = Infinity;
343
+ for (const area of drag.areas) {
344
+ const box = area.list.getBoundingClientRect();
345
+ const near = pointer.x >= box.left - NEAR_LIST &&
346
+ pointer.x <= box.right + NEAR_LIST &&
347
+ pointer.y >= box.top - NEAR_LIST &&
348
+ pointer.y <= box.bottom + NEAR_LIST;
349
+ if (!near)
350
+ continue;
351
+ for (const slot of area.slots) {
352
+ const away = distance(slot, box);
353
+ if (away < closest) {
354
+ closest = away;
355
+ best = { area, slot };
356
+ }
357
+ }
358
+ }
359
+ if (!best)
277
360
  return undefined;
278
- const distance = (slot) => {
279
- if (layout === "list")
280
- return Math.abs(pointer.y - (box.top + slot.y));
281
- const top = box.top + slot.y;
282
- return Math.hypot(pointer.x - (box.left + slot.x), Math.max(top - pointer.y, 0, pointer.y - top - slot.length));
283
- };
284
- const best = drag.slots.reduce((nearest, slot) => (distance(slot) < distance(nearest) ? slot : nearest));
285
- const index = drag.items.indexOf(source);
286
- return best.gap === index || best.gap === index + 1 ? undefined : best;
361
+ const index = best.area.items.indexOf(source);
362
+ return index >= 0 && (best.slot.gap === index || best.slot.gap === index + 1) ? undefined : best;
287
363
  }
288
- function shift(slot, distance) {
289
- const move = (item, by) => {
364
+ function shift(slot, by) {
365
+ const move = (item, offset) => {
290
366
  if (!item || !part)
291
367
  return;
292
- item.style.transform = distance
368
+ item.style.transform = by
293
369
  ? layout === "grid"
294
- ? `translateX(${by}px)`
295
- : `translateY(${by}px)`
370
+ ? `translateX(${offset}px)`
371
+ : `translateY(${offset}px)`
296
372
  : "";
297
373
  };
298
- move(slot?.before, -distance);
299
- move(slot?.after, distance);
374
+ move(slot?.before, -by);
375
+ move(slot?.after, by);
300
376
  }
301
377
  function showGap(found) {
302
378
  if (!drag)
303
379
  return;
304
- if (found !== drag.found) {
305
- shift(drag.found, 0);
306
- shift(found, part);
380
+ if (found?.slot !== drag.found?.slot) {
381
+ shift(drag.found?.slot, 0);
382
+ shift(found?.slot, part);
307
383
  }
308
384
  drag.found = found;
309
385
  drag.line.hidden = !found;
310
386
  if (!found)
311
387
  return;
312
- const box = list.getBoundingClientRect();
388
+ const box = found.area.list.getBoundingClientRect();
313
389
  if (layout === "grid") {
314
- drag.line.style.transform = `translate(${box.left + found.x - 1}px, ${box.top + found.y}px)`;
315
- drag.line.style.height = `${found.length}px`;
390
+ drag.line.style.transform = `translate(${box.left + found.slot.x - 1}px, ${box.top + found.slot.y}px)`;
391
+ drag.line.style.height = `${found.slot.length}px`;
316
392
  }
317
393
  else {
318
- drag.line.style.transform = `translate(${box.left + found.x}px, ${box.top + found.y - 1}px)`;
319
- drag.line.style.width = `${found.length}px`;
394
+ drag.line.style.transform = `translate(${box.left + found.slot.x}px, ${box.top + found.slot.y - 1}px)`;
395
+ drag.line.style.width = `${found.slot.length}px`;
320
396
  }
321
397
  }
322
398
  function restoreSource() {
323
399
  source.removeAttribute("data-sortable-source");
324
400
  source.removeAttribute("data-sortable-away");
325
401
  }
326
- function settle(chip) {
327
- flyChip(chip, source.isConnected ? source.getBoundingClientRect() : undefined, layout);
328
- if (!reduced() && source.isConnected)
329
- source.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 250, easing: EASING });
402
+ function settle(chip, item = source) {
403
+ const shown = item?.isConnected ? item : undefined;
404
+ flyChip(chip, shown?.getBoundingClientRect(), layout);
405
+ if (!reduced() && shown)
406
+ shown.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 250, easing: EASING });
330
407
  }
331
- async function land(chip, items, { gap }, clear) {
332
- const from = items.indexOf(source);
333
- const to = gap > from ? gap - 1 : gap;
408
+ async function land(chip, areas, { area, slot: { gap } }, clear) {
409
+ const from = itemsOf(list).indexOf(source);
334
410
  restoreSource();
335
- const clearAndCommit = (moved, place) => {
411
+ if (area.list === list) {
412
+ const to = gap > from ? gap - 1 : gap;
413
+ await flip(area.items, () => {
414
+ clear();
415
+ return commit(from, to);
416
+ }, source);
417
+ announce(`${nameOf(source)}, ${to + 1} / ${area.items.length}`);
418
+ settle(chip);
419
+ return;
420
+ }
421
+ const name = nameOf(source);
422
+ await flip(areas.flatMap(({ items }) => items), () => {
336
423
  clear();
337
- return commit(moved, place);
338
- };
339
- await commitWithFlip(items, from, to, clearAndCommit, source);
340
- announce(`${nameOf(source)}, ${to + 1} / ${items.length}`);
341
- settle(chip);
424
+ return link?.move(from, area.list.dataset.name, gap);
425
+ }, source);
426
+ announce(`${name}, ${gap + 1} / ${area.items.length + 1}`);
427
+ // A framework builds the row anew under its new parent
428
+ settle(chip, source.isConnected ? source : itemsOf(area.list)[gap]);
429
+ }
430
+ async function dropOn(chip, areas, name, clear) {
431
+ const from = itemsOf(list).indexOf(source);
432
+ restoreSource();
433
+ await flip(areas.flatMap(({ items }) => items), () => {
434
+ clear();
435
+ return link?.move(from, name);
436
+ }, source);
437
+ flyChip(chip, undefined, layout);
342
438
  }
343
439
  function finish(drop) {
344
440
  stopListening();
345
441
  if (!drag)
346
442
  return;
347
- const { chip, line, found, items, frame } = drag;
443
+ const { chip, line, found, areas, frame, target, rest } = drag;
348
444
  if (frame)
349
445
  cancelAnimationFrame(frame);
446
+ clearTimeout(rest);
447
+ target?.removeAttribute("data-over");
350
448
  // The pointer lifts over a row: that click must not act on it
351
449
  window.addEventListener("click", swallow, { capture: true, once: true });
352
450
  setTimeout(() => window.removeEventListener("click", swallow, { capture: true }));
@@ -354,12 +452,17 @@ function startDrag(event, list, source, layout, immediate, commit) {
354
452
  drag = undefined;
355
453
  // On a drop this waits for the flip to read where the parted items stand
356
454
  const clear = () => {
357
- list.removeAttribute("data-dragging");
455
+ areas.forEach((area) => area.list.removeAttribute("data-dragging"));
358
456
  document.documentElement.classList.remove(s.Dragging);
359
- shift(found, 0);
457
+ shift(found?.slot, 0);
360
458
  };
361
- if (drop && found) {
362
- void land(chip, items, found, clear);
459
+ const targetName = target?.dataset.name;
460
+ if (drop && targetName && targetName !== list.dataset.name) {
461
+ void dropOn(chip, areas, targetName, clear);
462
+ return;
463
+ }
464
+ if (drop && found && !target) {
465
+ void land(chip, areas, found, clear);
363
466
  return;
364
467
  }
365
468
  clear();
@@ -368,22 +471,24 @@ function startDrag(event, list, source, layout, immediate, commit) {
368
471
  }
369
472
  }
370
473
  /** Starts a drag from a press inside the list. Goes on the list's `pointerdown`. */
371
- export function sortablePointerDown(event, list, layout, commit) {
474
+ export function sortablePointerDown(event, list, layout, commit, link) {
372
475
  const target = event.target;
373
476
  if (event.button || target.closest("[data-sortable]") !== list)
374
477
  return;
375
478
  const source = itemOf(list, target);
376
- if (!source)
479
+ if (!source || source.hasAttribute(STATIC))
377
480
  return;
378
481
  const handle = target.closest(HANDLE);
379
- // A grip in sight is the only way to drag, otherwise anything but a control starts it
380
- if (source.querySelector(HANDLE) && showsHandles(list) ? !handle : target.closest(INTERACTIVE))
482
+ const control = target.closest(INTERACTIVE);
483
+ // A grip in sight is the only way to drag, otherwise anything but a control
484
+ // starts it, and a control that opens its row on a click may let a pull through
485
+ if (source.querySelector(HANDLE) && showsHandles(list) ? !handle : control && !control.closest(GRAB))
381
486
  return;
382
- startDrag(event, list, source, layout, !!handle, commit);
487
+ startDrag(event, list, source, layout, !!handle, commit, link);
383
488
  }
384
489
  const KEY_STEPS = { ArrowUp: -1, ArrowLeft: -1, ArrowDown: 1, ArrowRight: 1 };
385
490
  /** Moves the focused handle's item with the arrow keys. Goes on the list's `keydown`. */
386
- export async function sortableKeyDown(event, list, commit) {
491
+ export async function sortableKeyDown(event, list, commit, link) {
387
492
  const step = KEY_STEPS[event.key];
388
493
  const target = event.target;
389
494
  if (!step || target.closest("[data-sortable]") !== list)
@@ -394,10 +499,23 @@ export async function sortableKeyDown(event, list, commit) {
394
499
  const items = itemsOf(list);
395
500
  const from = items.indexOf(source);
396
501
  const to = from + step;
397
- if (to < 0 || to >= items.length)
502
+ if (to < 0 || to >= items.length) {
503
+ // Past the end of the list: on to the next list of the group
504
+ const lists = listsOf(list);
505
+ const next = lists[lists.indexOf(list) + step];
506
+ if (!next || !link)
507
+ return;
508
+ event.preventDefault();
509
+ const place = step > 0 ? 0 : itemsOf(next).length;
510
+ const name = nameOf(source);
511
+ await flip(lists.flatMap(itemsOf), () => link.move(from, next.dataset.name, place));
512
+ const landed = itemsOf(next)[place];
513
+ (landed?.querySelector(HANDLE) ?? landed)?.focus();
514
+ announce(`${name}, ${place + 1} / ${itemsOf(next).length}`);
398
515
  return;
516
+ }
399
517
  event.preventDefault();
400
- await commitWithFlip(items, from, to, commit);
518
+ await flip(items, () => commit(from, to));
401
519
  // Moving an element in the document drops its focus
402
520
  if (target.isConnected && document.activeElement !== target)
403
521
  target.focus();
@@ -1 +1 @@
1
- {"version":3,"file":"sortable.js","sourceRoot":"","sources":["../../../src/lib/sortable.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,wDAAwD,CAAA;AAsBtE,MAAM,cAAc,GAAG,CAAC,CAAA;AACxB,MAAM,UAAU,GAAG,GAAG,CAAA;AACtB,MAAM,WAAW,GAAG,EAAE,CAAA;AACtB,MAAM,WAAW,GAAG,CAAC,CAAA;AACrB,MAAM,WAAW,GAAG,EAAE,CAAA;AACtB,MAAM,SAAS,GAAG,EAAE,CAAA;AACpB,MAAM,UAAU,GAAG,EAAE,CAAA;AACrB,MAAM,IAAI,GAAG,CAAC,CAAA;AACd,8DAA8D;AAC9D,MAAM,MAAM,GAAG,2BAA2B,CAAA;AAC1C,MAAM,MAAM,GAAG,wBAAwB,CAAA;AACvC,MAAM,WAAW,GAAG;IAClB,SAAS;IACT,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,SAAS;IACT,UAAU;IACV,mBAAmB;IACnB,eAAe;IACf,iBAAiB;IACjB,iBAAiB;IACjB,aAAa;IACb,cAAc;IACd,eAAe;IACf,eAAe;IACf,YAAY;CACb,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAEX,2EAA2E;AAC3E,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,kCAAkC,CAAC,CAAC,OAAO,CAAA;AAEnF,MAAM,OAAO,GAAG,CAAC,IAAiB,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAkB,CAAA;AAE1E,yEAAyE;AACzE,MAAM,YAAY,GAAG,CAAC,IAAiB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,KAAK,MAAM,CAAA;AAEjH,uDAAuD;AACvD,MAAM,MAAM,GAAG,CAAC,IAAiB,EAAE,MAAe,EAAE,EAAE;IACpD,IAAI,IAAI,GAAmB,MAAM,CAAA;IACjC,OAAO,IAAI,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI;QAAE,IAAI,GAAG,IAAI,CAAC,aAAa,CAAA;IACrE,OAAO,IAA0B,CAAA;AACnC,CAAC,CAAA;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAI,KAAmB,EAAE,IAAY,EAAE,EAAU,EAAE,EAAE;IAC3E,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,CAAA;IACvB,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC3C,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,IAAiB,EAAE,EAAE;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,8BAA8B,CAAC,EAAE,WAAW,CAAA;IAC3G,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;IAC9B,oFAAoF;IACpF,MAAM,KAAK,GAAG,QAAQ,CAAC,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;IACnE,OAAO,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC;QACxB,IAAI,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IAC9G,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC,CAAA;AAED,mEAAmE;AACnE,MAAM,MAAM,GAAG,CAAC,IAAiB,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,CAAA;AAE3F,SAAS,QAAQ,CAAC,IAAiB;IACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;IAC1C,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAA;IACvB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;IACvC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAC7C,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAA;QAC/B,OAAO,CAAC,GAAG,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,GAAG,CAAA;QAC3C,OAAO,CAAC,GAAG,GAAG,EAAE,CAAA;QAChB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;QAC5C,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAA;QAC7B,KAAK,CAAC,WAAW,GAAG,IAAI,CAAA;QACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACpB,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAA;IAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QACtC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAA;QACzB,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;QAC1C,MAAM,CAAC,YAAY,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAA;QAC7C,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IACD,MAAM,CAAC,WAAW,GAAG,IAAI,CAAA;AAC3B,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,IAAiB,EAAE,EAAE;IACzC,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,IAAI,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAC9F,IAAI,aAAa,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAA;IAChH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED,gFAAgF;AAChF,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE,CACnC,WAAW,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,WAAW,EAAE,CAAC,CAAC,CAAA;AAE9E,SAAS,SAAS,CAAC,IAAiB,EAAE,KAAoB;IACxD,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAA;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAA;IAC/D,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAQ,EAAE;QAC/D,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;QACxB,MAAM,CAAC,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAA;QACxF,OAAO;YACL,GAAG;YACH,CAAC,EAAE,UAAU;YACb,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG;YACd,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,UAAU,GAAG,CAAC;YAClC,MAAM,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;YACtB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC;SAClB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,8FAA8F;AAC9F,SAAS,SAAS,CAAC,IAAiB,EAAE,KAAoB;IACxD,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAA;IACxC,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAA;IAC/D,MAAM,KAAK,GAAW,EAAE,CAAA;IACxB,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,CAAS,EAAE,IAAa,EAAE,MAAgB,EAAE,KAAe,EAAE,EAAE,CACvF,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IAEjG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;QAC/B,IAAI,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5E,OAAM;QACR,CAAC;QACD,IAAI,QAAQ;YAAE,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;QACvE,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IAC7B,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IACrE,OAAO,KAAK,CAAA;AACd,CAAC;AAED,qGAAqG;AACrG,SAAS,OAAO,CAAC,IAAiB,EAAE,EAAuB,EAAE,MAAsB;IACjF,IAAI,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,EAAE,CAAA;QACb,OAAM;IACR,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAA;IACzC,MAAM,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA;IAC7E,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAChD,IAAI,CAAC,OAAO,CACV;QACE,EAAE,SAAS,EAAE,aAAa,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE;QACrE,EAAE,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE;KACvD,EACD,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CACpD,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAA;AAClC,CAAC;AAED,qEAAqE;AACrE,KAAK,UAAU,cAAc,CAAC,KAAoB,EAAE,IAAY,EAAE,EAAU,EAAE,MAAsB,EAAE,IAAkB;IACtH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,CAAA;IACjF,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACtB,IAAI,OAAO,EAAE;QAAE,OAAM;IACrB,KAAK;SACF,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;SACnD,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAChB,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAY,CAAA;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAA;QACxC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;QAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAA;QAC3B,IAAI,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IAClI,CAAC,CAAC,CAAA;AACN,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,EAAE;IAC/B,KAAK,CAAC,eAAe,EAAE,CAAA;IACvB,KAAK,CAAC,cAAc,EAAE,CAAA;AACxB,CAAC,CAAA;AAED,SAAS,SAAS,CAAC,KAAmB,EAAE,IAAiB,EAAE,MAAmB,EAAE,MAAsB,EAAE,SAAkB,EAAE,MAAsB;IAChJ,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,SAAS,CAAA;IACzD,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;IACrD,MAAM,OAAO,GAAG,EAAE,GAAG,MAAM,EAAE,CAAA;IAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACnE,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACpC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACtF,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,IAWS,CAAA;IAEb,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IAC9C,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IAC1C,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAA;IAElD,SAAS,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAgB;QAChD,OAAO,CAAC,CAAC,GAAG,OAAO,CAAA;QACnB,OAAO,CAAC,CAAC,GAAG,OAAO,CAAA;QACnB,IAAI,IAAI;YAAE,OAAM;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,cAAc,CAAA;QAClF,IAAI,KAAK,IAAI,KAAK;YAAE,aAAa,EAAE,CAAA;aAC9B,IAAI,KAAK;YAAE,KAAK,EAAE,CAAA;IACzB,CAAC;IAED,SAAS,IAAI;QACX,MAAM,CAAC,IAAI,CAAC,CAAA;IACd,CAAC;IAED,SAAS,QAAQ;QACf,MAAM,CAAC,KAAK,CAAC,CAAA;IACf,CAAC;IAED,SAAS,KAAK,CAAC,QAAuB;QACpC,IAAI,QAAQ,CAAC,GAAG,KAAK,QAAQ;YAAE,OAAM;QACrC,QAAQ,CAAC,eAAe,EAAE,CAAA;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAA;IACf,CAAC;IAED,SAAS,WAAW,CAAC,UAAsB;QACzC,UAAU,CAAC,cAAc,EAAE,CAAA;IAC7B,CAAC;IAED,SAAS,aAAa;QACpB,YAAY,CAAC,SAAS,CAAC,CAAA;QACvB,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;QACjD,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;QAC7C,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAA;QACrD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;QAClD,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;IACtD,CAAC;IAED,SAAS,KAAK;QACZ,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QAC3B,MAAM,KAAK,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACjF,MAAM,CAAC,YAAY,EAAE,EAAE,eAAe,EAAE,CAAA;QACxC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;QAClD,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;QACtC,MAAM,CAAC,YAAY,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAA;QAC/C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;QAC/C,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;QACrE,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;QAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAC1C,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAA;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAClB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC1B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAA;QACtD,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;QAClD,IAAI,EAAE,CAAA;IACR,CAAC;IAED,SAAS,IAAI;QACX,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,UAAU,EAAE,CAAA;QACZ,MAAM,EAAE,CAAA;QACR,IAAI,CAAC,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC;IAED,SAAS,UAAU;QACjB,MAAM,GAAG,GAAG,QAAQ,EAAE,qBAAqB,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,CAAA;QACvF,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,WAAW,GAAG,OAAO,CAAC,CAAC,CAAA;QAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,WAAW,CAAA;QAClD,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC/E,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,IAAI,QAAQ;YAAE,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAA;;YACnC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,SAAS,MAAM;QACb,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,aAAa,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,CAAA;QAC1G,MAAM,GAAG,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAA;QAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAA;QACrH,MAAM,CAAC,eAAe,CAAC,oBAAoB,EAAE,CAAC,UAAU,CAAC,CAAA;QACzD,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;IACjD,CAAC;IAED,SAAS,WAAW;QAClB,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAA;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAA;QACxC,MAAM,IAAI,GACR,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,SAAS;YACjC,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,GAAG,SAAS;YAClC,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,SAAS;YAChC,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,SAAS,CAAA;QACrC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAA;QAC3B,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAE,EAAE;YAC9B,IAAI,MAAM,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YACtE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAA;YAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QACjH,CAAC,CAAA;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;QACxG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACxC,OAAO,IAAI,CAAC,GAAG,KAAK,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA;IACxE,CAAC;IAED,SAAS,KAAK,CAAC,IAAsB,EAAE,QAAgB;QACrD,MAAM,IAAI,GAAG,CAAC,IAAyB,EAAE,EAAU,EAAE,EAAE;YACrD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;gBAAE,OACnB;YAAC,IAAoB,CAAC,KAAK,CAAC,SAAS,GAAG,QAAQ;gBAC/C,CAAC,CAAC,MAAM,KAAK,MAAM;oBACjB,CAAC,CAAC,cAAc,EAAE,KAAK;oBACvB,CAAC,CAAC,cAAc,EAAE,KAAK;gBACzB,CAAC,CAAC,EAAE,CAAA;QACR,CAAC,CAAA;QACD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAA;QAC7B,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC7B,CAAC;IAED,SAAS,OAAO,CAAC,KAAuB;QACtC,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;YACpB,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACpB,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,CAAA;QACzB,IAAI,CAAC,KAAK;YAAE,OAAM;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAA;QACxC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,aAAa,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,KAAK,CAAA;YAC5F,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,aAAa,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAA;YAC5F,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,CAAA;QAC7C,CAAC;IACH,CAAC;IAED,SAAS,aAAa;QACpB,MAAM,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAA;QAC9C,MAAM,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAA;IAC9C,CAAC;IAED,SAAS,MAAM,CAAC,IAAiB;QAC/B,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QACtF,IAAI,CAAC,OAAO,EAAE,IAAI,MAAM,CAAC,WAAW;YAAE,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IAC3H,CAAC;IAED,KAAK,UAAU,IAAI,CAAC,IAAiB,EAAE,KAAoB,EAAE,EAAE,GAAG,EAAQ,EAAE,KAAiB;QAC3F,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAClC,MAAM,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;QACrC,aAAa,EAAE,CAAA;QACf,MAAM,cAAc,GAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACtD,KAAK,EAAE,CAAA;YACP,OAAO,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAC7B,CAAC,CAAA;QACD,MAAM,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,CAAC,CAAA;QAC7D,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;QAC1D,MAAM,CAAC,IAAI,CAAC,CAAA;IACd,CAAC;IAED,SAAS,MAAM,CAAC,IAAa;QAC3B,aAAa,EAAE,CAAA;QACf,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;QAChD,IAAI,KAAK;YAAE,oBAAoB,CAAC,KAAK,CAAC,CAAA;QACtC,8DAA8D;QAC9D,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QACxE,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACjF,IAAI,CAAC,MAAM,EAAE,CAAA;QACb,IAAI,GAAG,SAAS,CAAA;QAChB,yEAAyE;QACzE,MAAM,KAAK,GAAG,GAAG,EAAE;YACjB,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAA;YACrC,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;YACrD,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QACjB,CAAC,CAAA;QACD,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YAClB,KAAK,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;YACpC,OAAM;QACR,CAAC;QACD,KAAK,EAAE,CAAA;QACP,aAAa,EAAE,CAAA;QACf,MAAM,CAAC,IAAI,CAAC,CAAA;IACd,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,mBAAmB,CAAC,KAAmB,EAAE,IAAiB,EAAE,MAAsB,EAAE,MAAsB;IACxH,MAAM,MAAM,GAAG,KAAK,CAAC,MAAiB,CAAA;IACtC,IAAI,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,IAAI;QAAE,OAAM;IACtE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACnC,IAAI,CAAC,MAAM;QAAE,OAAM;IACnB,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,sFAAsF;IACtF,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QAAE,OAAM;IACtG,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC1D,CAAC;AAED,MAAM,SAAS,GAA2B,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAA;AAErG,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAoB,EAAE,IAAiB,EAAE,MAAsB;IACnG,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAA;IAC1C,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,IAAI;QAAE,OAAM;IAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IACnC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAAE,OAAM;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;IACtB,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM;QAAE,OAAM;IACxC,KAAK,CAAC,cAAc,EAAE,CAAA;IACtB,MAAM,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;IAC7C,oDAAoD;IACpD,IAAI,MAAM,CAAC,WAAW,IAAI,QAAQ,CAAC,aAAa,KAAK,MAAM;QAAE,MAAM,CAAC,KAAK,EAAE,CAAA;IAC3E,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;AAC5D,CAAC","sourcesContent":["import s from \"@plexui/styles/components/Sortable/Sortable.module.css\"\n\n// Drag to reorder, for any list of elements. Nothing moves until the drop: the\n// item leaves a flat slot and shrinks to a chip at the cursor, a line marks the\n// nearest gap, and only the drop changes the order. Items that stand apart part\n// at the gap. Rows that touch hold still: their text would run over the hairlines.\n\nexport type SortableLayout = \"list\" | \"grid\"\n\n/** Applies a move to the list. Resolves once the DOM shows the new order. */\nexport type SortableCommit = (from: number, to: number) => void | Promise<void>\n\ntype Slot = {\n gap: number\n /** Offsets from the list's corner, so a scroll under the drag keeps them true */\n x: number\n y: number\n length: number\n before?: Element\n after?: Element\n}\n\nconst START_DISTANCE = 4\nconst TOUCH_HOLD = 200\nconst SCROLL_EDGE = 80\nconst SCROLL_SLOW = 4\nconst SCROLL_FAST = 30\nconst NEAR_LIST = 40\nconst LINE_INSET = 16\nconst PART = 4\n// --cubic-enter: an animation here cannot read a CSS variable\nconst EASING = \"cubic-bezier(.19,1,.22,1)\"\nconst HANDLE = \"[data-sortable-handle]\"\nconst INTERACTIVE = [\n \"a[href]\",\n \"button\",\n \"input\",\n \"select\",\n \"summary\",\n \"textarea\",\n \"[contenteditable]\",\n \"[role=button]\",\n \"[role=checkbox]\",\n \"[role=combobox]\",\n \"[role=link]\",\n \"[role=radio]\",\n \"[role=slider]\",\n \"[role=switch]\",\n \"[role=tab]\",\n].join(\",\")\n\n// Read at the moment of use: the setting can change while the page is open\nconst reduced = () => window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n\nconst itemsOf = (list: HTMLElement) => [...list.children] as HTMLElement[]\n\n/** Grips stand in a table, elsewhere only when the list asks for them */\nconst showsHandles = (list: HTMLElement) => (list.dataset.handles ?? String(list.tagName === \"TBODY\")) === \"true\"\n\n/** The direct child of the list that holds `target` */\nconst itemOf = (list: HTMLElement, target: Element) => {\n let node: Element | null = target\n while (node && node.parentElement !== list) node = node.parentElement\n return node as HTMLElement | null\n}\n\n/** The order after a move. `to` counts the list without the moved item. */\nexport const moveItem = <T>(items: readonly T[], from: number, to: number) => {\n const next = [...items]\n next.splice(to, 0, ...next.splice(from, 1))\n return next\n}\n\nconst labelOf = (item: HTMLElement) => {\n const named = item.dataset.sortableLabel ?? item.querySelector(\"[data-sortable-label], label\")?.textContent\n if (named) return named.trim()\n // The cells of a row or the lines of a card run together: the first one is the name\n const texts = document.createTreeWalker(item, NodeFilter.SHOW_TEXT)\n while (texts.nextNode()) {\n if (texts.currentNode.textContent?.trim()) return texts.currentNode.parentElement?.textContent?.trim() ?? \"\"\n }\n return \"\"\n}\n\n/** What a screen reader hears: a picture has no text of its own */\nconst nameOf = (item: HTMLElement) => labelOf(item) || item.querySelector(\"img\")?.alt || \"\"\n\nfunction makeChip(item: HTMLElement) {\n const chip = document.createElement(\"div\")\n chip.className = s.Chip\n const image = item.querySelector(\"img\")\n if (image) {\n const picture = document.createElement(\"img\")\n picture.className = s.ChipImage\n picture.src = image.currentSrc || image.src\n picture.alt = \"\"\n chip.append(picture)\n }\n const text = labelOf(item)\n if (text) {\n const label = document.createElement(\"span\")\n label.className = s.ChipLabel\n label.textContent = text\n chip.append(label)\n }\n document.body.append(chip)\n return chip\n}\n\nfunction announce(text: string) {\n let region = document.querySelector(\"[data-sortable-live]\")\n if (!region) {\n region = document.createElement(\"div\")\n region.className = s.Live\n region.setAttribute(\"aria-live\", \"polite\")\n region.setAttribute(\"data-sortable-live\", \"\")\n document.body.append(region)\n }\n region.textContent = text\n}\n\nconst scrollParent = (list: HTMLElement) => {\n for (let node = list.parentElement; node && node !== document.body; node = node.parentElement) {\n if (/auto|scroll/.test(getComputedStyle(node).overflowY) && node.scrollHeight > node.clientHeight) return node\n }\n return undefined\n}\n\n// The nearer the edge the faster: slow to aim at a row, fast across a long list\nconst scrollStep = (depth: number) =>\n SCROLL_SLOW + (SCROLL_FAST - SCROLL_SLOW) * Math.min(depth / SCROLL_EDGE, 1)\n\nfunction listSlots(list: HTMLElement, items: HTMLElement[]) {\n const box = list.getBoundingClientRect()\n const rects = items.map((item) => item.getBoundingClientRect())\n return Array.from({ length: items.length + 1 }, (_, gap): Slot => {\n const above = rects[gap - 1]\n const below = rects[gap]\n const y = above && below ? (above.bottom + below.top) / 2 : (below?.top ?? above.bottom)\n return {\n gap,\n x: LINE_INSET,\n y: y - box.top,\n length: box.width - LINE_INSET * 2,\n before: items[gap - 1],\n after: items[gap],\n }\n })\n}\n\n// One slot per gap, and two where a line wraps: the end of one line and the start of the next\nfunction gridSlots(list: HTMLElement, items: HTMLElement[]) {\n const box = list.getBoundingClientRect()\n const half = (parseFloat(getComputedStyle(list).columnGap) || 8) / 2\n const rects = items.map((item) => item.getBoundingClientRect())\n const slots: Slot[] = []\n const add = (gap: number, x: number, rect: DOMRect, before?: Element, after?: Element) =>\n slots.push({ gap, x: x - box.left, y: rect.top - box.top, length: rect.height, before, after })\n\n rects.forEach((rect, gap) => {\n const previous = rects[gap - 1]\n if (previous && Math.abs(previous.top - rect.top) < rect.height / 2) {\n add(gap, (previous.right + rect.left) / 2, rect, items[gap - 1], items[gap])\n return\n }\n if (previous) add(gap, previous.right + half, previous, items[gap - 1])\n add(gap, rect.left - half, rect, undefined, items[gap])\n })\n const last = rects.length - 1\n add(rects.length, rects[last].right + half, rects[last], items[last])\n return slots\n}\n\n// The chip keeps its size and fades out: grown to the item, its text would stand over the item's own\nfunction flyChip(chip: HTMLElement, to: DOMRect | undefined, layout: SortableLayout) {\n if (reduced() || !to) {\n chip.remove()\n return\n }\n const from = chip.getBoundingClientRect()\n const x = layout === \"grid\" ? to.left + (to.width - from.width) / 2 : to.left\n const y = to.top + (to.height - from.height) / 2\n chip.animate(\n [\n { transform: `translate(${from.left}px, ${from.top}px)`, opacity: 1 },\n { transform: `translate(${x}px, ${y}px)`, opacity: 0 },\n ],\n { duration: 200, easing: EASING, fill: \"forwards\" },\n ).onfinish = () => chip.remove()\n}\n\n/** The items that changed place slide there from where they stood */\nasync function commitWithFlip(items: HTMLElement[], from: number, to: number, commit: SortableCommit, skip?: HTMLElement) {\n const before = new Map(items.map((item) => [item, item.getBoundingClientRect()]))\n await commit(from, to)\n if (reduced()) return\n items\n .filter((item) => item !== skip && item.isConnected)\n .forEach((item) => {\n const was = before.get(item) as DOMRect\n const now = item.getBoundingClientRect()\n const x = was.left - now.left\n const y = was.top - now.top\n if (x || y) item.animate([{ transform: `translate(${x}px, ${y}px)` }, { transform: \"none\" }], { duration: 200, easing: EASING })\n })\n}\n\nconst swallow = (event: Event) => {\n event.stopPropagation()\n event.preventDefault()\n}\n\nfunction startDrag(event: PointerEvent, list: HTMLElement, source: HTMLElement, layout: SortableLayout, immediate: boolean, commit: SortableCommit) {\n const touch = event.pointerType === \"touch\" && !immediate\n const origin = { x: event.clientX, y: event.clientY }\n const pointer = { ...origin }\n const holdTimer = touch ? setTimeout(begin, TOUCH_HOLD) : undefined\n const style = getComputedStyle(list)\n const part = parseFloat(layout === \"grid\" ? style.columnGap : style.rowGap) ? PART : 0\n const scroller = scrollParent(list)\n let drag:\n | {\n chip: HTMLElement\n line: HTMLElement\n width: number\n height: number\n items: HTMLElement[]\n slots: Slot[]\n frame?: number\n found?: Slot\n }\n | undefined\n\n window.addEventListener(\"pointermove\", onMove)\n window.addEventListener(\"pointerup\", onUp)\n window.addEventListener(\"pointercancel\", onCancel)\n\n function onMove({ clientX, clientY }: PointerEvent) {\n pointer.x = clientX\n pointer.y = clientY\n if (drag) return\n const moved = Math.hypot(clientX - origin.x, clientY - origin.y) >= START_DISTANCE\n if (moved && touch) stopListening()\n else if (moved) begin()\n }\n\n function onUp() {\n finish(true)\n }\n\n function onCancel() {\n finish(false)\n }\n\n function onKey(keyEvent: KeyboardEvent) {\n if (keyEvent.key !== \"Escape\") return\n keyEvent.stopPropagation()\n finish(false)\n }\n\n function blockScroll(touchEvent: TouchEvent) {\n touchEvent.preventDefault()\n }\n\n function stopListening() {\n clearTimeout(holdTimer)\n window.removeEventListener(\"pointermove\", onMove)\n window.removeEventListener(\"pointerup\", onUp)\n window.removeEventListener(\"pointercancel\", onCancel)\n window.removeEventListener(\"keydown\", onKey, true)\n window.removeEventListener(\"touchmove\", blockScroll)\n }\n\n function begin() {\n const items = itemsOf(list)\n const slots = layout === \"grid\" ? gridSlots(list, items) : listSlots(list, items)\n window.getSelection()?.removeAllRanges()\n document.documentElement.classList.add(s.Dragging)\n list.setAttribute(\"data-dragging\", \"\")\n source.setAttribute(\"data-sortable-source\", \"\")\n window.addEventListener(\"keydown\", onKey, true)\n window.addEventListener(\"touchmove\", blockScroll, { passive: false })\n const chip = makeChip(source)\n const line = document.createElement(\"div\")\n line.className = s.Line\n line.hidden = true\n document.body.append(line)\n const { width, height } = chip.getBoundingClientRect()\n drag = { chip, line, width, height, items, slots }\n tick()\n }\n\n function tick() {\n if (!drag) return\n autoScroll()\n update()\n drag.frame = requestAnimationFrame(tick)\n }\n\n function autoScroll() {\n const box = scroller?.getBoundingClientRect() ?? { top: 0, bottom: window.innerHeight }\n const above = box.top + SCROLL_EDGE - pointer.y\n const below = pointer.y - box.bottom + SCROLL_EDGE\n const step = above > 0 ? -scrollStep(above) : below > 0 ? scrollStep(below) : 0\n if (!step) return\n if (scroller) scroller.scrollTop += step\n else window.scrollBy(0, step)\n }\n\n function update() {\n if (!drag) return\n drag.chip.style.transform = `translate(${pointer.x - drag.width / 2}px, ${pointer.y - drag.height / 2}px)`\n const box = source.getBoundingClientRect()\n const overSource = pointer.x >= box.left && pointer.x <= box.right && pointer.y >= box.top && pointer.y <= box.bottom\n source.toggleAttribute(\"data-sortable-away\", !overSource)\n showGap(overSource ? undefined : nearestSlot())\n }\n\n function nearestSlot() {\n if (!drag) return undefined\n const box = list.getBoundingClientRect()\n const near =\n pointer.x >= box.left - NEAR_LIST &&\n pointer.x <= box.right + NEAR_LIST &&\n pointer.y >= box.top - NEAR_LIST &&\n pointer.y <= box.bottom + NEAR_LIST\n if (!near) return undefined\n const distance = (slot: Slot) => {\n if (layout === \"list\") return Math.abs(pointer.y - (box.top + slot.y))\n const top = box.top + slot.y\n return Math.hypot(pointer.x - (box.left + slot.x), Math.max(top - pointer.y, 0, pointer.y - top - slot.length))\n }\n const best = drag.slots.reduce((nearest, slot) => (distance(slot) < distance(nearest) ? slot : nearest))\n const index = drag.items.indexOf(source)\n return best.gap === index || best.gap === index + 1 ? undefined : best\n }\n\n function shift(slot: Slot | undefined, distance: number) {\n const move = (item: Element | undefined, by: number) => {\n if (!item || !part) return\n ;(item as HTMLElement).style.transform = distance\n ? layout === \"grid\"\n ? `translateX(${by}px)`\n : `translateY(${by}px)`\n : \"\"\n }\n move(slot?.before, -distance)\n move(slot?.after, distance)\n }\n\n function showGap(found: Slot | undefined) {\n if (!drag) return\n if (found !== drag.found) {\n shift(drag.found, 0)\n shift(found, part)\n }\n drag.found = found\n drag.line.hidden = !found\n if (!found) return\n const box = list.getBoundingClientRect()\n if (layout === \"grid\") {\n drag.line.style.transform = `translate(${box.left + found.x - 1}px, ${box.top + found.y}px)`\n drag.line.style.height = `${found.length}px`\n } else {\n drag.line.style.transform = `translate(${box.left + found.x}px, ${box.top + found.y - 1}px)`\n drag.line.style.width = `${found.length}px`\n }\n }\n\n function restoreSource() {\n source.removeAttribute(\"data-sortable-source\")\n source.removeAttribute(\"data-sortable-away\")\n }\n\n function settle(chip: HTMLElement) {\n flyChip(chip, source.isConnected ? source.getBoundingClientRect() : undefined, layout)\n if (!reduced() && source.isConnected) source.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 250, easing: EASING })\n }\n\n async function land(chip: HTMLElement, items: HTMLElement[], { gap }: Slot, clear: () => void) {\n const from = items.indexOf(source)\n const to = gap > from ? gap - 1 : gap\n restoreSource()\n const clearAndCommit: SortableCommit = (moved, place) => {\n clear()\n return commit(moved, place)\n }\n await commitWithFlip(items, from, to, clearAndCommit, source)\n announce(`${nameOf(source)}, ${to + 1} / ${items.length}`)\n settle(chip)\n }\n\n function finish(drop: boolean) {\n stopListening()\n if (!drag) return\n const { chip, line, found, items, frame } = drag\n if (frame) cancelAnimationFrame(frame)\n // The pointer lifts over a row: that click must not act on it\n window.addEventListener(\"click\", swallow, { capture: true, once: true })\n setTimeout(() => window.removeEventListener(\"click\", swallow, { capture: true }))\n line.remove()\n drag = undefined\n // On a drop this waits for the flip to read where the parted items stand\n const clear = () => {\n list.removeAttribute(\"data-dragging\")\n document.documentElement.classList.remove(s.Dragging)\n shift(found, 0)\n }\n if (drop && found) {\n void land(chip, items, found, clear)\n return\n }\n clear()\n restoreSource()\n settle(chip)\n }\n}\n\n/** Starts a drag from a press inside the list. Goes on the list's `pointerdown`. */\nexport function sortablePointerDown(event: PointerEvent, list: HTMLElement, layout: SortableLayout, commit: SortableCommit) {\n const target = event.target as Element\n if (event.button || target.closest(\"[data-sortable]\") !== list) return\n const source = itemOf(list, target)\n if (!source) return\n const handle = target.closest(HANDLE)\n // A grip in sight is the only way to drag, otherwise anything but a control starts it\n if (source.querySelector(HANDLE) && showsHandles(list) ? !handle : target.closest(INTERACTIVE)) return\n startDrag(event, list, source, layout, !!handle, commit)\n}\n\nconst KEY_STEPS: Record<string, number> = { ArrowUp: -1, ArrowLeft: -1, ArrowDown: 1, ArrowRight: 1 }\n\n/** Moves the focused handle's item with the arrow keys. Goes on the list's `keydown`. */\nexport async function sortableKeyDown(event: KeyboardEvent, list: HTMLElement, commit: SortableCommit) {\n const step = KEY_STEPS[event.key]\n const target = event.target as HTMLElement\n if (!step || target.closest(\"[data-sortable]\") !== list) return\n const source = itemOf(list, target)\n if (!source || (target !== source && !target.closest(HANDLE))) return\n const items = itemsOf(list)\n const from = items.indexOf(source)\n const to = from + step\n if (to < 0 || to >= items.length) return\n event.preventDefault()\n await commitWithFlip(items, from, to, commit)\n // Moving an element in the document drops its focus\n if (target.isConnected && document.activeElement !== target) target.focus()\n announce(`${nameOf(source)}, ${to + 1} / ${items.length}`)\n}\n"]}
1
+ {"version":3,"file":"sortable.js","sourceRoot":"","sources":["../../../src/lib/sortable.ts"],"names":[],"mappings":"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","sourcesContent":["import s from \"@plexui/styles/components/Sortable/Sortable.module.css\"\n\n// Drag to reorder, for any list of elements. Nothing moves until the drop: the\n// item leaves a flat slot and shrinks to a chip at the cursor, a line marks the\n// nearest gap, and only the drop changes the order. Items that stand apart part\n// at the gap. Rows that touch hold still: their text would run over the hairlines.\n// Lists of one group trade items, and a target outside them takes an item whole.\n\nexport type SortableLayout = \"list\" | \"grid\"\n\n/** Applies a move to the list. Resolves once the DOM shows the new order. */\nexport type SortableCommit = (from: number, to: number) => void | Promise<void>\n\n/** A move inside a list, into another list of its group or onto a target */\nexport type SortableMove<T = unknown> = {\n /** The entry of `value` that moved */\n item: T\n /** The `name` of the list it left */\n from: string\n /** Its place there */\n fromIndex: number\n /** The `name` of the list or the target it reached */\n to: string\n /** Its place after the move. A target has no places: the app decides. */\n toIndex?: number\n}\n\n/** What a list does when an item leaves it. Resolves once the DOM shows the move. */\nexport type SortableLink = {\n move: (fromIndex: number, to: string, toIndex?: number) => void | Promise<void>\n hold?: (name: string) => void\n}\n\ntype Slot = {\n gap: number\n /** Offsets from the list's corner, so a scroll under the drag keeps them true */\n x: number\n y: number\n length: number\n before?: Element\n after?: Element\n}\n\ntype Area = {\n list: HTMLElement\n items: HTMLElement[]\n slots: Slot[]\n}\n\ntype Found = {\n area: Area\n slot: Slot\n}\n\nconst START_DISTANCE = 4\nconst TOUCH_HOLD = 200\n// Long enough to pass over a target on the way to another\nconst TARGET_HOLD = 500\nconst SCROLL_EDGE = 80\nconst SCROLL_SLOW = 4\nconst SCROLL_FAST = 30\nconst NEAR_LIST = 40\nconst LINE_INSET = 16\nconst PART = 4\n// --cubic-enter: an animation here cannot read a CSS variable\nconst EASING = \"cubic-bezier(.19,1,.22,1)\"\nconst HANDLE = \"[data-sortable-handle]\"\nconst GRAB = \"[data-sortable-grab]\"\nconst STATIC = \"data-sortable-static\"\nconst INTERACTIVE = [\n \"a[href]\",\n \"button\",\n \"input\",\n \"select\",\n \"summary\",\n \"textarea\",\n \"[contenteditable]\",\n \"[role=button]\",\n \"[role=checkbox]\",\n \"[role=combobox]\",\n \"[role=link]\",\n \"[role=radio]\",\n \"[role=slider]\",\n \"[role=switch]\",\n \"[role=tab]\",\n].join(\",\")\n\n// Read at the moment of use: the setting can change while the page is open\nconst reduced = () => window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n\n/** How far the line stands in from the sides of the list */\nconst lineInset = (list: HTMLElement) => {\n const inset = parseFloat(getComputedStyle(list).getPropertyValue(\"--sortable-line-inset\"))\n return Number.isNaN(inset) ? LINE_INSET : inset\n}\n\n/** A head row or an empty message stands among the items and is not one of them */\nconst itemsOf = (list: HTMLElement) => ([...list.children] as HTMLElement[]).filter((item) => !item.hasAttribute(STATIC))\n\n/** The lists a drag from this one can reach, in the order of the page */\nconst listsOf = (list: HTMLElement) => {\n const { group } = list.dataset\n if (!group) return [list]\n return [...document.querySelectorAll<HTMLElement>(`[data-sortable][data-group=\"${CSS.escape(group)}\"]:not([data-disabled])`)]\n}\n\n/** Grips stand in a table, elsewhere only when the list asks for them */\nconst showsHandles = (list: HTMLElement) => (list.dataset.handles ?? String(list.tagName === \"TBODY\")) === \"true\"\n\n/** The direct child of the list that holds `target` */\nconst itemOf = (list: HTMLElement, target: Element) => {\n let node: Element | null = target\n while (node && node.parentElement !== list) node = node.parentElement\n return node as HTMLElement | null\n}\n\n/** The order after a move. `to` counts the list without the moved item. */\nexport const moveItem = <T>(items: readonly T[], from: number, to: number) => {\n const next = [...items]\n next.splice(to, 0, ...next.splice(from, 1))\n return next\n}\n\nconst labelOf = (item: HTMLElement) => {\n const named = item.dataset.sortableLabel ?? item.querySelector(\"[data-sortable-label], label\")?.textContent\n if (named) return named.trim()\n // The cells of a row or the lines of a card run together: the first one is the name\n const texts = document.createTreeWalker(item, NodeFilter.SHOW_TEXT)\n while (texts.nextNode()) {\n if (texts.currentNode.textContent?.trim()) return texts.currentNode.parentElement?.textContent?.trim() ?? \"\"\n }\n return \"\"\n}\n\n/** What a screen reader hears: a picture has no text of its own */\nconst nameOf = (item: HTMLElement) => labelOf(item) || item.querySelector(\"img\")?.alt || \"\"\n\nfunction makeChip(item: HTMLElement) {\n const chip = document.createElement(\"div\")\n chip.className = s.Chip\n const image = item.querySelector<HTMLElement>(\"[data-sortable-image], img\")\n if (image instanceof HTMLImageElement) {\n const picture = document.createElement(\"img\")\n picture.className = s.ChipImage\n picture.src = image.currentSrc || image.src\n picture.alt = \"\"\n chip.append(picture)\n } else if (image) {\n // A cropped background: the chip takes the element as it stands, at the chip's size\n const picture = image.cloneNode(false) as HTMLElement\n picture.className = s.ChipImage\n picture.hidden = false\n chip.append(picture)\n }\n const text = labelOf(item)\n if (text) {\n const label = document.createElement(\"span\")\n label.className = s.ChipLabel\n label.textContent = text\n chip.append(label)\n }\n document.body.append(chip)\n return chip\n}\n\nfunction announce(text: string) {\n let region = document.querySelector(\"[data-sortable-live]\")\n if (!region) {\n region = document.createElement(\"div\")\n region.className = s.Live\n region.setAttribute(\"aria-live\", \"polite\")\n region.setAttribute(\"data-sortable-live\", \"\")\n document.body.append(region)\n }\n region.textContent = text\n}\n\nconst scrollParent = (start: Element | null) => {\n for (let node = start; node && node !== document.body; node = node.parentElement) {\n if (/auto|scroll/.test(getComputedStyle(node).overflowY) && node.scrollHeight > node.clientHeight) return node\n }\n return undefined\n}\n\n// The nearer the edge the faster: slow to aim at a row, fast across a long list\nconst scrollStep = (depth: number) =>\n SCROLL_SLOW + (SCROLL_FAST - SCROLL_SLOW) * Math.min(depth / SCROLL_EDGE, 1)\n\nfunction listSlots(list: HTMLElement, items: HTMLElement[]) {\n const box = list.getBoundingClientRect()\n const inset = lineInset(list)\n if (!items.length) {\n // Above a message or an empty row: the line must not cross its text\n const rest = (list.lastElementChild ?? list).getBoundingClientRect()\n return [{ gap: 0, x: inset, y: rest.top - box.top, length: box.width - inset * 2 }]\n }\n const rects = items.map((item) => item.getBoundingClientRect())\n return Array.from({ length: items.length + 1 }, (_, gap): Slot => {\n const above = rects[gap - 1]\n const below = rects[gap]\n const y = above && below ? (above.bottom + below.top) / 2 : (below?.top ?? above.bottom)\n return {\n gap,\n x: inset,\n y: y - box.top,\n length: box.width - inset * 2,\n before: items[gap - 1],\n after: items[gap],\n }\n })\n}\n\n// One slot per gap, and two where a line wraps: the end of one line and the start of the next\nfunction gridSlots(list: HTMLElement, items: HTMLElement[]) {\n const box = list.getBoundingClientRect()\n if (!items.length) return [{ gap: 0, x: 0, y: 0, length: box.height }]\n const half = (parseFloat(getComputedStyle(list).columnGap) || 8) / 2\n const rects = items.map((item) => item.getBoundingClientRect())\n const slots: Slot[] = []\n const add = (gap: number, x: number, rect: DOMRect, before?: Element, after?: Element) =>\n slots.push({ gap, x: x - box.left, y: rect.top - box.top, length: rect.height, before, after })\n\n rects.forEach((rect, gap) => {\n const previous = rects[gap - 1]\n if (previous && Math.abs(previous.top - rect.top) < rect.height / 2) {\n add(gap, (previous.right + rect.left) / 2, rect, items[gap - 1], items[gap])\n return\n }\n if (previous) add(gap, previous.right + half, previous, items[gap - 1])\n add(gap, rect.left - half, rect, undefined, items[gap])\n })\n const last = rects.length - 1\n add(rects.length, rects[last].right + half, rects[last], items[last])\n return slots\n}\n\n// The chip keeps its size and fades out: grown to the item, its text would stand over the item's own\nfunction flyChip(chip: HTMLElement, to: DOMRect | undefined, layout: SortableLayout) {\n if (reduced() || !to) {\n chip.remove()\n return\n }\n const from = chip.getBoundingClientRect()\n const x = layout === \"grid\" ? to.left + (to.width - from.width) / 2 : to.left\n const y = to.top + (to.height - from.height) / 2\n chip.animate(\n [\n { transform: `translate(${from.left}px, ${from.top}px)`, opacity: 1 },\n { transform: `translate(${x}px, ${y}px)`, opacity: 0 },\n ],\n { duration: 200, easing: EASING, fill: \"forwards\" },\n ).onfinish = () => chip.remove()\n}\n\n/** The items that changed place slide there from where they stood */\nasync function flip(items: HTMLElement[], work: () => void | Promise<void>, skip?: HTMLElement) {\n const before = new Map(items.map((item) => [item, item.getBoundingClientRect()]))\n await work()\n if (reduced()) return\n items\n .filter((item) => item !== skip && item.isConnected)\n .forEach((item) => {\n const was = before.get(item) as DOMRect\n const now = item.getBoundingClientRect()\n const x = was.left - now.left\n const y = was.top - now.top\n if (x || y) item.animate([{ transform: `translate(${x}px, ${y}px)` }, { transform: \"none\" }], { duration: 200, easing: EASING })\n })\n}\n\nconst swallow = (event: Event) => {\n event.stopPropagation()\n event.preventDefault()\n}\n\nfunction startDrag(\n event: PointerEvent,\n list: HTMLElement,\n source: HTMLElement,\n layout: SortableLayout,\n immediate: boolean,\n commit: SortableCommit,\n link?: SortableLink,\n) {\n const touch = event.pointerType === \"touch\" && !immediate\n const origin = { x: event.clientX, y: event.clientY }\n const pointer = { ...origin }\n const holdTimer = touch ? setTimeout(begin, TOUCH_HOLD) : undefined\n const style = getComputedStyle(list)\n const part = parseFloat(layout === \"grid\" ? style.columnGap : style.rowGap) ? PART : 0\n const scroller = scrollParent(list)\n const { group } = list.dataset\n const targets = group ? `[data-sortable-target=\"${CSS.escape(group)}\"]` : undefined\n let drag:\n | {\n chip: HTMLElement\n line: HTMLElement\n width: number\n height: number\n areas: Area[]\n frame?: number\n found?: Found\n under?: Element | null\n target?: HTMLElement\n rest?: ReturnType<typeof setTimeout>\n }\n | undefined\n\n window.addEventListener(\"pointermove\", onMove)\n window.addEventListener(\"pointerup\", onUp)\n window.addEventListener(\"pointercancel\", onCancel)\n\n function onMove({ clientX, clientY }: PointerEvent) {\n pointer.x = clientX\n pointer.y = clientY\n if (drag) return\n const moved = Math.hypot(clientX - origin.x, clientY - origin.y) >= START_DISTANCE\n if (moved && touch) stopListening()\n else if (moved) begin()\n }\n\n function onUp() {\n finish(true)\n }\n\n function onCancel() {\n finish(false)\n }\n\n function onKey(keyEvent: KeyboardEvent) {\n if (keyEvent.key !== \"Escape\") return\n keyEvent.stopPropagation()\n finish(false)\n }\n\n function blockScroll(touchEvent: TouchEvent) {\n touchEvent.preventDefault()\n }\n\n function stopListening() {\n clearTimeout(holdTimer)\n window.removeEventListener(\"pointermove\", onMove)\n window.removeEventListener(\"pointerup\", onUp)\n window.removeEventListener(\"pointercancel\", onCancel)\n window.removeEventListener(\"keydown\", onKey, true)\n window.removeEventListener(\"touchmove\", blockScroll)\n }\n\n function measure() {\n return listsOf(list).map((entry) => {\n const items = itemsOf(entry)\n entry.setAttribute(\"data-dragging\", \"\")\n return { list: entry, items, slots: layout === \"grid\" ? gridSlots(entry, items) : listSlots(entry, items) }\n })\n }\n\n function begin() {\n const areas = measure()\n window.getSelection()?.removeAllRanges()\n document.documentElement.classList.add(s.Dragging)\n source.setAttribute(\"data-sortable-source\", \"\")\n window.addEventListener(\"keydown\", onKey, true)\n window.addEventListener(\"touchmove\", blockScroll, { passive: false })\n const chip = makeChip(source)\n const line = document.createElement(\"div\")\n line.className = s.Line\n line.hidden = true\n document.body.append(line)\n const { width, height } = chip.getBoundingClientRect()\n drag = { chip, line, width, height, areas }\n tick()\n }\n\n function tick() {\n if (!drag) return\n drag.under = targets ? document.elementFromPoint(pointer.x, pointer.y) : undefined\n autoScroll()\n update()\n drag.frame = requestAnimationFrame(tick)\n }\n\n /** A column of targets with a scroll of its own scrolls alone, the page stays */\n function panelUnder() {\n const panel = targets && drag?.under ? scrollParent(drag.under) : undefined\n return panel && panel !== scroller && panel.querySelector(targets as string) ? panel : undefined\n }\n\n function autoScroll() {\n const area = panelUnder() ?? scroller\n const box = area?.getBoundingClientRect() ?? { top: 0, bottom: window.innerHeight }\n const above = box.top + SCROLL_EDGE - pointer.y\n const below = pointer.y - box.bottom + SCROLL_EDGE\n const step = above > 0 ? -scrollStep(above) : below > 0 ? scrollStep(below) : 0\n if (!step) return\n if (area) area.scrollTop += step\n else window.scrollBy(0, step)\n }\n\n function update() {\n if (!drag) return\n drag.chip.style.transform = `translate(${pointer.x - drag.width / 2}px, ${pointer.y - drag.height / 2}px)`\n const target = (targets && drag.under?.closest<HTMLElement>(targets)) || undefined\n if (target !== drag.target) pointAt(target)\n const box = source.getBoundingClientRect()\n const overSource = pointer.x >= box.left && pointer.x <= box.right && pointer.y >= box.top && pointer.y <= box.bottom\n source.toggleAttribute(\"data-sortable-away\", !overSource)\n showGap(target || overSource ? undefined : nearestSlot())\n }\n\n function pointAt(target: HTMLElement | undefined) {\n if (!drag) return\n clearTimeout(drag.rest)\n drag.target?.removeAttribute(\"data-over\")\n drag.target = target\n if (!target) return\n target.setAttribute(\"data-over\", \"\")\n drag.rest = setTimeout(() => {\n link?.hold?.(target.dataset.name as string)\n // What the hold changed is drawn two frames on: a list opened, the page jumped\n requestAnimationFrame(() => requestAnimationFrame(() => drag && (drag.areas = measure())))\n }, TARGET_HOLD)\n }\n\n function distance(slot: Slot, box: DOMRect) {\n if (layout === \"list\") return Math.abs(pointer.y - (box.top + slot.y))\n const top = box.top + slot.y\n return Math.hypot(pointer.x - (box.left + slot.x), Math.max(top - pointer.y, 0, pointer.y - top - slot.length))\n }\n\n function nearestSlot() {\n if (!drag) return undefined\n let best: Found | undefined\n let closest = Infinity\n for (const area of drag.areas) {\n const box = area.list.getBoundingClientRect()\n const near =\n pointer.x >= box.left - NEAR_LIST &&\n pointer.x <= box.right + NEAR_LIST &&\n pointer.y >= box.top - NEAR_LIST &&\n pointer.y <= box.bottom + NEAR_LIST\n if (!near) continue\n for (const slot of area.slots) {\n const away = distance(slot, box)\n if (away < closest) {\n closest = away\n best = { area, slot }\n }\n }\n }\n if (!best) return undefined\n const index = best.area.items.indexOf(source)\n return index >= 0 && (best.slot.gap === index || best.slot.gap === index + 1) ? undefined : best\n }\n\n function shift(slot: Slot | undefined, by: number) {\n const move = (item: Element | undefined, offset: number) => {\n if (!item || !part) return\n ;(item as HTMLElement).style.transform = by\n ? layout === \"grid\"\n ? `translateX(${offset}px)`\n : `translateY(${offset}px)`\n : \"\"\n }\n move(slot?.before, -by)\n move(slot?.after, by)\n }\n\n function showGap(found: Found | undefined) {\n if (!drag) return\n if (found?.slot !== drag.found?.slot) {\n shift(drag.found?.slot, 0)\n shift(found?.slot, part)\n }\n drag.found = found\n drag.line.hidden = !found\n if (!found) return\n const box = found.area.list.getBoundingClientRect()\n if (layout === \"grid\") {\n drag.line.style.transform = `translate(${box.left + found.slot.x - 1}px, ${box.top + found.slot.y}px)`\n drag.line.style.height = `${found.slot.length}px`\n } else {\n drag.line.style.transform = `translate(${box.left + found.slot.x}px, ${box.top + found.slot.y - 1}px)`\n drag.line.style.width = `${found.slot.length}px`\n }\n }\n\n function restoreSource() {\n source.removeAttribute(\"data-sortable-source\")\n source.removeAttribute(\"data-sortable-away\")\n }\n\n function settle(chip: HTMLElement, item: HTMLElement | undefined = source) {\n const shown = item?.isConnected ? item : undefined\n flyChip(chip, shown?.getBoundingClientRect(), layout)\n if (!reduced() && shown) shown.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 250, easing: EASING })\n }\n\n async function land(chip: HTMLElement, areas: Area[], { area, slot: { gap } }: Found, clear: () => void) {\n const from = itemsOf(list).indexOf(source)\n restoreSource()\n if (area.list === list) {\n const to = gap > from ? gap - 1 : gap\n await flip(\n area.items,\n () => {\n clear()\n return commit(from, to)\n },\n source,\n )\n announce(`${nameOf(source)}, ${to + 1} / ${area.items.length}`)\n settle(chip)\n return\n }\n const name = nameOf(source)\n await flip(\n areas.flatMap(({ items }) => items),\n () => {\n clear()\n return link?.move(from, area.list.dataset.name as string, gap)\n },\n source,\n )\n announce(`${name}, ${gap + 1} / ${area.items.length + 1}`)\n // A framework builds the row anew under its new parent\n settle(chip, source.isConnected ? source : itemsOf(area.list)[gap])\n }\n\n async function dropOn(chip: HTMLElement, areas: Area[], name: string, clear: () => void) {\n const from = itemsOf(list).indexOf(source)\n restoreSource()\n await flip(\n areas.flatMap(({ items }) => items),\n () => {\n clear()\n return link?.move(from, name)\n },\n source,\n )\n flyChip(chip, undefined, layout)\n }\n\n function finish(drop: boolean) {\n stopListening()\n if (!drag) return\n const { chip, line, found, areas, frame, target, rest } = drag\n if (frame) cancelAnimationFrame(frame)\n clearTimeout(rest)\n target?.removeAttribute(\"data-over\")\n // The pointer lifts over a row: that click must not act on it\n window.addEventListener(\"click\", swallow, { capture: true, once: true })\n setTimeout(() => window.removeEventListener(\"click\", swallow, { capture: true }))\n line.remove()\n drag = undefined\n // On a drop this waits for the flip to read where the parted items stand\n const clear = () => {\n areas.forEach((area) => area.list.removeAttribute(\"data-dragging\"))\n document.documentElement.classList.remove(s.Dragging)\n shift(found?.slot, 0)\n }\n const targetName = target?.dataset.name\n if (drop && targetName && targetName !== list.dataset.name) {\n void dropOn(chip, areas, targetName, clear)\n return\n }\n if (drop && found && !target) {\n void land(chip, areas, found, clear)\n return\n }\n clear()\n restoreSource()\n settle(chip)\n }\n}\n\n/** Starts a drag from a press inside the list. Goes on the list's `pointerdown`. */\nexport function sortablePointerDown(\n event: PointerEvent,\n list: HTMLElement,\n layout: SortableLayout,\n commit: SortableCommit,\n link?: SortableLink,\n) {\n const target = event.target as Element\n if (event.button || target.closest(\"[data-sortable]\") !== list) return\n const source = itemOf(list, target)\n if (!source || source.hasAttribute(STATIC)) return\n const handle = target.closest(HANDLE)\n const control = target.closest(INTERACTIVE)\n // A grip in sight is the only way to drag, otherwise anything but a control\n // starts it, and a control that opens its row on a click may let a pull through\n if (source.querySelector(HANDLE) && showsHandles(list) ? !handle : control && !control.closest(GRAB)) return\n startDrag(event, list, source, layout, !!handle, commit, link)\n}\n\nconst KEY_STEPS: Record<string, number> = { ArrowUp: -1, ArrowLeft: -1, ArrowDown: 1, ArrowRight: 1 }\n\n/** Moves the focused handle's item with the arrow keys. Goes on the list's `keydown`. */\nexport async function sortableKeyDown(event: KeyboardEvent, list: HTMLElement, commit: SortableCommit, link?: SortableLink) {\n const step = KEY_STEPS[event.key]\n const target = event.target as HTMLElement\n if (!step || target.closest(\"[data-sortable]\") !== list) return\n const source = itemOf(list, target)\n if (!source || (target !== source && !target.closest(HANDLE))) return\n const items = itemsOf(list)\n const from = items.indexOf(source)\n const to = from + step\n if (to < 0 || to >= items.length) {\n // Past the end of the list: on to the next list of the group\n const lists = listsOf(list)\n const next = lists[lists.indexOf(list) + step]\n if (!next || !link) return\n event.preventDefault()\n const place = step > 0 ? 0 : itemsOf(next).length\n const name = nameOf(source)\n await flip(lists.flatMap(itemsOf), () => link.move(from, next.dataset.name as string, place))\n const landed = itemsOf(next)[place]\n ;(landed?.querySelector<HTMLElement>(HANDLE) ?? landed)?.focus()\n announce(`${name}, ${place + 1} / ${itemsOf(next).length}`)\n return\n }\n event.preventDefault()\n await flip(items, () => commit(from, to))\n // Moving an element in the document drops its focus\n if (target.isConnected && document.activeElement !== target) target.focus()\n announce(`${nameOf(source)}, ${to + 1} / ${items.length}`)\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { ComponentProps, ElementType, ReactNode } from "react";
2
- import { type SortableLayout } from "../../lib/sortable.js";
2
+ import { type SortableLayout, type SortableMove } from "../../lib/sortable.js";
3
3
  export type SortableProps<T> = {
4
4
  /**
5
5
  * The list, in the order of the children
@@ -29,15 +29,32 @@ export type SortableProps<T> = {
29
29
  * @default true in a table, otherwise false
30
30
  */
31
31
  handles?: boolean;
32
+ /**
33
+ * Lists of one group trade items, and a `Sortable.Target` of that group takes them. Give each list a `name`.
34
+ */
35
+ group?: string;
36
+ /**
37
+ * Names the list in `onMove`
38
+ */
39
+ name?: string;
40
+ /**
41
+ * An item moved, inside this list or out of it. Out of it the app updates both lists: `onChange` is for a move inside one.
42
+ */
43
+ onMove?: (move: SortableMove<T>) => void;
44
+ /**
45
+ * A drag rests on a `Sortable.Target` of the group: open what it stands for or go there
46
+ */
47
+ onHold?: (name: string) => void;
32
48
  /**
33
49
  * The items, one direct child per entry of `value`, keyed by the entry and not by its index
34
50
  */
35
51
  children?: ReactNode;
36
52
  } & Omit<ComponentProps<"div">, "children" | "onChange">;
37
53
  /** Reorders its direct children by dragging, from anywhere but a control, or by a `Sortable.Handle` where grips are shown. */
38
- export declare function Sortable<T>({ value, onChange, layout, as: Tag, disabled, handles, className, children, onPointerDown, onKeyDown, ...rest }: SortableProps<T>): import("react/jsx-runtime").JSX.Element;
54
+ export declare function Sortable<T>({ value, onChange, layout, as: Tag, disabled, handles, group, name, onMove, onHold, className, children, onPointerDown, onKeyDown, ...rest }: SortableProps<T>): import("react/jsx-runtime").JSX.Element;
39
55
  export declare namespace Sortable {
40
56
  var Handle: typeof SortableHandle;
57
+ var Target: typeof SortableTarget;
41
58
  }
42
59
  export type SortableHandleProps = {
43
60
  /**
@@ -48,4 +65,21 @@ export type SortableHandleProps = {
48
65
  } & ComponentProps<"button">;
49
66
  /** The grip of an item. Arrow keys move the item while the handle has focus. */
50
67
  declare function SortableHandle({ "aria-label": ariaLabel, className, children, ...rest }: SortableHandleProps): import("react/jsx-runtime").JSX.Element;
68
+ export type SortableTargetProps = {
69
+ /**
70
+ * The `group` of the lists whose items it takes
71
+ */
72
+ group: string;
73
+ /**
74
+ * Names the target in `onMove` and `onHold` on the list
75
+ */
76
+ name: string;
77
+ /**
78
+ * Element to render
79
+ * @default div
80
+ */
81
+ as?: ElementType;
82
+ } & ComponentProps<"div">;
83
+ /** A place outside the lists that takes an item whole: a folder, a category in a side list. */
84
+ declare function SortableTarget({ group, name, as: Tag, className, ...rest }: SortableTargetProps): import("react/jsx-runtime").JSX.Element;
51
85
  export {};
@@ -1 +1,2 @@
1
- export { Sortable, type SortableHandleProps, type SortableProps } from "./Sortable.js";
1
+ export { Sortable, type SortableHandleProps, type SortableProps, type SortableTargetProps, } from "./Sortable.js";
2
+ export type { SortableMove } from "../../lib/sortable.js";
@@ -1,9 +1,27 @@
1
1
  export type SortableLayout = "list" | "grid";
2
2
  /** Applies a move to the list. Resolves once the DOM shows the new order. */
3
3
  export type SortableCommit = (from: number, to: number) => void | Promise<void>;
4
+ /** A move inside a list, into another list of its group or onto a target */
5
+ export type SortableMove<T = unknown> = {
6
+ /** The entry of `value` that moved */
7
+ item: T;
8
+ /** The `name` of the list it left */
9
+ from: string;
10
+ /** Its place there */
11
+ fromIndex: number;
12
+ /** The `name` of the list or the target it reached */
13
+ to: string;
14
+ /** Its place after the move. A target has no places: the app decides. */
15
+ toIndex?: number;
16
+ };
17
+ /** What a list does when an item leaves it. Resolves once the DOM shows the move. */
18
+ export type SortableLink = {
19
+ move: (fromIndex: number, to: string, toIndex?: number) => void | Promise<void>;
20
+ hold?: (name: string) => void;
21
+ };
4
22
  /** The order after a move. `to` counts the list without the moved item. */
5
23
  export declare const moveItem: <T>(items: readonly T[], from: number, to: number) => T[];
6
24
  /** Starts a drag from a press inside the list. Goes on the list's `pointerdown`. */
7
- export declare function sortablePointerDown(event: PointerEvent, list: HTMLElement, layout: SortableLayout, commit: SortableCommit): void;
25
+ export declare function sortablePointerDown(event: PointerEvent, list: HTMLElement, layout: SortableLayout, commit: SortableCommit, link?: SortableLink): void;
8
26
  /** Moves the focused handle's item with the arrow keys. Goes on the list's `keydown`. */
9
- export declare function sortableKeyDown(event: KeyboardEvent, list: HTMLElement, commit: SortableCommit): Promise<void>;
27
+ export declare function sortableKeyDown(event: KeyboardEvent, list: HTMLElement, commit: SortableCommit, link?: SortableLink): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plexui/ui",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Modern design system for building high-quality applications",
5
5
  "type": "module",
6
6
  "license": "MIT",