Skip to content

Commit 5dc41a2

Browse files
fix: custom space key handling when a button element is on the composed path
If there is a button element on the composed path, then the browser will send a click event on the button when space key is pressed. stopPropagation does not work as this is not a propagated event but something done by the browser. So, whenever a button is detected on the event's composed path, use custom space key handling.
1 parent 6b52088 commit 5dc41a2

2 files changed

Lines changed: 51 additions & 10 deletions

File tree

src/visualBuilder/utils/__test__/handleFieldMouseDown.test.ts

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,26 +128,21 @@ describe("handle numeric field key down", () => {
128128
});
129129

130130
describe("handle keydown in button contenteditable", () => {
131-
let button: HTMLButtonElement | undefined;
132-
let spiedPreventDefault: MockInstance<(e: []) => void> | undefined;
133-
let spiedInsertSpaceAtCursor:
134-
| MockInstance<(typeof insertSpaceAtCursor)["insertSpaceAtCursor"]>
135-
| undefined;
136-
137131
test("should insert space in button content-editable", () => {
132+
let spiedPreventDefault: MockInstance<(e: []) => void> | undefined;
138133
vi.spyOn(window, "getSelection").mockReturnValue({
139-
// @ts-ignore
134+
// @ts-expect-error mocking only required properties
140135
getRangeAt: (n: number) => ({
141136
startOffset: 0,
142137
endOffset: 0,
143138
}),
144139
});
145-
spiedInsertSpaceAtCursor = vi.spyOn(
140+
const spiedInsertSpaceAtCursor = vi.spyOn(
146141
insertSpaceAtCursor,
147142
"insertSpaceAtCursor"
148143
);
149144

150-
button = document.createElement("button");
145+
const button = document.createElement("button");
151146
button.innerHTML = "Test";
152147
button.setAttribute("contenteditable", "true");
153148
button.setAttribute(
@@ -170,6 +165,45 @@ describe("handle keydown in button contenteditable", () => {
170165
expect(spiedPreventDefault).toHaveBeenCalledTimes(1);
171166
expect(spiedInsertSpaceAtCursor).toHaveBeenCalledWith(button);
172167
});
168+
169+
test("should insert space in span content-editable inside button", () => {
170+
let spiedPreventDefault: MockInstance<(e: []) => void> | undefined;
171+
vi.spyOn(window, "getSelection").mockReturnValue({
172+
// @ts-expect-error mocking only required properties
173+
getRangeAt: (n: number) => ({
174+
startOffset: 0,
175+
endOffset: 0,
176+
}),
177+
});
178+
const spiedInsertSpaceAtCursor = vi.spyOn(
179+
insertSpaceAtCursor,
180+
"insertSpaceAtCursor"
181+
);
182+
183+
const button = document.createElement("button");
184+
const span = document.createElement("span");
185+
button.appendChild(span);
186+
span.setAttribute("contenteditable", "true");
187+
span.setAttribute(
188+
VISUAL_BUILDER_FIELD_TYPE_ATTRIBUTE_KEY,
189+
"single_line"
190+
);
191+
192+
span.addEventListener("keydown", (e) => {
193+
spiedPreventDefault = vi.spyOn(e, "preventDefault");
194+
handleFieldKeyDown(e);
195+
});
196+
197+
const keyDownEvent = new KeyboardEvent("keydown", {
198+
bubbles: true,
199+
key: "Space",
200+
code: "Space",
201+
});
202+
span.dispatchEvent(keyDownEvent);
203+
204+
expect(spiedPreventDefault).toHaveBeenCalledTimes(1);
205+
expect(spiedInsertSpaceAtCursor).toHaveBeenCalledWith(span);
206+
});
173207
});
174208

175209
describe("handle single line field key down", () => {

src/visualBuilder/utils/handleFieldMouseDown.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ export function handleFieldKeyDown(e: Event): void {
4444
VISUAL_BUILDER_FIELD_TYPE_ATTRIBUTE_KEY
4545
) as FieldDataType | null;
4646

47-
if (targetElement.tagName === "BUTTON") {
47+
if (
48+
event
49+
.composedPath()
50+
.some(
51+
(element) =>
52+
element instanceof Element && element.tagName === "BUTTON"
53+
)
54+
) {
4855
handleKeyDownOnButton(event);
4956
}
5057
if (fieldType === FieldDataType.NUMBER) {

0 commit comments

Comments
 (0)