mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
The image editor canvas only used part of the viewport, and the right sidebar was a fixed width that could clip its controls on shorter screens. - Canvas: the canvas container used `flex-1`, but its parent wrapper in editor-page.tsx was not a flex container, so it collapsed to the Konva Stage's content height (~600px), leaving a large inert region below. Make the wrapper a flex container so the canvas fills the available area. - Rulers: ruler background/ticks were set via `ctx.fillStyle = "var(--color-card)"`, which canvas 2D cannot parse, so the default black fill remained and painted the rulers as solid black bars. Resolve the theme tokens to concrete colors from computed style at draw time (theme-aware). - Right panel: add a left-edge drag handle to resize the panel (240-480px, persisted to localStorage) and `min-h-0` so the tab content scrolls internally instead of pushing the color controls off-screen. Adds editor-layout.spec.ts (canvas-fill + resize) and a ruler-not-black regression test. All 7 targeted editor e2e tests pass.
99 lines
3.8 KiB
TypeScript
99 lines
3.8 KiB
TypeScript
import { createNewDocument, expect, test } from "./helpers";
|
|
|
|
test.describe("Editor Rulers and Guides", () => {
|
|
test.beforeEach(async ({ editorPage: page }) => {
|
|
await createNewDocument(page);
|
|
});
|
|
|
|
test("rulers are hidden by default", async ({ editorPage: page }) => {
|
|
// The ruler canvases render only when rulersVisible is true.
|
|
// By default rulers are hidden, so the ruler-specific canvases
|
|
// (with cursor-col-resize / cursor-row-resize) should not be present.
|
|
const horizontalRuler = page.locator("canvas.cursor-col-resize");
|
|
const verticalRuler = page.locator("canvas.cursor-row-resize");
|
|
|
|
await expect(horizontalRuler).toHaveCount(0);
|
|
await expect(verticalRuler).toHaveCount(0);
|
|
});
|
|
|
|
test("Ctrl+R toggles ruler visibility", async ({ editorPage: page }) => {
|
|
// Initially hidden
|
|
const horizontalRuler = page.locator("canvas.cursor-col-resize");
|
|
await expect(horizontalRuler).toHaveCount(0);
|
|
|
|
// Press Ctrl+R to show rulers
|
|
await page.keyboard.press("Control+r");
|
|
await page.waitForTimeout(500);
|
|
|
|
// Now they should appear
|
|
await expect(page.locator("canvas.cursor-col-resize")).toBeVisible();
|
|
await expect(page.locator("canvas.cursor-row-resize")).toBeVisible();
|
|
|
|
// Press Ctrl+R again to hide
|
|
await page.keyboard.press("Control+r");
|
|
await page.waitForTimeout(500);
|
|
|
|
await expect(page.locator("canvas.cursor-col-resize")).toHaveCount(0);
|
|
await expect(page.locator("canvas.cursor-row-resize")).toHaveCount(0);
|
|
});
|
|
|
|
test("horizontal ruler appears at top edge", async ({ editorPage: page }) => {
|
|
// Enable rulers
|
|
await page.keyboard.press("Control+r");
|
|
await page.waitForTimeout(500);
|
|
|
|
const horizontalRuler = page.locator("canvas.cursor-col-resize");
|
|
await expect(horizontalRuler).toBeVisible();
|
|
|
|
// Ruler should have a fixed height of 20px (RULER_SIZE)
|
|
const box = await horizontalRuler.boundingBox();
|
|
expect(box).not.toBeNull();
|
|
expect(box?.height).toBe(20);
|
|
|
|
// Ruler should stretch to full width (w-full class)
|
|
expect(box?.width).toBeGreaterThan(100);
|
|
});
|
|
|
|
test("vertical ruler appears at left edge", async ({ editorPage: page }) => {
|
|
// Enable rulers
|
|
await page.keyboard.press("Control+r");
|
|
await page.waitForTimeout(500);
|
|
|
|
const verticalRuler = page.locator("canvas.cursor-row-resize");
|
|
await expect(verticalRuler).toBeVisible();
|
|
|
|
// Ruler should have a fixed width of 20px (RULER_SIZE)
|
|
const box = await verticalRuler.boundingBox();
|
|
expect(box).not.toBeNull();
|
|
expect(box?.width).toBe(20);
|
|
|
|
// Ruler should stretch to fill the available height
|
|
expect(box?.height).toBeGreaterThan(100);
|
|
});
|
|
|
|
test("rulers render a themed background, not solid black (issue #258)", async ({
|
|
editorPage: page,
|
|
}) => {
|
|
// Canvas 2D `fillStyle` cannot read CSS `var(--...)` colors; the regression
|
|
// left the default black fill in place and painted the rulers as solid
|
|
// black bars. Verify both rulers paint a light (card) background instead.
|
|
await page.keyboard.press("Control+r");
|
|
await page.waitForTimeout(500);
|
|
|
|
for (const selector of ["canvas.cursor-col-resize", "canvas.cursor-row-resize"]) {
|
|
const ruler = page.locator(selector);
|
|
await expect(ruler).toBeVisible();
|
|
const pixel = await ruler.evaluate((cv: HTMLCanvasElement) => {
|
|
const ctx = cv.getContext("2d", { willReadFrequently: true });
|
|
const d = ctx?.getImageData(Math.floor(cv.width / 2), Math.floor(cv.height / 2), 1, 1).data;
|
|
return d ? [d[0], d[1], d[2], d[3]] : null;
|
|
});
|
|
expect(pixel).not.toBeNull();
|
|
// Not the default-black fill the bug produced...
|
|
expect(pixel).not.toEqual([0, 0, 0, 255]);
|
|
// ...and unmistakably a light background (white card sums to 765).
|
|
expect((pixel?.[0] ?? 0) + (pixel?.[1] ?? 0) + (pixel?.[2] ?? 0)).toBeGreaterThan(300);
|
|
}
|
|
});
|
|
});
|