fix(studio): read z-index from live iframe DOM, rename Layer to Z-index

Replace fragile regex z-index parsing with getComputedStyle on the
preview iframe elements — the same source of truth the inspector uses.

Rename "Layer" to "Z-index" in the design panel for clarity.
This commit is contained in:
Miguel Ángel
2026-05-21 18:28:17 -04:00
parent 0999ed56e6
commit 34a4ad2ed3
3 changed files with 21 additions and 7 deletions
+3
View File
@@ -192,6 +192,7 @@ export function StudioApp() {
projectId,
blockName,
activeCompPath,
previewIframe: previewIframeRef.current,
timelineElements,
readProjectFile: fileManager.readProjectFile,
writeProjectFile: fileManager.writeProjectFile,
@@ -235,6 +236,7 @@ export function StudioApp() {
blockName,
activeCompPath,
placement,
previewIframe: previewIframeRef.current,
timelineElements,
readProjectFile: fileManager.readProjectFile,
writeProjectFile: fileManager.writeProjectFile,
@@ -265,6 +267,7 @@ export function StudioApp() {
blockName,
activeCompPath,
visualPosition: position,
previewIframe: previewIframeRef.current,
timelineElements,
readProjectFile: fileManager.readProjectFile,
writeProjectFile: fileManager.writeProjectFile,
@@ -323,7 +323,7 @@ export const PropertyPanel = memo(function PropertyPanel({
</div>
<div className="mt-3">
<MetricField
label="Layer"
label="Z-index"
value={String(parseInt(styles["z-index"] || "auto", 10) || 0)}
scrub
onCommit={(next) => onSetStyle("z-index", next)}
+17 -6
View File
@@ -9,12 +9,28 @@ import { formatTimelineAttributeNumber } from "../player/components/timelineEdit
import { saveProjectFilesWithHistory } from "./studioFileHistory";
import type { EditHistoryKind } from "./editHistory";
function getMaxZIndexFromIframe(iframe: HTMLIFrameElement | null): number {
try {
const doc = iframe?.contentDocument;
if (!doc) return 0;
let max = 0;
for (const el of doc.body.querySelectorAll("*")) {
const z = parseInt(getComputedStyle(el).zIndex, 10);
if (Number.isFinite(z) && z > max) max = z;
}
return max;
} catch {
return 0;
}
}
interface AddBlockOptions {
projectId: string;
blockName: string;
activeCompPath: string | null;
placement?: { start: number; track: number };
visualPosition?: { left: number; top: number };
previewIframe?: HTMLIFrameElement | null;
timelineElements: TimelineElement[];
readProjectFile: (path: string) => Promise<string>;
writeProjectFile: (path: string, content: string) => Promise<void>;
@@ -126,12 +142,7 @@ export async function addBlockToProject(
? Math.max(...relevantElements.map((te) => te.track)) + 1
: 1);
const zIndexMatches = originalContent.matchAll(/z-index:\s*(\d+)/g);
let maxExistingZ = 0;
for (const m of zIndexMatches) {
maxExistingZ = Math.max(maxExistingZ, parseInt(m[1]!, 10));
}
const zIndex = maxExistingZ + 1;
const zIndex = getMaxZIndexFromIframe(opts.previewIframe ?? null) + 1;
const width = isBlock
? (block as { dimensions: { width: number } }).dimensions.width