diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3fdf652..245fea3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 3.1.1
+
+- Correctly display component using forwardRef
+- Fix menu position when div is taller than viewport
+- Use dynamic z-index to always be on top of the targeted element (like MUI dialog) (fixes #9)
+
## 3.1.0
- Experimental support for React 19. `_debugSource` [was removed](https://github.com/facebook/react/pull/28265) in React 19. The PR says that tools should lazily generate component stack strace, but I couldn't find a way to use the React devtools globals to generate one for a given Fiber node. I've aksed some React team members about insights on how to make this works, but for now I decided to patch the jsx dev runtime (when serving it) to reinject into Fiber node the source prop added by JSX transform.
diff --git a/package.json b/package.json
index 87b1472..f40f637 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "vite-plugin-react-click-to-component",
"type": "module",
- "version": "3.1.0",
+ "version": "3.1.1",
"license": "MIT",
"scripts": {
"postinstall": "cd playground && bun i",
diff --git a/playground/src/App.tsx b/playground/src/App.tsx
index 57df1af..ffaed92 100644
--- a/playground/src/App.tsx
+++ b/playground/src/App.tsx
@@ -24,5 +24,6 @@ export const App = () => (
Click on the Vite and React logos to learn more
+ Tall div
);
diff --git a/src/client.ts b/src/client.ts
index 981c8d8..9a3b7ca 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -9,7 +9,7 @@ style.innerHTML = `[data-click-to-component-target] {
}
#click-to-component-menu {
position: fixed !important;
- z-index: 1000 !important;
+ z-index: 1000;
margin-top: 8px !important;
margin-bottom: 8px !important;
background: #222 !important;
@@ -62,6 +62,16 @@ window.addEventListener("mousemove", (event) => {
event.target.dataset["clickToComponentTarget"] = "true";
});
+const getMaxZIndex = (target: HTMLElement, current: number) => {
+ const parent = target.parentElement;
+ if (!parent || parent === document.body) return current;
+ const zIndex = parseInt(window.getComputedStyle(parent).zIndex);
+ return getMaxZIndex(
+ parent,
+ isNaN(zIndex) ? current : Math.max(zIndex, current),
+ );
+};
+
window.addEventListener("contextmenu", (event) => {
if (!event.altKey) return;
const target = event.target;
@@ -69,6 +79,8 @@ window.addEventListener("contextmenu", (event) => {
event.preventDefault();
const layers = getLayersForElement(target);
if (layers.length === 0) return;
+ const zIndex = getMaxZIndex(target, 999);
+ if (zIndex > 999) menuElement.style.zIndex = `${zIndex + 1}`;
const rect = target.getBoundingClientRect();
if (rect.bottom < window.innerHeight / 2) {
menuElement.style.top = `${rect.bottom}px`;
@@ -79,9 +91,14 @@ window.addEventListener("contextmenu", (event) => {
menuElement.style.top = "";
menuElement.style.maxHeight = `${rect.top - 16}px`;
} else {
- menuElement.style.bottom = `${window.innerHeight - rect.bottom}px`;
+ const bottomVisible = rect.bottom < window.innerHeight;
+ menuElement.style.bottom = `${
+ bottomVisible ? window.innerHeight - rect.bottom : 0
+ }px`;
menuElement.style.top = "";
- menuElement.style.maxHeight = `${rect.bottom - 16}px`;
+ menuElement.style.maxHeight = `${
+ (bottomVisible ? rect.bottom : window.innerHeight) - 16
+ }px`;
}
if (rect.left < window.innerWidth / 2) {
menuElement.style.left = `${rect.left}px`;
@@ -147,7 +164,10 @@ const getLayersForElement = (element: Element) => {
const name =
typeof instance.type === "string"
? instance.type
- : instance.type.displayName ?? instance.type.name;
+ : instance.type.displayName ??
+ instance.type.name ??
+ instance.type.render?.name ??
+ "undefined";
layers.push({ name, path });
}
instance = instance._debugOwner;
@@ -175,7 +195,9 @@ type Fiber = {
_debugSource?: Source;
_debugInfo?: Source; // Injected by React jsxDev patch for React 19
_debugOwner?: Fiber;
- type: string | { displayName?: string; name: string };
+ type:
+ | string
+ | { displayName?: string; name?: string; render?: () => unknown };
};
const getReactInstanceForElement = (element: Element): Fiber | undefined => {