diff --git a/src/shapes/core.spec.ts b/src/shapes/core.spec.ts index 3ff24730..30edf49e 100644 --- a/src/shapes/core.spec.ts +++ b/src/shapes/core.spec.ts @@ -2,6 +2,7 @@ import { expect, describe, test } from "vitest"; import { canHaveOutlineWithinGroup, getCommonStyle, + hasFillStyle, hasStrokeStyle, isInvisibleClippingShape, isSameShapeParentScope, @@ -86,6 +87,14 @@ describe("isSameShapeParentScope", () => { }); }); +describe("hasFillStyle", () => { + test("should return true when a shape has fill property", () => { + expect(hasFillStyle(createShape(getCommonStruct, "group", {}))).toBe(false); + expect(hasFillStyle(createShape(getCommonStruct, "line", {}))).toBe(true); + expect(hasFillStyle(createShape(getCommonStruct, "rectangle", {}))).toBe(true); + }); +}); + describe("hasStrokeStyle", () => { test("should return true when a shape has stroke property", () => { expect(hasStrokeStyle(createShape(getCommonStruct, "group", {}))).toBe(false); diff --git a/src/shapes/core.ts b/src/shapes/core.ts index 8b2afc47..671c4e21 100644 --- a/src/shapes/core.ts +++ b/src/shapes/core.ts @@ -177,6 +177,10 @@ export function isSameShapeParentScope(a?: ShapeSelectionScope, b?: ShapeSelecti return a === b; } +export function hasFillStyle(shape: Shape): shape is Shape & { fill: FillStyle } { + return "fill" in shape; +} + export function hasStrokeStyle(shape: Shape): shape is Shape & { stroke: StrokeStyle } { return "stroke" in shape; } diff --git a/src/shapes/index.spec.ts b/src/shapes/index.spec.ts index db67f64e..e575b7b5 100644 --- a/src/shapes/index.spec.ts +++ b/src/shapes/index.spec.ts @@ -23,6 +23,8 @@ import { createBoxPadding } from "../utils/boxPadding"; import { TreeRootShape } from "./tree/treeRoot"; import { struct as unknownStruct } from "./unknown"; import { EllipseShape } from "./ellipse"; +import { createFillStyle } from "../utils/fillStyle"; +import { COLORS } from "../utils/color"; describe("getCommonStruct", () => { test("should return the struct of the type", () => { @@ -405,4 +407,15 @@ describe("switchShapeType", () => { expect(result0.rx).toBeCloseTo(50); expect(result0.ry).toBeCloseTo(100); }); + + test("should return switched shape: keep fill and stroke", () => { + const rect = createShape(getCommonStruct, "rectangle", { + id: "a", + fill: createFillStyle({ color: COLORS.GRAY_1 }), + stroke: createStrokeStyle({ color: COLORS.YELLOW }), + }); + const result0 = switchShapeType(getCommonStruct, rect, "ellipse") as EllipseShape; + expect(result0.fill).toEqual(rect.fill); + expect(result0.stroke).toEqual(rect.stroke); + }); }); diff --git a/src/shapes/index.ts b/src/shapes/index.ts index 50b7b8d7..c43e85ea 100644 --- a/src/shapes/index.ts +++ b/src/shapes/index.ts @@ -1,6 +1,13 @@ import { AffineMatrix, IRectangle, IVec2, getOuterRectangle, getRectCenter, multiAffines, sub } from "okageo"; import { BoxPadding, CommonStyle, Shape, Size } from "../models"; -import { GetShapeStruct as _GetShapeStruct, ShapeContext, ShapeSnappingLines, TextContainer } from "./core"; +import { + GetShapeStruct as _GetShapeStruct, + hasFillStyle, + hasStrokeStyle, + ShapeContext, + ShapeSnappingLines, + TextContainer, +} from "./core"; import { struct as unknownStruct } from "./unknown"; import * as geometry from "../utils/geometry"; import { DocOutput } from "../models/document"; @@ -437,5 +444,8 @@ export function switchShapeType(getStruct: GetShapeStruct, src: Shape, type: str srcRect.y, ]); - return { ...dist, ...resizePatch, rotation: src.rotation }; + const fill = hasFillStyle(src) ? { fill: src.fill } : {}; + const stroke = hasStrokeStyle(src) ? { stroke: src.stroke } : {}; + + return { ...dist, ...resizePatch, rotation: src.rotation, ...fill, ...stroke }; }