@@ -57,10 +57,13 @@ function htmlLabel(text: string): string {
5757 if ( ! tagMatch ) return text ;
5858 const tag = tagMatch [ 1 ] ;
5959 const rest = text . slice ( tagMatch [ 0 ] . length ) ;
60+ // style: primeira propriedade do CSS (ex.: "font-size")
6061 const styleMatch = / \b s t y l e \s * = \s * [ ' " ] \s * ( [ a - z A - Z - ] + ) / . exec ( rest ) ;
6162 if ( styleMatch ) return styleMatch [ 1 ] ;
62- const attrMatch = / \s + ( [ a - z A - Z ] [ a - z A - Z 0 - 9 - ] * ) \s * = / . exec ( rest ) ;
63- if ( attrMatch ) return attrMatch [ 1 ] ;
63+ // Demais atributos: retorna o VALOR (ex.: class='fade fade-1' → "fade fade-1"),
64+ // não o nome do atributo, para refletir o conteúdo real do elemento.
65+ const attrMatch = / \s + [ a - z A - Z ] [ a - z A - Z 0 - 9 - ] * \s * = \s * [ ' " ] ( [ ^ ' " ] + ) [ ' " ] / . exec ( rest ) ;
66+ if ( attrMatch ) return attrMatch [ 1 ] . trim ( ) ;
6467 return `<${ tag } >` ;
6568}
6669
@@ -79,7 +82,11 @@ const TRECHO_KEY = '__trecho__';
7982
8083export function VisualEditsMenu ( { menu, onSelect, onClose } : Props ) {
8184 const ref = useRef < HTMLDivElement | null > ( null ) ;
82- const [ adjusted , setAdjusted ] = useState < { left : number ; top : number } | null > ( null ) ;
85+ const [ adjusted , setAdjusted ] = useState < {
86+ left : number ;
87+ top : number ;
88+ anchor ?: { left : number ; top : number ; width : number ; height : number } ;
89+ } | null > ( null ) ;
8390 const [ activeKey , setActiveKey ] = useState < string | null > ( null ) ;
8491
8592 useEffect ( ( ) => {
@@ -97,11 +104,13 @@ export function VisualEditsMenu({ menu, onSelect, onClose }: Props) {
97104
98105 let cx = menu . x ;
99106 let cy = menu . y ;
107+ let anchorRect : { left : number ; top : number ; width : number ; height : number } | undefined ;
100108 const anchor = document . querySelector < HTMLElement > ( '[data-ve-anchor="preview-canvas"]' ) ;
101109 if ( anchor ) {
102110 const ar = anchor . getBoundingClientRect ( ) ;
103111 cx = ar . left + ar . width / 2 ;
104112 cy = ar . top + ar . height / 2 ;
113+ anchorRect = { left : ar . left , top : ar . top , width : ar . width , height : ar . height } ;
105114 }
106115
107116 let left = cx - rect . width / 2 ;
@@ -110,7 +119,7 @@ export function VisualEditsMenu({ menu, onSelect, onClose }: Props) {
110119 if ( top + rect . height > vh - VIEWPORT_PAD ) top = vh - rect . height - VIEWPORT_PAD ;
111120 if ( left < VIEWPORT_PAD ) left = VIEWPORT_PAD ;
112121 if ( top < VIEWPORT_PAD ) top = VIEWPORT_PAD ;
113- setAdjusted ( { left, top } ) ;
122+ setAdjusted ( { left, top, anchor : anchorRect } ) ;
114123 } , [ menu ] ) ;
115124
116125 useEffect ( ( ) => {
@@ -138,16 +147,20 @@ export function VisualEditsMenu({ menu, onSelect, onClose }: Props) {
138147
139148 if ( ! menu ) return null ;
140149
141- // Backdrop z-[59], menu z-[60]
142- const backdropStyle : React . CSSProperties = {
143- position : 'fixed' ,
144- inset : 0 ,
145- zIndex : 59 ,
146- backgroundColor : 'rgba(0,0,0,0.35)' ,
147- backdropFilter : 'blur(1px)' ,
148- WebkitBackdropFilter : 'blur(1px)' ,
149- visibility : adjusted ? 'visible' : 'hidden' ,
150- } ;
150+ // Backdrop limitado ao container do preview (não cobre a aplicação inteira).
151+ const backdropStyle : React . CSSProperties = adjusted ?. anchor
152+ ? {
153+ position : 'fixed' ,
154+ left : adjusted . anchor . left ,
155+ top : adjusted . anchor . top ,
156+ width : adjusted . anchor . width ,
157+ height : adjusted . anchor . height ,
158+ zIndex : 59 ,
159+ backgroundColor : 'rgba(0,0,0,0.35)' ,
160+ backdropFilter : 'blur(1px)' ,
161+ WebkitBackdropFilter : 'blur(1px)' ,
162+ }
163+ : { display : 'none' } ;
151164
152165 const menuStyle : React . CSSProperties = {
153166 position : 'fixed' ,
0 commit comments