@sfxcode/formkit-openvue 0.8.1 → 0.9.1

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.
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.formRepeaterDefinition = void 0;
7
7
  var _vue = require("@formkit/vue");
8
8
  var _composables = require("../composables");
9
+ var _clonePlain = require("../utils/clonePlain");
9
10
  const {
10
11
  addList,
11
12
  addElement,
@@ -13,18 +14,21 @@ const {
13
14
  addComponent
14
15
  } = (0, _composables.useFormKitSchema)();
15
16
  function addButtonGroup(buttonGroupClass = "", buttonGroupItemClass = "", buttonSize, render = "true") {
16
- const addActionButtonComponent = (onClick = "", icon = "", severity = "", render2 = "true", disabled = "false") => {
17
+ const addActionButtonComponent = (onClick = "", icon = "", severity = "", render2 = "true", disabled = "false", label = "") => {
18
+ const name = `${label} + " " + ($index + 1)`;
17
19
  return addElement("div", [addComponent("Button", {
18
- onClick,
20
+ "onClick": onClick,
19
21
  icon,
20
22
  severity,
21
23
  disabled,
22
- size: buttonSize
24
+ "size": buttonSize,
25
+ "aria-label": name,
26
+ "title": name
23
27
  })], {
24
28
  class: buttonGroupItemClass
25
29
  }, render2);
26
30
  };
27
- return addElement("div", [addActionButtonComponent("$moveNodeUp($node.parent, $index)", "oi oi-arrow-up", "secondary", "$renderMoveButtons", "$index === 0"), addActionButtonComponent("$removeNode($node.parent, $index)", "oi oi-trash", "danger", "$displayDeleteButton", "$node.parent.value.length === $minItems"), addActionButtonComponent("$cloneNode($node.parent, $index)", "oi oi-clone", "", "$displayCloneButton", "$node.parent.value.length > $maxItems -1"), addActionButtonComponent("$addNode($node.parent, $index)", "oi oi-plus", "", "$displayAddButton", "$node.parent.value.length > $maxItems -1"), addActionButtonComponent("$moveNodeDown($node.parent, $index)", "oi oi-arrow-down", "secondary", "$renderMoveButtons", "$index === $node.parent.value.length -1")], {
31
+ return addElement("div", [addActionButtonComponent("$moveNodeUp($node.parent, $index)", "oi oi-arrow-up", "secondary", "$renderMoveButtons", "$index === 0", "$moveUpLabel"), addActionButtonComponent("$removeNode($node.parent, $index)", "oi oi-trash", "danger", "$displayDeleteButton", "$node.parent.value.length === $minItems", "$deleteLabel"), addActionButtonComponent("$cloneNode($node.parent, $index)", "oi oi-clone", "", "$displayCloneButton", "$node.parent.value.length > $maxItems -1", "$cloneLabel"), addActionButtonComponent("$addNode($node.parent, $index)", "oi oi-plus", "", "$displayAddButton", "$node.parent.value.length > $maxItems -1", "$addLabel"), addActionButtonComponent("$moveNodeDown($node.parent, $index)", "oi oi-arrow-down", "secondary", "$renderMoveButtons", "$index === $node.parent.value.length -1", "$moveDownLabel")], {
28
32
  class: buttonGroupClass
29
33
  }, render);
30
34
  }
@@ -39,6 +43,19 @@ function addInsertButton(label = "Add Item", icon = "i-lucide-plus", styleClass
39
43
  class: styleClass
40
44
  }, render);
41
45
  }
46
+ function addUndoBar(render = "true") {
47
+ return addElement("div", [addElement("div", [addElement("span", ["$deletedLabel"]), addComponent("Button", {
48
+ onClick: "$undoRemoveNode($node)",
49
+ label: "$undoLabel",
50
+ size: "small",
51
+ variant: "text"
52
+ })], {
53
+ class: "formkit-repeater-undo"
54
+ }, "$removedItem")], {
55
+ "role": "status",
56
+ "aria-live": "polite"
57
+ }, render);
58
+ }
42
59
  function addDragHandle(handleClass = "", iconClass = "", render = "true") {
43
60
  return addElement("span", [addElement("i", [], {
44
61
  class: iconClass
@@ -58,13 +75,14 @@ const formRepeaterDefinition = exports.formRepeaterDefinition = (0, _vue.createI
58
75
  onDragleave: "$dragNodeLeave($index)",
59
76
  onDrop: "$dropNode($node.parent, $index)",
60
77
  onDragend: "$dragNodeEnd"
61
- })], true, {})], true, "true", {
62
- value: "$value"
78
+ })], true, {}), addUndoBar("$undoDelete")], true, "true", {
79
+ value: "$value",
80
+ validation: "$repeaterValidation"
63
81
  })], {
64
82
  class: "$internalListClass",
65
83
  id: "$internalListId"
66
84
  }, true), {
67
- props: ["insertButtonLabel", "insertButtonClass", "insertButtonSize", "alwaysDisplayInsertButton", "newItem", "listClass", "listItemClass", "hideButtonGroup", "hideMoveButtons", "buttonGroupClass", "buttonGroupItemClass", "buttonSize", "displayCloneButton", "displayAddButton", "displayDeleteButton", "minItems", "maxItems", "displayDragHandle", "draggable", "dragHandleClass", "dragHandleIconClass"],
85
+ props: ["insertButtonLabel", "insertButtonClass", "insertButtonSize", "alwaysDisplayInsertButton", "newItem", "listClass", "listItemClass", "hideButtonGroup", "hideMoveButtons", "buttonGroupClass", "buttonGroupItemClass", "buttonSize", "displayCloneButton", "displayAddButton", "displayDeleteButton", "minItems", "maxItems", "moveUpLabel", "moveDownLabel", "deleteLabel", "cloneLabel", "addLabel", "undoDelete", "undoLabel", "deletedLabel", "undoTimeout", "displayDragHandle", "draggable", "dragHandleClass", "dragHandleIconClass"],
68
86
  features: [addRepeaterHandler]
69
87
  });
70
88
  function addRepeaterHandler(node) {
@@ -72,12 +90,20 @@ function addRepeaterHandler(node) {
72
90
  array.splice(index2, 0, array.splice(index1, 1)[0]);
73
91
  return array;
74
92
  };
75
- const uuid = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2);
76
93
  node.on("created", () => {
77
94
  if (node.context) {
78
95
  let dragStartIndex = null;
79
- let dragOverIndex = null;
80
- const newItem = node.context.newItem || {};
96
+ const makeNewItem = () => (0, _clonePlain.clonePlain)(node.context?.newItem || {});
97
+ const instanceId = String(node.props.id ?? node.name);
98
+ const context = node.context;
99
+ context.dragOverIndex = null;
100
+ let undoTimer;
101
+ const forgetRemoved = () => {
102
+ clearTimeout(undoTimer);
103
+ undoTimer = void 0;
104
+ context.removedItem = void 0;
105
+ };
106
+ node.on("destroying", () => clearTimeout(undoTimer));
81
107
  node.context.listName = node.name;
82
108
  node.context.renderButtons = !node.context.hideButtonGroup;
83
109
  node.context.insertButtonSize = node.context.insertButtonSize ? node.context.insertButtonSize : "";
@@ -89,39 +115,68 @@ function addRepeaterHandler(node) {
89
115
  node.context.internalDragHandleClass = node.context.dragHandleClass ? `formkit-repeater-drag-handle ${node.context.dragHandleClass}` : "formkit-repeater-drag-handle";
90
116
  node.context.internalListClass = node.context.listClass ? `formkit-items ${node.context.listClass}` : "formkit-items";
91
117
  node.context.internalListItemClass = node.context.listItemClass ? `formkit-item ${node.context.listItemClass}` : "formkit-item";
92
- node.context.internalListId = `formkit-items-${uuid}`;
118
+ node.context.moveUpLabel = node.context.moveUpLabel || "Move item up";
119
+ node.context.moveDownLabel = node.context.moveDownLabel || "Move item down";
120
+ node.context.deleteLabel = node.context.deleteLabel || "Delete item";
121
+ node.context.cloneLabel = node.context.cloneLabel || "Clone item";
122
+ node.context.addLabel = node.context.addLabel || "Add item below";
123
+ node.context.undoDelete = !!node.context.undoDelete;
124
+ node.context.undoLabel = node.context.undoLabel || "Undo";
125
+ node.context.deletedLabel = node.context.deletedLabel || "Item deleted";
126
+ node.context.undoTimeout = node.context.undoTimeout !== void 0 ? Number(node.context.undoTimeout) : 8e3;
127
+ node.context.removedItem = void 0;
128
+ node.context.minItems = node.context.minItems !== void 0 ? node.context.minItems : 0;
129
+ node.context.maxItems = node.context.maxItems !== void 0 ? node.context.maxItems : Number.POSITIVE_INFINITY;
130
+ node.context.repeaterValidation = [["+length", node.context.minItems, node.context.maxItems]];
131
+ node.context.internalListId = `formkit-items-${instanceId}`;
93
132
  node.context.getListItemClass = index => {
94
- if (dragOverIndex === index && dragStartIndex !== index) return `${node.context?.internalListItemClass} formkit-repeater-drop-target`;
133
+ if (context.dragOverIndex === index && dragStartIndex !== index) return `${node.context?.internalListItemClass} formkit-repeater-drop-target`;
95
134
  return node.context?.internalListItemClass?.toString() ?? "";
96
135
  };
97
136
  node.context.getListItemId = index => {
98
- return `formkit-item-${index}-${uuid}`;
137
+ return `formkit-item-${index}-${instanceId}`;
99
138
  };
100
139
  node.context.insertNode = parentNode => () => {
101
140
  if (parentNode && Array.isArray(parentNode._value)) {
102
- const newArray = [{
103
- ...newItem
104
- }, ...parentNode.value];
141
+ const newArray = [makeNewItem(), ...parentNode.value];
105
142
  parentNode.input(newArray, false);
106
143
  }
107
144
  };
108
145
  node.context.removeNode = (parentNode, index) => () => {
109
146
  if (parentNode && Array.isArray(parentNode._value)) {
147
+ const removed = (0, _clonePlain.clonePlain)(parentNode._value[index]);
110
148
  parentNode.input(parentNode._value.filter((_, i) => i !== index), false);
149
+ if (context.undoDelete) {
150
+ clearTimeout(undoTimer);
151
+ context.removedItem = {
152
+ index,
153
+ item: removed
154
+ };
155
+ const timeout = Number(context.undoTimeout);
156
+ undoTimer = timeout > 0 ? setTimeout(forgetRemoved, timeout) : void 0;
157
+ }
158
+ }
159
+ };
160
+ node.context.undoRemoveNode = parentNode => () => {
161
+ const removed = context.removedItem;
162
+ if (removed && parentNode && Array.isArray(parentNode._value) && parentNode._value.length < Number(context.maxItems)) {
163
+ const array = [...parentNode.value];
164
+ array.splice(Math.min(removed.index, array.length), 0, (0, _clonePlain.clonePlain)(removed.item));
165
+ parentNode.input(array, false);
111
166
  }
167
+ forgetRemoved();
112
168
  };
113
169
  node.context.addNode = (parentNode, index) => () => {
114
170
  if (parentNode && Array.isArray(parentNode._value)) {
115
171
  const array = parentNode.value;
116
- array.splice(index + 1, 0, newItem);
172
+ array.splice(index + 1, 0, makeNewItem());
117
173
  parentNode.input(array, false);
118
174
  }
119
175
  };
120
176
  node.context.cloneNode = (parentNode, index) => () => {
121
177
  if (parentNode && Array.isArray(parentNode._value)) {
122
- const item = parentNode.value[index];
123
178
  const array = parentNode.value;
124
- array.splice(index + 1, 0, item);
179
+ array.splice(index + 1, 0, (0, _clonePlain.clonePlain)(array[index]));
125
180
  parentNode.input(array, false);
126
181
  }
127
182
  };
@@ -144,35 +199,35 @@ function addRepeaterHandler(node) {
144
199
  };
145
200
  node.context.dragNodeOver = targetIndex => event => {
146
201
  event?.preventDefault();
147
- dragOverIndex = targetIndex;
202
+ context.dragOverIndex = targetIndex;
148
203
  if (event?.dataTransfer) event.dataTransfer.dropEffect = "move";
149
204
  };
150
205
  node.context.dragNodeLeave = targetIndex => () => {
151
- if (dragOverIndex === targetIndex) dragOverIndex = null;
206
+ if (context.dragOverIndex === targetIndex) context.dragOverIndex = null;
152
207
  };
153
208
  node.context.dropNode = (parentNode, targetIndex) => event => {
154
209
  event?.preventDefault();
155
210
  if (!parentNode || !Array.isArray(parentNode._value)) {
156
- dragOverIndex = null;
211
+ context.dragOverIndex = null;
157
212
  return;
158
213
  }
159
214
  const sourceFromEvent = Number.parseInt(event?.dataTransfer?.getData("text/plain") || "", 10);
160
215
  const sourceIndex = Number.isInteger(sourceFromEvent) ? sourceFromEvent : dragStartIndex;
161
216
  if (sourceIndex === null || sourceIndex === targetIndex) {
162
- dragOverIndex = null;
217
+ context.dragOverIndex = null;
163
218
  return;
164
219
  }
165
220
  if (sourceIndex < 0 || sourceIndex >= parentNode.value.length) {
166
- dragOverIndex = null;
221
+ context.dragOverIndex = null;
167
222
  return;
168
223
  }
169
224
  parentNode.input(swapElements(parentNode.value, sourceIndex, targetIndex), false);
170
225
  dragStartIndex = null;
171
- dragOverIndex = null;
226
+ context.dragOverIndex = null;
172
227
  };
173
228
  node.context.dragNodeEnd = () => {
174
229
  dragStartIndex = null;
175
- dragOverIndex = null;
230
+ context.dragOverIndex = null;
176
231
  };
177
232
  }
178
233
  });
@@ -1,23 +1,54 @@
1
1
  import { createInput } from "@formkit/vue";
2
2
  import { useFormKitSchema } from "../composables/index.mjs";
3
+ import { clonePlain } from "../utils/clonePlain.mjs";
3
4
  const { addList, addElement, addListGroup, addComponent } = useFormKitSchema();
4
5
  function addButtonGroup(buttonGroupClass = "", buttonGroupItemClass = "", buttonSize, render = "true") {
5
- const addActionButtonComponent = (onClick = "", icon = "", severity = "", render2 = "true", disabled = "false") => {
6
- return addElement("div", [addComponent("Button", { onClick, icon, severity, disabled, size: buttonSize })], { class: buttonGroupItemClass }, render2);
6
+ const addActionButtonComponent = (onClick = "", icon = "", severity = "", render2 = "true", disabled = "false", label = "") => {
7
+ const name = `${label} + " " + ($index + 1)`;
8
+ return addElement("div", [
9
+ addComponent("Button", {
10
+ "onClick": onClick,
11
+ icon,
12
+ severity,
13
+ disabled,
14
+ "size": buttonSize,
15
+ "aria-label": name,
16
+ "title": name
17
+ })
18
+ ], { class: buttonGroupItemClass }, render2);
7
19
  };
8
20
  return addElement("div", [
9
- addActionButtonComponent("$moveNodeUp($node.parent, $index)", "oi oi-arrow-up", "secondary", "$renderMoveButtons", "$index === 0"),
10
- addActionButtonComponent("$removeNode($node.parent, $index)", "oi oi-trash", "danger", "$displayDeleteButton", "$node.parent.value.length === $minItems"),
11
- addActionButtonComponent("$cloneNode($node.parent, $index)", "oi oi-clone", "", "$displayCloneButton", "$node.parent.value.length > $maxItems -1"),
12
- addActionButtonComponent("$addNode($node.parent, $index)", "oi oi-plus", "", "$displayAddButton", "$node.parent.value.length > $maxItems -1"),
13
- addActionButtonComponent("$moveNodeDown($node.parent, $index)", "oi oi-arrow-down", "secondary", "$renderMoveButtons", "$index === $node.parent.value.length -1")
21
+ addActionButtonComponent("$moveNodeUp($node.parent, $index)", "oi oi-arrow-up", "secondary", "$renderMoveButtons", "$index === 0", "$moveUpLabel"),
22
+ addActionButtonComponent("$removeNode($node.parent, $index)", "oi oi-trash", "danger", "$displayDeleteButton", "$node.parent.value.length === $minItems", "$deleteLabel"),
23
+ addActionButtonComponent("$cloneNode($node.parent, $index)", "oi oi-clone", "", "$displayCloneButton", "$node.parent.value.length > $maxItems -1", "$cloneLabel"),
24
+ addActionButtonComponent("$addNode($node.parent, $index)", "oi oi-plus", "", "$displayAddButton", "$node.parent.value.length > $maxItems -1", "$addLabel"),
25
+ addActionButtonComponent("$moveNodeDown($node.parent, $index)", "oi oi-arrow-down", "secondary", "$renderMoveButtons", "$index === $node.parent.value.length -1", "$moveDownLabel")
14
26
  ], { class: buttonGroupClass }, render);
15
27
  }
16
28
  function addInsertButton(label = "Add Item", icon = "i-lucide-plus", styleClass = "", buttonSize, render = "true") {
17
29
  return addElement("div", [
18
- addComponent("Button", { onClick: "$insertNode($node)", label, icon, size: buttonSize, disabled: "$node.value.length > $maxItems -1" })
30
+ addComponent("Button", {
31
+ onClick: "$insertNode($node)",
32
+ label,
33
+ icon,
34
+ size: buttonSize,
35
+ disabled: "$node.value.length > $maxItems -1"
36
+ })
19
37
  ], { class: styleClass }, render);
20
38
  }
39
+ function addUndoBar(render = "true") {
40
+ return addElement("div", [
41
+ addElement("div", [
42
+ addElement("span", ["$deletedLabel"]),
43
+ addComponent("Button", {
44
+ onClick: "$undoRemoveNode($node)",
45
+ label: "$undoLabel",
46
+ size: "small",
47
+ variant: "text"
48
+ })
49
+ ], { class: "formkit-repeater-undo" }, "$removedItem")
50
+ ], { "role": "status", "aria-live": "polite" }, render);
51
+ }
21
52
  function addDragHandle(handleClass = "", iconClass = "", render = "true") {
22
53
  return addElement("span", [
23
54
  addElement("i", [], { class: iconClass })
@@ -45,11 +76,43 @@ export const formRepeaterDefinition = createInput(
45
76
  onDrop: "$dropNode($node.parent, $index)",
46
77
  onDragend: "$dragNodeEnd"
47
78
  })
48
- ], true, {})
49
- ], true, "true", { value: "$value" })
79
+ ], true, {}),
80
+ addUndoBar("$undoDelete")
81
+ ], true, "true", { value: "$value", validation: "$repeaterValidation" })
50
82
  ], { class: "$internalListClass", id: "$internalListId" }, true),
51
83
  {
52
- props: ["insertButtonLabel", "insertButtonClass", "insertButtonSize", "alwaysDisplayInsertButton", "newItem", "listClass", "listItemClass", "hideButtonGroup", "hideMoveButtons", "buttonGroupClass", "buttonGroupItemClass", "buttonSize", "displayCloneButton", "displayAddButton", "displayDeleteButton", "minItems", "maxItems", "displayDragHandle", "draggable", "dragHandleClass", "dragHandleIconClass"],
84
+ props: [
85
+ "insertButtonLabel",
86
+ "insertButtonClass",
87
+ "insertButtonSize",
88
+ "alwaysDisplayInsertButton",
89
+ "newItem",
90
+ "listClass",
91
+ "listItemClass",
92
+ "hideButtonGroup",
93
+ "hideMoveButtons",
94
+ "buttonGroupClass",
95
+ "buttonGroupItemClass",
96
+ "buttonSize",
97
+ "displayCloneButton",
98
+ "displayAddButton",
99
+ "displayDeleteButton",
100
+ "minItems",
101
+ "maxItems",
102
+ "moveUpLabel",
103
+ "moveDownLabel",
104
+ "deleteLabel",
105
+ "cloneLabel",
106
+ "addLabel",
107
+ "undoDelete",
108
+ "undoLabel",
109
+ "deletedLabel",
110
+ "undoTimeout",
111
+ "displayDragHandle",
112
+ "draggable",
113
+ "dragHandleClass",
114
+ "dragHandleIconClass"
115
+ ],
53
116
  features: [addRepeaterHandler]
54
117
  }
55
118
  );
@@ -58,12 +121,20 @@ function addRepeaterHandler(node) {
58
121
  array.splice(index2, 0, array.splice(index1, 1)[0]);
59
122
  return array;
60
123
  };
61
- const uuid = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2);
62
124
  node.on("created", () => {
63
125
  if (node.context) {
64
126
  let dragStartIndex = null;
65
- let dragOverIndex = null;
66
- const newItem = node.context.newItem || {};
127
+ const makeNewItem = () => clonePlain(node.context?.newItem || {});
128
+ const instanceId = String(node.props.id ?? node.name);
129
+ const context = node.context;
130
+ context.dragOverIndex = null;
131
+ let undoTimer;
132
+ const forgetRemoved = () => {
133
+ clearTimeout(undoTimer);
134
+ undoTimer = void 0;
135
+ context.removedItem = void 0;
136
+ };
137
+ node.on("destroying", () => clearTimeout(undoTimer));
67
138
  node.context.listName = node.name;
68
139
  node.context.renderButtons = !node.context.hideButtonGroup;
69
140
  node.context.insertButtonSize = node.context.insertButtonSize ? node.context.insertButtonSize : "";
@@ -75,38 +146,71 @@ function addRepeaterHandler(node) {
75
146
  node.context.internalDragHandleClass = node.context.dragHandleClass ? `formkit-repeater-drag-handle ${node.context.dragHandleClass}` : "formkit-repeater-drag-handle";
76
147
  node.context.internalListClass = node.context.listClass ? `formkit-items ${node.context.listClass}` : "formkit-items";
77
148
  node.context.internalListItemClass = node.context.listItemClass ? `formkit-item ${node.context.listItemClass}` : "formkit-item";
78
- node.context.internalListId = `formkit-items-${uuid}`;
149
+ node.context.moveUpLabel = node.context.moveUpLabel || "Move item up";
150
+ node.context.moveDownLabel = node.context.moveDownLabel || "Move item down";
151
+ node.context.deleteLabel = node.context.deleteLabel || "Delete item";
152
+ node.context.cloneLabel = node.context.cloneLabel || "Clone item";
153
+ node.context.addLabel = node.context.addLabel || "Add item below";
154
+ node.context.undoDelete = !!node.context.undoDelete;
155
+ node.context.undoLabel = node.context.undoLabel || "Undo";
156
+ node.context.deletedLabel = node.context.deletedLabel || "Item deleted";
157
+ node.context.undoTimeout = node.context.undoTimeout !== void 0 ? Number(node.context.undoTimeout) : 8e3;
158
+ node.context.removedItem = void 0;
159
+ node.context.minItems = node.context.minItems !== void 0 ? node.context.minItems : 0;
160
+ node.context.maxItems = node.context.maxItems !== void 0 ? node.context.maxItems : Number.POSITIVE_INFINITY;
161
+ node.context.repeaterValidation = [
162
+ ["+length", node.context.minItems, node.context.maxItems]
163
+ ];
164
+ node.context.internalListId = `formkit-items-${instanceId}`;
79
165
  node.context.getListItemClass = (index) => {
80
- if (dragOverIndex === index && dragStartIndex !== index)
166
+ if (context.dragOverIndex === index && dragStartIndex !== index)
81
167
  return `${node.context?.internalListItemClass} formkit-repeater-drop-target`;
82
168
  return node.context?.internalListItemClass?.toString() ?? "";
83
169
  };
84
170
  node.context.getListItemId = (index) => {
85
- return `formkit-item-${index}-${uuid}`;
171
+ return `formkit-item-${index}-${instanceId}`;
86
172
  };
87
173
  node.context.insertNode = (parentNode) => () => {
88
174
  if (parentNode && Array.isArray(parentNode._value)) {
89
- const newArray = [{ ...newItem }, ...parentNode.value];
175
+ const newArray = [
176
+ makeNewItem(),
177
+ ...parentNode.value
178
+ ];
90
179
  parentNode.input(newArray, false);
91
180
  }
92
181
  };
93
182
  node.context.removeNode = (parentNode, index) => () => {
94
183
  if (parentNode && Array.isArray(parentNode._value)) {
184
+ const removed = clonePlain(parentNode._value[index]);
95
185
  parentNode.input(parentNode._value.filter((_, i) => i !== index), false);
186
+ if (context.undoDelete) {
187
+ clearTimeout(undoTimer);
188
+ context.removedItem = { index, item: removed };
189
+ const timeout = Number(context.undoTimeout);
190
+ undoTimer = timeout > 0 ? setTimeout(forgetRemoved, timeout) : void 0;
191
+ }
192
+ }
193
+ };
194
+ node.context.undoRemoveNode = (parentNode) => () => {
195
+ const removed = context.removedItem;
196
+ if (removed && parentNode && Array.isArray(parentNode._value) && parentNode._value.length < Number(context.maxItems)) {
197
+ const array = [...parentNode.value];
198
+ array.splice(Math.min(removed.index, array.length), 0, clonePlain(removed.item));
199
+ parentNode.input(array, false);
96
200
  }
201
+ forgetRemoved();
97
202
  };
98
203
  node.context.addNode = (parentNode, index) => () => {
99
204
  if (parentNode && Array.isArray(parentNode._value)) {
100
205
  const array = parentNode.value;
101
- array.splice(index + 1, 0, newItem);
206
+ array.splice(index + 1, 0, makeNewItem());
102
207
  parentNode.input(array, false);
103
208
  }
104
209
  };
105
210
  node.context.cloneNode = (parentNode, index) => () => {
106
211
  if (parentNode && Array.isArray(parentNode._value)) {
107
- const item = parentNode.value[index];
108
212
  const array = parentNode.value;
109
- array.splice(index + 1, 0, item);
213
+ array.splice(index + 1, 0, clonePlain(array[index]));
110
214
  parentNode.input(array, false);
111
215
  }
112
216
  };
@@ -131,37 +235,37 @@ function addRepeaterHandler(node) {
131
235
  };
132
236
  node.context.dragNodeOver = (targetIndex) => (event) => {
133
237
  event?.preventDefault();
134
- dragOverIndex = targetIndex;
238
+ context.dragOverIndex = targetIndex;
135
239
  if (event?.dataTransfer)
136
240
  event.dataTransfer.dropEffect = "move";
137
241
  };
138
242
  node.context.dragNodeLeave = (targetIndex) => () => {
139
- if (dragOverIndex === targetIndex)
140
- dragOverIndex = null;
243
+ if (context.dragOverIndex === targetIndex)
244
+ context.dragOverIndex = null;
141
245
  };
142
246
  node.context.dropNode = (parentNode, targetIndex) => (event) => {
143
247
  event?.preventDefault();
144
248
  if (!parentNode || !Array.isArray(parentNode._value)) {
145
- dragOverIndex = null;
249
+ context.dragOverIndex = null;
146
250
  return;
147
251
  }
148
252
  const sourceFromEvent = Number.parseInt(event?.dataTransfer?.getData("text/plain") || "", 10);
149
253
  const sourceIndex = Number.isInteger(sourceFromEvent) ? sourceFromEvent : dragStartIndex;
150
254
  if (sourceIndex === null || sourceIndex === targetIndex) {
151
- dragOverIndex = null;
255
+ context.dragOverIndex = null;
152
256
  return;
153
257
  }
154
258
  if (sourceIndex < 0 || sourceIndex >= parentNode.value.length) {
155
- dragOverIndex = null;
259
+ context.dragOverIndex = null;
156
260
  return;
157
261
  }
158
262
  parentNode.input(swapElements(parentNode.value, sourceIndex, targetIndex), false);
159
263
  dragStartIndex = null;
160
- dragOverIndex = null;
264
+ context.dragOverIndex = null;
161
265
  };
162
266
  node.context.dragNodeEnd = () => {
163
267
  dragStartIndex = null;
164
- dragOverIndex = null;
268
+ context.dragOverIndex = null;
165
269
  };
166
270
  }
167
271
  });
@@ -0,0 +1,9 @@
1
+ import type { AutoAnimateOptions } from '@formkit/auto-animate';
2
+ import type { FormKitNode } from '@formkit/core';
3
+ /** Sections to animate, per input type. `global` applies to every input. */
4
+ export type AutoAnimateTargets = Record<string, string[]>;
5
+ /**
6
+ * Drop-in replacement for `createAutoAnimatePlugin` from `@formkit/addons` with the same
7
+ * arguments, that does not stack animations on an element after inputs are added to it.
8
+ */
9
+ export declare function createAutoAnimatePlugin(options?: Partial<AutoAnimateOptions>, targets?: AutoAnimateTargets): (node: FormKitNode) => void;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createAutoAnimatePlugin = createAutoAnimatePlugin;
7
+ var _autoAnimate = _interopRequireDefault(require("@formkit/auto-animate"));
8
+ var _core = require("@formkit/core");
9
+ var _inputs = require("@formkit/inputs");
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ const DEFAULT_KEY = "true";
12
+ const optionsByKey = /* @__PURE__ */new Map();
13
+ const attached = /* @__PURE__ */new WeakSet();
14
+ const pendingIds = /* @__PURE__ */new Set();
15
+ let observer = null;
16
+ let attachTimer;
17
+ function attachNewTargets() {
18
+ if (typeof document === "undefined") return;
19
+ document.querySelectorAll("[data-auto-animate]").forEach(target => {
20
+ if (attached.has(target)) return;
21
+ attached.add(target);
22
+ (0, _autoAnimate.default)(target, optionsByKey.get(target.getAttribute("data-auto-animate") ?? "") ?? {});
23
+ });
24
+ }
25
+ function checkPendingIds() {
26
+ if (typeof document === "undefined") return;
27
+ pendingIds.forEach(id => {
28
+ if (!document.getElementById(id)) return;
29
+ pendingIds.delete(id);
30
+ clearTimeout(attachTimer);
31
+ attachTimer = setTimeout(attachNewTargets, 250);
32
+ });
33
+ }
34
+ function observeUntilRendered() {
35
+ if (observer || typeof document === "undefined") return;
36
+ checkPendingIds();
37
+ if (!pendingIds.size) return;
38
+ observer = new MutationObserver(() => {
39
+ checkPendingIds();
40
+ if (!pendingIds.size) {
41
+ observer?.disconnect();
42
+ observer = null;
43
+ }
44
+ });
45
+ observer.observe(document, {
46
+ childList: true,
47
+ subtree: true
48
+ });
49
+ }
50
+ function createAutoAnimatePlugin(options = {}, targets = {}) {
51
+ optionsByKey.set(DEFAULT_KEY, options);
52
+ return node => {
53
+ node.on("created", () => {
54
+ if (typeof node.props.definition?.schema !== "function") return;
55
+ const typeTargets = targets[node.props.type] ?? [];
56
+ const originalSchema = node.props.definition.schema;
57
+ node.props.definition.schema = extensions => {
58
+ const schema = originalSchema(extensions);
59
+ const finalSchema = Array.isArray(schema) ? schema[0] : schema;
60
+ let marked = false;
61
+ (0, _inputs.eachSection)(finalSchema, section => {
62
+ if (!(0, _core.isDOM)(section)) return;
63
+ let key;
64
+ const meta = section.meta;
65
+ if (meta?.autoAnimate) {
66
+ key = DEFAULT_KEY;
67
+ if (typeof meta.autoAnimate === "object") {
68
+ key = `${node.props.id}-${meta.section ?? "section"}`;
69
+ optionsByKey.set(key, {
70
+ ...options,
71
+ ...meta.autoAnimate
72
+ });
73
+ }
74
+ } else {
75
+ const sectionName = meta?.section;
76
+ if (typeof sectionName === "string" && (targets.global?.includes(sectionName) || typeTargets.includes(sectionName))) key = DEFAULT_KEY;
77
+ }
78
+ if (key === void 0) return;
79
+ section.attrs = {
80
+ ...section.attrs,
81
+ "data-auto-animate": key
82
+ };
83
+ marked = true;
84
+ });
85
+ if (marked && node.props.id && typeof window !== "undefined") {
86
+ pendingIds.add(node.props.id);
87
+ observeUntilRendered();
88
+ }
89
+ return finalSchema;
90
+ };
91
+ });
92
+ };
93
+ }