feat(editor): board shell with iframe frame and selection overlay
React Flow board (pan/zoom + frame drag are pure editor-side transforms — zero canvas-protocol traffic, <16ms budget) hosting one iframe frame node on the adapter origin. The frame waits for runtime.ready (queue-drain) behind an explicit 'Starting preview…' skeleton, then requests a single Element via render-frame (core-runner-protocol schema) plus geometry; agent-reported geometry stays frame-local and click reports drive store selection. The selection ring renders as an editor-side overlay from reported geometry — chrome never inside the customer's document (ADR-028). Stories + jsdom component tests for board/frame/overlay; Storybook stories glob extended to packages/editor (verified via static build). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
31
packages/editor/src/ui/components/selection-overlay.test.tsx
Normal file
31
packages/editor/src/ui/components/selection-overlay.test.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { SelectionOverlay } from "./selection-overlay";
|
||||
|
||||
describe("SelectionOverlay", () => {
|
||||
it("renders nothing when rect is null (no selection)", () => {
|
||||
render(<SelectionOverlay rect={null} />);
|
||||
expect(screen.queryByTestId("selection-overlay")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("positions the ring from the agent-reported rect", () => {
|
||||
render(
|
||||
<SelectionOverlay rect={{ x: 24, y: 12, width: 320, height: 48 }} />,
|
||||
);
|
||||
const overlay = screen.getByTestId("selection-overlay");
|
||||
expect(overlay).toHaveStyle({
|
||||
position: "absolute",
|
||||
left: "24px",
|
||||
top: "12px",
|
||||
width: "320px",
|
||||
height: "48px",
|
||||
});
|
||||
});
|
||||
|
||||
it("is chrome, not content: hidden from a11y and inert to pointers (ADR-028)", () => {
|
||||
render(<SelectionOverlay rect={{ x: 0, y: 0, width: 10, height: 10 }} />);
|
||||
const overlay = screen.getByTestId("selection-overlay");
|
||||
expect(overlay).toHaveAttribute("aria-hidden", "true");
|
||||
expect(overlay).toHaveStyle({ pointerEvents: "none" });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user