Skip to content

Commit 7f6ce29

Browse files
committed
Refactored codebase into a more function-based library of operations; Added freezing and basic editing functionality to TokenDetails
1 parent 1a128bd commit 7f6ce29

19 files changed

+870
-421
lines changed

package-lock.json

Lines changed: 408 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"eslint-plugin-react-hooks": "^5.2.0",
5858
"eslint-plugin-react-refresh": "^0.4.19",
5959
"globals": "^16.0.0",
60+
"sass-embedded": "^1.89.1",
6061
"typescript": "~5.8.3",
6162
"typescript-eslint": "^8.30.1",
6263
"vite": "^6.3.5",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.token-details {
2+
&__selected-target {
3+
border: 2px solid red !important;
4+
cursor: pointer;
5+
}
6+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import _ from "lodash";
2+
import { type ReactNode, useEffect, useState } from "react";
3+
import { Button, Typography } from "antd";
4+
import { variablesUsedByElement } from "../../utils/variable-parsing/findVariablesUsedByElement";
5+
import { transformVariableToReact } from "../../utils/variable-parsing/transformVariableToReact";
6+
import "./TokenDetails.scss";
7+
8+
const { Text } = Typography;
9+
10+
export const TokenDetails = () => {
11+
const [target, setTarget] = useState<HTMLElement | null>(null);
12+
const [frozen, setFrozen] = useState(false); // State to manage if the target is frozen
13+
const [editable, setEditable] = useState(false); // State to manage if the variable values should be editable
14+
15+
const saveVariableValues = () => {
16+
setEditable(false);
17+
};
18+
19+
const targetTokenDetails = (target: HTMLElement | null): ReactNode => {
20+
if (target) {
21+
try {
22+
const elementName = target.tagName;
23+
const elementVariables = variablesUsedByElement(target);
24+
return (
25+
<>
26+
<Text strong>{_.lowerCase(elementName)}</Text>
27+
<br />
28+
<br />
29+
{elementVariables.map((variable) =>
30+
transformVariableToReact(variable, editable)
31+
)}
32+
<br />
33+
<Button
34+
onClick={() =>
35+
editable ? saveVariableValues() : setEditable(true)
36+
}
37+
type="primary"
38+
size="small"
39+
>
40+
{editable ? "Save" : "Edit"}
41+
</Button>
42+
<br />
43+
<br />
44+
<Button
45+
onClick={() => setFrozen(false)}
46+
color="cyan"
47+
variant="solid"
48+
size="small"
49+
>
50+
Unfreeze
51+
</Button>
52+
</>
53+
);
54+
} catch (e) {
55+
console.log(e);
56+
}
57+
} else {
58+
return <h4>No target selected </h4>;
59+
}
60+
};
61+
62+
useEffect(() => {
63+
const interceptClick = (event: MouseEvent) => {
64+
if (!(event.target instanceof HTMLElement)) {
65+
return;
66+
}
67+
68+
if (event.target.matches(".tokenInspector *")) {
69+
console.log("Click on token inspector, NOT freezing target");
70+
// If the click is not on the token inspector, do not freeze
71+
return;
72+
}
73+
74+
event.preventDefault();
75+
event.stopPropagation();
76+
77+
setFrozen(true);
78+
};
79+
80+
const changeTarget = (
81+
currentTarget: HTMLElement | null,
82+
newTarget: HTMLElement | null,
83+
targetFrozen: boolean
84+
) => {
85+
// If the target is frozen, do not change anything
86+
if (targetFrozen) {
87+
return;
88+
}
89+
90+
if (currentTarget) {
91+
currentTarget.classList.remove("token-details__selected-target");
92+
}
93+
if (newTarget) {
94+
newTarget.classList.add("token-details__selected-target");
95+
document
96+
.querySelectorAll(".token-details__selected-target")
97+
.forEach((el) => {
98+
if (el !== newTarget) {
99+
el.classList.remove("token-details__selected-target");
100+
}
101+
});
102+
console.log("Changing target!");
103+
setTarget(newTarget);
104+
}
105+
};
106+
107+
const handleMouseOver = (event: MouseEvent) => {
108+
const targetElement = event.target as HTMLElement;
109+
if (targetElement) {
110+
if (
111+
!targetElement.matches(".tokenInspector") &&
112+
!targetElement.matches(".tokenInspector *")
113+
) {
114+
changeTarget(target, targetElement, frozen);
115+
}
116+
}
117+
};
118+
119+
const handleMouseOut = (event: MouseEvent) => {
120+
const targetElement = event.target as HTMLElement;
121+
if (targetElement) {
122+
if (
123+
!targetElement.matches(".tokenInspector") &&
124+
!targetElement.matches(".tokenInspector *")
125+
) {
126+
changeTarget(target, null, frozen);
127+
}
128+
}
129+
};
130+
131+
document.addEventListener("mouseover", handleMouseOver);
132+
document.addEventListener("mouseout", handleMouseOut);
133+
document.addEventListener("click", interceptClick);
134+
135+
return () => {
136+
document.removeEventListener("mouseover", handleMouseOver);
137+
document.removeEventListener("mouseout", handleMouseOut);
138+
document.removeEventListener("click", interceptClick);
139+
};
140+
}, [frozen, target]);
141+
142+
return targetTokenDetails(target);
143+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./TokenDetails";

0 commit comments

Comments
 (0)