@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.
Files changed (178) hide show
  1. package/dist/browser/dev/excalidraw-assets-dev/{chunk-JGDL4H2X.js → chunk-3DLVY5XU.js} +8272 -6864
  2. package/dist/browser/dev/excalidraw-assets-dev/chunk-3DLVY5XU.js.map +7 -0
  3. package/dist/browser/dev/excalidraw-assets-dev/{chunk-V7NFEZA6.js → chunk-NOAEU4NM.js} +9 -2
  4. package/dist/browser/dev/excalidraw-assets-dev/chunk-NOAEU4NM.js.map +7 -0
  5. package/dist/browser/dev/excalidraw-assets-dev/{en-ZSVWGT55.js → en-7IBTMWBG.js} +2 -2
  6. package/dist/browser/dev/excalidraw-assets-dev/{image-RJG3J34Y.js → image-N5AC7SEK.js} +2 -6
  7. package/dist/browser/dev/index.css +85 -50
  8. package/dist/browser/dev/index.css.map +3 -3
  9. package/dist/browser/dev/index.js +4375 -3766
  10. package/dist/browser/dev/index.js.map +4 -4
  11. package/dist/browser/prod/excalidraw-assets/{chunk-LDVEIXGO.js → chunk-7CSIPVOW.js} +2 -2
  12. package/dist/browser/prod/excalidraw-assets/chunk-TX3BU7T2.js +47 -0
  13. package/dist/browser/prod/excalidraw-assets/{en-UPNEHLDS.js → en-LOGQBETY.js} +1 -1
  14. package/dist/browser/prod/excalidraw-assets/image-3V4U7GZE.js +1 -0
  15. package/dist/browser/prod/index.css +1 -1
  16. package/dist/browser/prod/index.js +40 -40
  17. package/dist/dev/index.css +85 -50
  18. package/dist/dev/index.css.map +3 -3
  19. package/dist/dev/index.js +8688 -6706
  20. package/dist/dev/index.js.map +4 -4
  21. package/dist/{prod/locales/en-ZXYG7GCR.json → dev/locales/en-V6KXFSCK.json} +8 -1
  22. package/dist/excalidraw/actions/actionAlign.d.ts +7 -6
  23. package/dist/excalidraw/actions/actionAlign.js +14 -14
  24. package/dist/excalidraw/actions/actionClipboard.d.ts +7 -3
  25. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +7 -3
  26. package/dist/excalidraw/actions/actionDeleteSelected.js +103 -34
  27. package/dist/excalidraw/actions/actionDuplicateSelection.js +105 -95
  28. package/dist/excalidraw/actions/actionFlip.js +16 -7
  29. package/dist/excalidraw/actions/actionFrame.d.ts +493 -0
  30. package/dist/excalidraw/actions/actionFrame.js +45 -2
  31. package/dist/excalidraw/actions/actionGroup.js +6 -4
  32. package/dist/excalidraw/actions/actionProperties.js +145 -116
  33. package/dist/excalidraw/actions/actionSelectAll.js +4 -3
  34. package/dist/excalidraw/actions/shortcuts.d.ts +1 -1
  35. package/dist/excalidraw/actions/shortcuts.js +1 -0
  36. package/dist/excalidraw/actions/types.d.ts +1 -1
  37. package/dist/excalidraw/align.d.ts +2 -1
  38. package/dist/excalidraw/align.js +15 -6
  39. package/dist/excalidraw/clipboard.d.ts +27 -5
  40. package/dist/excalidraw/clipboard.js +55 -28
  41. package/dist/excalidraw/components/Actions.d.ts +2 -1
  42. package/dist/excalidraw/components/Actions.js +4 -2
  43. package/dist/excalidraw/components/ActiveConfirmDialog.d.ts +1 -1
  44. package/dist/excalidraw/components/ActiveConfirmDialog.js +2 -3
  45. package/dist/excalidraw/components/App.d.ts +1 -0
  46. package/dist/excalidraw/components/App.js +216 -111
  47. package/dist/excalidraw/components/ColorPicker/ColorInput.js +2 -3
  48. package/dist/excalidraw/components/ColorPicker/ColorPicker.js +2 -3
  49. package/dist/excalidraw/components/ColorPicker/CustomColorList.js +1 -1
  50. package/dist/excalidraw/components/ColorPicker/Picker.js +1 -1
  51. package/dist/excalidraw/components/ColorPicker/PickerColorList.js +1 -1
  52. package/dist/excalidraw/components/ColorPicker/ShadeList.js +1 -1
  53. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
  54. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.js +1 -1
  55. package/dist/excalidraw/components/CommandPalette/CommandPalette.js +3 -3
  56. package/dist/excalidraw/components/ConfirmDialog.js +17 -5
  57. package/dist/excalidraw/components/Dialog.js +2 -3
  58. package/dist/excalidraw/components/EyeDropper.d.ts +1 -1
  59. package/dist/excalidraw/components/EyeDropper.js +1 -1
  60. package/dist/excalidraw/components/IconPicker.d.ts +2 -2
  61. package/dist/excalidraw/components/IconPicker.js +56 -53
  62. package/dist/excalidraw/components/LayerUI.js +6 -6
  63. package/dist/excalidraw/components/LibraryMenu.d.ts +2 -16
  64. package/dist/excalidraw/components/LibraryMenu.js +70 -28
  65. package/dist/excalidraw/components/LibraryMenuHeaderContent.js +4 -5
  66. package/dist/excalidraw/components/MobileMenu.js +1 -1
  67. package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirm.js +2 -3
  68. package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.d.ts +1 -1
  69. package/dist/excalidraw/components/OverwriteConfirm/OverwriteConfirmState.js +2 -3
  70. package/dist/excalidraw/components/Range.d.ts +9 -0
  71. package/dist/excalidraw/components/Range.js +24 -0
  72. package/dist/excalidraw/components/SearchMenu.d.ts +1 -1
  73. package/dist/excalidraw/components/SearchMenu.js +3 -4
  74. package/dist/excalidraw/components/Sidebar/Sidebar.d.ts +1 -1
  75. package/dist/excalidraw/components/Sidebar/Sidebar.js +2 -3
  76. package/dist/excalidraw/components/Stats/Collapsible.d.ts +2 -1
  77. package/dist/excalidraw/components/Stats/Collapsible.js +2 -2
  78. package/dist/excalidraw/components/Stats/Dimension.js +94 -8
  79. package/dist/excalidraw/components/Stats/MultiDimension.js +8 -5
  80. package/dist/excalidraw/components/Stats/Position.js +63 -3
  81. package/dist/excalidraw/components/Stats/index.js +21 -4
  82. package/dist/excalidraw/components/Stats/utils.d.ts +1 -1
  83. package/dist/excalidraw/components/Stats/utils.js +2 -55
  84. package/dist/excalidraw/components/TTDDialog/TTDDialog.js +1 -1
  85. package/dist/excalidraw/components/ToolButton.js +4 -9
  86. package/dist/excalidraw/components/hoc/withInternalFallback.js +3 -3
  87. package/dist/excalidraw/components/hyperlink/Hyperlink.js +6 -12
  88. package/dist/excalidraw/components/icons.d.ts +9 -0
  89. package/dist/excalidraw/components/icons.js +4 -4
  90. package/dist/excalidraw/components/main-menu/DefaultItems.js +2 -3
  91. package/dist/excalidraw/constants.d.ts +5 -1
  92. package/dist/excalidraw/constants.js +9 -1
  93. package/dist/excalidraw/context/tunnels.d.ts +2 -1
  94. package/dist/excalidraw/context/tunnels.js +3 -1
  95. package/dist/excalidraw/data/blob.d.ts +1 -0
  96. package/dist/excalidraw/data/blob.js +7 -3
  97. package/dist/excalidraw/data/filesystem.d.ts +2 -1
  98. package/dist/excalidraw/data/filesystem.js +1 -0
  99. package/dist/excalidraw/data/image.d.ts +0 -6
  100. package/dist/excalidraw/data/image.js +1 -43
  101. package/dist/excalidraw/data/index.js +6 -6
  102. package/dist/excalidraw/data/library.d.ts +9 -3
  103. package/dist/excalidraw/data/library.js +43 -6
  104. package/dist/excalidraw/data/restore.js +26 -8
  105. package/dist/excalidraw/data/url.d.ts +0 -1
  106. package/dist/excalidraw/data/url.js +2 -4
  107. package/dist/excalidraw/editor-jotai.d.ts +56 -0
  108. package/dist/excalidraw/editor-jotai.js +8 -0
  109. package/dist/excalidraw/element/binding.d.ts +9 -6
  110. package/dist/excalidraw/element/binding.js +124 -44
  111. package/dist/excalidraw/element/bounds.js +10 -0
  112. package/dist/excalidraw/element/cropElement.d.ts +5 -0
  113. package/dist/excalidraw/element/cropElement.js +28 -1
  114. package/dist/excalidraw/element/dragElements.js +13 -7
  115. package/dist/excalidraw/element/elbowArrow.d.ts +16 -0
  116. package/dist/excalidraw/element/elbowArrow.js +1268 -0
  117. package/dist/excalidraw/element/embeddable.js +4 -5
  118. package/dist/excalidraw/element/flowchart.d.ts +1 -1
  119. package/dist/excalidraw/element/flowchart.js +25 -9
  120. package/dist/excalidraw/element/heading.d.ts +5 -1
  121. package/dist/excalidraw/element/heading.js +5 -1
  122. package/dist/excalidraw/element/image.js +19 -5
  123. package/dist/excalidraw/element/linearElementEditor.d.ts +9 -10
  124. package/dist/excalidraw/element/linearElementEditor.js +97 -38
  125. package/dist/excalidraw/element/mutateElement.d.ts +3 -1
  126. package/dist/excalidraw/element/mutateElement.js +31 -4
  127. package/dist/excalidraw/element/newElement.d.ts +8 -12
  128. package/dist/excalidraw/element/newElement.js +36 -21
  129. package/dist/excalidraw/element/resizeElements.d.ts +20 -5
  130. package/dist/excalidraw/element/resizeElements.js +593 -361
  131. package/dist/excalidraw/element/sortElements.js +1 -4
  132. package/dist/excalidraw/element/types.d.ts +23 -1
  133. package/dist/excalidraw/fonts/Fonts.d.ts +0 -16
  134. package/dist/excalidraw/fonts/Fonts.js +6 -31
  135. package/dist/excalidraw/frame.d.ts +11 -5
  136. package/dist/excalidraw/frame.js +146 -35
  137. package/dist/excalidraw/groups.js +3 -0
  138. package/dist/excalidraw/hooks/useLibraryItemSvg.d.ts +1 -1
  139. package/dist/excalidraw/hooks/useLibraryItemSvg.js +2 -3
  140. package/dist/excalidraw/hooks/useScrollPosition.js +1 -1
  141. package/dist/excalidraw/i18n.js +3 -4
  142. package/dist/excalidraw/index.js +3 -4
  143. package/dist/excalidraw/locales/en.json +8 -1
  144. package/dist/excalidraw/renderer/interactiveScene.js +43 -32
  145. package/dist/excalidraw/renderer/staticScene.js +6 -4
  146. package/dist/excalidraw/renderer/staticSvgScene.js +1 -1
  147. package/dist/excalidraw/scene/Shape.js +40 -17
  148. package/dist/excalidraw/scene/comparisons.d.ts +0 -477
  149. package/dist/excalidraw/scene/comparisons.js +0 -37
  150. package/dist/excalidraw/scene/export.d.ts +7 -0
  151. package/dist/excalidraw/scene/export.js +107 -43
  152. package/dist/excalidraw/scene/index.d.ts +1 -1
  153. package/dist/excalidraw/scene/index.js +1 -1
  154. package/dist/excalidraw/scene/selection.js +4 -1
  155. package/dist/excalidraw/types.d.ts +15 -0
  156. package/dist/excalidraw/utility-types.d.ts +1 -0
  157. package/dist/excalidraw/utils.d.ts +8 -1
  158. package/dist/excalidraw/utils.js +9 -0
  159. package/dist/excalidraw/visualdebug.d.ts +8 -1
  160. package/dist/excalidraw/visualdebug.js +3 -0
  161. package/dist/math/line.d.ts +19 -0
  162. package/dist/math/line.js +32 -3
  163. package/dist/math/point.d.ts +10 -0
  164. package/dist/math/point.js +12 -1
  165. package/dist/prod/index.css +1 -1
  166. package/dist/prod/index.js +29 -44
  167. package/dist/{dev/locales/en-ZXYG7GCR.json → prod/locales/en-V6KXFSCK.json} +8 -1
  168. package/package.json +5 -2
  169. package/dist/browser/dev/excalidraw-assets-dev/chunk-JGDL4H2X.js.map +0 -7
  170. package/dist/browser/dev/excalidraw-assets-dev/chunk-V7NFEZA6.js.map +0 -7
  171. package/dist/browser/prod/excalidraw-assets/chunk-S2XKB3DE.js +0 -62
  172. package/dist/browser/prod/excalidraw-assets/image-OFI2YYMP.js +0 -1
  173. package/dist/excalidraw/element/routing.d.ts +0 -12
  174. package/dist/excalidraw/element/routing.js +0 -642
  175. package/dist/excalidraw/jotai.d.ts +0 -34
  176. package/dist/excalidraw/jotai.js +0 -18
  177. /package/dist/browser/dev/excalidraw-assets-dev/{en-ZSVWGT55.js.map → en-7IBTMWBG.js.map} +0 -0
  178. /package/dist/browser/dev/excalidraw-assets-dev/{image-RJG3J34Y.js.map → image-N5AC7SEK.js.map} +0 -0
@@ -46,6 +46,10 @@
46
46
  "arrowhead_triangle_outline": "Triangle (outline)",
47
47
  "arrowhead_diamond": "Diamond",
48
48
  "arrowhead_diamond_outline": "Diamond (outline)",
49
+ "arrowhead_crowfoot_many": "Crow's foot (many)",
50
+ "arrowhead_crowfoot_one": "Crow's foot (one)",
51
+ "arrowhead_crowfoot_one_or_many": "Crow's foot (one or many)",
52
+ "more_options": "More options",
49
53
  "arrowtypes": "Arrow type",
50
54
  "arrowtype_sharp": "Sharp arrow",
51
55
  "arrowtype_round": "Curved arrow",
@@ -157,8 +161,11 @@
157
161
  "zoomToFit": "Zoom to fit all elements",
158
162
  "installPWA": "Install Excalidraw locally (PWA)",
159
163
  "autoResize": "Enable text auto-resizing",
164
+ "imageCropping": "Image cropping",
165
+ "unCroppedDimension": "Uncropped dimension",
160
166
  "copyElementLink": "Copy link to object",
161
- "linkToElement": "Link to object"
167
+ "linkToElement": "Link to object",
168
+ "wrapSelectionInFrame": "Wrap selection in frame"
162
169
  },
163
170
  "elementLink": {
164
171
  "title": "Link to object",
@@ -1,6 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import type { ExcalidrawElement } from "../element/types";
3
3
  import type { AppClassProperties, AppState, UIAppState } from "../types";
4
+ export declare const alignActionsPredicate: (appState: UIAppState, app: AppClassProperties) => boolean;
4
5
  export declare const actionAlignTop: {
5
6
  name: "alignTop";
6
7
  label: string;
@@ -8,7 +9,7 @@ export declare const actionAlignTop: {
8
9
  trackEvent: {
9
10
  category: "element";
10
11
  };
11
- predicate: (elements: readonly ExcalidrawElement[], appState: UIAppState, _: unknown, app: AppClassProperties) => boolean;
12
+ predicate: (elements: readonly ExcalidrawElement[], appState: AppState, appProps: import("../types").ExcalidrawProps, app: AppClassProperties) => boolean;
12
13
  perform: (elements: readonly import("../element/types").OrderedExcalidrawElement[], appState: Readonly<AppState>, _: any, app: AppClassProperties) => {
13
14
  appState: Readonly<AppState>;
14
15
  elements: ExcalidrawElement[];
@@ -26,7 +27,7 @@ export declare const actionAlignBottom: {
26
27
  trackEvent: {
27
28
  category: "element";
28
29
  };
29
- predicate: (elements: readonly ExcalidrawElement[], appState: UIAppState, _: unknown, app: AppClassProperties) => boolean;
30
+ predicate: (elements: readonly ExcalidrawElement[], appState: AppState, appProps: import("../types").ExcalidrawProps, app: AppClassProperties) => boolean;
30
31
  perform: (elements: readonly import("../element/types").OrderedExcalidrawElement[], appState: Readonly<AppState>, _: any, app: AppClassProperties) => {
31
32
  appState: Readonly<AppState>;
32
33
  elements: ExcalidrawElement[];
@@ -44,7 +45,7 @@ export declare const actionAlignLeft: {
44
45
  trackEvent: {
45
46
  category: "element";
46
47
  };
47
- predicate: (elements: readonly ExcalidrawElement[], appState: UIAppState, _: unknown, app: AppClassProperties) => boolean;
48
+ predicate: (elements: readonly ExcalidrawElement[], appState: AppState, appProps: import("../types").ExcalidrawProps, app: AppClassProperties) => boolean;
48
49
  perform: (elements: readonly import("../element/types").OrderedExcalidrawElement[], appState: Readonly<AppState>, _: any, app: AppClassProperties) => {
49
50
  appState: Readonly<AppState>;
50
51
  elements: ExcalidrawElement[];
@@ -62,7 +63,7 @@ export declare const actionAlignRight: {
62
63
  trackEvent: {
63
64
  category: "element";
64
65
  };
65
- predicate: (elements: readonly ExcalidrawElement[], appState: UIAppState, _: unknown, app: AppClassProperties) => boolean;
66
+ predicate: (elements: readonly ExcalidrawElement[], appState: AppState, appProps: import("../types").ExcalidrawProps, app: AppClassProperties) => boolean;
66
67
  perform: (elements: readonly import("../element/types").OrderedExcalidrawElement[], appState: Readonly<AppState>, _: any, app: AppClassProperties) => {
67
68
  appState: Readonly<AppState>;
68
69
  elements: ExcalidrawElement[];
@@ -80,7 +81,7 @@ export declare const actionAlignVerticallyCentered: {
80
81
  trackEvent: {
81
82
  category: "element";
82
83
  };
83
- predicate: (elements: readonly ExcalidrawElement[], appState: UIAppState, _: unknown, app: AppClassProperties) => boolean;
84
+ predicate: (elements: readonly ExcalidrawElement[], appState: AppState, appProps: import("../types").ExcalidrawProps, app: AppClassProperties) => boolean;
84
85
  perform: (elements: readonly import("../element/types").OrderedExcalidrawElement[], appState: Readonly<AppState>, _: any, app: AppClassProperties) => {
85
86
  appState: Readonly<AppState>;
86
87
  elements: ExcalidrawElement[];
@@ -97,7 +98,7 @@ export declare const actionAlignHorizontallyCentered: {
97
98
  trackEvent: {
98
99
  category: "element";
99
100
  };
100
- predicate: (elements: readonly ExcalidrawElement[], appState: UIAppState, _: unknown, app: AppClassProperties) => boolean;
101
+ predicate: (elements: readonly ExcalidrawElement[], appState: AppState, appProps: import("../types").ExcalidrawProps, app: AppClassProperties) => boolean;
101
102
  perform: (elements: readonly import("../element/types").OrderedExcalidrawElement[], appState: Readonly<AppState>, _: any, app: AppClassProperties) => {
102
103
  appState: Readonly<AppState>;
103
104
  elements: ExcalidrawElement[];
@@ -11,7 +11,7 @@ import { isSomeElementSelected } from "../scene";
11
11
  import { StoreAction } from "../store";
12
12
  import { arrayToMap, getShortcutKey } from "../utils";
13
13
  import { register } from "./register";
14
- const alignActionsPredicate = (elements, appState, _, app) => {
14
+ export const alignActionsPredicate = (appState, app) => {
15
15
  const selectedElements = app.scene.getSelectedElements(appState);
16
16
  return (selectedElements.length > 1 &&
17
17
  // TODO enable aligning frames when implemented properly
@@ -20,7 +20,7 @@ const alignActionsPredicate = (elements, appState, _, app) => {
20
20
  const alignSelectedElements = (elements, appState, app, alignment) => {
21
21
  const selectedElements = app.scene.getSelectedElements(appState);
22
22
  const elementsMap = arrayToMap(elements);
23
- const updatedElements = alignElements(selectedElements, elementsMap, alignment);
23
+ const updatedElements = alignElements(selectedElements, elementsMap, alignment, app.scene);
24
24
  const updatedElementsMap = arrayToMap(updatedElements);
25
25
  return updateFrameMembershipOfSelectedElements(elements.map((element) => updatedElementsMap.get(element.id) || element), appState, app);
26
26
  };
@@ -29,7 +29,7 @@ export const actionAlignTop = register({
29
29
  label: "labels.alignTop",
30
30
  icon: AlignTopIcon,
31
31
  trackEvent: { category: "element" },
32
- predicate: alignActionsPredicate,
32
+ predicate: (elements, appState, appProps, app) => alignActionsPredicate(appState, app),
33
33
  perform: (elements, appState, _, app) => {
34
34
  return {
35
35
  appState,
@@ -41,14 +41,14 @@ export const actionAlignTop = register({
41
41
  };
42
42
  },
43
43
  keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.shiftKey && event.key === KEYS.ARROW_UP,
44
- PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(elements, appState, null, app), type: "button", icon: AlignTopIcon, onClick: () => updateData(null), title: `${t("labels.alignTop")} — ${getShortcutKey("CtrlOrCmd+Shift+Up")}`, "aria-label": t("labels.alignTop"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
44
+ PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(appState, app), type: "button", icon: AlignTopIcon, onClick: () => updateData(null), title: `${t("labels.alignTop")} — ${getShortcutKey("CtrlOrCmd+Shift+Up")}`, "aria-label": t("labels.alignTop"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
45
45
  });
46
46
  export const actionAlignBottom = register({
47
47
  name: "alignBottom",
48
48
  label: "labels.alignBottom",
49
49
  icon: AlignBottomIcon,
50
50
  trackEvent: { category: "element" },
51
- predicate: alignActionsPredicate,
51
+ predicate: (elements, appState, appProps, app) => alignActionsPredicate(appState, app),
52
52
  perform: (elements, appState, _, app) => {
53
53
  return {
54
54
  appState,
@@ -60,14 +60,14 @@ export const actionAlignBottom = register({
60
60
  };
61
61
  },
62
62
  keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.shiftKey && event.key === KEYS.ARROW_DOWN,
63
- PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(elements, appState, null, app), type: "button", icon: AlignBottomIcon, onClick: () => updateData(null), title: `${t("labels.alignBottom")} — ${getShortcutKey("CtrlOrCmd+Shift+Down")}`, "aria-label": t("labels.alignBottom"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
63
+ PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(appState, app), type: "button", icon: AlignBottomIcon, onClick: () => updateData(null), title: `${t("labels.alignBottom")} — ${getShortcutKey("CtrlOrCmd+Shift+Down")}`, "aria-label": t("labels.alignBottom"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
64
64
  });
65
65
  export const actionAlignLeft = register({
66
66
  name: "alignLeft",
67
67
  label: "labels.alignLeft",
68
68
  icon: AlignLeftIcon,
69
69
  trackEvent: { category: "element" },
70
- predicate: alignActionsPredicate,
70
+ predicate: (elements, appState, appProps, app) => alignActionsPredicate(appState, app),
71
71
  perform: (elements, appState, _, app) => {
72
72
  return {
73
73
  appState,
@@ -79,14 +79,14 @@ export const actionAlignLeft = register({
79
79
  };
80
80
  },
81
81
  keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.shiftKey && event.key === KEYS.ARROW_LEFT,
82
- PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(elements, appState, null, app), type: "button", icon: AlignLeftIcon, onClick: () => updateData(null), title: `${t("labels.alignLeft")} — ${getShortcutKey("CtrlOrCmd+Shift+Left")}`, "aria-label": t("labels.alignLeft"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
82
+ PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(appState, app), type: "button", icon: AlignLeftIcon, onClick: () => updateData(null), title: `${t("labels.alignLeft")} — ${getShortcutKey("CtrlOrCmd+Shift+Left")}`, "aria-label": t("labels.alignLeft"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
83
83
  });
84
84
  export const actionAlignRight = register({
85
85
  name: "alignRight",
86
86
  label: "labels.alignRight",
87
87
  icon: AlignRightIcon,
88
88
  trackEvent: { category: "element" },
89
- predicate: alignActionsPredicate,
89
+ predicate: (elements, appState, appProps, app) => alignActionsPredicate(appState, app),
90
90
  perform: (elements, appState, _, app) => {
91
91
  return {
92
92
  appState,
@@ -98,14 +98,14 @@ export const actionAlignRight = register({
98
98
  };
99
99
  },
100
100
  keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.shiftKey && event.key === KEYS.ARROW_RIGHT,
101
- PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(elements, appState, null, app), type: "button", icon: AlignRightIcon, onClick: () => updateData(null), title: `${t("labels.alignRight")} — ${getShortcutKey("CtrlOrCmd+Shift+Right")}`, "aria-label": t("labels.alignRight"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
101
+ PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(appState, app), type: "button", icon: AlignRightIcon, onClick: () => updateData(null), title: `${t("labels.alignRight")} — ${getShortcutKey("CtrlOrCmd+Shift+Right")}`, "aria-label": t("labels.alignRight"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
102
102
  });
103
103
  export const actionAlignVerticallyCentered = register({
104
104
  name: "alignVerticallyCentered",
105
105
  label: "labels.centerVertically",
106
106
  icon: CenterVerticallyIcon,
107
107
  trackEvent: { category: "element" },
108
- predicate: alignActionsPredicate,
108
+ predicate: (elements, appState, appProps, app) => alignActionsPredicate(appState, app),
109
109
  perform: (elements, appState, _, app) => {
110
110
  return {
111
111
  appState,
@@ -116,14 +116,14 @@ export const actionAlignVerticallyCentered = register({
116
116
  storeAction: StoreAction.CAPTURE,
117
117
  };
118
118
  },
119
- PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(elements, appState, null, app), type: "button", icon: CenterVerticallyIcon, onClick: () => updateData(null), title: t("labels.centerVertically"), "aria-label": t("labels.centerVertically"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
119
+ PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(appState, app), type: "button", icon: CenterVerticallyIcon, onClick: () => updateData(null), title: t("labels.centerVertically"), "aria-label": t("labels.centerVertically"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
120
120
  });
121
121
  export const actionAlignHorizontallyCentered = register({
122
122
  name: "alignHorizontallyCentered",
123
123
  label: "labels.centerHorizontally",
124
124
  icon: CenterHorizontallyIcon,
125
125
  trackEvent: { category: "element" },
126
- predicate: alignActionsPredicate,
126
+ predicate: (elements, appState, appProps, app) => alignActionsPredicate(appState, app),
127
127
  perform: (elements, appState, _, app) => {
128
128
  return {
129
129
  appState,
@@ -134,5 +134,5 @@ export const actionAlignHorizontallyCentered = register({
134
134
  storeAction: StoreAction.CAPTURE,
135
135
  };
136
136
  },
137
- PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(elements, appState, null, app), type: "button", icon: CenterHorizontallyIcon, onClick: () => updateData(null), title: t("labels.centerHorizontally"), "aria-label": t("labels.centerHorizontally"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
137
+ PanelComponent: ({ elements, appState, updateData, app }) => (_jsx(ToolButton, { hidden: !alignActionsPredicate(appState, app), type: "button", icon: CenterHorizontallyIcon, onClick: () => updateData(null), title: t("labels.centerHorizontally"), "aria-label": t("labels.centerHorizontally"), visible: isSomeElementSelected(getNonDeletedElements(elements), appState) })),
138
138
  });
@@ -776,8 +776,13 @@ export declare const actionCut: {
776
776
  } & import("../types").ActiveTool;
777
777
  multiElement: null;
778
778
  activeEmbeddable: null;
779
- selectedElementIds: {};
780
- selectedGroupIds: {};
779
+ selectedElementIds: Readonly<{
780
+ [id: string]: true;
781
+ }>;
782
+ selectedGroupIds: {
783
+ [groupId: string]: boolean;
784
+ };
785
+ editingGroupId: string | null;
781
786
  contextMenu: {
782
787
  items: import("../components/ContextMenu").ContextMenuItems;
783
788
  top: number;
@@ -873,7 +878,6 @@ export declare const actionCut: {
873
878
  gridStep: number;
874
879
  gridModeEnabled: boolean;
875
880
  viewModeEnabled: boolean;
876
- editingGroupId: string | null;
877
881
  width: number;
878
882
  height: number;
879
883
  offsetTop: number;
@@ -401,8 +401,13 @@ export declare const actionDeleteSelected: {
401
401
  } & import("../types").ActiveTool;
402
402
  multiElement: null;
403
403
  activeEmbeddable: null;
404
- selectedElementIds: {};
405
- selectedGroupIds: {};
404
+ selectedElementIds: Readonly<{
405
+ [id: string]: true;
406
+ }>;
407
+ selectedGroupIds: {
408
+ [groupId: string]: boolean;
409
+ };
410
+ editingGroupId: string | null;
406
411
  contextMenu: {
407
412
  items: import("../components/ContextMenu").ContextMenuItems;
408
413
  top: number;
@@ -498,7 +503,6 @@ export declare const actionDeleteSelected: {
498
503
  gridStep: number;
499
504
  gridModeEnabled: boolean;
500
505
  viewModeEnabled: boolean;
501
- editingGroupId: string | null;
502
506
  width: number;
503
507
  height: number;
504
508
  offsetTop: number;
@@ -6,53 +6,122 @@ import { t } from "../i18n";
6
6
  import { register } from "./register";
7
7
  import { getNonDeletedElements } from "../element";
8
8
  import { mutateElement, newElementWith } from "../element/mutateElement";
9
- import { getElementsInGroup } from "../groups";
9
+ import { getElementsInGroup, selectGroupsForSelectedElements } from "../groups";
10
10
  import { LinearElementEditor } from "../element/linearElementEditor";
11
11
  import { fixBindingsAfterDeletion } from "../element/binding";
12
12
  import { isBoundToContainer, isElbowArrow, isFrameLikeElement, } from "../element/typeChecks";
13
13
  import { updateActiveTool } from "../utils";
14
14
  import { TrashIcon } from "../components/icons";
15
15
  import { StoreAction } from "../store";
16
- import { mutateElbowArrow } from "../element/routing";
16
+ import { getContainerElement } from "../element/textElement";
17
+ import { getFrameChildren } from "../frame";
17
18
  const deleteSelectedElements = (elements, appState, app) => {
18
- const elementsMap = app.scene.getNonDeletedElementsMap();
19
19
  const framesToBeDeleted = new Set(getSelectedElements(elements.filter((el) => isFrameLikeElement(el)), appState).map((el) => el.id));
20
- return {
21
- elements: elements.map((el) => {
22
- if (appState.selectedElementIds[el.id]) {
23
- if (el.boundElements) {
24
- el.boundElements.forEach((candidate) => {
25
- const bound = app.scene
26
- .getNonDeletedElementsMap()
27
- .get(candidate.id);
28
- if (bound && isElbowArrow(bound)) {
29
- mutateElement(bound, {
30
- startBinding: el.id === bound.startBinding?.elementId
31
- ? null
32
- : bound.startBinding,
33
- endBinding: el.id === bound.endBinding?.elementId
34
- ? null
35
- : bound.endBinding,
36
- });
37
- mutateElbowArrow(bound, elementsMap, bound.points);
38
- }
39
- });
20
+ const selectedElementIds = {};
21
+ const elementsMap = app.scene.getNonDeletedElementsMap();
22
+ const processedElements = new Set();
23
+ for (const frameId of framesToBeDeleted) {
24
+ const frameChildren = getFrameChildren(elements, frameId);
25
+ for (const el of frameChildren) {
26
+ if (processedElements.has(el.id)) {
27
+ continue;
28
+ }
29
+ if (isBoundToContainer(el)) {
30
+ const containerElement = getContainerElement(el, elementsMap);
31
+ if (containerElement) {
32
+ selectedElementIds[containerElement.id] = true;
40
33
  }
41
- return newElementWith(el, { isDeleted: true });
42
34
  }
35
+ else {
36
+ selectedElementIds[el.id] = true;
37
+ }
38
+ processedElements.add(el.id);
39
+ }
40
+ }
41
+ let shouldSelectEditingGroup = true;
42
+ const nextElements = elements.map((el) => {
43
+ if (appState.selectedElementIds[el.id]) {
44
+ const boundElement = isBoundToContainer(el)
45
+ ? getContainerElement(el, elementsMap)
46
+ : null;
43
47
  if (el.frameId && framesToBeDeleted.has(el.frameId)) {
44
- return newElementWith(el, { isDeleted: true });
48
+ shouldSelectEditingGroup = false;
49
+ selectedElementIds[el.id] = true;
50
+ return el;
51
+ }
52
+ if (boundElement?.frameId &&
53
+ framesToBeDeleted.has(boundElement?.frameId)) {
54
+ return el;
55
+ }
56
+ if (el.boundElements) {
57
+ el.boundElements.forEach((candidate) => {
58
+ const bound = app.scene.getNonDeletedElementsMap().get(candidate.id);
59
+ if (bound && isElbowArrow(bound)) {
60
+ mutateElement(bound, {
61
+ startBinding: el.id === bound.startBinding?.elementId
62
+ ? null
63
+ : bound.startBinding,
64
+ endBinding: el.id === bound.endBinding?.elementId ? null : bound.endBinding,
65
+ });
66
+ mutateElement(bound, { points: bound.points });
67
+ }
68
+ });
69
+ }
70
+ return newElementWith(el, { isDeleted: true });
71
+ }
72
+ // if deleting a frame, remove the children from it and select them
73
+ if (el.frameId && framesToBeDeleted.has(el.frameId)) {
74
+ shouldSelectEditingGroup = false;
75
+ if (!isBoundToContainer(el)) {
76
+ selectedElementIds[el.id] = true;
77
+ }
78
+ return newElementWith(el, { frameId: null });
79
+ }
80
+ if (isBoundToContainer(el) && appState.selectedElementIds[el.containerId]) {
81
+ return newElementWith(el, { isDeleted: true });
82
+ }
83
+ return el;
84
+ });
85
+ let nextEditingGroupId = appState.editingGroupId;
86
+ // select next eligible element in currently editing group or supergroup
87
+ if (shouldSelectEditingGroup && appState.editingGroupId) {
88
+ const elems = getElementsInGroup(nextElements, appState.editingGroupId).filter((el) => !el.isDeleted);
89
+ if (elems.length > 1) {
90
+ if (elems[0]) {
91
+ selectedElementIds[elems[0].id] = true;
92
+ }
93
+ }
94
+ else {
95
+ nextEditingGroupId = null;
96
+ if (elems[0]) {
97
+ selectedElementIds[elems[0].id] = true;
45
98
  }
46
- if (isBoundToContainer(el) &&
47
- appState.selectedElementIds[el.containerId]) {
48
- return newElementWith(el, { isDeleted: true });
99
+ const lastElementInGroup = elems[0];
100
+ if (lastElementInGroup) {
101
+ const editingGroupIdx = lastElementInGroup.groupIds.findIndex((groupId) => {
102
+ return groupId === appState.editingGroupId;
103
+ });
104
+ const superGroupId = lastElementInGroup.groupIds[editingGroupIdx + 1];
105
+ if (superGroupId) {
106
+ const elems = getElementsInGroup(nextElements, superGroupId).filter((el) => !el.isDeleted);
107
+ if (elems.length > 1) {
108
+ nextEditingGroupId = superGroupId;
109
+ elems.forEach((el) => {
110
+ selectedElementIds[el.id] = true;
111
+ });
112
+ }
113
+ }
49
114
  }
50
- return el;
51
- }),
115
+ }
116
+ }
117
+ return {
118
+ elements: nextElements,
52
119
  appState: {
53
120
  ...appState,
54
- selectedElementIds: {},
55
- selectedGroupIds: {},
121
+ ...selectGroupsForSelectedElements({
122
+ selectedElementIds,
123
+ editingGroupId: nextEditingGroupId,
124
+ }, nextElements, appState, null),
56
125
  },
57
126
  };
58
127
  };
@@ -116,7 +185,7 @@ export const actionDeleteSelected = register({
116
185
  ? null
117
186
  : endBindingElement,
118
187
  };
119
- LinearElementEditor.deletePoints(element, selectedPointsIndices, elementsMap);
188
+ LinearElementEditor.deletePoints(element, selectedPointsIndices);
120
189
  return {
121
190
  elements,
122
191
  appState: {
@@ -133,7 +202,7 @@ export const actionDeleteSelected = register({
133
202
  };
134
203
  }
135
204
  let { elements: nextElements, appState: nextAppState } = deleteSelectedElements(elements, appState, app);
136
- fixBindingsAfterDeletion(nextElements, elements.filter(({ id }) => appState.selectedElementIds[id]));
205
+ fixBindingsAfterDeletion(nextElements, nextElements.filter((el) => el.isDeleted));
137
206
  nextAppState = handleGroupEditingState(nextAppState, nextElements);
138
207
  return {
139
208
  elements: nextElements,