mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
fix(studio): make canvas selection hit intended elements (#1907)
* test(studio): add design-panel QA fixture and triage matrix Fixture project covering all panel-editable element archetypes, plus the QA findings matrix from the design-panel bug campaign. * fix(studio): make canvas selection hit intended elements - honor author pointer-events:none in hit-testing (was selecting invisible overlays) - pause playback before mousedown sampling; fall back to hover selection on null resolve - invalidate committed selection when the active composition changes - double-click keeps selection and defers to multi-candidate click cycling * fix(studio): close remaining selection-layer review findings - hoverSelection fallback now wired at all 3 mousedown call sites (box-click, blocked-drag, plain overlay click) instead of just the overlay path - pointer-events override detection reads computed style, not inline style, so a CSS-class opt-in (not just inline style=) on a descendant is honored - defensively remove the pointer-events override before the group-fallback check too, closing a theoretical gap in the no-elementsFromPoint branch - a click that resolves to nothing (dead-zone / deselect) no longer leaves playback paused if it was already playing
This commit is contained in:
@@ -345,6 +345,101 @@ describe("DomEditOverlay", () => {
|
||||
Element.prototype.getBoundingClientRect = originalGetBoundingClientRect;
|
||||
host.remove();
|
||||
});
|
||||
|
||||
it("passes the tracked hover selection when clicking the existing selection box", async () => {
|
||||
const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect;
|
||||
Element.prototype.getBoundingClientRect = function (): DOMRect {
|
||||
return {
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 800,
|
||||
bottom: 450,
|
||||
width: 800,
|
||||
height: 450,
|
||||
x: 0,
|
||||
y: 0,
|
||||
toJSON: () => ({}),
|
||||
};
|
||||
};
|
||||
|
||||
const host = document.createElement("div");
|
||||
document.body.append(host);
|
||||
const root = createRoot(host);
|
||||
const selection: DomEditSelection = {
|
||||
element: document.createElement("div"),
|
||||
id: "hero-title",
|
||||
selector: ".hero-title",
|
||||
selectorIndex: 0,
|
||||
sourceFile: "index.html",
|
||||
tagName: "div",
|
||||
label: "Hero Title",
|
||||
textContent: "Hello",
|
||||
textFields: [],
|
||||
capabilities: {
|
||||
canEditText: true,
|
||||
canEditLayout: true,
|
||||
canMove: false,
|
||||
canApplyManualOffset: false,
|
||||
canApplyManualSize: false,
|
||||
canApplyManualRotation: false,
|
||||
canAdjustOpacity: true,
|
||||
canAdjustFill: true,
|
||||
canAdjustBorderRadius: true,
|
||||
canAdjustStroke: true,
|
||||
canAdjustShadow: true,
|
||||
canAdjustZIndex: true,
|
||||
},
|
||||
computedStyle: {
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
},
|
||||
};
|
||||
const hoverSelection: DomEditSelection = { ...selection, id: "hovered-sibling" };
|
||||
const onCanvasMouseDown = vi.fn();
|
||||
const iframeRef = { current: document.createElement("iframe") as HTMLIFrameElement | null };
|
||||
|
||||
function Harness() {
|
||||
return React.createElement(DomEditOverlay, {
|
||||
...createOverlayProps({
|
||||
iframeRef,
|
||||
selection,
|
||||
hoverSelection,
|
||||
onSelectionChange: () => {},
|
||||
}),
|
||||
onCanvasMouseDown,
|
||||
});
|
||||
}
|
||||
|
||||
act(() => {
|
||||
root.render(React.createElement(Harness));
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await new Promise<void>((resolve) => {
|
||||
requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
||||
});
|
||||
});
|
||||
|
||||
const selectionBox = host.querySelector(
|
||||
'[data-dom-edit-selection-box="true"]',
|
||||
) as HTMLDivElement;
|
||||
expect(selectionBox).toBeTruthy();
|
||||
|
||||
act(() => {
|
||||
selectionBox.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
});
|
||||
|
||||
expect(onCanvasMouseDown).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.objectContaining({ hoverSelection }),
|
||||
);
|
||||
|
||||
act(() => {
|
||||
root.unmount();
|
||||
});
|
||||
Element.prototype.getBoundingClientRect = originalGetBoundingClientRect;
|
||||
host.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveDomEditCoordinateScale", () => {
|
||||
|
||||
Reference in New Issue
Block a user