From ebf2923c5e4479abda93f00ddb5e530ef6e8e8ca Mon Sep 17 00:00:00 2001 From: Rene <1595098+ReneCode@users.noreply.github.com> Date: Sun, 26 Jul 2020 00:42:06 +0200 Subject: [PATCH] Issues/1827 group-ungroup icons (#1956) * show group and ungroup action-icon * change group-icon visiblilty don't show group if selected is only a single element or a single group of elements Co-authored-by: rene_mbp --- .../{actionGroup.ts => actionGroup.tsx} | 64 ++++++++- src/components/Actions.tsx | 2 + src/components/icons.tsx | 125 ++++++++++++++++++ src/tests/regressionTests.test.tsx | 3 +- 4 files changed, 190 insertions(+), 4 deletions(-) rename src/actions/{actionGroup.ts => actionGroup.tsx} (68%) diff --git a/src/actions/actionGroup.ts b/src/actions/actionGroup.tsx similarity index 68% rename from src/actions/actionGroup.ts rename to src/actions/actionGroup.tsx index 7755a41d..4d606ad4 100644 --- a/src/actions/actionGroup.ts +++ b/src/actions/actionGroup.tsx @@ -1,7 +1,11 @@ +import React from "react"; import { KEYS } from "../keys"; +import { t } from "../i18n"; +import { getShortcutKey } from "../utils"; import { register } from "./register"; +import { group, ungroup } from "../components/icons"; import { newElementWith } from "../element/mutateElement"; -import { getSelectedElements } from "../scene"; +import { getSelectedElements, isSomeElementSelected } from "../scene"; import { getSelectedGroupIds, selectGroup, @@ -13,6 +17,39 @@ import { } from "../groups"; import { getNonDeletedElements } from "../element"; import { randomId } from "../random"; +import { ToolButton } from "../components/ToolButton"; +import { ExcalidrawElement } from "../element/types"; +import { AppState } from "../types"; + +const allElementsInSameGroup = (elements: readonly ExcalidrawElement[]) => { + if (elements.length >= 2) { + const groupIds = elements[0].groupIds; + for (const groupId of groupIds) { + if ( + elements.reduce( + (acc, element) => acc && isElementInGroup(element, groupId), + true, + ) + ) { + return true; + } + } + } + return false; +}; + +const enableActionGroup = ( + elements: readonly ExcalidrawElement[], + appState: AppState, +) => { + const selectedElements = getSelectedElements( + getNonDeletedElements(elements), + appState, + ); + return ( + selectedElements.length >= 2 && !allElementsInSameGroup(selectedElements) + ); +}; export const actionGroup = register({ name: "group", @@ -91,7 +128,7 @@ export const actionGroup = register({ contextMenuOrder: 4, contextItemLabel: "labels.group", contextItemPredicate: (elements, appState) => - getSelectedElements(getNonDeletedElements(elements), appState).length > 1, + enableActionGroup(elements, appState), keyTest: (event) => { return ( !event.shiftKey && @@ -99,6 +136,17 @@ export const actionGroup = register({ event.keyCode === KEYS.G_KEY_CODE ); }, + PanelComponent: ({ elements, appState, updateData }) => ( + + ), }); export const actionUngroup = register({ @@ -140,4 +188,16 @@ export const actionUngroup = register({ contextItemLabel: "labels.ungroup", contextItemPredicate: (elements, appState) => getSelectedGroupIds(appState).length > 0, + + PanelComponent: ({ elements, appState, updateData }) => ( + + ), }); diff --git a/src/components/Actions.tsx b/src/components/Actions.tsx index 8c06af08..e430e206 100644 --- a/src/components/Actions.tsx +++ b/src/components/Actions.tsx @@ -78,6 +78,8 @@ export const SelectedShapeActions = ({
{renderAction("duplicateSelection")} {renderAction("deleteSelectedElements")} + {renderAction("group")} + {renderAction("ungroup")}
)} diff --git a/src/components/icons.tsx b/src/components/icons.tsx index 901cdb91..c489baf0 100644 --- a/src/components/icons.tsx +++ b/src/components/icons.tsx @@ -212,3 +212,128 @@ export const shield = createIcon( "M11.553 22.894a.998.998 0 00.894 0s3.037-1.516 5.465-4.097C19.616 16.987 21 14.663 21 12V5a1 1 0 00-.649-.936l-8-3a.998.998 0 00-.702 0l-8 3A1 1 0 003 5v7c0 2.663 1.384 4.987 3.088 6.797 2.428 2.581 5.465 4.097 5.465 4.097zm-1.303-8.481l6.644-6.644a.856.856 0 111.212 1.212l-7.25 7.25a.856.856 0 01-1.212 0l-3.75-3.75a.856.856 0 111.212-1.212l3.144 3.144z", { width: 24 }, ); + +export const group = createIcon( + <> + + + + + + + + + , + { width: 182, height: 182 }, +); +export const ungroup = createIcon( + <> + + + + + + + + + + + , + { width: 182, height: 182 }, +); diff --git a/src/tests/regressionTests.test.tsx b/src/tests/regressionTests.test.tsx index de2d03fe..297cf1f9 100644 --- a/src/tests/regressionTests.test.tsx +++ b/src/tests/regressionTests.test.tsx @@ -973,7 +973,6 @@ describe("regression tests", () => { "Copy styles", "Paste styles", "Delete", - "Group selection", "Ungroup selection", "Add to library", "Send backward", @@ -984,7 +983,7 @@ describe("regression tests", () => { ]; expect(contextMenu).not.toBeNull(); - expect(contextMenu?.children.length).toBe(11); + expect(contextMenu?.children.length).toBe(10); options?.forEach((opt, i) => { expect(opt.textContent).toBe(expectedOptions[i]); });