feat: add contextual layer inspector
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
documentAddRasterLayerCommand,
|
||||
documentApplyLayerMaskOperationCommand,
|
||||
documentGroupLayersCommand,
|
||||
documentDuplicateLayerCommand,
|
||||
documentMoveLayerCommand,
|
||||
documentRemoveArtboardCommand,
|
||||
documentRemoveLayerCommand,
|
||||
@@ -21,6 +22,7 @@ import {
|
||||
documentSetArtboardVisibleCommand,
|
||||
documentSetLayerClippingMaskCommand,
|
||||
documentSetLayerLockedCommand,
|
||||
documentSetLayerOpacityCommand,
|
||||
documentSetLayerVisibleCommand,
|
||||
documentUpdateAssetSourceCommand,
|
||||
documentUngroupLayerCommand,
|
||||
@@ -335,6 +337,46 @@ describe("document commands", () => {
|
||||
expect(locked.document.artboards[0]?.layers[0]?.locked).toBe(true);
|
||||
});
|
||||
|
||||
test("sets normalized opacity and refuses locked layer edits", () => {
|
||||
const state = documentWithLayers([raster("a", "A")]);
|
||||
const translucent = documentSetLayerOpacityCommand.execute({ state }, { layerId: "a", opacity: 0.35 });
|
||||
const clamped = documentSetLayerOpacityCommand.execute({ state: translucent }, { layerId: "a", opacity: 2 });
|
||||
const lockedState = documentSetLayerLockedCommand.execute({ state: clamped }, { layerId: "a", locked: true });
|
||||
const ignored = documentSetLayerOpacityCommand.execute({ state: lockedState }, { layerId: "a", opacity: 0 });
|
||||
|
||||
expect(translucent.document.artboards[0]?.layers[0]?.opacity).toBe(0.35);
|
||||
expect(clamped.document.artboards[0]?.layers[0]?.opacity).toBe(1);
|
||||
expect(ignored).toBe(lockedState);
|
||||
});
|
||||
|
||||
test("duplicates a nested group with remapped child mask references", () => {
|
||||
const maskedTarget = { ...raster("target", "Target"), layerMask: { kind: "raster" as const, maskLayerId: "mask", enabled: true, inverted: false } };
|
||||
const parent = { ...group("parent", "Parent"), children: [raster("mask", "Mask"), maskedTarget] };
|
||||
const state = documentWithLayers([parent]);
|
||||
const next = documentDuplicateLayerCommand.execute(
|
||||
{ state },
|
||||
{ layerId: "parent", idByLayerId: { parent: "parent-copy", mask: "mask-copy", target: "target-copy" } },
|
||||
);
|
||||
|
||||
const duplicate = next.document.artboards[0]?.layers[1];
|
||||
expect(next.document.artboards[0]?.layers.map((layer) => layer.id)).toEqual(["parent", "parent-copy"]);
|
||||
expect(duplicate?.type === "group" ? duplicate.children.map((layer) => layer.id) : []).toEqual(["mask-copy", "target-copy"]);
|
||||
expect(duplicate?.type === "group" ? duplicate.children[1]?.layerMask?.maskLayerId : undefined).toBe("mask-copy");
|
||||
expect(next.editor.selection.layerIds).toEqual(["parent-copy"]);
|
||||
});
|
||||
|
||||
test("duplicates an attached top-level mask beside its target", () => {
|
||||
const target = { ...raster("target", "Target"), layerMask: { kind: "raster" as const, maskLayerId: "mask", enabled: true, inverted: false } };
|
||||
const state = documentWithLayers([raster("mask", "Mask"), target]);
|
||||
const next = documentDuplicateLayerCommand.execute(
|
||||
{ state },
|
||||
{ layerId: "target", idByLayerId: { mask: "mask-copy", target: "target-copy" } },
|
||||
);
|
||||
|
||||
expect(next.document.artboards[0]?.layers.map((layer) => layer.id)).toEqual(["mask", "target", "mask-copy", "target-copy"]);
|
||||
expect(next.document.artboards[0]?.layers[3]?.layerMask?.maskLayerId).toBe("mask-copy");
|
||||
});
|
||||
|
||||
test("sets artboard bounds", () => {
|
||||
const state = documentAddArtboardCommand.execute(
|
||||
{ state: createInitialAppState("Test") },
|
||||
|
||||
Reference in New Issue
Block a user