Skip to content

Commit 8bf9416

Browse files
committed
fix(visual-edits): badge VAR azul, overlay só no preview, Tx sem CSS
- Badge VAR: azul (era roxo) - Overlay de esmaecer movido para HtmlPreview — cobre apenas o painel de preview, não o editor à esquerda; levemente mais escuro (20%) - Classificação de Tx corrigida: texto visível exige ao menos uma letra e nenhum char CSS (: ;); fragmentos de CSS e atributos HTML são ignorados ou marcados como </> quando contêm '<'
1 parent a8199e9 commit 8bf9416

4 files changed

Lines changed: 36 additions & 24 deletions

File tree

src/App.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ export default function App() {
365365
viewport={viewport}
366366
onViewportChange={setViewport}
367367
onLocate={onVisualEditsLocate}
368+
menuOpen={veMenu !== null}
368369
/>
369370
}
370371
/>

src/components/HtmlPreview.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ interface HtmlPreviewProps {
2525
// Recebe o loc clicado e as coordenadas já convertidas para a janela principal
2626
// (levando em conta a posição e a escala do iframe).
2727
onLocate?: (loc: string, screenX: number, screenY: number) => void;
28+
menuOpen?: boolean;
2829
}
2930

3031
const MIN_W = 200;
@@ -51,6 +52,7 @@ export function HtmlPreview({
5152
viewport,
5253
onViewportChange,
5354
onLocate,
55+
menuOpen,
5456
}: HtmlPreviewProps) {
5557
const [showWarnings, setShowWarnings] = useState(false);
5658
const iframeRef = useRef<HTMLIFrameElement | null>(null);
@@ -239,6 +241,9 @@ export function HtmlPreview({
239241
ref={canvasRef}
240242
className={`relative flex flex-1 items-center justify-center overflow-hidden bg-[hsl(var(--preview-bg))]${visualEditsEnabled ? ' ve-border-pulse' : ''}`}
241243
>
244+
{menuOpen && (
245+
<div className="absolute inset-0 bg-black/20 z-[59] pointer-events-none" />
246+
)}
242247
{error ? (
243248
<div className="flex h-full w-full flex-col items-center justify-center gap-3 p-8 text-center">
244249
<AlertTriangle className="h-12 w-12 text-destructive" />

src/components/VisualEditsMenu.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ function TypeBadge({ kind }: { kind: BadgeKind }) {
4545
}
4646
return (
4747
<span
48-
className={`${base} bg-violet-100 text-violet-600 border-violet-200 dark:bg-violet-900/40 dark:text-violet-400 dark:border-violet-700`}
48+
className={`${base} bg-blue-100 text-blue-600 border-blue-200 dark:bg-blue-900/40 dark:text-blue-400 dark:border-blue-700`}
4949
>
5050
VAR
5151
</span>
@@ -125,11 +125,6 @@ export function VisualEditsMenu({ menu, onSelect, onClose }: Props) {
125125

126126
return (
127127
<>
128-
<div
129-
className="fixed inset-0 bg-black/10"
130-
style={{ zIndex: 59 }}
131-
onClick={onClose}
132-
/>
133128
<div
134129
ref={ref}
135130
style={menuStyle}

src/lib/daxParser/varDependencies.ts

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,23 @@ function splitLiteral(
4141
const contentEnd = loc.end - 1;
4242
const content = src.slice(contentStart, contentEnd);
4343
const out: Array<{ kind: 'html' | 'text'; text: string; loc: SourceLoc }> = [];
44-
let lastEnd = 0;
44+
45+
// Texto visível: deve ter pelo menos uma letra e nenhum caractere CSS (:;)
46+
const isVisibleText = (s: string) => /[a-zA-ZÀ-ÿ]/.test(s) && !/[;:]/.test(s);
47+
4548
TAG_SPLIT_RE.lastIndex = 0;
4649
let m: RegExpExecArray | null;
50+
let lastEnd = 0;
51+
let foundTag = false;
52+
4753
while ((m = TAG_SPLIT_RE.exec(content)) !== null) {
54+
foundTag = true;
4855
if (m.index > lastEnd) {
49-
const text = content.slice(lastEnd, m.index);
50-
if (text.trim().length > 0) {
56+
const text = content.slice(lastEnd, m.index).trim();
57+
if (text.length > 0 && isVisibleText(text)) {
5158
out.push({
5259
kind: 'text',
53-
text: text.trim(),
60+
text,
5461
loc: { start: contentStart + lastEnd, end: contentStart + m.index },
5562
});
5663
}
@@ -62,23 +69,27 @@ function splitLiteral(
6269
});
6370
lastEnd = m.index + m[0].length;
6471
}
65-
if (lastEnd < content.length) {
66-
const tail = content.slice(lastEnd);
67-
if (tail.trim().length > 0) {
68-
out.push({
69-
kind: 'text',
70-
text: tail.trim(),
71-
loc: { start: contentStart + lastEnd, end: contentEnd },
72-
});
72+
73+
if (foundTag && lastEnd < content.length) {
74+
const tail = content.slice(lastEnd).trim();
75+
if (tail.length > 0 && isVisibleText(tail)) {
76+
out.push({ kind: 'text', text: tail, loc: { start: contentStart + lastEnd, end: contentEnd } });
7377
}
7478
}
75-
if (out.length === 0 && content.trim().length > 0) {
76-
out.push({
77-
kind: 'text',
78-
text: content.trim(),
79-
loc: { start: contentStart, end: contentEnd },
80-
});
79+
80+
// Nenhuma tag completa encontrada: classifica o literal inteiro.
81+
if (!foundTag) {
82+
if (content.includes('<')) {
83+
// Tag incompleta (ex.: "<div style='width:") → fragmento HTML
84+
out.push({ kind: 'html', text: content, loc: { start: contentStart, end: contentEnd } });
85+
} else {
86+
const trimmed = content.trim();
87+
if (trimmed.length > 0 && isVisibleText(trimmed)) {
88+
out.push({ kind: 'text', text: trimmed, loc: { start: contentStart, end: contentEnd } });
89+
}
90+
}
8191
}
92+
8293
return out;
8394
}
8495

0 commit comments

Comments
 (0)