-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhandleFieldMouseDown.ts
More file actions
133 lines (119 loc) · 3.85 KB
/
handleFieldMouseDown.ts
File metadata and controls
133 lines (119 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { throttle } from "lodash-es";
import { sendFieldEvent } from "../generators/generateOverlay";
import {
ALLOWED_INLINE_EDITABLE_FIELD,
VISUAL_BUILDER_FIELD_TYPE_ATTRIBUTE_KEY,
numericInputRegex,
} from "./constants";
import { FieldDataType } from "./types/index.types";
import { VisualBuilderPostMessageEvents } from "./types/postMessage.types";
import { insertSpaceAtCursor } from "./insertSpaceAtCursor";
import { VisualBuilder } from "..";
export function handleFieldInput(e: Event): void {
const event = e as InputEvent;
const targetElement = event.target as HTMLElement;
const fieldType = targetElement.getAttribute(
VISUAL_BUILDER_FIELD_TYPE_ATTRIBUTE_KEY
) as FieldDataType | null;
if (
event.type === "input" &&
ALLOWED_INLINE_EDITABLE_FIELD.includes(fieldType as FieldDataType)
) {
if (
!VisualBuilder.VisualBuilderGlobalState.value
.focusFieldReceivedInput
) {
VisualBuilder.VisualBuilderGlobalState.value.focusFieldReceivedInput =
true;
}
throttledFieldSync();
}
}
const throttledFieldSync = throttle(() => {
try {
const visualBuilderContainer = document.querySelector(
".visual-builder__container"
) as HTMLElement;
if (!visualBuilderContainer) return;
sendFieldEvent({
visualBuilderContainer,
eventType: VisualBuilderPostMessageEvents.SYNC_FIELD,
});
} catch (error) {
console.error("Error in throttledFieldSync", error);
}
}, 300);
export function handleFieldKeyDown(e: Event): void {
const event = e as KeyboardEvent;
const targetElement = event.target as HTMLElement;
const fieldType = targetElement.getAttribute(
VISUAL_BUILDER_FIELD_TYPE_ATTRIBUTE_KEY
) as FieldDataType | null;
if (targetElement.tagName === "BUTTON") {
handleKeyDownOnButton(event);
}
if (fieldType === FieldDataType.NUMBER) {
handleNumericFieldKeyDown(event);
} else if (fieldType === FieldDataType.SINGLELINE) {
handleSingleLineFieldKeyDown(event);
}
}
// spaces do not work inside a button content-editable
// this adds a space and moves the cursor ahead, the
// button press event is also prevented
function handleKeyDownOnButton(e: KeyboardEvent) {
if (e.code === "Space" && e.target) {
e.preventDefault();
insertSpaceAtCursor(e.target as HTMLElement);
}
}
function handleSingleLineFieldKeyDown(e: KeyboardEvent) {
if (e.code === "Enter") {
e.preventDefault();
}
}
function handleNumericFieldKeyDown(event: KeyboardEvent): void {
const targetElement = event.target as HTMLElement;
const allowedKeys = [
"Backspace",
"Tab",
"Enter",
"End",
"Home",
"ArrowLeft",
"ArrowRight",
"Delete",
];
if (
event.ctrlKey ||
event.metaKey ||
event.altKey ||
allowedKeys.includes(event.code)
) {
// Allow Ctrl, Cmd, Alt, and special keys
return;
}
if (event.code.includes("Digit")) {
return;
}
const nonNumericAllowedCharacters = ["-", ".", "e", "E"];
if (!nonNumericAllowedCharacters.includes(event.key)) {
event.preventDefault();
return;
}
const selection = {
startOffset: window.getSelection()?.getRangeAt(0).startOffset || 0,
endOffset: window.getSelection()?.getRangeAt(0).endOffset || 0,
};
const existingInput = targetElement.textContent || "";
const currentOutputArr = existingInput.split("");
currentOutputArr.splice(
selection.startOffset,
selection.endOffset - selection.startOffset,
event.key
);
const currentInput = currentOutputArr.join("");
if (!numericInputRegex.test(currentInput)) {
event.preventDefault();
}
}