Skip to content

Commit 4c026eb

Browse files
committed
feat(VE-5170): customize add button position
1 parent 66ef1f1 commit 4c026eb

2 files changed

Lines changed: 108 additions & 14 deletions

File tree

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

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe("getChildrenDirection", () => {
2525

2626
(getChildElements as any).mockReturnValue([null, null, vi.fn()]);
2727

28+
expect(parentElement.getAttribute("data-add-direction")).toBe(null);
2829
const result = getChildrenDirection(editableElement, "test");
2930
expect(result).toBe("none");
3031
});
@@ -67,6 +68,7 @@ describe("getChildrenDirection", () => {
6768
toJSON: () => ({}),
6869
});
6970

71+
expect(parentElement.getAttribute("data-add-direction")).toBe(null);
7072
const result = getChildrenDirection(editableElement, "test");
7173
expect(result).toBe("horizontal");
7274
});
@@ -84,6 +86,7 @@ describe("getChildrenDirection", () => {
8486
secondChildElement,
8587
vi.fn(),
8688
]);
89+
8790

8891
vi.spyOn(firstChildElement, "getBoundingClientRect").mockReturnValue({
8992
left: 0,
@@ -109,7 +112,82 @@ describe("getChildrenDirection", () => {
109112
toJSON: () => ({}),
110113
});
111114

115+
expect(parentElement.getAttribute("data-add-direction")).toBe(null);
112116
const result = getChildrenDirection(editableElement, "test");
113117
expect(result).toBe("vertical");
114118
});
115-
});
119+
120+
it("should return direction from parent's data-add-direction if it exists with valid value", () => {
121+
const editableElement = document.createElement("div");
122+
const parentElement = document.createElement("div");
123+
124+
vi.spyOn(editableElement, "closest").mockReturnValue(parentElement);
125+
126+
// Test vertical direction
127+
parentElement.setAttribute("data-add-direction", "vertical");
128+
const resultVertical = getChildrenDirection(editableElement, "test");
129+
expect(resultVertical).toBe("vertical");
130+
131+
// Test horizontal direction
132+
parentElement.setAttribute("data-add-direction", "horizontal");
133+
const resultHorizontal = getChildrenDirection(editableElement, "test");
134+
expect(resultHorizontal).toBe("horizontal");
135+
});
136+
137+
it("should calculate direction when parent's data-add-direction has invalid value", () => {
138+
const editableElement = document.createElement("div");
139+
const parentElement = document.createElement("div");
140+
const firstChildElement = document.createElement("div");
141+
const secondChildElement = document.createElement("div");
142+
143+
vi.spyOn(editableElement, "closest").mockReturnValue(parentElement);
144+
parentElement.setAttribute("data-add-direction", "invalid");
145+
146+
(getChildElements as any).mockReturnValue([
147+
firstChildElement,
148+
secondChildElement,
149+
vi.fn(),
150+
]);
151+
152+
vi.spyOn(firstChildElement, "getBoundingClientRect").mockReturnValue({
153+
left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, x: 0, y: 0,
154+
toJSON: () => ({})
155+
});
156+
vi.spyOn(secondChildElement, "getBoundingClientRect").mockReturnValue({
157+
left: 10, top: 0, right: 10, bottom: 0, width: 0, height: 0, x: 10, y: 0,
158+
toJSON: () => ({})
159+
});
160+
161+
const result = getChildrenDirection(editableElement, "test");
162+
expect(result).toBe("horizontal");
163+
});
164+
165+
it("should calculate direction when parent's data-add-direction is empty string", () => {
166+
const editableElement = document.createElement("div");
167+
const parentElement = document.createElement("div");
168+
const firstChildElement = document.createElement("div");
169+
const secondChildElement = document.createElement("div");
170+
171+
vi.spyOn(editableElement, "closest").mockReturnValue(parentElement);
172+
parentElement.setAttribute("data-add-direction", "");
173+
174+
(getChildElements as any).mockReturnValue([
175+
firstChildElement,
176+
secondChildElement,
177+
vi.fn(),
178+
]);
179+
180+
vi.spyOn(firstChildElement, "getBoundingClientRect").mockReturnValue({
181+
left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, x: 0, y: 0,
182+
toJSON: () => ({})
183+
});
184+
vi.spyOn(secondChildElement, "getBoundingClientRect").mockReturnValue({
185+
left: 0, top: 10, right: 0, bottom: 10, width: 0, height: 0, x: 0, y: 10,
186+
toJSON: () => ({})
187+
});
188+
189+
const result = getChildrenDirection(editableElement, "test");
190+
expect(result).toBe("vertical");
191+
});
192+
193+
});
Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import getChildElements from "./getChildElements";
22

3+
4+
const validPositions = ["vertical", "horizontal", "none"] as const;
5+
type ValidPositions = typeof validPositions[number];
6+
37
export default function getChildrenDirection(
48
editableElement: Element,
59
parentCslpValue: string
6-
): "none" | "horizontal" | "vertical" {
10+
): ValidPositions {
711
if (!editableElement) {
812
return "none";
913
}
@@ -16,22 +20,34 @@ export default function getChildrenDirection(
1620
return "none";
1721
}
1822

19-
const [firstChildElement, secondChildElement, removeClone] =
20-
getChildElements(parentElement, parentCslpValue);
23+
const directionFromParentElement =
24+
parentElement.getAttribute("data-add-direction");
25+
26+
const isValidParentDirection = validPositions.includes(
27+
directionFromParentElement as ValidPositions
28+
);
2129

22-
if (!firstChildElement) return "none";
2330

24-
// get horizontal and vertical position differences
25-
const firstChildBounds = firstChildElement.getBoundingClientRect();
26-
const secondChildBounds = secondChildElement.getBoundingClientRect();
31+
if (directionFromParentElement && isValidParentDirection) {
32+
return directionFromParentElement as ValidPositions;
33+
} else {
34+
const [firstChildElement, secondChildElement, removeClone] =
35+
getChildElements(parentElement, parentCslpValue);
2736

28-
const deltaX = Math.abs(firstChildBounds.left - secondChildBounds.left);
29-
const deltaY = Math.abs(firstChildBounds.top - secondChildBounds.top);
37+
if (!firstChildElement) return "none";
3038

31-
const dir = deltaX > deltaY ? "horizontal" : "vertical";
39+
// get horizontal and vertical position differences
40+
const firstChildBounds = firstChildElement.getBoundingClientRect();
41+
const secondChildBounds = secondChildElement.getBoundingClientRect();
3242

33-
// remove the clone that was created in case there was only one child
34-
removeClone();
43+
const deltaX = Math.abs(firstChildBounds.left - secondChildBounds.left);
44+
const deltaY = Math.abs(firstChildBounds.top - secondChildBounds.top);
3545

36-
return dir;
46+
const dir = deltaX > deltaY ? "horizontal" : "vertical";
47+
48+
// remove the clone that was created in case there was only one child
49+
removeClone();
50+
51+
return dir;
52+
}
3753
}

0 commit comments

Comments
 (0)