feat: color picker redesign (#6216)

Co-authored-by: Maielo <maielo.mv@gmail.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
This commit is contained in:
Barnabás Molnár
2023-05-18 16:06:27 +02:00
committed by GitHub
parent 6977c32631
commit 5b7596582f
55 changed files with 4010 additions and 2699 deletions

View File

@ -1,4 +1,4 @@
import { ColorPicker } from "../components/ColorPicker";
import { ColorPicker } from "../components/ColorPicker/ColorPicker";
import { ZoomInIcon, ZoomOutIcon } from "../components/icons";
import { ToolButton } from "../components/ToolButton";
import { CURSOR_TYPE, MIN_ZOOM, THEME, ZOOM_STEP } from "../constants";
@ -19,6 +19,7 @@ import {
isEraserActive,
isHandToolActive,
} from "../appState";
import { DEFAULT_CANVAS_BACKGROUND_PICKS } from "../colors";
export const actionChangeViewBackgroundColor = register({
name: "changeViewBackgroundColor",
@ -35,24 +36,21 @@ export const actionChangeViewBackgroundColor = register({
commitToHistory: !!value.viewBackgroundColor,
};
},
PanelComponent: ({ elements, appState, updateData }) => {
PanelComponent: ({ elements, appState, updateData, appProps }) => {
// FIXME move me to src/components/mainMenu/DefaultItems.tsx
return (
<div style={{ position: "relative" }}>
<ColorPicker
label={t("labels.canvasBackground")}
type="canvasBackground"
color={appState.viewBackgroundColor}
onChange={(color) => updateData({ viewBackgroundColor: color })}
isActive={appState.openPopup === "canvasColorPicker"}
setActive={(active) =>
updateData({ openPopup: active ? "canvasColorPicker" : null })
}
data-testid="canvas-background-picker"
elements={elements}
appState={appState}
/>
</div>
<ColorPicker
palette={null}
topPicks={DEFAULT_CANVAS_BACKGROUND_PICKS}
label={t("labels.canvasBackground")}
type="canvasBackground"
color={appState.viewBackgroundColor}
onChange={(color) => updateData({ viewBackgroundColor: color })}
data-testid="canvas-background-picker"
elements={elements}
appState={appState}
updateData={updateData}
/>
);
},
});

View File

@ -14,7 +14,7 @@ import {
} from "../element/bounds";
import { isLinearElement } from "../element/typeChecks";
import { LinearElementEditor } from "../element/linearElementEditor";
import { KEYS } from "../keys";
import { CODES, KEYS } from "../keys";
const enableActionFlipHorizontal = (
elements: readonly ExcalidrawElement[],
@ -48,7 +48,7 @@ export const actionFlipHorizontal = register({
commitToHistory: true,
};
},
keyTest: (event) => event.shiftKey && event.code === "KeyH",
keyTest: (event) => event.shiftKey && event.code === CODES.H,
contextItemLabel: "labels.flipHorizontal",
predicate: (elements, appState) =>
enableActionFlipHorizontal(elements, appState),
@ -65,7 +65,7 @@ export const actionFlipVertical = register({
};
},
keyTest: (event) =>
event.shiftKey && event.code === "KeyV" && !event[KEYS.CTRL_OR_CMD],
event.shiftKey && event.code === CODES.V && !event[KEYS.CTRL_OR_CMD],
contextItemLabel: "labels.flipVertical",
predicate: (elements, appState) =>
enableActionFlipVertical(elements, appState),

View File

@ -1,7 +1,13 @@
import { AppState } from "../../src/types";
import {
DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE,
DEFAULT_ELEMENT_BACKGROUND_PICKS,
DEFAULT_ELEMENT_STROKE_COLOR_PALETTE,
DEFAULT_ELEMENT_STROKE_PICKS,
} from "../colors";
import { trackEvent } from "../analytics";
import { ButtonIconSelect } from "../components/ButtonIconSelect";
import { ColorPicker } from "../components/ColorPicker";
import { ColorPicker } from "../components/ColorPicker/ColorPicker";
import { IconPicker } from "../components/IconPicker";
// TODO barnabasmolnar/editor-redesign
// TextAlignTopIcon, TextAlignBottomIcon,TextAlignMiddleIcon,
@ -226,10 +232,12 @@ export const actionChangeStrokeColor = register({
commitToHistory: !!value.currentItemStrokeColor,
};
},
PanelComponent: ({ elements, appState, updateData }) => (
PanelComponent: ({ elements, appState, updateData, appProps }) => (
<>
<h3 aria-hidden="true">{t("labels.stroke")}</h3>
<ColorPicker
topPicks={DEFAULT_ELEMENT_STROKE_PICKS}
palette={DEFAULT_ELEMENT_STROKE_COLOR_PALETTE}
type="elementStroke"
label={t("labels.stroke")}
color={getFormValue(
@ -239,12 +247,9 @@ export const actionChangeStrokeColor = register({
appState.currentItemStrokeColor,
)}
onChange={(color) => updateData({ currentItemStrokeColor: color })}
isActive={appState.openPopup === "strokeColorPicker"}
setActive={(active) =>
updateData({ openPopup: active ? "strokeColorPicker" : null })
}
elements={elements}
appState={appState}
updateData={updateData}
/>
</>
),
@ -269,10 +274,12 @@ export const actionChangeBackgroundColor = register({
commitToHistory: !!value.currentItemBackgroundColor,
};
},
PanelComponent: ({ elements, appState, updateData }) => (
PanelComponent: ({ elements, appState, updateData, appProps }) => (
<>
<h3 aria-hidden="true">{t("labels.background")}</h3>
<ColorPicker
topPicks={DEFAULT_ELEMENT_BACKGROUND_PICKS}
palette={DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE}
type="elementBackground"
label={t("labels.background")}
color={getFormValue(
@ -282,12 +289,9 @@ export const actionChangeBackgroundColor = register({
appState.currentItemBackgroundColor,
)}
onChange={(color) => updateData({ currentItemBackgroundColor: color })}
isActive={appState.openPopup === "backgroundColorPicker"}
setActive={(active) =>
updateData({ openPopup: active ? "backgroundColorPicker" : null })
}
elements={elements}
appState={appState}
updateData={updateData}
/>
</>
),

View File

@ -1,9 +1,14 @@
import ExcalidrawApp from "../excalidraw-app";
import { t } from "../i18n";
import { CODES } from "../keys";
import { API } from "../tests/helpers/api";
import { Keyboard, Pointer, UI } from "../tests/helpers/ui";
import { fireEvent, render, screen } from "../tests/test-utils";
import {
act,
fireEvent,
render,
screen,
togglePopover,
} from "../tests/test-utils";
import { copiedStyles } from "./actionStyles";
const { h } = window;
@ -14,7 +19,14 @@ describe("actionStyles", () => {
beforeEach(async () => {
await render(<ExcalidrawApp />);
});
it("should copy & paste styles via keyboard", () => {
afterEach(async () => {
// https://github.com/floating-ui/floating-ui/issues/1908#issuecomment-1301553793
// affects node v16+
await act(async () => {});
});
it("should copy & paste styles via keyboard", async () => {
UI.clickTool("rectangle");
mouse.down(10, 10);
mouse.up(20, 20);
@ -24,10 +36,10 @@ describe("actionStyles", () => {
mouse.up(20, 20);
// Change some styles of second rectangle
UI.clickLabeledElement("Stroke");
UI.clickLabeledElement(t("colors.c92a2a"));
UI.clickLabeledElement("Background");
UI.clickLabeledElement(t("colors.e64980"));
togglePopover("Stroke");
UI.clickOnTestId("color-red");
togglePopover("Background");
UI.clickOnTestId("color-blue");
// Fill style
fireEvent.click(screen.getByTitle("Cross-hatch"));
// Stroke width
@ -60,8 +72,8 @@ describe("actionStyles", () => {
const firstRect = API.getSelectedElement();
expect(firstRect.id).toBe(h.elements[0].id);
expect(firstRect.strokeColor).toBe("#c92a2a");
expect(firstRect.backgroundColor).toBe("#e64980");
expect(firstRect.strokeColor).toBe("#e03131");
expect(firstRect.backgroundColor).toBe("#a5d8ff");
expect(firstRect.fillStyle).toBe("cross-hatch");
expect(firstRect.strokeWidth).toBe(2); // Bold: 2
expect(firstRect.strokeStyle).toBe("dotted");