@excalidraw/excalidraw 0.17.1-c0b80a0 → 0.17.1-c329470
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.
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-JGDL4H2X.js → chunk-3DLVY5XU.js} +8272 -6864
- package/dist/browser/dev/excalidraw-assets-dev/chunk-3DLVY5XU.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{chunk-V7NFEZA6.js → chunk-NOAEU4NM.js} +9 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-NOAEU4NM.js.map +7 -0
- package/dist/browser/dev/excalidraw-assets-dev/{en-ZSVWGT55.js → en-7IBTMWBG.js} +2 -2
- package/dist/browser/dev/excalidraw-assets-dev/{image-RJG3J34Y.js → image-N5AC7SEK.js} +2 -6
- package/dist/browser/dev/index.css +85 -50
- package/dist/browser/dev/index.css.map +3 -3
- package/dist/browser/dev/index.js +4375 -3766
- package/dist/browser/dev/index.js.map +4 -4
- package/dist/browser/prod/excalidraw-assets/{chunk-LDVEIXGO.js → chunk-7CSIPVOW.js} +2 -2
- package/dist/browser/prod/excalidraw-assets/chunk-TX3BU7T2.js +47 -0
- package/dist/browser/prod/excalidraw-assets/{en-UPNEHLDS.js → en-LOGQBETY.js} +1 -1
- package/dist/browser/prod/excalidraw-assets/image-3V4U7GZE.js +1 -0
- package/dist/browser/prod/index.css +1 -1
- package/dist/browser/prod/index.js +40 -40
- package/dist/dev/index.css +85 -50
- package/dist/dev/index.css.map +3 -3
- package/dist/dev/index.js +8688 -6706
- package/dist/dev/index.js.map +4 -4
- package/dist/{prod/locales/en-ZXYG7GCR.json → dev/locales/en-V6KXFSCK.json} +8 -1
- package/dist/excalidraw/actions/actionAlign.d.ts +7 -6
- package/dist/excalidraw/actions/actionAlign.js +14 -14
- package/dist/excalidraw/actions/actionClipboard.d.ts +7 -3
- package/dist/excalidraw/actions/actionDeleteSelected.d.ts +7 -3
- package/dist/excalidraw/actions/actionDeleteSelected.js +103 -34
- package/dist/excalidraw/actions/actionDuplicateSelection.js +105 -95
- package/dist/excalidraw/actions/actionFlip.js +16 -7
- package/dist/excalidraw/actions/actionFrame.d.ts +493 -0
- package/dist/excalidraw/actions/actionFrame.js +45 -2
- package/dist/excalidraw/actions/actionGroup.js +6 -4
- package/dist/excalidraw/actions/actionProperties.js +145 -116
- package/dist/excalidraw/actions/actionSelectAll.js +4 -3
- package/dist/excalidraw/actions/shortcuts.d.ts +1 -1
- package/dist/excalidraw/actions/shortcuts.js +1 -0
- package/dist/excalidraw/actions/types.d.ts +1 -1
- package/dist/excalidraw/align.d.ts +2 -1
- package/dist/excalidraw/align.js +15 -6
- package/dist/excalidraw/clipboard.d.ts +27 -5
- package/dist/excalidraw/clipboard.js +55 -28
- package/dist/excalidraw/components/Actions.d.ts +2 -1
- package/dist/excalidraw/components/Actions.js +4 -2
- package/dist/excalidraw/components/ActiveConfirmDialog.d.ts +1 -1
- package/dist/excalidraw/components/ActiveConfirmDialog.js +2 -3
- package/dist/excalidraw/components/App.d.ts +1 -0
- package/dist/excalidraw/components/App.js +216 -111
- package/dist/excalidraw/components/ColorPicker/ColorInput.js +2 -3
- package/dist/excalidraw/components/ColorPicker/ColorPicker.js +2 -3
- package/dist/excalidraw/components/ColorPicker/CustomColorList.js +1 -1
- package/dist/excalidraw/components/ColorPicker/Picker.js +1 -1
- package/dist/excalidraw/components/ColorPicker/PickerColorList.js +1 -1
- package/dist/excalidraw/components/ColorPicker/ShadeList.js +1 -1
- package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
- package/dist/excalidraw/components/ColorPicker/colorPickerUtils.js +1 -1
- package/dist/excalidraw/components/CommandPalette/CommandPalette.js +3 -3
- package/dist/excalidraw/components/ConfirmDialog.js +17 -5
- package/dist/excalidraw/components/Dialog.js +2 -3
- package/dist/excalidraw/components/EyeDropper.d.ts +1 -1
- package/dist/excalidraw/components/EyeDropper.js +1 -1
- package/dist/excalidraw/components/IconPicker.d.ts +2 -2
- package/dist/excalidraw/components/IconPicker.js +56 -53
- package/dist/excalidraw/components/LayerUI.js +6 -6
- package/dist/excalidraw/components/LibraryMenu.d.ts +2 -16
- package/dist/excalidraw/components/LibraryMenu.js +70 -28
- package/dist/excalidraw/components/LibraryMenuHeaderContent.js +4 -5
- package/dist/excalidraw/components/MobileMenu.js +1 -1
- package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirm.js +2 -3
- package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
- package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.js +2 -3
- package/dist/excalidraw/components/Range.d.ts +9 -0
- package/dist/excalidraw/components/Range.js +24 -0
- package/dist/excalidraw/components/SearchMenu.d.ts +1 -1
- package/dist/excalidraw/components/SearchMenu.js +3 -4
- package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
- package/dist/excalidraw/components/Sidebar/Sidebar.js +2 -3
- package/dist/excalidraw/components/Stats/Collapsible.d.ts +2 -1
- package/dist/excalidraw/components/Stats/Collapsible.js +2 -2
- package/dist/excalidraw/components/Stats/Dimension.js +94 -8
- package/dist/excalidraw/components/Stats/MultiDimension.js +8 -5
- package/dist/excalidraw/components/Stats/Position.js +63 -3
- package/dist/excalidraw/components/Stats/index.js +21 -4
- package/dist/excalidraw/components/Stats/utils.d.ts +1 -1
- package/dist/excalidraw/components/Stats/utils.js +2 -55
- package/dist/excalidraw/components/TTDDialog/TTDDialog.js +1 -1
- package/dist/excalidraw/components/ToolButton.js +4 -9
- package/dist/excalidraw/components/hoc/withInternalFallback.js +3 -3
- package/dist/excalidraw/components/hyperlink/Hyperlink.js +6 -12
- package/dist/excalidraw/components/icons.d.ts +9 -0
- package/dist/excalidraw/components/icons.js +4 -4
- package/dist/excalidraw/components/main-menu/DefaultItems.js +2 -3
- package/dist/excalidraw/constants.d.ts +5 -1
- package/dist/excalidraw/constants.js +9 -1
- package/dist/excalidraw/context/tunnels.d.ts +2 -1
- package/dist/excalidraw/context/tunnels.js +3 -1
- package/dist/excalidraw/data/blob.d.ts +1 -0
- package/dist/excalidraw/data/blob.js +7 -3
- package/dist/excalidraw/data/filesystem.d.ts +2 -1
- package/dist/excalidraw/data/filesystem.js +1 -0
- package/dist/excalidraw/data/image.d.ts +0 -6
- package/dist/excalidraw/data/image.js +1 -43
- package/dist/excalidraw/data/index.js +6 -6
- package/dist/excalidraw/data/library.d.ts +9 -3
- package/dist/excalidraw/data/library.js +43 -6
- package/dist/excalidraw/data/restore.js +26 -8
- package/dist/excalidraw/data/url.d.ts +0 -1
- package/dist/excalidraw/data/url.js +2 -4
- package/dist/excalidraw/editor-jotai.d.ts +56 -0
- package/dist/excalidraw/editor-jotai.js +8 -0
- package/dist/excalidraw/element/binding.d.ts +9 -6
- package/dist/excalidraw/element/binding.js +124 -44
- package/dist/excalidraw/element/bounds.js +10 -0
- package/dist/excalidraw/element/cropElement.d.ts +5 -0
- package/dist/excalidraw/element/cropElement.js +28 -1
- package/dist/excalidraw/element/dragElements.js +13 -7
- package/dist/excalidraw/element/elbowArrow.d.ts +16 -0
- package/dist/excalidraw/element/elbowArrow.js +1268 -0
- package/dist/excalidraw/element/embeddable.js +4 -5
- package/dist/excalidraw/element/flowchart.d.ts +1 -1
- package/dist/excalidraw/element/flowchart.js +25 -9
- package/dist/excalidraw/element/heading.d.ts +5 -1
- package/dist/excalidraw/element/heading.js +5 -1
- package/dist/excalidraw/element/image.js +19 -5
- package/dist/excalidraw/element/linearElementEditor.d.ts +9 -10
- package/dist/excalidraw/element/linearElementEditor.js +97 -38
- package/dist/excalidraw/element/mutateElement.d.ts +3 -1
- package/dist/excalidraw/element/mutateElement.js +31 -4
- package/dist/excalidraw/element/newElement.d.ts +8 -12
- package/dist/excalidraw/element/newElement.js +36 -21
- package/dist/excalidraw/element/resizeElements.d.ts +20 -5
- package/dist/excalidraw/element/resizeElements.js +593 -361
- package/dist/excalidraw/element/sortElements.js +1 -4
- package/dist/excalidraw/element/types.d.ts +23 -1
- package/dist/excalidraw/fonts/Fonts.d.ts +0 -16
- package/dist/excalidraw/fonts/Fonts.js +6 -31
- package/dist/excalidraw/frame.d.ts +11 -5
- package/dist/excalidraw/frame.js +146 -35
- package/dist/excalidraw/groups.js +3 -0
- package/dist/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
- package/dist/excalidraw/hooks/useLibraryItemSvg.js +2 -3
- package/dist/excalidraw/hooks/useScrollPosition.js +1 -1
- package/dist/excalidraw/i18n.js +3 -4
- package/dist/excalidraw/index.js +3 -4
- package/dist/excalidraw/locales/en.json +8 -1
- package/dist/excalidraw/renderer/interactiveScene.js +43 -32
- package/dist/excalidraw/renderer/staticScene.js +6 -4
- package/dist/excalidraw/renderer/staticSvgScene.js +1 -1
- package/dist/excalidraw/scene/Shape.js +40 -17
- package/dist/excalidraw/scene/comparisons.d.ts +0 -477
- package/dist/excalidraw/scene/comparisons.js +0 -37
- package/dist/excalidraw/scene/export.d.ts +7 -0
- package/dist/excalidraw/scene/export.js +107 -43
- package/dist/excalidraw/scene/index.d.ts +1 -1
- package/dist/excalidraw/scene/index.js +1 -1
- package/dist/excalidraw/scene/selection.js +4 -1
- package/dist/excalidraw/types.d.ts +15 -0
- package/dist/excalidraw/utility-types.d.ts +1 -0
- package/dist/excalidraw/utils.d.ts +8 -1
- package/dist/excalidraw/utils.js +9 -0
- package/dist/excalidraw/visualdebug.d.ts +8 -1
- package/dist/excalidraw/visualdebug.js +3 -0
- package/dist/math/line.d.ts +19 -0
- package/dist/math/line.js +32 -3
- package/dist/math/point.d.ts +10 -0
- package/dist/math/point.js +12 -1
- package/dist/prod/index.css +1 -1
- package/dist/prod/index.js +29 -44
- package/dist/{dev/locales/en-ZXYG7GCR.json → prod/locales/en-V6KXFSCK.json} +8 -1
- package/package.json +5 -2
- package/dist/browser/dev/excalidraw-assets-dev/chunk-JGDL4H2X.js.map +0 -7
- package/dist/browser/dev/excalidraw-assets-dev/chunk-V7NFEZA6.js.map +0 -7
- package/dist/browser/prod/excalidraw-assets/chunk-S2XKB3DE.js +0 -62
- package/dist/browser/prod/excalidraw-assets/image-OFI2YYMP.js +0 -1
- package/dist/excalidraw/element/routing.d.ts +0 -12
- package/dist/excalidraw/element/routing.js +0 -642
- package/dist/excalidraw/jotai.d.ts +0 -34
- package/dist/excalidraw/jotai.js +0 -18
- /package/dist/browser/dev/excalidraw-assets-dev/{en-ZSVWGT55.js.map → en-7IBTMWBG.js.map} +0 -0
- /package/dist/browser/dev/excalidraw-assets-dev/{image-RJG3J34Y.js.map → image-N5AC7SEK.js.map} +0 -0
|
@@ -5,18 +5,17 @@ import { duplicateElement, getNonDeletedElements } from "../element";
|
|
|
5
5
|
import { isSomeElementSelected } from "../scene";
|
|
6
6
|
import { ToolButton } from "../components/ToolButton";
|
|
7
7
|
import { t } from "../i18n";
|
|
8
|
-
import { arrayToMap, getShortcutKey } from "../utils";
|
|
8
|
+
import { arrayToMap, castArray, findLastIndex, getShortcutKey, invariant, } from "../utils";
|
|
9
9
|
import { LinearElementEditor } from "../element/linearElementEditor";
|
|
10
10
|
import { selectGroupsForSelectedElements, getSelectedGroupForElement, getElementsInGroup, } from "../groups";
|
|
11
11
|
import { fixBindingsAfterDuplication } from "../element/binding";
|
|
12
12
|
import { DEFAULT_GRID_SIZE } from "../constants";
|
|
13
|
-
import { bindTextToShapeAfterDuplication, getBoundTextElement, } from "../element/textElement";
|
|
14
|
-
import { isBoundToContainer, isFrameLikeElement } from "../element/typeChecks";
|
|
13
|
+
import { bindTextToShapeAfterDuplication, getBoundTextElement, getContainerElement, } from "../element/textElement";
|
|
14
|
+
import { hasBoundTextElement, isBoundToContainer, isFrameLikeElement, } from "../element/typeChecks";
|
|
15
15
|
import { normalizeElementOrder } from "../element/sortElements";
|
|
16
16
|
import { DuplicateIcon } from "../components/icons";
|
|
17
17
|
import { bindElementsToFramesAfterDuplication, getFrameChildren, } from "../frame";
|
|
18
18
|
import { excludeElementsInFramesFromSelection, getSelectedElements, } from "../scene/selection";
|
|
19
|
-
import { syncMovedIndices } from "../fractionalIndex";
|
|
20
19
|
import { StoreAction } from "../store";
|
|
21
20
|
export const actionDuplicateSelection = register({
|
|
22
21
|
name: "duplicateSelection",
|
|
@@ -39,8 +38,15 @@ export const actionDuplicateSelection = register({
|
|
|
39
38
|
return false;
|
|
40
39
|
}
|
|
41
40
|
}
|
|
41
|
+
const nextState = duplicateElements(elements, appState);
|
|
42
|
+
if (app.props.onDuplicate && nextState.elements) {
|
|
43
|
+
const mappedElements = app.props.onDuplicate(nextState.elements, elements);
|
|
44
|
+
if (mappedElements) {
|
|
45
|
+
nextState.elements = mappedElements;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
42
48
|
return {
|
|
43
|
-
...
|
|
49
|
+
...nextState,
|
|
44
50
|
storeAction: StoreAction.CAPTURE,
|
|
45
51
|
};
|
|
46
52
|
},
|
|
@@ -49,25 +55,35 @@ export const actionDuplicateSelection = register({
|
|
|
49
55
|
});
|
|
50
56
|
const duplicateElements = (elements, appState) => {
|
|
51
57
|
// ---------------------------------------------------------------------------
|
|
52
|
-
// step (1)
|
|
53
|
-
const sortedElements = normalizeElementOrder(elements);
|
|
54
58
|
const groupIdMap = new Map();
|
|
55
59
|
const newElements = [];
|
|
56
60
|
const oldElements = [];
|
|
57
61
|
const oldIdToDuplicatedId = new Map();
|
|
58
62
|
const duplicatedElementsMap = new Map();
|
|
63
|
+
const elementsMap = arrayToMap(elements);
|
|
59
64
|
const duplicateAndOffsetElement = (element) => {
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
const elements = castArray(element);
|
|
66
|
+
const _newElements = elements.reduce((acc, element) => {
|
|
67
|
+
if (processedIds.has(element.id)) {
|
|
68
|
+
return acc;
|
|
69
|
+
}
|
|
70
|
+
processedIds.set(element.id, true);
|
|
71
|
+
const newElement = duplicateElement(appState.editingGroupId, groupIdMap, element, {
|
|
72
|
+
x: element.x + DEFAULT_GRID_SIZE / 2,
|
|
73
|
+
y: element.y + DEFAULT_GRID_SIZE / 2,
|
|
74
|
+
});
|
|
75
|
+
processedIds.set(newElement.id, true);
|
|
76
|
+
duplicatedElementsMap.set(newElement.id, newElement);
|
|
77
|
+
oldIdToDuplicatedId.set(element.id, newElement.id);
|
|
78
|
+
oldElements.push(element);
|
|
79
|
+
newElements.push(newElement);
|
|
80
|
+
acc.push(newElement);
|
|
81
|
+
return acc;
|
|
82
|
+
}, []);
|
|
83
|
+
return (Array.isArray(element) ? _newElements : _newElements[0] || null);
|
|
69
84
|
};
|
|
70
|
-
|
|
85
|
+
elements = normalizeElementOrder(elements);
|
|
86
|
+
const idsOfElementsToDuplicate = arrayToMap(getSelectedElements(elements, appState, {
|
|
71
87
|
includeBoundTextElement: true,
|
|
72
88
|
includeElementsInFrames: true,
|
|
73
89
|
}));
|
|
@@ -82,97 +98,91 @@ const duplicateElements = (elements, appState) => {
|
|
|
82
98
|
// For convenience we mark even the newly created ones even though we don't
|
|
83
99
|
// loop over them.
|
|
84
100
|
const processedIds = new Map();
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
101
|
+
const elementsWithClones = elements.slice();
|
|
102
|
+
const insertAfterIndex = (index, elements) => {
|
|
103
|
+
invariant(index !== -1, "targetIndex === -1 ");
|
|
104
|
+
if (!Array.isArray(elements) && !elements) {
|
|
105
|
+
return;
|
|
88
106
|
}
|
|
89
|
-
|
|
107
|
+
elementsWithClones.splice(index + 1, 0, ...castArray(elements));
|
|
90
108
|
};
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (processedIds.
|
|
109
|
+
const frameIdsToDuplicate = new Set(elements
|
|
110
|
+
.filter((el) => idsOfElementsToDuplicate.has(el.id) && isFrameLikeElement(el))
|
|
111
|
+
.map((el) => el.id));
|
|
112
|
+
for (const element of elements) {
|
|
113
|
+
if (processedIds.has(element.id)) {
|
|
96
114
|
continue;
|
|
97
115
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
116
|
+
if (!idsOfElementsToDuplicate.has(element.id)) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
// groups
|
|
120
|
+
// -------------------------------------------------------------------------
|
|
121
|
+
const groupId = getSelectedGroupForElement(appState, element);
|
|
122
|
+
if (groupId) {
|
|
123
|
+
const groupElements = getElementsInGroup(elements, groupId).flatMap((element) => isFrameLikeElement(element)
|
|
124
|
+
? [...getFrameChildren(elements, element.id), element]
|
|
125
|
+
: [element]);
|
|
126
|
+
const targetIndex = findLastIndex(elementsWithClones, (el) => {
|
|
127
|
+
return el.groupIds?.includes(groupId);
|
|
128
|
+
});
|
|
129
|
+
insertAfterIndex(targetIndex, duplicateAndOffsetElement(groupElements));
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
// frame duplication
|
|
133
|
+
// -------------------------------------------------------------------------
|
|
134
|
+
if (element.frameId && frameIdsToDuplicate.has(element.frameId)) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (isFrameLikeElement(element)) {
|
|
138
|
+
const frameId = element.id;
|
|
139
|
+
const frameChildren = getFrameChildren(elements, frameId);
|
|
140
|
+
const targetIndex = findLastIndex(elementsWithClones, (el) => {
|
|
141
|
+
return el.frameId === frameId || el.id === frameId;
|
|
142
|
+
});
|
|
143
|
+
insertAfterIndex(targetIndex, duplicateAndOffsetElement([...frameChildren, element]));
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
// text container
|
|
147
|
+
// -------------------------------------------------------------------------
|
|
148
|
+
if (hasBoundTextElement(element)) {
|
|
149
|
+
const boundTextElement = getBoundTextElement(element, elementsMap);
|
|
150
|
+
const targetIndex = findLastIndex(elementsWithClones, (el) => {
|
|
151
|
+
return (el.id === element.id ||
|
|
152
|
+
("containerId" in el && el.containerId === element.id));
|
|
153
|
+
});
|
|
154
|
+
if (boundTextElement) {
|
|
155
|
+
insertAfterIndex(targetIndex, duplicateAndOffsetElement([element, boundTextElement]));
|
|
136
156
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// they will have been copied along with the frame atomically in the
|
|
140
|
-
// above branch, so we must skip those elements here
|
|
141
|
-
//
|
|
142
|
-
// now, for elements do not belong any frames or elements whose frames
|
|
143
|
-
// are selected (or elements that are left out from the above
|
|
144
|
-
// steps for whatever reason) we (should at least) duplicate them here
|
|
145
|
-
if (!element.frameId || !idsOfElementsToDuplicate.has(element.frameId)) {
|
|
146
|
-
elementsWithClones.push(...markAsProcessed([element, duplicateAndOffsetElement(element)]));
|
|
157
|
+
else {
|
|
158
|
+
insertAfterIndex(targetIndex, duplicateAndOffsetElement(element));
|
|
147
159
|
}
|
|
160
|
+
continue;
|
|
148
161
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const element = elementsWithClones[index];
|
|
162
|
-
if (!finalElementIds.get(element.id)) {
|
|
163
|
-
finalElementIds.set(element.id, true);
|
|
164
|
-
finalElementsReversed.push(element);
|
|
162
|
+
if (isBoundToContainer(element)) {
|
|
163
|
+
const container = getContainerElement(element, elementsMap);
|
|
164
|
+
const targetIndex = findLastIndex(elementsWithClones, (el) => {
|
|
165
|
+
return el.id === element.id || el.id === container?.id;
|
|
166
|
+
});
|
|
167
|
+
if (container) {
|
|
168
|
+
insertAfterIndex(targetIndex, duplicateAndOffsetElement([container, element]));
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
insertAfterIndex(targetIndex, duplicateAndOffsetElement(element));
|
|
172
|
+
}
|
|
173
|
+
continue;
|
|
165
174
|
}
|
|
175
|
+
// default duplication (regular elements)
|
|
176
|
+
// -------------------------------------------------------------------------
|
|
177
|
+
insertAfterIndex(findLastIndex(elementsWithClones, (el) => el.id === element.id), duplicateAndOffsetElement(element));
|
|
166
178
|
}
|
|
167
|
-
// step (3)
|
|
168
|
-
const finalElements = syncMovedIndices(finalElementsReversed.reverse(), arrayToMap(newElements));
|
|
169
179
|
// ---------------------------------------------------------------------------
|
|
170
180
|
bindTextToShapeAfterDuplication(elementsWithClones, oldElements, oldIdToDuplicatedId);
|
|
171
181
|
fixBindingsAfterDuplication(elementsWithClones, oldElements, oldIdToDuplicatedId);
|
|
172
|
-
bindElementsToFramesAfterDuplication(
|
|
182
|
+
bindElementsToFramesAfterDuplication(elementsWithClones, oldElements, oldIdToDuplicatedId);
|
|
173
183
|
const nextElementsToSelect = excludeElementsInFramesFromSelection(newElements);
|
|
174
184
|
return {
|
|
175
|
-
elements:
|
|
185
|
+
elements: elementsWithClones,
|
|
176
186
|
appState: {
|
|
177
187
|
...appState,
|
|
178
188
|
...selectGroupsForSelectedElements({
|
|
@@ -183,7 +193,7 @@ const duplicateElements = (elements, appState) => {
|
|
|
183
193
|
}
|
|
184
194
|
return acc;
|
|
185
195
|
}, {}),
|
|
186
|
-
}, getNonDeletedElements(
|
|
196
|
+
}, getNonDeletedElements(elementsWithClones), appState, null),
|
|
187
197
|
},
|
|
188
198
|
};
|
|
189
199
|
};
|
|
@@ -4,14 +4,14 @@ import { getNonDeletedElements } from "../element";
|
|
|
4
4
|
import { resizeMultipleElements } from "../element/resizeElements";
|
|
5
5
|
import { arrayToMap } from "../utils";
|
|
6
6
|
import { CODES, KEYS } from "../keys";
|
|
7
|
-
import { getCommonBoundingBox } from "../element/bounds";
|
|
8
7
|
import { bindOrUnbindLinearElements, isBindingEnabled, } from "../element/binding";
|
|
9
8
|
import { updateFrameMembershipOfSelectedElements } from "../frame";
|
|
10
9
|
import { flipHorizontal, flipVertical } from "../components/icons";
|
|
11
10
|
import { StoreAction } from "../store";
|
|
12
11
|
import { isArrowElement, isElbowArrow, isLinearElement, } from "../element/typeChecks";
|
|
13
|
-
import { mutateElbowArrow } from "../element/routing";
|
|
14
12
|
import { mutateElement, newElementWith } from "../element/mutateElement";
|
|
13
|
+
import { deepCopyElement } from "../element/newElement";
|
|
14
|
+
import { getCommonBoundingBox } from "../element/bounds";
|
|
15
15
|
export const actionFlipHorizontal = register({
|
|
16
16
|
name: "flipHorizontal",
|
|
17
17
|
label: "labels.flipHorizontal",
|
|
@@ -59,9 +59,17 @@ const flipElements = (selectedElements, elementsMap, appState, flipDirection, ap
|
|
|
59
59
|
});
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
|
-
const {
|
|
63
|
-
resizeMultipleElements(
|
|
64
|
-
|
|
62
|
+
const { midX, midY } = getCommonBoundingBox(selectedElements);
|
|
63
|
+
resizeMultipleElements(selectedElements, elementsMap, "nw", app.scene, new Map(Array.from(elementsMap.values()).map((element) => [
|
|
64
|
+
element.id,
|
|
65
|
+
deepCopyElement(element),
|
|
66
|
+
])), {
|
|
67
|
+
flipByX: flipDirection === "horizontal",
|
|
68
|
+
flipByY: flipDirection === "vertical",
|
|
69
|
+
shouldResizeFromCenter: true,
|
|
70
|
+
shouldMaintainAspectRatio: true,
|
|
71
|
+
});
|
|
72
|
+
bindOrUnbindLinearElements(selectedElements.filter(isLinearElement), elementsMap, app.scene.getNonDeletedElements(), app.scene, isBindingEnabled(appState), [], appState.zoom);
|
|
65
73
|
// ---------------------------------------------------------------------------
|
|
66
74
|
// flipping arrow elements (and potentially other) makes the selection group
|
|
67
75
|
// "move" across the canvas because of how arrows can bump against the "wall"
|
|
@@ -76,8 +84,9 @@ const flipElements = (selectedElements, elementsMap, appState, flipDirection, ap
|
|
|
76
84
|
x: element.x + diffX,
|
|
77
85
|
y: element.y + diffY,
|
|
78
86
|
}));
|
|
79
|
-
elbowArrows.forEach((element) =>
|
|
80
|
-
|
|
87
|
+
elbowArrows.forEach((element) => mutateElement(element, {
|
|
88
|
+
x: element.x + diffX,
|
|
89
|
+
y: element.y + diffY,
|
|
81
90
|
}));
|
|
82
91
|
// ---------------------------------------------------------------------------
|
|
83
92
|
return selectedElements;
|