@brunoalz/smartgesti-site-editor 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/editor/BlockSelector.js +5 -2
  2. package/dist/editor/BlockSelector.js.map +1 -1
  3. package/dist/editor/LandingPageEditor.d.ts.map +1 -1
  4. package/dist/editor/LandingPageEditor.js +163 -151
  5. package/dist/editor/LandingPageEditor.js.map +1 -1
  6. package/dist/editor/PropertyEditor/BlockPropertyEditor.d.ts.map +1 -1
  7. package/dist/editor/PropertyEditor/BlockPropertyEditor.js +86 -48
  8. package/dist/editor/PropertyEditor/BlockPropertyEditor.js.map +1 -1
  9. package/dist/engine/export/exporters/sections/AdminSectionExporters.d.ts +6 -0
  10. package/dist/engine/export/exporters/sections/AdminSectionExporters.d.ts.map +1 -0
  11. package/dist/engine/export/exporters/sections/AdminSectionExporters.js +157 -0
  12. package/dist/engine/export/exporters/sections/AdminSectionExporters.js.map +1 -0
  13. package/dist/engine/export/exporters/sections/index.d.ts.map +1 -1
  14. package/dist/engine/export/exporters/sections/index.js +37 -33
  15. package/dist/engine/export/exporters/sections/index.js.map +1 -1
  16. package/dist/engine/index.js +98 -95
  17. package/dist/engine/index.js.map +1 -1
  18. package/dist/engine/preview/Preview.d.ts.map +1 -1
  19. package/dist/engine/preview/Preview.js +165 -160
  20. package/dist/engine/preview/Preview.js.map +1 -1
  21. package/dist/engine/registry/blocks/sections/aboutSection.d.ts +3 -0
  22. package/dist/engine/registry/blocks/sections/aboutSection.d.ts.map +1 -0
  23. package/dist/engine/registry/blocks/sections/aboutSection.js +117 -0
  24. package/dist/engine/registry/blocks/sections/aboutSection.js.map +1 -0
  25. package/dist/engine/registry/blocks/sections/contactSection.d.ts +3 -0
  26. package/dist/engine/registry/blocks/sections/contactSection.d.ts.map +1 -0
  27. package/dist/engine/registry/blocks/sections/contactSection.js +118 -0
  28. package/dist/engine/registry/blocks/sections/contactSection.js.map +1 -0
  29. package/dist/engine/registry/blocks/sections/index.d.ts +3 -0
  30. package/dist/engine/registry/blocks/sections/index.d.ts.map +1 -1
  31. package/dist/engine/registry/blocks/sections/productShowcase.d.ts +3 -0
  32. package/dist/engine/registry/blocks/sections/productShowcase.d.ts.map +1 -0
  33. package/dist/engine/registry/blocks/sections/productShowcase.js +108 -0
  34. package/dist/engine/registry/blocks/sections/productShowcase.js.map +1 -0
  35. package/dist/engine/render/renderers/sections/AboutSectionRenderer.d.ts +3 -0
  36. package/dist/engine/render/renderers/sections/AboutSectionRenderer.d.ts.map +1 -0
  37. package/dist/engine/render/renderers/sections/AboutSectionRenderer.js +246 -0
  38. package/dist/engine/render/renderers/sections/AboutSectionRenderer.js.map +1 -0
  39. package/dist/engine/render/renderers/sections/ContactSectionRenderer.d.ts +3 -0
  40. package/dist/engine/render/renderers/sections/ContactSectionRenderer.d.ts.map +1 -0
  41. package/dist/engine/render/renderers/sections/ContactSectionRenderer.js +287 -0
  42. package/dist/engine/render/renderers/sections/ContactSectionRenderer.js.map +1 -0
  43. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.d.ts +3 -0
  44. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.d.ts.map +1 -0
  45. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.js +287 -0
  46. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.js.map +1 -0
  47. package/dist/engine/render/renderers/sections/index.js +26 -20
  48. package/dist/engine/render/renderers/sections/index.js.map +1 -1
  49. package/dist/engine/schema/siteDocument.d.ts +96 -2
  50. package/dist/engine/schema/siteDocument.d.ts.map +1 -1
  51. package/dist/engine/schema/siteDocument.js.map +1 -1
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +109 -106
  55. package/dist/index.js.map +1 -1
  56. package/dist/shared/schema.d.ts +1 -1
  57. package/dist/shared/schema.d.ts.map +1 -1
  58. package/dist/shared/schema.js +7 -4
  59. package/dist/shared/schema.js.map +1 -1
  60. package/dist/shared/templates/index.d.ts +2 -0
  61. package/dist/shared/templates/index.d.ts.map +1 -1
  62. package/dist/shared/templates/index.js +42 -23
  63. package/dist/shared/templates/index.js.map +1 -1
  64. package/dist/shared/templates/smartgesti-admin.d.ts +3 -0
  65. package/dist/shared/templates/smartgesti-admin.d.ts.map +1 -0
  66. package/dist/shared/templates/smartgesti-admin.js +426 -0
  67. package/dist/shared/templates/smartgesti-admin.js.map +1 -0
  68. package/dist/utils/blockIcons.d.ts.map +1 -1
  69. package/dist/utils/blockIcons.js +3 -0
  70. package/dist/utils/blockIcons.js.map +1 -1
  71. package/dist/viewer/LandingPageViewer.d.ts.map +1 -1
  72. package/dist/viewer/LandingPageViewer.js +66 -65
  73. package/dist/viewer/LandingPageViewer.js.map +1 -1
  74. package/package.json +1 -1
@@ -1,90 +1,90 @@
1
1
  import { jsx as C, jsxs as W } from "react/jsx-runtime";
2
- import { useRef as y, useState as j, useEffect as k, useMemo as F } from "react";
2
+ import { useRef as y, useState as j, useEffect as x, useMemo as F } from "react";
3
3
  import { componentRegistry as X } from "../registry/registry.js";
4
4
  import { exportPageToHtml as Y, exportBlockToHtml as K } from "../export/exportHtml.js";
5
5
  import { detectChangedBlocks as Q } from "../../utils/changeDetector.js";
6
6
  import { hashDocument as P } from "../../utils/documentHash.js";
7
7
  import { logger as D } from "../../utils/logger.js";
8
- function U(a, v) {
9
- const s = (E) => {
10
- for (const c of E) {
11
- if (c.id === v) return c;
12
- const i = c.props;
13
- if (i?.children && Array.isArray(i.children)) {
14
- const r = s(i.children);
8
+ function U(o, v) {
9
+ const u = (w) => {
10
+ for (const d of w) {
11
+ if (d.id === v) return d;
12
+ const n = d.props;
13
+ if (n?.children && Array.isArray(n.children)) {
14
+ const r = u(n.children);
15
15
  if (r) return r;
16
16
  }
17
- if (c.type === "card") {
18
- if (i.header && Array.isArray(i.header)) {
19
- const r = s(i.header);
17
+ if (d.type === "card") {
18
+ if (n.header && Array.isArray(n.header)) {
19
+ const r = u(n.header);
20
20
  if (r) return r;
21
21
  }
22
- if (i.content && Array.isArray(i.content)) {
23
- const r = s(i.content);
22
+ if (n.content && Array.isArray(n.content)) {
23
+ const r = u(n.content);
24
24
  if (r) return r;
25
25
  }
26
- if (i.footer && Array.isArray(i.footer)) {
27
- const r = s(i.footer);
26
+ if (n.footer && Array.isArray(n.footer)) {
27
+ const r = u(n.footer);
28
28
  if (r) return r;
29
29
  }
30
30
  }
31
31
  }
32
32
  return null;
33
33
  };
34
- return s(a.structure);
34
+ return u(o.structure);
35
35
  }
36
- function V(a) {
37
- const v = {}, s = (E) => {
38
- for (const c of E) {
39
- const i = X.get(c.type);
40
- v[c.id] = i?.name || c.type;
41
- const r = c.props;
42
- r?.children && Array.isArray(r.children) && s(r.children), c.type === "card" && (Array.isArray(r?.header) && s(r.header), Array.isArray(r?.content) && s(r.content), Array.isArray(r?.footer) && s(r.footer));
36
+ function V(o) {
37
+ const v = {}, u = (w) => {
38
+ for (const d of w) {
39
+ const n = X.get(d.type);
40
+ v[d.id] = n?.name || d.type;
41
+ const r = d.props;
42
+ r?.children && Array.isArray(r.children) && u(r.children), d.type === "card" && (Array.isArray(r?.header) && u(r.header), Array.isArray(r?.content) && u(r.content), Array.isArray(r?.footer) && u(r.footer));
43
43
  }
44
44
  };
45
- return a?.structure && s(a.structure), v;
45
+ return o?.structure && u(o.structure), v;
46
46
  }
47
- function le({
48
- document: a,
47
+ function ae({
48
+ document: o,
49
49
  pageId: v,
50
- className: s,
51
- style: E,
52
- onBlockClick: c,
53
- selectedBlockId: i,
50
+ className: u,
51
+ style: w,
52
+ onBlockClick: d,
53
+ selectedBlockId: n,
54
54
  showSelectionOverlay: r = !1,
55
55
  focusedGroup: H = null
56
56
  }) {
57
- const l = y(null), _ = y(null), A = y(null), R = y(null), B = y(!1), [G, N] = j(!0), I = y(i), z = y(r), $ = y(H);
58
- k(() => {
59
- I.current = i;
60
- }, [i]), k(() => {
61
- z.current = r;
62
- }, [r]), k(() => {
63
- $.current = H;
57
+ const s = y(null), E = y(null), _ = y(null), J = y(null), B = y(!1), [$, A] = j(!0), I = y(n), R = y(r), M = y(H);
58
+ x(() => {
59
+ I.current = n;
60
+ }, [n]), x(() => {
61
+ R.current = r;
62
+ }, [r]), x(() => {
63
+ M.current = H;
64
64
  }, [H]);
65
- const u = F(() => v ? a.pages.find((t) => t.id === v) : a.pages[0], [a, v]), M = y({});
66
- k(() => {
67
- M.current = V(u);
68
- }, [u]);
65
+ const f = F(() => v ? o.pages.find((t) => t.id === v) : o.pages[0], [o, v]), z = y({});
66
+ x(() => {
67
+ z.current = V(f);
68
+ }, [f]);
69
69
  const L = (t) => {
70
- if (!l.current) return;
71
- const e = l.current.contentDocument || l.current.contentWindow?.document;
70
+ if (!s.current) return;
71
+ const e = s.current.contentDocument || s.current.contentWindow?.document;
72
72
  if (!e) return;
73
- const o = z.current, n = $.current;
73
+ const i = R.current, l = M.current;
74
74
  requestAnimationFrame(() => {
75
- const p = e.getElementById("block-highlight");
76
- p && p.remove(), e.querySelectorAll("[data-block-id]").forEach((w) => {
77
- const f = w;
78
- f.style.outline = "", f.style.outlineOffset = "";
75
+ const c = e.getElementById("block-highlight");
76
+ c && c.remove(), e.querySelectorAll("[data-block-id]").forEach((T) => {
77
+ const g = T;
78
+ g.style.outline = "", g.style.outlineOffset = "";
79
79
  });
80
- const d = e.getElementById("sg-block-label");
81
- d && d.remove();
82
- const T = e.getElementById("sg-group-highlight");
83
- T && T.remove();
84
- const x = e.getElementById("sg-group-label");
85
- if (x && x.remove(), t) {
86
- const w = e.createElement("style");
87
- if (w.id = "block-highlight", w.textContent = `
80
+ const b = e.getElementById("sg-block-label");
81
+ b && b.remove();
82
+ const N = e.getElementById("sg-group-highlight");
83
+ N && N.remove();
84
+ const p = e.getElementById("sg-group-label");
85
+ if (p && p.remove(), t) {
86
+ const T = e.createElement("style");
87
+ if (T.id = "block-highlight", T.textContent = `
88
88
  [data-block-id="${t}"] {
89
89
  outline: 2px solid #3b82f6 !important;
90
90
  outline-offset: 2px !important;
@@ -101,47 +101,47 @@ function le({
101
101
  pointer-events: none;
102
102
  z-index: -1;
103
103
  }
104
- `, e.head.appendChild(w), o) {
105
- const f = e.querySelector(`[data-block-id="${t}"]`);
106
- if (f) {
107
- const h = M.current[t] || t, b = e.createElement("div");
108
- b.id = "sg-block-label", b.textContent = h, b.style.cssText = "position:absolute;top:-22px;left:0;background:#3b82f6;color:#fff;font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px 4px 0 0;z-index:10000;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:16px;", getComputedStyle(f).position === "static" && (f.style.position = "relative"), f.appendChild(b);
104
+ `, e.head.appendChild(T), i) {
105
+ const g = e.querySelector(`[data-block-id="${t}"]`);
106
+ if (g) {
107
+ const m = z.current[t] || t, k = e.createElement("div");
108
+ k.id = "sg-block-label", k.textContent = m, k.style.cssText = "position:absolute;top:-22px;left:0;background:#3b82f6;color:#fff;font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px 4px 0 0;z-index:10000;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:16px;", getComputedStyle(g).position === "static" && (g.style.position = "relative"), g.appendChild(k);
109
109
  }
110
110
  }
111
- if (n) {
112
- const h = e.querySelector(`[data-block-id="${t}"]`)?.querySelector(`[data-block-group="${n}"]`);
113
- if (h) {
114
- const b = e.createElement("style");
115
- b.id = "sg-group-highlight", b.textContent = `
116
- [data-block-id="${t}"] [data-block-group="${n}"] {
111
+ if (l) {
112
+ const m = e.querySelector(`[data-block-id="${t}"]`)?.querySelector(`[data-block-group="${l}"]`);
113
+ if (m) {
114
+ const k = e.createElement("style");
115
+ k.id = "sg-group-highlight", k.textContent = `
116
+ [data-block-id="${t}"] [data-block-group="${l}"] {
117
117
  outline: 2px solid #8b5cf6 !important;
118
118
  outline-offset: 2px !important;
119
119
  position: relative;
120
120
  }
121
- `, e.head.appendChild(b);
121
+ `, e.head.appendChild(k);
122
122
  const S = e.createElement("div");
123
- S.id = "sg-group-label", S.textContent = n, S.style.cssText = "position:absolute;top:-20px;right:0;background:#8b5cf6;color:#fff;font-size:10px;font-weight:600;padding:2px 8px;border-radius:4px 4px 0 0;z-index:10001;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:14px;", getComputedStyle(h).position === "static" && (h.style.position = "relative"), h.appendChild(S);
123
+ S.id = "sg-group-label", S.textContent = l, S.style.cssText = "position:absolute;top:-20px;right:0;background:#8b5cf6;color:#fff;font-size:10px;font-weight:600;padding:2px 8px;border-radius:4px 4px 0 0;z-index:10001;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:14px;", getComputedStyle(m).position === "static" && (m.style.position = "relative"), m.appendChild(S);
124
124
  }
125
125
  }
126
126
  }
127
127
  });
128
- }, J = () => {
129
- l.current?.contentWindow && l.current.contentWindow.postMessage({
128
+ }, q = () => {
129
+ s.current?.contentWindow && s.current.contentWindow.postMessage({
130
130
  type: "sg-set-block-names",
131
- names: M.current
131
+ names: z.current
132
132
  }, "*");
133
- }, q = (t) => {
134
- if (!l.current) return;
135
- const e = l.current.contentDocument || l.current.contentWindow?.document;
133
+ }, O = (t) => {
134
+ if (!s.current) return;
135
+ const e = s.current.contentDocument || s.current.contentWindow?.document;
136
136
  if (!e) return;
137
- const o = e.getElementById("sg-hover-overlay");
138
- if (o && o.remove(), !t) {
139
- const n = e.getElementById("sg-hover-tooltip");
140
- n && (n.style.opacity = "0");
137
+ const i = e.getElementById("sg-hover-overlay");
138
+ if (i && i.remove(), !t) {
139
+ const l = e.getElementById("sg-hover-tooltip");
140
+ l && (l.style.opacity = "0");
141
141
  }
142
142
  if (t) {
143
- const n = e.createElement("style");
144
- n.id = "sg-hover-overlay", n.textContent = `
143
+ const l = e.createElement("style");
144
+ l.id = "sg-hover-overlay", l.textContent = `
145
145
  [data-block-id] {
146
146
  cursor: pointer;
147
147
  transition: outline 0.15s ease, outline-offset 0.15s ease;
@@ -159,15 +159,15 @@ function le({
159
159
  outline-offset: 1px !important;
160
160
  background: rgba(139, 92, 246, 0.04);
161
161
  }
162
- `, e.head.appendChild(n), J();
162
+ `, e.head.appendChild(l), q();
163
163
  }
164
164
  L(I.current || null);
165
- }, m = (t, e) => {
166
- if (!(!l.current || !u))
165
+ }, h = (t, e) => {
166
+ if (!(!s.current || !f))
167
167
  try {
168
- e && N(!0);
169
- let o = Y(u, t, !0);
170
- const n = `
168
+ e && A(!0);
169
+ let i = Y(f, t, !0);
170
+ const l = `
171
171
  <script>
172
172
  (function() {
173
173
  // Click handler
@@ -271,115 +271,120 @@ function le({
271
271
  })();
272
272
  <\/script>
273
273
  `;
274
- o = o.replace("</body>", `${n}</body>`), o.includes("</body>") || (o = o + n);
275
- const p = l.current, g = () => {
276
- L(I.current || null), z.current && q(!0);
274
+ i = i.replace("</body>", `${l}</body>`), i.includes("</body>") || (i = i + l);
275
+ const c = s.current, a = () => {
276
+ L(I.current || null), R.current && O(!0);
277
277
  };
278
- e ? (p.onload = () => {
279
- N(!1), _.current = JSON.parse(JSON.stringify(t)), A.current = P(t), g();
278
+ e ? (c.onload = () => {
279
+ A(!1), E.current = JSON.parse(JSON.stringify(t)), _.current = P(t), a();
280
280
  }, setTimeout(() => {
281
- N(!1), _.current = JSON.parse(JSON.stringify(t)), A.current = P(t), g();
282
- }, 1e3)) : (_.current = JSON.parse(JSON.stringify(t)), A.current = P(t), p.onload = () => {
283
- g();
284
- }), p.srcdoc = o;
285
- } catch (o) {
286
- D.error("[Preview] Error:", o), e && N(!1);
281
+ A(!1), E.current = JSON.parse(JSON.stringify(t)), _.current = P(t), a();
282
+ }, 1e3)) : (E.current = JSON.parse(JSON.stringify(t)), _.current = P(t), c.onload = () => {
283
+ a();
284
+ }), c.srcdoc = i;
285
+ } catch (i) {
286
+ D.error("[Preview] Error:", i), e && A(!1);
287
287
  }
288
- }, O = (t, e) => {
289
- if (!(!l.current || !u))
288
+ }, G = (t, e) => {
289
+ if (!(!s.current || !f))
290
290
  try {
291
- const o = U(u, t);
292
- if (!o) {
293
- m(e, !1);
291
+ const i = U(f, t);
292
+ if (!i) {
293
+ h(e, !1);
294
294
  return;
295
295
  }
296
- const n = K(o, void 0, e.theme);
296
+ const l = K(i, void 0, e.theme);
297
297
  requestAnimationFrame(() => {
298
- const p = l.current;
299
- if (!p) return;
300
- const g = p.contentDocument || p.contentWindow?.document;
301
- if (!g) return;
302
- const d = g.querySelector(`[data-block-id="${t}"]`);
303
- if (d)
298
+ const c = s.current;
299
+ if (!c) return;
300
+ const a = c.contentDocument || c.contentWindow?.document;
301
+ if (!a) return;
302
+ const b = a.querySelector(`[data-block-id="${t}"]`);
303
+ if (b)
304
304
  try {
305
- g.querySelectorAll(`style[data-block-style="${t}"]`).forEach((h) => h.remove());
306
- const x = g.createElement("div");
307
- x.innerHTML = n, x.querySelectorAll("style").forEach((h) => {
308
- h.setAttribute("data-block-style", t);
305
+ a.querySelectorAll(`style[data-block-style="${t}"]`).forEach((m) => m.remove());
306
+ const p = a.createElement("div");
307
+ p.innerHTML = l, p.querySelectorAll("style").forEach((m) => {
308
+ m.setAttribute("data-block-style", t);
309
309
  });
310
- const f = g.createDocumentFragment();
311
- for (; x.firstChild; )
312
- f.appendChild(x.firstChild);
313
- f.childNodes.length > 0 ? d.parentNode?.replaceChild(f, d) : d.outerHTML = n, _.current = JSON.parse(JSON.stringify(e)), A.current = P(e), L(I.current || null);
314
- } catch (T) {
315
- D.error("[Preview] Erro ao atualizar:", T), m(e, !1);
310
+ const g = a.createDocumentFragment();
311
+ for (; p.firstChild; )
312
+ g.appendChild(p.firstChild);
313
+ g.childNodes.length > 0 ? b.parentNode?.replaceChild(g, b) : b.outerHTML = l, E.current = JSON.parse(JSON.stringify(e)), _.current = P(e), L(I.current || null);
314
+ } catch (N) {
315
+ D.error("[Preview] Erro ao atualizar:", N), h(e, !1);
316
316
  }
317
317
  else
318
- m(e, !1);
318
+ h(e, !1);
319
319
  });
320
- } catch (o) {
321
- D.error("[Preview] Erro:", o), m(e, !1);
320
+ } catch (i) {
321
+ D.error("[Preview] Erro:", i), h(e, !1);
322
322
  }
323
323
  };
324
- return k(() => {
325
- if (!u) {
326
- N(!1);
324
+ return x(() => {
325
+ if (!f) {
326
+ A(!1);
327
327
  return;
328
328
  }
329
- const t = P(a);
329
+ const t = P(o);
330
330
  if (!B.current) {
331
- l.current && (B.current = !0, R.current = u?.id ?? null, m(a, !0));
331
+ s.current && (B.current = !0, J.current = f?.id ?? null, h(o, !0));
332
332
  return;
333
333
  }
334
- if (!l.current) return;
335
- const e = u?.id ?? null;
336
- if (R.current !== e) {
337
- R.current = e, m(a, !1);
334
+ if (!s.current) return;
335
+ const e = f?.id ?? null;
336
+ if (J.current !== e) {
337
+ J.current = e, h(o, !1);
338
338
  return;
339
339
  }
340
- if (A.current === t)
340
+ if (_.current === t)
341
341
  return;
342
- const o = Q(
343
- _.current || a,
344
- a,
345
- u?.id
342
+ const i = E.current ? JSON.stringify(E.current.theme) : null, l = JSON.stringify(o.theme);
343
+ if (i !== l) {
344
+ h(o, !1);
345
+ return;
346
+ }
347
+ const c = Q(
348
+ E.current || o,
349
+ o,
350
+ f?.id
346
351
  );
347
- if (o.length === 0) {
352
+ if (c.length === 0) {
348
353
  D.debug(
349
354
  "[Preview] Hash changed but no changes detected, forcing reload"
350
- ), m(a, !1);
355
+ ), h(o, !1);
351
356
  return;
352
357
  }
353
- if (o.some(
354
- (n) => n.blockId === "__structural__" || n.changedProps?.includes("children")
358
+ if (c.some(
359
+ (a) => a.blockId === "__structural__" || a.changedProps?.includes("children")
355
360
  )) {
356
- m(a, !1);
361
+ h(o, !1);
357
362
  return;
358
363
  }
359
- if (o.length === 1) {
360
- const n = o[0];
361
- if (!(n.changedProps || []).some(
362
- (d) => d === "children" || d === "header" || d === "content" || d === "footer"
364
+ if (c.length === 1) {
365
+ const a = c[0];
366
+ if (!(a.changedProps || []).some(
367
+ (p) => p === "children" || p === "header" || p === "content" || p === "footer"
363
368
  )) {
364
- O(n.blockId, a);
369
+ G(a.blockId, o);
365
370
  return;
366
371
  }
367
372
  }
368
- m(a, !1);
369
- }, [a, u]), k(() => {
370
- B.current && L(i || null);
371
- }, [i, H]), k(() => {
372
- B.current && q(r);
373
- }, [r]), k(() => {
374
- if (!c) return;
373
+ h(o, !1);
374
+ }, [o, f]), x(() => {
375
+ B.current && L(n || null);
376
+ }, [n, H]), x(() => {
377
+ B.current && O(r);
378
+ }, [r]), x(() => {
379
+ if (!d) return;
375
380
  const t = (e) => {
376
- e.data?.type === "block-click" && e.data?.blockId && c(e.data.blockId, e.data.group || void 0);
381
+ e.data?.type === "block-click" && e.data?.blockId && d(e.data.blockId, e.data.group || void 0);
377
382
  };
378
383
  return window.addEventListener("message", t), () => {
379
384
  window.removeEventListener("message", t);
380
385
  };
381
- }, [c]), u ? /* @__PURE__ */ W("div", { className: s, style: { position: "relative", ...E }, children: [
382
- G && /* @__PURE__ */ C(
386
+ }, [d]), f ? /* @__PURE__ */ W("div", { className: u, style: { position: "relative", ...w }, children: [
387
+ $ && /* @__PURE__ */ C(
383
388
  "div",
384
389
  {
385
390
  style: {
@@ -400,7 +405,7 @@ function le({
400
405
  /* @__PURE__ */ C(
401
406
  "iframe",
402
407
  {
403
- ref: l,
408
+ ref: s,
404
409
  style: {
405
410
  width: "100%",
406
411
  height: "100%",
@@ -410,9 +415,9 @@ function le({
410
415
  title: "Preview do site"
411
416
  }
412
417
  )
413
- ] }) : /* @__PURE__ */ C("div", { className: s, style: E, children: /* @__PURE__ */ C("div", { style: { padding: "2rem", textAlign: "center", color: "#6b7280" }, children: "Página não encontrada" }) });
418
+ ] }) : /* @__PURE__ */ C("div", { className: u, style: w, children: /* @__PURE__ */ C("div", { style: { padding: "2rem", textAlign: "center", color: "#6b7280" }, children: "Página não encontrada" }) });
414
419
  }
415
420
  export {
416
- le as Preview
421
+ ae as Preview
417
422
  };
418
423
  //# sourceMappingURL=Preview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Preview.js","sources":["../../../src/engine/preview/Preview.tsx"],"sourcesContent":["/**\n * Preview\n * Sem dependências circulares, sem reloads desnecessários\n */\n\nimport React, { useEffect, useRef, useState, useMemo } from \"react\";\nimport { SiteDocument, Block } from \"../schema/siteDocument\";\nimport { componentRegistry } from \"../registry/registry\";\nimport { exportPageToHtml, exportBlockToHtml } from \"../export/exportHtml\";\nimport { detectChangedBlocks } from \"../../utils/changeDetector\";\nimport { hashDocument } from \"../../utils/documentHash\";\nimport { logger } from \"../../utils/logger\";\n\nexport interface PreviewProps {\n document: SiteDocument;\n pageId?: string;\n className?: string;\n style?: React.CSSProperties;\n onBlockClick?: (blockId: string, group?: string) => void;\n selectedBlockId?: string | null;\n /** Exibe hover e label de seleção nos blocos do preview */\n showSelectionOverlay?: boolean;\n /** Grupo focado para indicador visual no preview */\n focusedGroup?: string | null;\n}\n\n/**\n * Encontra um bloco na estrutura recursivamente\n */\nfunction findBlockInPage(page: any, blockId: string): Block | null {\n const findInBlocks = (blocks: Block[]): Block | null => {\n for (const block of blocks) {\n if (block.id === blockId) return block;\n const props = block.props as Record<string, any>;\n if (props?.children && Array.isArray(props.children)) {\n const found = findInBlocks(props.children);\n if (found) return found;\n }\n if (block.type === \"card\") {\n if (props.header && Array.isArray(props.header)) {\n const found = findInBlocks(props.header);\n if (found) return found;\n }\n if (props.content && Array.isArray(props.content)) {\n const found = findInBlocks(props.content);\n if (found) return found;\n }\n if (props.footer && Array.isArray(props.footer)) {\n const found = findInBlocks(props.footer);\n if (found) return found;\n }\n }\n }\n return null;\n };\n return findInBlocks(page.structure);\n}\n\n/**\n * Monta mapa blockId → nome legível (da registry)\n */\nfunction buildBlockNameMap(page: any): Record<string, string> {\n const map: Record<string, string> = {};\n const walk = (blocks: Block[]) => {\n for (const block of blocks) {\n const def = componentRegistry.get(block.type);\n map[block.id] = def?.name || block.type;\n const props = block.props as Record<string, any>;\n if (props?.children && Array.isArray(props.children)) walk(props.children);\n if (block.type === \"card\") {\n if (Array.isArray(props?.header)) walk(props.header);\n if (Array.isArray(props?.content)) walk(props.content);\n if (Array.isArray(props?.footer)) walk(props.footer);\n }\n }\n };\n if (page?.structure) walk(page.structure);\n return map;\n}\n\n/**\n * Componente de preview usando iframe isolado\n */\nexport function Preview({\n document,\n pageId,\n className,\n style,\n onBlockClick,\n selectedBlockId,\n showSelectionOverlay = false,\n focusedGroup = null,\n}: PreviewProps) {\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const previousDocRef = useRef<SiteDocument | null>(null);\n const previousDocHashRef = useRef<string | null>(null);\n const previousPageIdRef = useRef<string | null>(null);\n const isInitializedRef = useRef<boolean>(false);\n const [isLoading, setIsLoading] = useState(true);\n\n // Usar ref para selectedBlockId (necessário para highlight assíncrono)\n const selectedBlockIdRef = useRef(selectedBlockId);\n const showSelectionOverlayRef = useRef(showSelectionOverlay);\n const focusedGroupRef = useRef(focusedGroup);\n\n // Atualizar refs quando props mudam\n useEffect(() => {\n selectedBlockIdRef.current = selectedBlockId;\n }, [selectedBlockId]);\n\n useEffect(() => {\n showSelectionOverlayRef.current = showSelectionOverlay;\n }, [showSelectionOverlay]);\n\n useEffect(() => {\n focusedGroupRef.current = focusedGroup;\n }, [focusedGroup]);\n\n const page = useMemo(() => {\n return pageId\n ? document.pages.find((p) => p.id === pageId)\n : document.pages[0];\n }, [document, pageId]);\n\n // Mapa blockId → nome legível para labels\n const blockNameMapRef = useRef<Record<string, string>>({});\n useEffect(() => {\n blockNameMapRef.current = buildBlockNameMap(page);\n }, [page]);\n\n // Atualizar highlight + selection overlay diretamente no iframe (sem reload)\n const updateHighlight = (blockId: string | null) => {\n if (!iframeRef.current) return;\n\n const iframeDoc =\n iframeRef.current.contentDocument ||\n iframeRef.current.contentWindow?.document;\n if (!iframeDoc) return;\n\n const overlayEnabled = showSelectionOverlayRef.current;\n const group = focusedGroupRef.current;\n\n requestAnimationFrame(() => {\n // Remover highlight anterior\n const oldStyle = iframeDoc.getElementById(\"block-highlight\");\n if (oldStyle) oldStyle.remove();\n\n const allBlocks = iframeDoc.querySelectorAll(\"[data-block-id]\");\n allBlocks.forEach((el) => {\n const htmlEl = el as HTMLElement;\n htmlEl.style.outline = \"\";\n htmlEl.style.outlineOffset = \"\";\n });\n\n // Remover labels anteriores\n const oldLabel = iframeDoc.getElementById(\"sg-block-label\");\n if (oldLabel) oldLabel.remove();\n const oldGroupStyle = iframeDoc.getElementById(\"sg-group-highlight\");\n if (oldGroupStyle) oldGroupStyle.remove();\n const oldGroupLabel = iframeDoc.getElementById(\"sg-group-label\");\n if (oldGroupLabel) oldGroupLabel.remove();\n\n // Adicionar novo highlight\n if (blockId) {\n const highlightStyle = iframeDoc.createElement(\"style\");\n highlightStyle.id = \"block-highlight\";\n highlightStyle.textContent = `\n [data-block-id=\"${blockId}\"] {\n outline: 2px solid #3b82f6 !important;\n outline-offset: 2px !important;\n position: relative;\n }\n [data-block-id=\"${blockId}\"]::before {\n content: '';\n position: absolute;\n top: -4px;\n left: -4px;\n right: -4px;\n bottom: -4px;\n background: rgba(59, 130, 246, 0.1);\n pointer-events: none;\n z-index: -1;\n }\n `;\n iframeDoc.head.appendChild(highlightStyle);\n\n // Selection label (only when overlay is enabled)\n if (overlayEnabled) {\n const selectedEl = iframeDoc.querySelector(`[data-block-id=\"${blockId}\"]`) as HTMLElement;\n if (selectedEl) {\n const blockName = blockNameMapRef.current[blockId] || blockId;\n const label = iframeDoc.createElement(\"div\");\n label.id = \"sg-block-label\";\n label.textContent = blockName;\n label.style.cssText = \"position:absolute;top:-22px;left:0;background:#3b82f6;color:#fff;font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px 4px 0 0;z-index:10000;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:16px;\";\n const pos = getComputedStyle(selectedEl).position;\n if (pos === \"static\") selectedEl.style.position = \"relative\";\n selectedEl.appendChild(label);\n }\n }\n\n // Indicador de grupo — mostra qual sub-seção foi clicada (purple)\n if (group) {\n const blockEl = iframeDoc.querySelector(`[data-block-id=\"${blockId}\"]`);\n const groupEl = blockEl?.querySelector(`[data-block-group=\"${group}\"]`) as HTMLElement;\n if (groupEl) {\n const ghStyle = iframeDoc.createElement(\"style\");\n ghStyle.id = \"sg-group-highlight\";\n ghStyle.textContent = `\n [data-block-id=\"${blockId}\"] [data-block-group=\"${group}\"] {\n outline: 2px solid #8b5cf6 !important;\n outline-offset: 2px !important;\n position: relative;\n }\n `;\n iframeDoc.head.appendChild(ghStyle);\n\n const gLabel = iframeDoc.createElement(\"div\");\n gLabel.id = \"sg-group-label\";\n gLabel.textContent = group;\n gLabel.style.cssText = \"position:absolute;top:-20px;right:0;background:#8b5cf6;color:#fff;font-size:10px;font-weight:600;padding:2px 8px;border-radius:4px 4px 0 0;z-index:10001;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:14px;\";\n const gPos = getComputedStyle(groupEl).position;\n if (gPos === \"static\") groupEl.style.position = \"relative\";\n groupEl.appendChild(gLabel);\n }\n }\n }\n });\n };\n\n // Enviar mapa de nomes para o iframe\n const sendBlockNamesToIframe = () => {\n if (!iframeRef.current?.contentWindow) return;\n iframeRef.current.contentWindow.postMessage({\n type: \"sg-set-block-names\",\n names: blockNameMapRef.current,\n }, \"*\");\n };\n\n // Atualizar hover overlay (injetar/remover CSS de hover nos blocos)\n const updateSelectionOverlay = (enabled: boolean) => {\n if (!iframeRef.current) return;\n\n const iframeDoc =\n iframeRef.current.contentDocument ||\n iframeRef.current.contentWindow?.document;\n if (!iframeDoc) return;\n\n const existingStyle = iframeDoc.getElementById(\"sg-hover-overlay\");\n if (existingStyle) existingStyle.remove();\n\n // Remove tooltip when disabling\n if (!enabled) {\n const tooltip = iframeDoc.getElementById(\"sg-hover-tooltip\");\n if (tooltip) tooltip.style.opacity = \"0\";\n }\n\n if (enabled) {\n const hoverStyle = iframeDoc.createElement(\"style\");\n hoverStyle.id = \"sg-hover-overlay\";\n hoverStyle.textContent = `\n [data-block-id] {\n cursor: pointer;\n transition: outline 0.15s ease, outline-offset 0.15s ease;\n }\n [data-block-id]:hover {\n outline: 2px dashed #94a3b8 !important;\n outline-offset: 2px !important;\n }\n [data-block-group] {\n cursor: pointer;\n transition: outline 0.15s ease, background 0.15s ease;\n }\n [data-block-group]:hover {\n outline: 1.5px dashed #a78bfa !important;\n outline-offset: 1px !important;\n background: rgba(139, 92, 246, 0.04);\n }\n `;\n iframeDoc.head.appendChild(hoverStyle);\n sendBlockNamesToIframe();\n }\n\n // Re-apply highlight (recalcula label)\n updateHighlight(selectedBlockIdRef.current || null);\n };\n\n // Atualizar preview completo (com srcdoc - causa reload)\n const updateFullPreview = (doc: SiteDocument, showLoading: boolean) => {\n if (!iframeRef.current || !page) return;\n\n try {\n if (showLoading) {\n setIsLoading(true);\n }\n\n let html = exportPageToHtml(page, doc, true);\n\n // Adicionar click handler + hover handler: links não navegam, enviam editor-navigate; outros cliques enviam block-click\n const clickHandler = `\n <script>\n (function() {\n // Click handler\n document.addEventListener('click', function(e) {\n var target = e.target;\n var anchor = target;\n while (anchor && anchor.tagName !== 'A') {\n anchor = anchor.parentElement;\n }\n if (anchor && anchor.tagName === 'A' && anchor.href) {\n e.preventDefault();\n e.stopPropagation();\n window.parent.postMessage({\n type: 'editor-navigate',\n href: anchor.getAttribute('href') || anchor.href\n }, '*');\n return;\n }\n var element = target;\n var group = null;\n while (element && !element.dataset.blockId) {\n if (element.dataset && element.dataset.blockGroup && !group) {\n group = element.dataset.blockGroup;\n }\n element = element.parentElement;\n }\n if (element && element.dataset.blockId) {\n window.parent.postMessage({\n type: 'block-click',\n blockId: element.dataset.blockId,\n group: group\n }, '*');\n }\n }, true);\n\n // Hover tooltip — block name map injected from parent via postMessage\n var _blockNames = {};\n var _hoverTooltip = null;\n\n window.addEventListener('message', function(e) {\n if (e.data && e.data.type === 'sg-set-block-names') {\n _blockNames = e.data.names || {};\n }\n });\n\n function getTooltip() {\n if (_hoverTooltip) return _hoverTooltip;\n _hoverTooltip = document.createElement('div');\n _hoverTooltip.id = 'sg-hover-tooltip';\n _hoverTooltip.style.cssText = 'position:fixed;top:0;left:0;background:#334155;color:#fff;font-size:11px;font-weight:500;padding:3px 8px;border-radius:4px;z-index:99999;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:16px;opacity:0;transition:opacity 0.12s ease;box-shadow:0 2px 6px rgba(0,0,0,0.2);';\n document.body.appendChild(_hoverTooltip);\n return _hoverTooltip;\n }\n\n var _currentHoveredBlock = null;\n var _currentHoveredGroup = null;\n\n document.addEventListener('mouseover', function(e) {\n // Check if hover overlay is active\n if (!document.getElementById('sg-hover-overlay')) return;\n var el = e.target;\n var groupName = null;\n while (el && !el.dataset.blockId) {\n if (el.dataset && el.dataset.blockGroup && !groupName) {\n groupName = el.dataset.blockGroup;\n }\n el = el.parentElement;\n }\n if (el && el.dataset.blockId) {\n if (el !== _currentHoveredBlock || groupName !== _currentHoveredGroup) {\n _currentHoveredBlock = el;\n _currentHoveredGroup = groupName;\n var tt = getTooltip();\n var blockName = _blockNames[el.dataset.blockId] || el.dataset.blockId;\n tt.textContent = groupName ? (blockName + ' \\\\u203A ' + groupName) : blockName;\n tt.style.opacity = '1';\n }\n }\n }, true);\n\n document.addEventListener('mousemove', function(e) {\n if (_hoverTooltip && _hoverTooltip.style.opacity === '1') {\n _hoverTooltip.style.left = (e.clientX + 12) + 'px';\n _hoverTooltip.style.top = (e.clientY - 28) + 'px';\n }\n }, true);\n\n document.addEventListener('mouseout', function(e) {\n var el = e.target;\n while (el && !el.dataset.blockId) el = el.parentElement;\n if (el === _currentHoveredBlock) {\n var related = e.relatedTarget;\n while (related && related !== el) related = related.parentElement;\n if (!related) {\n _currentHoveredBlock = null;\n _currentHoveredGroup = null;\n if (_hoverTooltip) _hoverTooltip.style.opacity = '0';\n }\n }\n }, true);\n })();\n </script>\n `;\n html = html.replace(\"</body>\", `${clickHandler}</body>`);\n if (!html.includes(\"</body>\")) {\n html = html + clickHandler;\n }\n\n const iframe = iframeRef.current;\n\n const applyOverlayAfterLoad = () => {\n updateHighlight(selectedBlockIdRef.current || null);\n if (showSelectionOverlayRef.current) {\n updateSelectionOverlay(true);\n }\n };\n\n if (showLoading) {\n iframe.onload = () => {\n setIsLoading(false);\n previousDocRef.current = JSON.parse(JSON.stringify(doc));\n previousDocHashRef.current = hashDocument(doc);\n applyOverlayAfterLoad();\n };\n setTimeout(() => {\n setIsLoading(false);\n previousDocRef.current = JSON.parse(JSON.stringify(doc));\n previousDocHashRef.current = hashDocument(doc);\n applyOverlayAfterLoad();\n }, 1000);\n } else {\n previousDocRef.current = JSON.parse(JSON.stringify(doc));\n previousDocHashRef.current = hashDocument(doc);\n iframe.onload = () => {\n applyOverlayAfterLoad();\n };\n }\n\n iframe.srcdoc = html;\n } catch (error) {\n logger.error(\"[Preview] Error:\", error);\n if (showLoading) {\n setIsLoading(false);\n }\n }\n };\n\n // Atualizar apenas um bloco (sem reload)\n const updatePartialPreview = (blockId: string, doc: SiteDocument) => {\n if (!iframeRef.current || !page) return;\n\n try {\n const block = findBlockInPage(page, blockId);\n if (!block) {\n updateFullPreview(doc, false);\n return;\n }\n\n const blockHtml = exportBlockToHtml(block, undefined, doc.theme);\n\n requestAnimationFrame(() => {\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n const iframeDoc =\n iframe.contentDocument || iframe.contentWindow?.document;\n if (!iframeDoc) return;\n\n const element = iframeDoc.querySelector(`[data-block-id=\"${blockId}\"]`);\n if (element) {\n try {\n // Remover <style> tags antigas associadas a este bloco\n const oldStyles = iframeDoc.querySelectorAll(`style[data-block-style=\"${blockId}\"]`);\n oldStyles.forEach(s => s.remove());\n\n const temp = iframeDoc.createElement(\"div\");\n temp.innerHTML = blockHtml;\n\n // Marcar e extrair <style> tags para inserção separada\n const styleTags = temp.querySelectorAll(\"style\");\n styleTags.forEach(style => {\n style.setAttribute(\"data-block-style\", blockId);\n });\n\n // Usar DocumentFragment para substituir com múltiplos elementos irmãos\n // (ex: <style>hover CSS</style><button>text</button>)\n const fragment = iframeDoc.createDocumentFragment();\n while (temp.firstChild) {\n fragment.appendChild(temp.firstChild);\n }\n\n if (fragment.childNodes.length > 0) {\n element.parentNode?.replaceChild(fragment, element);\n } else {\n element.outerHTML = blockHtml;\n }\n\n // Atualizar refs\n previousDocRef.current = JSON.parse(JSON.stringify(doc));\n previousDocHashRef.current = hashDocument(doc);\n\n // Reaplicar highlight\n updateHighlight(selectedBlockIdRef.current || null);\n } catch (error) {\n logger.error(\"[Preview] Erro ao atualizar:\", error);\n updateFullPreview(doc, false);\n }\n } else {\n updateFullPreview(doc, false);\n }\n });\n } catch (error) {\n logger.error(\"[Preview] Erro:\", error);\n updateFullPreview(doc, false);\n }\n };\n\n // Efeito para mudanças no DOCUMENTO (não no selectedBlockId)\n useEffect(() => {\n if (!page) {\n setIsLoading(false);\n return;\n }\n\n const currentDocHash = hashDocument(document);\n\n // Primeira renderização\n if (!isInitializedRef.current) {\n if (iframeRef.current) {\n isInitializedRef.current = true;\n previousPageIdRef.current = page?.id ?? null;\n updateFullPreview(document, true);\n }\n return;\n }\n\n if (!iframeRef.current) return;\n\n // Detectar troca de página (pageId mudou)\n const currentPageId = page?.id ?? null;\n if (previousPageIdRef.current !== currentPageId) {\n previousPageIdRef.current = currentPageId;\n updateFullPreview(document, false);\n return;\n }\n\n // Se hash não mudou, não há mudanças no documento\n if (previousDocHashRef.current === currentDocHash) {\n return;\n }\n\n // Detectar mudanças na página atual\n const changedBlocks = detectChangedBlocks(\n previousDocRef.current || document,\n document,\n page?.id,\n );\n\n // Se não há mudanças detectadas mas o hash mudou, forçar reload\n if (changedBlocks.length === 0) {\n logger.debug(\n \"[Preview] Hash changed but no changes detected, forcing reload\",\n );\n updateFullPreview(document, false);\n return;\n }\n\n // Mudança estrutural (bloco adicionado/removido) = reload completo\n if (\n changedBlocks.some(\n (c) =>\n c.blockId === \"__structural__\" ||\n c.changedProps?.includes(\"children\"),\n )\n ) {\n updateFullPreview(document, false);\n return;\n }\n\n // Mudança de 1 bloco (não estrutural) = atualização parcial\n if (changedBlocks.length === 1) {\n const change = changedBlocks[0];\n const changedProps = change.changedProps || [];\n\n const isStructural = changedProps.some(\n (prop) =>\n prop === \"children\" ||\n prop === \"header\" ||\n prop === \"content\" ||\n prop === \"footer\",\n );\n\n if (!isStructural) {\n updatePartialPreview(change.blockId, document);\n return;\n }\n }\n\n // Fallback: reload completo SEM loader\n updateFullPreview(document, false);\n }, [document, page]); // APENAS document e page - sem funções\n\n // Efeito SEPARADO para highlight (não recarrega o preview)\n useEffect(() => {\n if (!isInitializedRef.current) return;\n updateHighlight(selectedBlockId || null);\n }, [selectedBlockId, focusedGroup]); // eslint-disable-line react-hooks/exhaustive-deps -- updateHighlight reads focusedGroupRef\n\n // Efeito para toggle do selection overlay\n useEffect(() => {\n if (!isInitializedRef.current) return;\n updateSelectionOverlay(showSelectionOverlay);\n }, [showSelectionOverlay]); // eslint-disable-line react-hooks/exhaustive-deps -- same pattern as updateFullPreview\n\n // Listener para cliques\n useEffect(() => {\n if (!onBlockClick) return;\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === \"block-click\" && event.data?.blockId) {\n onBlockClick(event.data.blockId, event.data.group || undefined);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => {\n window.removeEventListener(\"message\", handleMessage);\n };\n }, [onBlockClick]);\n\n if (!page) {\n return (\n <div className={className} style={style}>\n <div style={{ padding: \"2rem\", textAlign: \"center\", color: \"#6b7280\" }}>\n Página não encontrada\n </div>\n </div>\n );\n }\n\n return (\n <div className={className} style={{ position: \"relative\", ...style }}>\n {isLoading && (\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(255, 255, 255, 0.8)\",\n zIndex: 10,\n }}\n >\n <div style={{ color: \"#6b7280\" }}>Carregando preview...</div>\n </div>\n )}\n <iframe\n ref={iframeRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n border: \"none\",\n backgroundColor: \"#ffffff\",\n }}\n title=\"Preview do site\"\n />\n </div>\n );\n}\n"],"names":["findBlockInPage","page","blockId","findInBlocks","blocks","block","props","found","buildBlockNameMap","map","walk","def","componentRegistry","Preview","document","pageId","className","style","onBlockClick","selectedBlockId","showSelectionOverlay","focusedGroup","iframeRef","useRef","previousDocRef","previousDocHashRef","previousPageIdRef","isInitializedRef","isLoading","setIsLoading","useState","selectedBlockIdRef","showSelectionOverlayRef","focusedGroupRef","useEffect","useMemo","p","blockNameMapRef","updateHighlight","iframeDoc","overlayEnabled","group","oldStyle","el","htmlEl","oldLabel","oldGroupStyle","oldGroupLabel","highlightStyle","selectedEl","blockName","label","groupEl","ghStyle","gLabel","sendBlockNamesToIframe","updateSelectionOverlay","enabled","existingStyle","tooltip","hoverStyle","updateFullPreview","doc","showLoading","html","exportPageToHtml","clickHandler","iframe","applyOverlayAfterLoad","hashDocument","error","logger","updatePartialPreview","blockHtml","exportBlockToHtml","element","s","temp","fragment","currentDocHash","currentPageId","changedBlocks","detectChangedBlocks","c","change","prop","handleMessage","event","jsxs","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Preview.js","sources":["../../../src/engine/preview/Preview.tsx"],"sourcesContent":["/**\n * Preview\n * Sem dependências circulares, sem reloads desnecessários\n */\n\nimport React, { useEffect, useRef, useState, useMemo } from \"react\";\nimport { SiteDocument, Block } from \"../schema/siteDocument\";\nimport { componentRegistry } from \"../registry/registry\";\nimport { exportPageToHtml, exportBlockToHtml } from \"../export/exportHtml\";\nimport { detectChangedBlocks } from \"../../utils/changeDetector\";\nimport { hashDocument } from \"../../utils/documentHash\";\nimport { logger } from \"../../utils/logger\";\n\nexport interface PreviewProps {\n document: SiteDocument;\n pageId?: string;\n className?: string;\n style?: React.CSSProperties;\n onBlockClick?: (blockId: string, group?: string) => void;\n selectedBlockId?: string | null;\n /** Exibe hover e label de seleção nos blocos do preview */\n showSelectionOverlay?: boolean;\n /** Grupo focado para indicador visual no preview */\n focusedGroup?: string | null;\n}\n\n/**\n * Encontra um bloco na estrutura recursivamente\n */\nfunction findBlockInPage(page: any, blockId: string): Block | null {\n const findInBlocks = (blocks: Block[]): Block | null => {\n for (const block of blocks) {\n if (block.id === blockId) return block;\n const props = block.props as Record<string, any>;\n if (props?.children && Array.isArray(props.children)) {\n const found = findInBlocks(props.children);\n if (found) return found;\n }\n if (block.type === \"card\") {\n if (props.header && Array.isArray(props.header)) {\n const found = findInBlocks(props.header);\n if (found) return found;\n }\n if (props.content && Array.isArray(props.content)) {\n const found = findInBlocks(props.content);\n if (found) return found;\n }\n if (props.footer && Array.isArray(props.footer)) {\n const found = findInBlocks(props.footer);\n if (found) return found;\n }\n }\n }\n return null;\n };\n return findInBlocks(page.structure);\n}\n\n/**\n * Monta mapa blockId → nome legível (da registry)\n */\nfunction buildBlockNameMap(page: any): Record<string, string> {\n const map: Record<string, string> = {};\n const walk = (blocks: Block[]) => {\n for (const block of blocks) {\n const def = componentRegistry.get(block.type);\n map[block.id] = def?.name || block.type;\n const props = block.props as Record<string, any>;\n if (props?.children && Array.isArray(props.children)) walk(props.children);\n if (block.type === \"card\") {\n if (Array.isArray(props?.header)) walk(props.header);\n if (Array.isArray(props?.content)) walk(props.content);\n if (Array.isArray(props?.footer)) walk(props.footer);\n }\n }\n };\n if (page?.structure) walk(page.structure);\n return map;\n}\n\n/**\n * Componente de preview usando iframe isolado\n */\nexport function Preview({\n document,\n pageId,\n className,\n style,\n onBlockClick,\n selectedBlockId,\n showSelectionOverlay = false,\n focusedGroup = null,\n}: PreviewProps) {\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const previousDocRef = useRef<SiteDocument | null>(null);\n const previousDocHashRef = useRef<string | null>(null);\n const previousPageIdRef = useRef<string | null>(null);\n const isInitializedRef = useRef<boolean>(false);\n const [isLoading, setIsLoading] = useState(true);\n\n // Usar ref para selectedBlockId (necessário para highlight assíncrono)\n const selectedBlockIdRef = useRef(selectedBlockId);\n const showSelectionOverlayRef = useRef(showSelectionOverlay);\n const focusedGroupRef = useRef(focusedGroup);\n\n // Atualizar refs quando props mudam\n useEffect(() => {\n selectedBlockIdRef.current = selectedBlockId;\n }, [selectedBlockId]);\n\n useEffect(() => {\n showSelectionOverlayRef.current = showSelectionOverlay;\n }, [showSelectionOverlay]);\n\n useEffect(() => {\n focusedGroupRef.current = focusedGroup;\n }, [focusedGroup]);\n\n const page = useMemo(() => {\n return pageId\n ? document.pages.find((p) => p.id === pageId)\n : document.pages[0];\n }, [document, pageId]);\n\n // Mapa blockId → nome legível para labels\n const blockNameMapRef = useRef<Record<string, string>>({});\n useEffect(() => {\n blockNameMapRef.current = buildBlockNameMap(page);\n }, [page]);\n\n // Atualizar highlight + selection overlay diretamente no iframe (sem reload)\n const updateHighlight = (blockId: string | null) => {\n if (!iframeRef.current) return;\n\n const iframeDoc =\n iframeRef.current.contentDocument ||\n iframeRef.current.contentWindow?.document;\n if (!iframeDoc) return;\n\n const overlayEnabled = showSelectionOverlayRef.current;\n const group = focusedGroupRef.current;\n\n requestAnimationFrame(() => {\n // Remover highlight anterior\n const oldStyle = iframeDoc.getElementById(\"block-highlight\");\n if (oldStyle) oldStyle.remove();\n\n const allBlocks = iframeDoc.querySelectorAll(\"[data-block-id]\");\n allBlocks.forEach((el) => {\n const htmlEl = el as HTMLElement;\n htmlEl.style.outline = \"\";\n htmlEl.style.outlineOffset = \"\";\n });\n\n // Remover labels anteriores\n const oldLabel = iframeDoc.getElementById(\"sg-block-label\");\n if (oldLabel) oldLabel.remove();\n const oldGroupStyle = iframeDoc.getElementById(\"sg-group-highlight\");\n if (oldGroupStyle) oldGroupStyle.remove();\n const oldGroupLabel = iframeDoc.getElementById(\"sg-group-label\");\n if (oldGroupLabel) oldGroupLabel.remove();\n\n // Adicionar novo highlight\n if (blockId) {\n const highlightStyle = iframeDoc.createElement(\"style\");\n highlightStyle.id = \"block-highlight\";\n highlightStyle.textContent = `\n [data-block-id=\"${blockId}\"] {\n outline: 2px solid #3b82f6 !important;\n outline-offset: 2px !important;\n position: relative;\n }\n [data-block-id=\"${blockId}\"]::before {\n content: '';\n position: absolute;\n top: -4px;\n left: -4px;\n right: -4px;\n bottom: -4px;\n background: rgba(59, 130, 246, 0.1);\n pointer-events: none;\n z-index: -1;\n }\n `;\n iframeDoc.head.appendChild(highlightStyle);\n\n // Selection label (only when overlay is enabled)\n if (overlayEnabled) {\n const selectedEl = iframeDoc.querySelector(`[data-block-id=\"${blockId}\"]`) as HTMLElement;\n if (selectedEl) {\n const blockName = blockNameMapRef.current[blockId] || blockId;\n const label = iframeDoc.createElement(\"div\");\n label.id = \"sg-block-label\";\n label.textContent = blockName;\n label.style.cssText = \"position:absolute;top:-22px;left:0;background:#3b82f6;color:#fff;font-size:11px;font-weight:600;padding:2px 8px;border-radius:4px 4px 0 0;z-index:10000;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:16px;\";\n const pos = getComputedStyle(selectedEl).position;\n if (pos === \"static\") selectedEl.style.position = \"relative\";\n selectedEl.appendChild(label);\n }\n }\n\n // Indicador de grupo — mostra qual sub-seção foi clicada (purple)\n if (group) {\n const blockEl = iframeDoc.querySelector(`[data-block-id=\"${blockId}\"]`);\n const groupEl = blockEl?.querySelector(`[data-block-group=\"${group}\"]`) as HTMLElement;\n if (groupEl) {\n const ghStyle = iframeDoc.createElement(\"style\");\n ghStyle.id = \"sg-group-highlight\";\n ghStyle.textContent = `\n [data-block-id=\"${blockId}\"] [data-block-group=\"${group}\"] {\n outline: 2px solid #8b5cf6 !important;\n outline-offset: 2px !important;\n position: relative;\n }\n `;\n iframeDoc.head.appendChild(ghStyle);\n\n const gLabel = iframeDoc.createElement(\"div\");\n gLabel.id = \"sg-group-label\";\n gLabel.textContent = group;\n gLabel.style.cssText = \"position:absolute;top:-20px;right:0;background:#8b5cf6;color:#fff;font-size:10px;font-weight:600;padding:2px 8px;border-radius:4px 4px 0 0;z-index:10001;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:14px;\";\n const gPos = getComputedStyle(groupEl).position;\n if (gPos === \"static\") groupEl.style.position = \"relative\";\n groupEl.appendChild(gLabel);\n }\n }\n }\n });\n };\n\n // Enviar mapa de nomes para o iframe\n const sendBlockNamesToIframe = () => {\n if (!iframeRef.current?.contentWindow) return;\n iframeRef.current.contentWindow.postMessage({\n type: \"sg-set-block-names\",\n names: blockNameMapRef.current,\n }, \"*\");\n };\n\n // Atualizar hover overlay (injetar/remover CSS de hover nos blocos)\n const updateSelectionOverlay = (enabled: boolean) => {\n if (!iframeRef.current) return;\n\n const iframeDoc =\n iframeRef.current.contentDocument ||\n iframeRef.current.contentWindow?.document;\n if (!iframeDoc) return;\n\n const existingStyle = iframeDoc.getElementById(\"sg-hover-overlay\");\n if (existingStyle) existingStyle.remove();\n\n // Remove tooltip when disabling\n if (!enabled) {\n const tooltip = iframeDoc.getElementById(\"sg-hover-tooltip\");\n if (tooltip) tooltip.style.opacity = \"0\";\n }\n\n if (enabled) {\n const hoverStyle = iframeDoc.createElement(\"style\");\n hoverStyle.id = \"sg-hover-overlay\";\n hoverStyle.textContent = `\n [data-block-id] {\n cursor: pointer;\n transition: outline 0.15s ease, outline-offset 0.15s ease;\n }\n [data-block-id]:hover {\n outline: 2px dashed #94a3b8 !important;\n outline-offset: 2px !important;\n }\n [data-block-group] {\n cursor: pointer;\n transition: outline 0.15s ease, background 0.15s ease;\n }\n [data-block-group]:hover {\n outline: 1.5px dashed #a78bfa !important;\n outline-offset: 1px !important;\n background: rgba(139, 92, 246, 0.04);\n }\n `;\n iframeDoc.head.appendChild(hoverStyle);\n sendBlockNamesToIframe();\n }\n\n // Re-apply highlight (recalcula label)\n updateHighlight(selectedBlockIdRef.current || null);\n };\n\n // Atualizar preview completo (com srcdoc - causa reload)\n const updateFullPreview = (doc: SiteDocument, showLoading: boolean) => {\n if (!iframeRef.current || !page) return;\n\n try {\n if (showLoading) {\n setIsLoading(true);\n }\n\n let html = exportPageToHtml(page, doc, true);\n\n // Adicionar click handler + hover handler: links não navegam, enviam editor-navigate; outros cliques enviam block-click\n const clickHandler = `\n <script>\n (function() {\n // Click handler\n document.addEventListener('click', function(e) {\n var target = e.target;\n var anchor = target;\n while (anchor && anchor.tagName !== 'A') {\n anchor = anchor.parentElement;\n }\n if (anchor && anchor.tagName === 'A' && anchor.href) {\n e.preventDefault();\n e.stopPropagation();\n window.parent.postMessage({\n type: 'editor-navigate',\n href: anchor.getAttribute('href') || anchor.href\n }, '*');\n return;\n }\n var element = target;\n var group = null;\n while (element && !element.dataset.blockId) {\n if (element.dataset && element.dataset.blockGroup && !group) {\n group = element.dataset.blockGroup;\n }\n element = element.parentElement;\n }\n if (element && element.dataset.blockId) {\n window.parent.postMessage({\n type: 'block-click',\n blockId: element.dataset.blockId,\n group: group\n }, '*');\n }\n }, true);\n\n // Hover tooltip — block name map injected from parent via postMessage\n var _blockNames = {};\n var _hoverTooltip = null;\n\n window.addEventListener('message', function(e) {\n if (e.data && e.data.type === 'sg-set-block-names') {\n _blockNames = e.data.names || {};\n }\n });\n\n function getTooltip() {\n if (_hoverTooltip) return _hoverTooltip;\n _hoverTooltip = document.createElement('div');\n _hoverTooltip.id = 'sg-hover-tooltip';\n _hoverTooltip.style.cssText = 'position:fixed;top:0;left:0;background:#334155;color:#fff;font-size:11px;font-weight:500;padding:3px 8px;border-radius:4px;z-index:99999;pointer-events:none;font-family:system-ui,sans-serif;white-space:nowrap;line-height:16px;opacity:0;transition:opacity 0.12s ease;box-shadow:0 2px 6px rgba(0,0,0,0.2);';\n document.body.appendChild(_hoverTooltip);\n return _hoverTooltip;\n }\n\n var _currentHoveredBlock = null;\n var _currentHoveredGroup = null;\n\n document.addEventListener('mouseover', function(e) {\n // Check if hover overlay is active\n if (!document.getElementById('sg-hover-overlay')) return;\n var el = e.target;\n var groupName = null;\n while (el && !el.dataset.blockId) {\n if (el.dataset && el.dataset.blockGroup && !groupName) {\n groupName = el.dataset.blockGroup;\n }\n el = el.parentElement;\n }\n if (el && el.dataset.blockId) {\n if (el !== _currentHoveredBlock || groupName !== _currentHoveredGroup) {\n _currentHoveredBlock = el;\n _currentHoveredGroup = groupName;\n var tt = getTooltip();\n var blockName = _blockNames[el.dataset.blockId] || el.dataset.blockId;\n tt.textContent = groupName ? (blockName + ' \\\\u203A ' + groupName) : blockName;\n tt.style.opacity = '1';\n }\n }\n }, true);\n\n document.addEventListener('mousemove', function(e) {\n if (_hoverTooltip && _hoverTooltip.style.opacity === '1') {\n _hoverTooltip.style.left = (e.clientX + 12) + 'px';\n _hoverTooltip.style.top = (e.clientY - 28) + 'px';\n }\n }, true);\n\n document.addEventListener('mouseout', function(e) {\n var el = e.target;\n while (el && !el.dataset.blockId) el = el.parentElement;\n if (el === _currentHoveredBlock) {\n var related = e.relatedTarget;\n while (related && related !== el) related = related.parentElement;\n if (!related) {\n _currentHoveredBlock = null;\n _currentHoveredGroup = null;\n if (_hoverTooltip) _hoverTooltip.style.opacity = '0';\n }\n }\n }, true);\n })();\n </script>\n `;\n html = html.replace(\"</body>\", `${clickHandler}</body>`);\n if (!html.includes(\"</body>\")) {\n html = html + clickHandler;\n }\n\n const iframe = iframeRef.current;\n\n const applyOverlayAfterLoad = () => {\n updateHighlight(selectedBlockIdRef.current || null);\n if (showSelectionOverlayRef.current) {\n updateSelectionOverlay(true);\n }\n };\n\n if (showLoading) {\n iframe.onload = () => {\n setIsLoading(false);\n previousDocRef.current = JSON.parse(JSON.stringify(doc));\n previousDocHashRef.current = hashDocument(doc);\n applyOverlayAfterLoad();\n };\n setTimeout(() => {\n setIsLoading(false);\n previousDocRef.current = JSON.parse(JSON.stringify(doc));\n previousDocHashRef.current = hashDocument(doc);\n applyOverlayAfterLoad();\n }, 1000);\n } else {\n previousDocRef.current = JSON.parse(JSON.stringify(doc));\n previousDocHashRef.current = hashDocument(doc);\n iframe.onload = () => {\n applyOverlayAfterLoad();\n };\n }\n\n iframe.srcdoc = html;\n } catch (error) {\n logger.error(\"[Preview] Error:\", error);\n if (showLoading) {\n setIsLoading(false);\n }\n }\n };\n\n // Atualizar apenas um bloco (sem reload)\n const updatePartialPreview = (blockId: string, doc: SiteDocument) => {\n if (!iframeRef.current || !page) return;\n\n try {\n const block = findBlockInPage(page, blockId);\n if (!block) {\n updateFullPreview(doc, false);\n return;\n }\n\n const blockHtml = exportBlockToHtml(block, undefined, doc.theme);\n\n requestAnimationFrame(() => {\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n const iframeDoc =\n iframe.contentDocument || iframe.contentWindow?.document;\n if (!iframeDoc) return;\n\n const element = iframeDoc.querySelector(`[data-block-id=\"${blockId}\"]`);\n if (element) {\n try {\n // Remover <style> tags antigas associadas a este bloco\n const oldStyles = iframeDoc.querySelectorAll(`style[data-block-style=\"${blockId}\"]`);\n oldStyles.forEach(s => s.remove());\n\n const temp = iframeDoc.createElement(\"div\");\n temp.innerHTML = blockHtml;\n\n // Marcar e extrair <style> tags para inserção separada\n const styleTags = temp.querySelectorAll(\"style\");\n styleTags.forEach(style => {\n style.setAttribute(\"data-block-style\", blockId);\n });\n\n // Usar DocumentFragment para substituir com múltiplos elementos irmãos\n // (ex: <style>hover CSS</style><button>text</button>)\n const fragment = iframeDoc.createDocumentFragment();\n while (temp.firstChild) {\n fragment.appendChild(temp.firstChild);\n }\n\n if (fragment.childNodes.length > 0) {\n element.parentNode?.replaceChild(fragment, element);\n } else {\n element.outerHTML = blockHtml;\n }\n\n // Atualizar refs\n previousDocRef.current = JSON.parse(JSON.stringify(doc));\n previousDocHashRef.current = hashDocument(doc);\n\n // Reaplicar highlight\n updateHighlight(selectedBlockIdRef.current || null);\n } catch (error) {\n logger.error(\"[Preview] Erro ao atualizar:\", error);\n updateFullPreview(doc, false);\n }\n } else {\n updateFullPreview(doc, false);\n }\n });\n } catch (error) {\n logger.error(\"[Preview] Erro:\", error);\n updateFullPreview(doc, false);\n }\n };\n\n // Efeito para mudanças no DOCUMENTO (não no selectedBlockId)\n useEffect(() => {\n if (!page) {\n setIsLoading(false);\n return;\n }\n\n const currentDocHash = hashDocument(document);\n\n // Primeira renderização\n if (!isInitializedRef.current) {\n if (iframeRef.current) {\n isInitializedRef.current = true;\n previousPageIdRef.current = page?.id ?? null;\n updateFullPreview(document, true);\n }\n return;\n }\n\n if (!iframeRef.current) return;\n\n // Detectar troca de página (pageId mudou)\n const currentPageId = page?.id ?? null;\n if (previousPageIdRef.current !== currentPageId) {\n previousPageIdRef.current = currentPageId;\n updateFullPreview(document, false);\n return;\n }\n\n // Se hash não mudou, não há mudanças no documento\n if (previousDocHashRef.current === currentDocHash) {\n return;\n }\n\n // Se o theme mudou, forçar reload completo (CSS variables precisam ser regeneradas)\n const prevThemeJson = previousDocRef.current ? JSON.stringify(previousDocRef.current.theme) : null;\n const currThemeJson = JSON.stringify(document.theme);\n if (prevThemeJson !== currThemeJson) {\n updateFullPreview(document, false);\n return;\n }\n\n // Detectar mudanças na página atual\n const changedBlocks = detectChangedBlocks(\n previousDocRef.current || document,\n document,\n page?.id,\n );\n\n // Se não há mudanças detectadas mas o hash mudou, forçar reload\n if (changedBlocks.length === 0) {\n logger.debug(\n \"[Preview] Hash changed but no changes detected, forcing reload\",\n );\n updateFullPreview(document, false);\n return;\n }\n\n // Mudança estrutural (bloco adicionado/removido) = reload completo\n if (\n changedBlocks.some(\n (c) =>\n c.blockId === \"__structural__\" ||\n c.changedProps?.includes(\"children\"),\n )\n ) {\n updateFullPreview(document, false);\n return;\n }\n\n // Mudança de 1 bloco (não estrutural) = atualização parcial\n if (changedBlocks.length === 1) {\n const change = changedBlocks[0];\n const changedProps = change.changedProps || [];\n\n const isStructural = changedProps.some(\n (prop) =>\n prop === \"children\" ||\n prop === \"header\" ||\n prop === \"content\" ||\n prop === \"footer\",\n );\n\n if (!isStructural) {\n updatePartialPreview(change.blockId, document);\n return;\n }\n }\n\n // Fallback: reload completo SEM loader\n updateFullPreview(document, false);\n }, [document, page]); // APENAS document e page - sem funções\n\n // Efeito SEPARADO para highlight (não recarrega o preview)\n useEffect(() => {\n if (!isInitializedRef.current) return;\n updateHighlight(selectedBlockId || null);\n }, [selectedBlockId, focusedGroup]); // eslint-disable-line react-hooks/exhaustive-deps -- updateHighlight reads focusedGroupRef\n\n // Efeito para toggle do selection overlay\n useEffect(() => {\n if (!isInitializedRef.current) return;\n updateSelectionOverlay(showSelectionOverlay);\n }, [showSelectionOverlay]); // eslint-disable-line react-hooks/exhaustive-deps -- same pattern as updateFullPreview\n\n // Listener para cliques\n useEffect(() => {\n if (!onBlockClick) return;\n\n const handleMessage = (event: MessageEvent) => {\n if (event.data?.type === \"block-click\" && event.data?.blockId) {\n onBlockClick(event.data.blockId, event.data.group || undefined);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => {\n window.removeEventListener(\"message\", handleMessage);\n };\n }, [onBlockClick]);\n\n if (!page) {\n return (\n <div className={className} style={style}>\n <div style={{ padding: \"2rem\", textAlign: \"center\", color: \"#6b7280\" }}>\n Página não encontrada\n </div>\n </div>\n );\n }\n\n return (\n <div className={className} style={{ position: \"relative\", ...style }}>\n {isLoading && (\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(255, 255, 255, 0.8)\",\n zIndex: 10,\n }}\n >\n <div style={{ color: \"#6b7280\" }}>Carregando preview...</div>\n </div>\n )}\n <iframe\n ref={iframeRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n border: \"none\",\n backgroundColor: \"#ffffff\",\n }}\n title=\"Preview do site\"\n />\n </div>\n );\n}\n"],"names":["findBlockInPage","page","blockId","findInBlocks","blocks","block","props","found","buildBlockNameMap","map","walk","def","componentRegistry","Preview","document","pageId","className","style","onBlockClick","selectedBlockId","showSelectionOverlay","focusedGroup","iframeRef","useRef","previousDocRef","previousDocHashRef","previousPageIdRef","isInitializedRef","isLoading","setIsLoading","useState","selectedBlockIdRef","showSelectionOverlayRef","focusedGroupRef","useEffect","useMemo","p","blockNameMapRef","updateHighlight","iframeDoc","overlayEnabled","group","oldStyle","el","htmlEl","oldLabel","oldGroupStyle","oldGroupLabel","highlightStyle","selectedEl","blockName","label","groupEl","ghStyle","gLabel","sendBlockNamesToIframe","updateSelectionOverlay","enabled","existingStyle","tooltip","hoverStyle","updateFullPreview","doc","showLoading","html","exportPageToHtml","clickHandler","iframe","applyOverlayAfterLoad","hashDocument","error","logger","updatePartialPreview","blockHtml","exportBlockToHtml","element","s","temp","fragment","currentDocHash","currentPageId","prevThemeJson","currThemeJson","changedBlocks","detectChangedBlocks","c","change","prop","handleMessage","event","jsxs","jsx"],"mappings":";;;;;;;AA6BA,SAASA,EAAgBC,GAAWC,GAA+B;AACjE,QAAMC,IAAe,CAACC,MAAkC;AACtD,eAAWC,KAASD,GAAQ;AAC1B,UAAIC,EAAM,OAAOH,EAAS,QAAOG;AACjC,YAAMC,IAAQD,EAAM;AACpB,UAAIC,GAAO,YAAY,MAAM,QAAQA,EAAM,QAAQ,GAAG;AACpD,cAAMC,IAAQJ,EAAaG,EAAM,QAAQ;AACzC,YAAIC,EAAO,QAAOA;AAAA,MACpB;AACA,UAAIF,EAAM,SAAS,QAAQ;AACzB,YAAIC,EAAM,UAAU,MAAM,QAAQA,EAAM,MAAM,GAAG;AAC/C,gBAAMC,IAAQJ,EAAaG,EAAM,MAAM;AACvC,cAAIC,EAAO,QAAOA;AAAA,QACpB;AACA,YAAID,EAAM,WAAW,MAAM,QAAQA,EAAM,OAAO,GAAG;AACjD,gBAAMC,IAAQJ,EAAaG,EAAM,OAAO;AACxC,cAAIC,EAAO,QAAOA;AAAA,QACpB;AACA,YAAID,EAAM,UAAU,MAAM,QAAQA,EAAM,MAAM,GAAG;AAC/C,gBAAMC,IAAQJ,EAAaG,EAAM,MAAM;AACvC,cAAIC,EAAO,QAAOA;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAOJ,EAAaF,EAAK,SAAS;AACpC;AAKA,SAASO,EAAkBP,GAAmC;AAC5D,QAAMQ,IAA8B,CAAA,GAC9BC,IAAO,CAACN,MAAoB;AAChC,eAAWC,KAASD,GAAQ;AAC1B,YAAMO,IAAMC,EAAkB,IAAIP,EAAM,IAAI;AAC5C,MAAAI,EAAIJ,EAAM,EAAE,IAAIM,GAAK,QAAQN,EAAM;AACnC,YAAMC,IAAQD,EAAM;AACpB,MAAIC,GAAO,YAAY,MAAM,QAAQA,EAAM,QAAQ,KAAGI,EAAKJ,EAAM,QAAQ,GACrED,EAAM,SAAS,WACb,MAAM,QAAQC,GAAO,MAAM,KAAGI,EAAKJ,EAAM,MAAM,GAC/C,MAAM,QAAQA,GAAO,OAAO,KAAGI,EAAKJ,EAAM,OAAO,GACjD,MAAM,QAAQA,GAAO,MAAM,KAAGI,EAAKJ,EAAM,MAAM;AAAA,IAEvD;AAAA,EACF;AACA,SAAIL,GAAM,aAAWS,EAAKT,EAAK,SAAS,GACjCQ;AACT;AAKO,SAASI,GAAQ;AAAA,EACtB,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,sBAAAC,IAAuB;AAAA,EACvB,cAAAC,IAAe;AACjB,GAAiB;AACf,QAAMC,IAAYC,EAA0B,IAAI,GAC1CC,IAAiBD,EAA4B,IAAI,GACjDE,IAAqBF,EAAsB,IAAI,GAC/CG,IAAoBH,EAAsB,IAAI,GAC9CI,IAAmBJ,EAAgB,EAAK,GACxC,CAACK,GAAWC,CAAY,IAAIC,EAAS,EAAI,GAGzCC,IAAqBR,EAAOJ,CAAe,GAC3Ca,IAA0BT,EAAOH,CAAoB,GACrDa,IAAkBV,EAAOF,CAAY;AAG3C,EAAAa,EAAU,MAAM;AACd,IAAAH,EAAmB,UAAUZ;AAAA,EAC/B,GAAG,CAACA,CAAe,CAAC,GAEpBe,EAAU,MAAM;AACd,IAAAF,EAAwB,UAAUZ;AAAA,EACpC,GAAG,CAACA,CAAoB,CAAC,GAEzBc,EAAU,MAAM;AACd,IAAAD,EAAgB,UAAUZ;AAAA,EAC5B,GAAG,CAACA,CAAY,CAAC;AAEjB,QAAMpB,IAAOkC,EAAQ,MACZpB,IACHD,EAAS,MAAM,KAAK,CAACsB,MAAMA,EAAE,OAAOrB,CAAM,IAC1CD,EAAS,MAAM,CAAC,GACnB,CAACA,GAAUC,CAAM,CAAC,GAGfsB,IAAkBd,EAA+B,EAAE;AACzD,EAAAW,EAAU,MAAM;AACd,IAAAG,EAAgB,UAAU7B,EAAkBP,CAAI;AAAA,EAClD,GAAG,CAACA,CAAI,CAAC;AAGT,QAAMqC,IAAkB,CAACpC,MAA2B;AAClD,QAAI,CAACoB,EAAU,QAAS;AAExB,UAAMiB,IACJjB,EAAU,QAAQ,mBAClBA,EAAU,QAAQ,eAAe;AACnC,QAAI,CAACiB,EAAW;AAEhB,UAAMC,IAAiBR,EAAwB,SACzCS,IAAQR,EAAgB;AAE9B,0BAAsB,MAAM;AAE1B,YAAMS,IAAWH,EAAU,eAAe,iBAAiB;AAC3D,MAAIG,OAAmB,OAAA,GAELH,EAAU,iBAAiB,iBAAiB,EACpD,QAAQ,CAACI,MAAO;AACxB,cAAMC,IAASD;AACf,QAAAC,EAAO,MAAM,UAAU,IACvBA,EAAO,MAAM,gBAAgB;AAAA,MAC/B,CAAC;AAGD,YAAMC,IAAWN,EAAU,eAAe,gBAAgB;AAC1D,MAAIM,OAAmB,OAAA;AACvB,YAAMC,IAAgBP,EAAU,eAAe,oBAAoB;AACnE,MAAIO,OAA6B,OAAA;AACjC,YAAMC,IAAgBR,EAAU,eAAe,gBAAgB;AAI/D,UAHIQ,OAA6B,OAAA,GAG7B7C,GAAS;AACX,cAAM8C,IAAiBT,EAAU,cAAc,OAAO;AAuBtD,YAtBAS,EAAe,KAAK,mBACpBA,EAAe,cAAc;AAAA,4BACT9C,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKPA,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAY3BqC,EAAU,KAAK,YAAYS,CAAc,GAGrCR,GAAgB;AAClB,gBAAMS,IAAaV,EAAU,cAAc,mBAAmBrC,CAAO,IAAI;AACzE,cAAI+C,GAAY;AACd,kBAAMC,IAAYb,EAAgB,QAAQnC,CAAO,KAAKA,GAChDiD,IAAQZ,EAAU,cAAc,KAAK;AAC3C,YAAAY,EAAM,KAAK,kBACXA,EAAM,cAAcD,GACpBC,EAAM,MAAM,UAAU,qPACV,iBAAiBF,CAAU,EAAE,aAC7B,aAAUA,EAAW,MAAM,WAAW,aAClDA,EAAW,YAAYE,CAAK;AAAA,UAC9B;AAAA,QACF;AAGA,YAAIV,GAAO;AAET,gBAAMW,IADUb,EAAU,cAAc,mBAAmBrC,CAAO,IAAI,GAC7C,cAAc,sBAAsBuC,CAAK,IAAI;AACtE,cAAIW,GAAS;AACX,kBAAMC,IAAUd,EAAU,cAAc,OAAO;AAC/C,YAAAc,EAAQ,KAAK,sBACbA,EAAQ,cAAc;AAAA,gCACFnD,CAAO,yBAAyBuC,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA,eAMzDF,EAAU,KAAK,YAAYc,CAAO;AAElC,kBAAMC,IAASf,EAAU,cAAc,KAAK;AAC5C,YAAAe,EAAO,KAAK,kBACZA,EAAO,cAAcb,GACrBa,EAAO,MAAM,UAAU,sPACV,iBAAiBF,CAAO,EAAE,aAC1B,aAAUA,EAAQ,MAAM,WAAW,aAChDA,EAAQ,YAAYE,CAAM;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,GAGMC,IAAyB,MAAM;AACnC,IAAKjC,EAAU,SAAS,iBACxBA,EAAU,QAAQ,cAAc,YAAY;AAAA,MAC1C,MAAM;AAAA,MACN,OAAOe,EAAgB;AAAA,IAAA,GACtB,GAAG;AAAA,EACR,GAGMmB,IAAyB,CAACC,MAAqB;AACnD,QAAI,CAACnC,EAAU,QAAS;AAExB,UAAMiB,IACJjB,EAAU,QAAQ,mBAClBA,EAAU,QAAQ,eAAe;AACnC,QAAI,CAACiB,EAAW;AAEhB,UAAMmB,IAAgBnB,EAAU,eAAe,kBAAkB;AAIjE,QAHImB,OAA6B,OAAA,GAG7B,CAACD,GAAS;AACZ,YAAME,IAAUpB,EAAU,eAAe,kBAAkB;AAC3D,MAAIoB,MAASA,EAAQ,MAAM,UAAU;AAAA,IACvC;AAEA,QAAIF,GAAS;AACX,YAAMG,IAAarB,EAAU,cAAc,OAAO;AAClD,MAAAqB,EAAW,KAAK,oBAChBA,EAAW,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAmBzBrB,EAAU,KAAK,YAAYqB,CAAU,GACrCL,EAAA;AAAA,IACF;AAGA,IAAAjB,EAAgBP,EAAmB,WAAW,IAAI;AAAA,EACpD,GAGM8B,IAAoB,CAACC,GAAmBC,MAAyB;AACrE,QAAI,GAACzC,EAAU,WAAW,CAACrB;AAE3B,UAAI;AACF,QAAI8D,KACFlC,EAAa,EAAI;AAGnB,YAAImC,IAAOC,EAAiBhE,GAAM6D,GAAK,EAAI;AAG3C,cAAMI,IAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwGrB,QAAAF,IAAOA,EAAK,QAAQ,WAAW,GAAGE,CAAY,SAAS,GAClDF,EAAK,SAAS,SAAS,MAC1BA,IAAOA,IAAOE;AAGhB,cAAMC,IAAS7C,EAAU,SAEnB8C,IAAwB,MAAM;AAClC,UAAA9B,EAAgBP,EAAmB,WAAW,IAAI,GAC9CC,EAAwB,WAC1BwB,EAAuB,EAAI;AAAA,QAE/B;AAEA,QAAIO,KACFI,EAAO,SAAS,MAAM;AACpB,UAAAtC,EAAa,EAAK,GAClBL,EAAe,UAAU,KAAK,MAAM,KAAK,UAAUsC,CAAG,CAAC,GACvDrC,EAAmB,UAAU4C,EAAaP,CAAG,GAC7CM,EAAA;AAAA,QACF,GACA,WAAW,MAAM;AACf,UAAAvC,EAAa,EAAK,GAClBL,EAAe,UAAU,KAAK,MAAM,KAAK,UAAUsC,CAAG,CAAC,GACvDrC,EAAmB,UAAU4C,EAAaP,CAAG,GAC7CM,EAAA;AAAA,QACF,GAAG,GAAI,MAEP5C,EAAe,UAAU,KAAK,MAAM,KAAK,UAAUsC,CAAG,CAAC,GACvDrC,EAAmB,UAAU4C,EAAaP,CAAG,GAC7CK,EAAO,SAAS,MAAM;AACpB,UAAAC,EAAA;AAAA,QACF,IAGFD,EAAO,SAASH;AAAA,MAClB,SAASM,GAAO;AACd,QAAAC,EAAO,MAAM,oBAAoBD,CAAK,GAClCP,KACFlC,EAAa,EAAK;AAAA,MAEtB;AAAA,EACF,GAGM2C,IAAuB,CAACtE,GAAiB4D,MAAsB;AACnE,QAAI,GAACxC,EAAU,WAAW,CAACrB;AAE3B,UAAI;AACF,cAAMI,IAAQL,EAAgBC,GAAMC,CAAO;AAC3C,YAAI,CAACG,GAAO;AACV,UAAAwD,EAAkBC,GAAK,EAAK;AAC5B;AAAA,QACF;AAEA,cAAMW,IAAYC,EAAkBrE,GAAO,QAAWyD,EAAI,KAAK;AAE/D,8BAAsB,MAAM;AAC1B,gBAAMK,IAAS7C,EAAU;AACzB,cAAI,CAAC6C,EAAQ;AAEb,gBAAM5B,IACJ4B,EAAO,mBAAmBA,EAAO,eAAe;AAClD,cAAI,CAAC5B,EAAW;AAEhB,gBAAMoC,IAAUpC,EAAU,cAAc,mBAAmBrC,CAAO,IAAI;AACtE,cAAIyE;AACF,gBAAI;AAGF,cADkBpC,EAAU,iBAAiB,2BAA2BrC,CAAO,IAAI,EACzE,QAAQ,CAAA0E,MAAKA,EAAE,OAAA,CAAQ;AAEjC,oBAAMC,IAAOtC,EAAU,cAAc,KAAK;AAC1C,cAAAsC,EAAK,YAAYJ,GAGCI,EAAK,iBAAiB,OAAO,EACrC,QAAQ,CAAA5D,MAAS;AACzBA,gBAAAA,EAAM,aAAa,oBAAoBf,CAAO;AAAA,cAChD,CAAC;AAID,oBAAM4E,IAAWvC,EAAU,uBAAA;AAC3B,qBAAOsC,EAAK;AACV,gBAAAC,EAAS,YAAYD,EAAK,UAAU;AAGtC,cAAIC,EAAS,WAAW,SAAS,IAC/BH,EAAQ,YAAY,aAAaG,GAAUH,CAAO,IAElDA,EAAQ,YAAYF,GAItBjD,EAAe,UAAU,KAAK,MAAM,KAAK,UAAUsC,CAAG,CAAC,GACvDrC,EAAmB,UAAU4C,EAAaP,CAAG,GAG7CxB,EAAgBP,EAAmB,WAAW,IAAI;AAAA,YACpD,SAASuC,GAAO;AACd,cAAAC,EAAO,MAAM,gCAAgCD,CAAK,GAClDT,EAAkBC,GAAK,EAAK;AAAA,YAC9B;AAAA;AAEA,YAAAD,EAAkBC,GAAK,EAAK;AAAA,QAEhC,CAAC;AAAA,MACH,SAASQ,GAAO;AACd,QAAAC,EAAO,MAAM,mBAAmBD,CAAK,GACrCT,EAAkBC,GAAK,EAAK;AAAA,MAC9B;AAAA,EACF;AA2HA,SAxHA5B,EAAU,MAAM;AACd,QAAI,CAACjC,GAAM;AACT,MAAA4B,EAAa,EAAK;AAClB;AAAA,IACF;AAEA,UAAMkD,IAAiBV,EAAavD,CAAQ;AAG5C,QAAI,CAACa,EAAiB,SAAS;AAC7B,MAAIL,EAAU,YACZK,EAAiB,UAAU,IAC3BD,EAAkB,UAAUzB,GAAM,MAAM,MACxC4D,EAAkB/C,GAAU,EAAI;AAElC;AAAA,IACF;AAEA,QAAI,CAACQ,EAAU,QAAS;AAGxB,UAAM0D,IAAgB/E,GAAM,MAAM;AAClC,QAAIyB,EAAkB,YAAYsD,GAAe;AAC/C,MAAAtD,EAAkB,UAAUsD,GAC5BnB,EAAkB/C,GAAU,EAAK;AACjC;AAAA,IACF;AAGA,QAAIW,EAAmB,YAAYsD;AACjC;AAIF,UAAME,IAAgBzD,EAAe,UAAU,KAAK,UAAUA,EAAe,QAAQ,KAAK,IAAI,MACxF0D,IAAgB,KAAK,UAAUpE,EAAS,KAAK;AACnD,QAAImE,MAAkBC,GAAe;AACnC,MAAArB,EAAkB/C,GAAU,EAAK;AACjC;AAAA,IACF;AAGA,UAAMqE,IAAgBC;AAAA,MACpB5D,EAAe,WAAWV;AAAA,MAC1BA;AAAA,MACAb,GAAM;AAAA,IAAA;AAIR,QAAIkF,EAAc,WAAW,GAAG;AAC9B,MAAAZ,EAAO;AAAA,QACL;AAAA,MAAA,GAEFV,EAAkB/C,GAAU,EAAK;AACjC;AAAA,IACF;AAGA,QACEqE,EAAc;AAAA,MACZ,CAACE,MACCA,EAAE,YAAY,oBACdA,EAAE,cAAc,SAAS,UAAU;AAAA,IAAA,GAEvC;AACA,MAAAxB,EAAkB/C,GAAU,EAAK;AACjC;AAAA,IACF;AAGA,QAAIqE,EAAc,WAAW,GAAG;AAC9B,YAAMG,IAASH,EAAc,CAAC;AAW9B,UAAI,EAViBG,EAAO,gBAAgB,CAAA,GAEV;AAAA,QAChC,CAACC,MACCA,MAAS,cACTA,MAAS,YACTA,MAAS,aACTA,MAAS;AAAA,MAAA,GAGM;AACjB,QAAAf,EAAqBc,EAAO,SAASxE,CAAQ;AAC7C;AAAA,MACF;AAAA,IACF;AAGA,IAAA+C,EAAkB/C,GAAU,EAAK;AAAA,EACnC,GAAG,CAACA,GAAUb,CAAI,CAAC,GAGnBiC,EAAU,MAAM;AACd,IAAKP,EAAiB,WACtBW,EAAgBnB,KAAmB,IAAI;AAAA,EACzC,GAAG,CAACA,GAAiBE,CAAY,CAAC,GAGlCa,EAAU,MAAM;AACd,IAAKP,EAAiB,WACtB6B,EAAuBpC,CAAoB;AAAA,EAC7C,GAAG,CAACA,CAAoB,CAAC,GAGzBc,EAAU,MAAM;AACd,QAAI,CAAChB,EAAc;AAEnB,UAAMsE,IAAgB,CAACC,MAAwB;AAC7C,MAAIA,EAAM,MAAM,SAAS,iBAAiBA,EAAM,MAAM,WACpDvE,EAAauE,EAAM,KAAK,SAASA,EAAM,KAAK,SAAS,MAAS;AAAA,IAElE;AAEA,kBAAO,iBAAiB,WAAWD,CAAa,GACzC,MAAM;AACX,aAAO,oBAAoB,WAAWA,CAAa;AAAA,IACrD;AAAA,EACF,GAAG,CAACtE,CAAY,CAAC,GAEZjB,IAWH,gBAAAyF,EAAC,SAAI,WAAA1E,GAAsB,OAAO,EAAE,UAAU,YAAY,GAAGC,EAAA,GAC1D,UAAA;AAAA,IAAAW,KACC,gBAAA+D;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,UACjB,QAAQ;AAAA,QAAA;AAAA,QAGV,4BAAC,OAAA,EAAI,OAAO,EAAE,OAAO,UAAA,GAAa,UAAA,wBAAA,CAAqB;AAAA,MAAA;AAAA,IAAA;AAAA,IAG3D,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKrE;AAAA,QACL,OAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,iBAAiB;AAAA,QAAA;AAAA,QAEnB,OAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EACR,GACF,sBAtCG,OAAA,EAAI,WAAAN,GAAsB,OAAAC,GACzB,UAAA,gBAAA0E,EAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,WAAW,UAAU,OAAO,UAAA,GAAa,mCAExE,GACF;AAoCN;"}