@templatical/editor 0.6.7 → 0.7.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 (106) hide show
  1. package/README.md +26 -1
  2. package/dist/{AccessibilityPanel-B2MT0M58.js → AccessibilityPanel-D-PqmHdH.js} +2 -2
  3. package/dist/{AiChatSidebar-w5ek3Z76.js → AiChatSidebar-BwLECwsO.js} +1 -1
  4. package/dist/{AiFeatureMenu-ChlAWywJ.js → AiFeatureMenu-CVHKharv.js} +3 -3
  5. package/dist/{BlockA11yBadge-C0S6kPC4.js → BlockA11yBadge-BFIw0h1m.js} +2 -2
  6. package/dist/{CloudEditor-DYYaScFe.js → CloudEditor-DdZatjUe.js} +30 -21
  7. package/dist/{CollaboratorBar-Bo8vtPId.js → CollaboratorBar-VZKOv_Zn.js} +2 -2
  8. package/dist/{CommentsSidebar-BQROg36f.js → CommentsSidebar-BiRtaXYD.js} +3 -3
  9. package/dist/{CountdownBlock-Bxqe7zwL.js → CountdownBlock-Cq8A8WrM.js} +1 -1
  10. package/dist/{CountdownToolbar-CpFAnjSo.js → CountdownToolbar-CojjlZet.js} +2 -2
  11. package/dist/{DesignReferenceSidebar-CfqpcWX6.js → DesignReferenceSidebar-Ci9HIGbf.js} +2 -2
  12. package/dist/ModuleBrowserModal-D7IYx1Nh.js +206 -0
  13. package/dist/{ModulePreviewCanvas-Cw9GeGus.js → ModulePreviewCanvas-I-uMcK5G.js} +2 -2
  14. package/dist/{NumberWithSuffix-Dw8dN1Pt.js → NumberWithSuffix-CLTBb2Rj.js} +1 -1
  15. package/dist/{ParagraphEditor-DjDiUzmv.js → ParagraphEditor-BRQTNDFO.js} +156 -151
  16. package/dist/{RichTextEditorContent-CK3Om7ES.js → RichTextEditorContent-C3QSg7gd.js} +32 -28
  17. package/dist/{SaveModuleDialog-CSUPmfRP.js → SaveModuleDialog-DGGGNZfm.js} +6 -6
  18. package/dist/{SnapshotHistory-DwX2fj6N.js → SnapshotHistory-C97Iw6xw.js} +3 -3
  19. package/dist/{TemplateScoringPanel-BIAeCAEP.js → TemplateScoringPanel-V79yrEPC.js} +3 -3
  20. package/dist/{TestEmailModal-CIlBvWWn.js → TestEmailModal-B7S8H-VG.js} +3 -3
  21. package/dist/{TitleEditor-BCV5k6wj.js → TitleEditor-DhFTYzrw.js} +65 -60
  22. package/dist/{TplModal-C3Hq9b58.js → TplModal-BgABm6ju.js} +21 -17
  23. package/dist/{blockTypeIcons-iUurP50H.js → blockTypeIcons-BSf-3RJ-.js} +1 -1
  24. package/dist/bundle-stats.json +7 -7
  25. package/dist/cdn/chunks/{AccessibilityPanel-DnNB30b0.js → AccessibilityPanel-kgNBRaZV.js} +28 -28
  26. package/dist/cdn/chunks/{AccessibilityPanel-DnNB30b0.js.map → AccessibilityPanel-kgNBRaZV.js.map} +1 -1
  27. package/dist/cdn/chunks/{AiFeatureMenu-BKBh_ueF.js → AiFeatureMenu-CRkzwdMg.js} +15 -15
  28. package/dist/cdn/chunks/{AiFeatureMenu-BKBh_ueF.js.map → AiFeatureMenu-CRkzwdMg.js.map} +1 -1
  29. package/dist/cdn/chunks/{BlockA11yBadge-CnBu14Fj.js → BlockA11yBadge-BfuH2Hrg.js} +9 -9
  30. package/dist/cdn/chunks/{BlockA11yBadge-CnBu14Fj.js.map → BlockA11yBadge-BfuH2Hrg.js.map} +1 -1
  31. package/dist/cdn/chunks/{CloudEditor-CmR17piA.js → CloudEditor-h5JXI8WQ.js} +252 -243
  32. package/dist/cdn/chunks/CloudEditor-h5JXI8WQ.js.map +1 -0
  33. package/dist/cdn/chunks/{CollaboratorBar-BejZaFtY.js → CollaboratorBar-CMl3lAZU.js} +15 -15
  34. package/dist/cdn/chunks/{CollaboratorBar-BejZaFtY.js.map → CollaboratorBar-CMl3lAZU.js.map} +1 -1
  35. package/dist/cdn/chunks/{CountdownBlock-CjvUEHhE.js → CountdownBlock-D1RoaOgF.js} +18 -18
  36. package/dist/cdn/chunks/{CountdownBlock-CjvUEHhE.js.map → CountdownBlock-D1RoaOgF.js.map} +1 -1
  37. package/dist/cdn/chunks/{CountdownToolbar-Caokkqsg.js → CountdownToolbar-DltwuOer.js} +42 -42
  38. package/dist/cdn/chunks/{CountdownToolbar-Caokkqsg.js.map → CountdownToolbar-DltwuOer.js.map} +1 -1
  39. package/dist/cdn/chunks/{ModuleBrowserModal-Tb9a7L-K.js → ModuleBrowserModal-3uu2mXR9.js} +36 -36
  40. package/dist/cdn/chunks/{ModuleBrowserModal-Tb9a7L-K.js.map → ModuleBrowserModal-3uu2mXR9.js.map} +1 -1
  41. package/dist/cdn/chunks/{ModulePreviewCanvas-JWIEv5oS.js → ModulePreviewCanvas-K9CQFr7p.js} +37 -37
  42. package/dist/cdn/chunks/{ModulePreviewCanvas-JWIEv5oS.js.map → ModulePreviewCanvas-K9CQFr7p.js.map} +1 -1
  43. package/dist/cdn/chunks/{NumberWithSuffix-DrV8eumz.js → NumberWithSuffix-BIFgtqGs.js} +74 -74
  44. package/dist/cdn/chunks/{NumberWithSuffix-DrV8eumz.js.map → NumberWithSuffix-BIFgtqGs.js.map} +1 -1
  45. package/dist/cdn/chunks/{ParagraphEditor-CSfShBAO.js → ParagraphEditor-DlpZX_x4.js} +180 -176
  46. package/dist/cdn/chunks/ParagraphEditor-DlpZX_x4.js.map +1 -0
  47. package/dist/cdn/chunks/{RichTextEditorContent-DgqZzl8n.js → RichTextEditorContent-CPGT8h-O.js} +40 -37
  48. package/dist/cdn/chunks/RichTextEditorContent-CPGT8h-O.js.map +1 -0
  49. package/dist/cdn/chunks/{SaveModuleDialog-CxTwrIgx.js → SaveModuleDialog-_uaJscj1.js} +24 -24
  50. package/dist/cdn/chunks/{SaveModuleDialog-CxTwrIgx.js.map → SaveModuleDialog-_uaJscj1.js.map} +1 -1
  51. package/dist/cdn/chunks/TitleEditor-Kerz6US8.js +175 -0
  52. package/dist/cdn/chunks/TitleEditor-Kerz6US8.js.map +1 -0
  53. package/dist/cdn/chunks/{blockTypeIcons-DMt-2qR6.js → blockTypeIcons-BeOhGtoo.js} +7 -7
  54. package/dist/cdn/chunks/{blockTypeIcons-DMt-2qR6.js.map → blockTypeIcons-BeOhGtoo.js.map} +1 -1
  55. package/dist/cdn/chunks/{draggable-CNhyCGIO.js → draggable-P6QWzy4g.js} +1182 -1171
  56. package/dist/cdn/chunks/{draggable-CNhyCGIO.js.map → draggable-P6QWzy4g.js.map} +1 -1
  57. package/dist/cdn/chunks/{extensions-CUvwrffu.js → extensions-BZYkPlKr.js} +107 -108
  58. package/dist/cdn/chunks/extensions-BZYkPlKr.js.map +1 -0
  59. package/dist/cdn/chunks/{features-U3nzKc-R.js → features-DzIN-Nua.js} +925 -896
  60. package/dist/cdn/chunks/features-DzIN-Nua.js.map +1 -0
  61. package/dist/cdn/chunks/{icons-QcjADKIW.js → icons-Nvr6w13E.js} +2 -2
  62. package/dist/cdn/chunks/{icons-QcjADKIW.js.map → icons-Nvr6w13E.js.map} +1 -1
  63. package/dist/cdn/chunks/{media-library-Zcd_GInj.js → media-library-BzT7BoGU.js} +1189 -1183
  64. package/dist/cdn/chunks/media-library-BzT7BoGU.js.map +1 -0
  65. package/dist/cdn/chunks/{quality-8eo6DM3p.js → quality-C328caFm.js} +45 -45
  66. package/dist/cdn/chunks/{quality-8eo6DM3p.js.map → quality-C328caFm.js.map} +1 -1
  67. package/dist/cdn/chunks/{renderer-eHJyPiJH.js → renderer-DYpHh_uV.js} +20 -20
  68. package/dist/cdn/chunks/{renderer-eHJyPiJH.js.map → renderer-DYpHh_uV.js.map} +1 -1
  69. package/dist/cdn/chunks/{src-CthVYW_o.js → src-DKNTQJVO.js} +144 -144
  70. package/dist/cdn/chunks/{src-CthVYW_o.js.map → src-DKNTQJVO.js.map} +1 -1
  71. package/dist/cdn/chunks/{styles-CV5w3kjq.js → styles-DaTht5d7.js} +924 -899
  72. package/dist/cdn/chunks/styles-DaTht5d7.js.map +1 -0
  73. package/dist/cdn/chunks/{tiptap-IyIsncxY.js → tiptap-BwTCLVWl.js} +7 -7
  74. package/dist/cdn/chunks/{tiptap-IyIsncxY.js.map → tiptap-BwTCLVWl.js.map} +1 -1
  75. package/dist/cdn/editor.css +1 -1
  76. package/dist/cdn/editor.js +197 -146
  77. package/dist/cdn/editor.js.map +1 -1
  78. package/dist/{extensions-BF39Siqk.js → extensions-D-J02CiP.js} +50 -51
  79. package/dist/index.d.ts +56 -11
  80. package/dist/{keys-Bqs_0du9.js → keys-B5SJtPWf.js} +3 -3
  81. package/dist/style.css +1 -1
  82. package/dist/{styles-BgmKdc2x.js → styles-D_fEz49o.js} +497 -472
  83. package/dist/templatical-editor.js +182 -131
  84. package/dist/{useCloudI18n-CL_AwWwi.js → useCloudI18n-ByEMykjO.js} +1 -1
  85. package/dist/{useEditorCore-CnXrv71D.js → useEditorCore-uCU9Ny0M.js} +637 -619
  86. package/dist/{useI18n-CgmQftNf.js → useI18n-PEB8ioi_.js} +1 -1
  87. package/dist/{useMergeTag-vpwrZ9eQ.js → useMergeTag-C47xwU7X.js} +2 -2
  88. package/dist/usePopoverRoot-BxJrqnMD.js +8 -0
  89. package/package.json +7 -7
  90. package/dist/ModuleBrowserModal-CKhsaPnA.js +0 -206
  91. package/dist/cdn/chunks/CloudEditor-CmR17piA.js.map +0 -1
  92. package/dist/cdn/chunks/ParagraphEditor-CSfShBAO.js.map +0 -1
  93. package/dist/cdn/chunks/RichTextEditorContent-DgqZzl8n.js.map +0 -1
  94. package/dist/cdn/chunks/TitleEditor-DlqV7ODD.js +0 -171
  95. package/dist/cdn/chunks/TitleEditor-DlqV7ODD.js.map +0 -1
  96. package/dist/cdn/chunks/extensions-CUvwrffu.js.map +0 -1
  97. package/dist/cdn/chunks/features-U3nzKc-R.js.map +0 -1
  98. package/dist/cdn/chunks/media-library-Zcd_GInj.js.map +0 -1
  99. package/dist/cdn/chunks/styles-CV5w3kjq.js.map +0 -1
  100. /package/dist/{de-DcVOh9Fp.js → de-BhIWu_bO.js} +0 -0
  101. /package/dist/{de-DCaaCE5s.js → de-Di4MEjjx.js} +0 -0
  102. /package/dist/{emojiData-PQyVa4bU.js → emojiData-DX3E0XT-.js} +0 -0
  103. /package/dist/{en-DXCyK4-X.js → en-BSuzi-Pd.js} +0 -0
  104. /package/dist/{en-TZVJ_f6v.js → en-D7HRbYah.js} +0 -0
  105. /package/dist/{pt-BR-Vq7D7c11.js → pt-BR-CCVBRais.js} +0 -0
  106. /package/dist/{pt-BR-BMGasLBa.js → pt-BR-K32lt6YP.js} +0 -0
package/README.md CHANGED
@@ -8,7 +8,8 @@
8
8
  The visual editor for [Templatical](https://github.com/templatical/sdk) — an open-source drag-and-drop email editor with JSON templates and MJML output.
9
9
 
10
10
  - 🧩 **14 block types** — title, paragraph, image, button, section, divider, spacer, social icons, menu, table, HTML, video, countdown, custom
11
- - 🎨 **27 design tokens** — full theming, dark mode, custom fonts
11
+ - 🛡 **Shadow DOM isolated** — mounts inside an open shadow root by default so host page CSS cannot bleed in
12
+ - 🎨 **27 design tokens** — full theming via `--tpl-user-*` CSS variables, dark mode, custom fonts
12
13
  - 🔌 **Framework-agnostic** — works in React, Vue, Svelte, Angular, vanilla
13
14
  - 📦 **JSON in, MJML out** — portable templates, render with any email provider
14
15
  - 🌍 **Bilingual** — English + German built in
@@ -59,6 +60,29 @@ editor.unmount();
59
60
 
60
61
  First-class examples for **React, Vue, Svelte, Angular, and vanilla JS** are in the [installation guide](https://docs.templatical.com/getting-started/installation).
61
62
 
63
+ ## Shadow DOM by default
64
+
65
+ The editor mounts inside an open shadow root attached to your container. Host page CSS — including resets like `* { color: red !important }` — cannot cascade into editor elements, and editor utility classes cannot leak out.
66
+
67
+ ```ts
68
+ // Shadow DOM is on by default — no extra config
69
+ const editor = await init({ container: "#editor" });
70
+
71
+ // Opt out for light-DOM mount (older browsers, host-side document.querySelector access)
72
+ const editor = await init({ container: "#editor", shadowDom: false });
73
+ ```
74
+
75
+ Theme via `:host`-style CSS variables — set `--tpl-user-*` on the container (or any ancestor) and the value inherits across the shadow boundary:
76
+
77
+ ```css
78
+ #editor {
79
+ --tpl-user-primary: oklch(65% 0.2 280);
80
+ --tpl-user-radius: 14px;
81
+ }
82
+ ```
83
+
84
+ See the [Shadow DOM guide](https://docs.templatical.com/guide/shadow-dom) for trade-offs, opt-out semantics, and browser-support tiers.
85
+
62
86
  ## Cloud features
63
87
 
64
88
  For AI rewrite, real-time collaboration, comments, snapshots, and saved modules, use `initCloud()` instead. See the [Cloud guide](https://docs.templatical.com/cloud/getting-started).
@@ -69,6 +93,7 @@ For AI rewrite, real-time collaboration, comments, snapshots, and saved modules,
69
93
  - [Editor API reference](https://docs.templatical.com/api/editor)
70
94
  - [Block reference](https://docs.templatical.com/guide/blocks)
71
95
  - [Theming](https://docs.templatical.com/guide/theming)
96
+ - [Shadow DOM](https://docs.templatical.com/guide/shadow-dom)
72
97
  - [Custom blocks](https://docs.templatical.com/guide/custom-blocks)
73
98
 
74
99
  Full docs at **[docs.templatical.com](https://docs.templatical.com)**.
@@ -1,6 +1,6 @@
1
1
  import { A as e, F as t, M as n, _ as r, at as i, b as a, d as o, f as s, h as c, l, m as u, p as d, rt as f, st as p, v as m, w as h } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
- import { m as g, t as _ } from "./keys-Bqs_0du9.js";
3
- import { t as v } from "./useI18n-CgmQftNf.js";
2
+ import { m as g, t as _ } from "./keys-B5SJtPWf.js";
3
+ import { t as v } from "./useI18n-PEB8ioi_.js";
4
4
  import { t as y } from "./createLucideIcon-Di4mqmGn.js";
5
5
  import { t as b } from "./accessibility-BgUEA-Ai.js";
6
6
  import { t as x } from "./circle-alert-C0L9pUQ4.js";
@@ -1,6 +1,6 @@
1
1
  import { A as e, B as t, D as n, E as ee, L as r, M as i, X as a, _ as o, a as te, at as ne, b as s, f as c, h as l, l as u, m as d, p as f, rt as p, st as m, t as re, v as h, w as ie, z as ae } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
2
  import { o as oe, s as se } from "./dist-BzRLLpfq.js";
3
- import { O as g, i as ce, l as le, m as _, v as ue } from "./keys-Bqs_0du9.js";
3
+ import { A as g, i as ce, l as le, m as _, y as ue } from "./keys-B5SJtPWf.js";
4
4
  import { t as v } from "./createLucideIcon-Di4mqmGn.js";
5
5
  import { t as de } from "./circle-alert-C0L9pUQ4.js";
6
6
  import { t as fe } from "./loader-circle-_9bP23op.js";
@@ -1,11 +1,11 @@
1
1
  import { A as e, F as t, M as n, b as r, d as i, f as a, h as o, l as s, ot as c, p as l, st as u } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
- import "./useEditorCore-CnXrv71D.js";
3
- import { O as d, n as f } from "./keys-Bqs_0du9.js";
2
+ import "./useEditorCore-uCU9Ny0M.js";
3
+ import { A as d, n as f } from "./keys-B5SJtPWf.js";
4
4
  import { t as p } from "./image-up-1D_3XDdO.js";
5
5
  import { t as m } from "./shield-check-C5Gv2cM1.js";
6
6
  import { t as h } from "./sparkles-D1IGi_cC.js";
7
7
  import { t as g } from "./_plugin-vue_export-helper-B0hnzhyu.js";
8
- import { n as _ } from "./useCloudI18n-CL_AwWwi.js";
8
+ import { n as _ } from "./useCloudI18n-ByEMykjO.js";
9
9
  //#region src/cloud/components/AiFeatureMenu.vue?vue&type=script&setup=true&lang.ts
10
10
  var v = {
11
11
  class: "tpl-ai-feature-menu tpl:w-[280px] tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:py-1 tpl:bg-[var(--tpl-bg-elevated)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]",
@@ -1,6 +1,6 @@
1
1
  import { A as e, at as t, b as n, d as r, h as i, m as a, p as o, rt as s, w as c } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
- import { t as l } from "./keys-Bqs_0du9.js";
3
- import { t as u } from "./useI18n-CgmQftNf.js";
2
+ import { t as l } from "./keys-B5SJtPWf.js";
3
+ import { t as u } from "./useI18n-PEB8ioi_.js";
4
4
  import { t as d } from "./circle-alert-C0L9pUQ4.js";
5
5
  import { t as f } from "./triangle-alert-DWQySIE2.js";
6
6
  //#region src/components/canvas/BlockA11yBadge.vue?vue&type=script&setup=true&lang.ts
@@ -1,14 +1,14 @@
1
1
  import { A as e, B as t, L as n, M as r, O as i, Q as a, X as o, _ as s, at as c, b as l, c as u, d, f, g as p, h as m, j as h, k as g, l as _, m as v, o as y, ot as b, p as x, q as S, rt as C, st as w, t as T, v as E, y as D, z as O } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
2
  import { t as k } from "./timeouts-BSGxjuUF.js";
3
3
  import { E as A, i as j } from "./dist-DJmnUmW9.js";
4
- import { P as M, S as ee, t as N } from "./useEditorCore-CnXrv71D.js";
4
+ import { P as M, S as ee, t as N } from "./useEditorCore-uCU9Ny0M.js";
5
5
  import { s as P, t as F } from "./dist-BzRLLpfq.js";
6
- import { C as te, c as ne, i as I, l as L, n as R, u as z, w as B, x as V } from "./keys-Bqs_0du9.js";
7
- import { t as H } from "./useI18n-CgmQftNf.js";
6
+ import { E as te, S as ne, T as I, c as L, i as R, l as z, n as B, u as V } from "./keys-B5SJtPWf.js";
7
+ import { t as H } from "./useI18n-PEB8ioi_.js";
8
8
  import { t as U } from "./createLucideIcon-Di4mqmGn.js";
9
9
  import { t as W } from "./check-Bg5yrRmX.js";
10
10
  import { t as G } from "./circle-alert-C0L9pUQ4.js";
11
- import { a as K, c as re, i as q, l as ie, n as J, o as ae, r as oe, s as se, t as ce } from "./styles-BgmKdc2x.js";
11
+ import { a as K, c as re, i as q, l as ie, n as J, o as ae, r as oe, s as se, t as ce } from "./styles-D_fEz49o.js";
12
12
  import { t as Y } from "./clock-CDlEdqiP.js";
13
13
  import { t as X } from "./loader-circle-_9bP23op.js";
14
14
  import { t as Z } from "./message-circle-gzy2ZGJ3.js";
@@ -16,7 +16,7 @@ import { t as le } from "./send-BatIZC9a.js";
16
16
  import { t as ue } from "./sparkles-D1IGi_cC.js";
17
17
  import { t as de } from "./triangle-alert-DWQySIE2.js";
18
18
  import { t as fe } from "./_plugin-vue_export-helper-B0hnzhyu.js";
19
- import { n as Q } from "./useCloudI18n-CL_AwWwi.js";
19
+ import { n as Q } from "./useCloudI18n-ByEMykjO.js";
20
20
  import { d as $ } from "./styleConstants-fWzlIIwN.js";
21
21
  import { _ as pe, a as me, c as he, d as ge, f as _e, g as ve, h as ye, l as be, m as xe, n as Se, o as Ce, p as we, r as Te, s as Ee, t as De, v as Oe, y as ke } from "./cloud-a3VovHva.js";
22
22
  var Ae = U("save", [
@@ -268,7 +268,8 @@ function Ie(e) {
268
268
  enabled: () => t.autoSave !== !1 && v.hasFeature("auto_save")
269
269
  },
270
270
  themeExtraStyles: () => ({ "--tpl-drop-text": `"${r.canvas.dropHere}"` }),
271
- keyboardOptions: { onBeforeUndo: () => g?.showCollabUndoWarning() }
271
+ keyboardOptions: { onBeforeUndo: () => g?.showCollabUndoWarning() },
272
+ editorRoot: e.editorRoot
272
273
  }), T = Ne({
273
274
  isCollaborationEnabled: C,
274
275
  getCollaboratorCount: () => S?.collaborators.value.length ?? 0,
@@ -322,7 +323,7 @@ function Ie(e) {
322
323
  comments: F,
323
324
  channel: x.channel
324
325
  });
325
- let L = ye({
326
+ let z = ye({
326
327
  authManager: _,
327
328
  onError: t.onError
328
329
  }), H = o(!1), U = o(null), W = o(!1), G = pe({
@@ -334,7 +335,7 @@ function Ie(e) {
334
335
  s()?.filterByBlock(e);
335
336
  });
336
337
  }
337
- h(V, A.handleRequestMedia), h(I, _), h(R, O), h(z, F), h(te, L), h(B, G), h(ne, {
338
+ h(ne, A.handleRequestMedia), h(R, _), h(B, O), h(V, F), h(I, z), h(te, G), h(L, {
338
339
  plan: v,
339
340
  ai: O,
340
341
  comments: {
@@ -348,7 +349,7 @@ function Ie(e) {
348
349
  openBrowser: () => {
349
350
  W.value = !0;
350
351
  },
351
- moduleCount: d(() => L.modules.value.length)
352
+ moduleCount: d(() => z.modules.value.length)
352
353
  }
353
354
  });
354
355
  function q(e) {
@@ -367,7 +368,7 @@ function Ie(e) {
367
368
  if (!e.api.ok) throw Error("Health check failed: API is not reachable");
368
369
  if (!e.auth.ok) throw Error(`Health check failed: authentication error${e.auth.error ? ` - ${e.auth.error}` : ""}`);
369
370
  if (e.websocket.ok || M.warn("WebSocket health check failed:", e.websocket.error ?? "unknown error", "-- real-time features will be disabled."), await v.fetchConfig(), f) return;
370
- i.setCustomFontsEnabled(v.hasFeature("custom_fonts")), t.customBlocks?.length && v.hasFeature("custom_blocks") && w.registerCustomBlocks(t.customBlocks), t.theme && v.hasFeature("theme_customization") && (w.themeOverrides.value = t.theme), t.modules !== !1 && v.hasFeature("saved_modules") && L.loadModules(), a("ready");
371
+ i.setCustomFontsEnabled(v.hasFeature("custom_fonts")), t.customBlocks?.length && v.hasFeature("custom_blocks") && w.registerCustomBlocks(t.customBlocks), t.theme && v.hasFeature("theme_customization") && (w.themeOverrides.value = t.theme), t.modules !== !1 && v.hasFeature("saved_modules") && z.loadModules(), a("ready");
371
372
  } catch (e) {
372
373
  if (f) return;
373
374
  let n = e instanceof Error ? e : Error("Initialization failed", { cause: e });
@@ -397,7 +398,7 @@ function Ie(e) {
397
398
  exporter: j,
398
399
  testEmail: P,
399
400
  commentsInstance: F,
400
- savedModulesHeadless: L,
401
+ savedModulesHeadless: z,
401
402
  scoringInstance: G,
402
403
  panelState: D,
403
404
  snapshotPreview: E,
@@ -590,7 +591,7 @@ var Be = ["aria-label"], Ve = { class: "tpl:flex tpl:max-h-[80vh] tpl:w-full tpl
590
591
  },
591
592
  emits: ["save"],
592
593
  setup(t) {
593
- let n = D(() => import("./CollaboratorBar-Bo8vtPId.js")), r = D(() => import("./SnapshotHistory-DwX2fj6N.js")), i = D(() => import("./AiFeatureMenu-ChlAWywJ.js")), { t: a, format: o } = Q();
594
+ let n = D(() => import("./CollaboratorBar-VZKOv_Zn.js")), r = D(() => import("./SnapshotHistory-C97Iw6xw.js")), i = D(() => import("./AiFeatureMenu-CVHKharv.js")), { t: a, format: o } = Q();
594
595
  return (l, d) => (e(), m("header", Xe, [
595
596
  f("div", Ze, [t.featureFlags.templateLimit.value === null ? v("", !0) : (e(), m("span", Qe, w(C(o)(C(a).header.templatesUsed, {
596
597
  used: t.featureFlags.templateCount.value,
@@ -752,7 +753,7 @@ var Be = ["aria-label"], Ve = { class: "tpl:flex tpl:max-h-[80vh] tpl:w-full tpl
752
753
  "module-insert"
753
754
  ],
754
755
  setup(t, { expose: n, emit: r }) {
755
- let i = D(() => import("./AiChatSidebar-w5ek3Z76.js")), a = D(() => import("./CommentsSidebar-BQROg36f.js")), s = D(() => import("./DesignReferenceSidebar-CfqpcWX6.js")), c = D(() => import("./TemplateScoringPanel-BIAeCAEP.js")), l = D(() => import("./TestEmailModal-CIlBvWWn.js")), u = D(() => import("./SaveModuleDialog-CSUPmfRP.js")), d = D(() => import("./ModuleBrowserModal-CKhsaPnA.js")), f = D(async () => {
756
+ let i = D(() => import("./AiChatSidebar-BwLECwsO.js")), a = D(() => import("./CommentsSidebar-BiRtaXYD.js")), s = D(() => import("./DesignReferenceSidebar-Ci9HIGbf.js")), c = D(() => import("./TemplateScoringPanel-V79yrEPC.js")), l = D(() => import("./TestEmailModal-B7S8H-VG.js")), u = D(() => import("./SaveModuleDialog-DGGGNZfm.js")), d = D(() => import("./ModuleBrowserModal-D7IYx1Nh.js")), f = D(async () => {
756
757
  try {
757
758
  return (await import("@templatical/media-library")).MediaLibraryModal;
758
759
  } catch {
@@ -822,11 +823,13 @@ var Be = ["aria-label"], Ve = { class: "tpl:flex tpl:max-h-[80vh] tpl:w-full tpl
822
823
  E(C(f), {
823
824
  visible: t.panelState.mediaLibraryOpen.value,
824
825
  accept: t.panelState.mediaLibraryAccept.value,
826
+ "popover-target": t.core.popoverRoot.value,
825
827
  onSelect: t.mediaLib.handleMediaSelect,
826
828
  onClose: t.mediaLib.handleMediaLibraryClose
827
829
  }, null, 8, [
828
830
  "visible",
829
831
  "accept",
832
+ "popover-target",
830
833
  "onSelect",
831
834
  "onClose"
832
835
  ])
@@ -922,19 +925,21 @@ var Be = ["aria-label"], Ve = { class: "tpl:flex tpl:max-h-[80vh] tpl:w-full tpl
922
925
  config: {},
923
926
  translations: {},
924
927
  cloudTranslations: {},
925
- fontsManager: {}
928
+ fontsManager: {},
929
+ shadowRoot: {}
926
930
  },
927
931
  emits: ["ready"],
928
932
  setup(n, { expose: r, emit: a }) {
929
933
  let l = n;
930
- h(L, l.cloudTranslations);
934
+ h(z, l.cloudTranslations);
931
935
  let u = a, d = o(null), p = Ie({
932
936
  config: l.config,
933
937
  translations: l.translations,
934
938
  fontsManager: l.fontsManager,
935
939
  emit: u,
936
- getCommentsSidebar: () => d.value ? { filterByBlock: d.value.filterCommentsByBlock } : null
937
- }), { isInitializing: _, isAuthReady: S, initError: D, planConfigInstance: k, websocket: A, collaboration: M, isCollaborationEnabled: ee, editor: N, core: P, featureFlags: F, mediaLib: te, exporter: ne, testEmail: I, commentsInstance: R, savedModulesHeadless: z, panelState: B, snapshotPreview: V, collabWarning: H, showSaveModuleDialog: U, showModuleBrowserModal: W, saveModulePreSelectedBlockId: G, setThemeOverrides: re, setUiTheme: q } = p;
940
+ getCommentsSidebar: () => d.value ? { filterByBlock: d.value.filterCommentsByBlock } : null,
941
+ editorRoot: l.shadowRoot
942
+ }), { isInitializing: _, isAuthReady: S, initError: D, planConfigInstance: k, websocket: A, collaboration: M, isCollaborationEnabled: ee, editor: N, core: P, featureFlags: F, mediaLib: te, exporter: ne, testEmail: I, commentsInstance: L, savedModulesHeadless: R, panelState: B, snapshotPreview: V, collabWarning: H, showSaveModuleDialog: U, showModuleBrowserModal: W, saveModulePreSelectedBlockId: G, setThemeOverrides: re, setUiTheme: q } = p;
938
943
  async function J(e) {
939
944
  try {
940
945
  await I.sendTestEmail(e), B.testEmailModalOpen.value = !1;
@@ -1018,7 +1023,7 @@ var Be = ["aria-label"], Ve = { class: "tpl:flex tpl:max-h-[80vh] tpl:w-full tpl
1018
1023
  "feature-flags": C(F),
1019
1024
  "panel-state": C(B),
1020
1025
  "snapshot-preview": C(V),
1021
- "comments-instance": C(R),
1026
+ "comments-instance": C(L),
1022
1027
  "test-email": C(I),
1023
1028
  websocket: C(A),
1024
1029
  collaboration: C(M),
@@ -1149,7 +1154,7 @@ var Be = ["aria-label"], Ve = { class: "tpl:flex tpl:max-h-[80vh] tpl:w-full tpl
1149
1154
  "plan-config-instance": C(k),
1150
1155
  "test-email": C(I),
1151
1156
  "media-lib": C(te),
1152
- "saved-modules-headless": C(z),
1157
+ "saved-modules-headless": C(R),
1153
1158
  "show-save-module-dialog": C(U),
1154
1159
  "save-module-pre-selected-block-id": C(G),
1155
1160
  "show-module-browser-modal": C(W),
@@ -1170,9 +1175,13 @@ var Be = ["aria-label"], Ve = { class: "tpl:flex tpl:max-h-[80vh] tpl:w-full tpl
1170
1175
  "show-save-module-dialog",
1171
1176
  "save-module-pre-selected-block-id",
1172
1177
  "show-module-browser-modal"
1173
- ])) : v("", !0)
1178
+ ])) : v("", !0),
1179
+ f("div", {
1180
+ ref: (e) => C(P).popoverRoot.value = e,
1181
+ class: "tpl-popover-root"
1182
+ }, null, 512)
1174
1183
  ], 14, Ot));
1175
1184
  }
1176
- }), [["__scopeId", "data-v-b332971f"]]);
1185
+ }), [["__scopeId", "data-v-c00ce9ab"]]);
1177
1186
  //#endregion
1178
1187
  export { Mt as default };
@@ -1,7 +1,7 @@
1
1
  import { A as e, M as t, b as n, d as r, f as i, h as a, l as o, m as s, ot as c, p as l, rt as u, st as d } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
- import "./useEditorCore-CnXrv71D.js";
2
+ import "./useEditorCore-uCU9Ny0M.js";
3
3
  import { t as f } from "./createLucideIcon-Di4mqmGn.js";
4
- import { n as p } from "./useCloudI18n-CL_AwWwi.js";
4
+ import { n as p } from "./useCloudI18n-ByEMykjO.js";
5
5
  import { t as m } from "./readableTextColor-CY3SiRnt.js";
6
6
  var h = f("wifi-off", [
7
7
  ["path", {
@@ -1,6 +1,6 @@
1
1
  import { A as e, B as t, E as n, L as r, M as i, X as a, _ as ee, a as o, at as s, b as c, d as l, f as u, h as d, l as f, m as p, ot as te, p as m, rt as h, st as g, t as _, v, z as y } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
- import { O as b, i as ne, m as re, u as ie } from "./keys-Bqs_0du9.js";
3
- import { t as ae } from "./useI18n-CgmQftNf.js";
2
+ import { A as b, i as ne, m as re, u as ie } from "./keys-B5SJtPWf.js";
3
+ import { t as ae } from "./useI18n-PEB8ioi_.js";
4
4
  import { t as x } from "./createLucideIcon-Di4mqmGn.js";
5
5
  import { t as oe } from "./check-Bg5yrRmX.js";
6
6
  import { t as se } from "./chevron-down-tee-ghFi.js";
@@ -10,7 +10,7 @@ import { t as w } from "./send-BatIZC9a.js";
10
10
  import { t as T } from "./trash-2-424iqbpN.js";
11
11
  import { t as E } from "./x-Dlaenqta.js";
12
12
  import { t as D } from "./_plugin-vue_export-helper-B0hnzhyu.js";
13
- import { n as ce } from "./useCloudI18n-CL_AwWwi.js";
13
+ import { n as ce } from "./useCloudI18n-ByEMykjO.js";
14
14
  import { t as le } from "./formatRelativeTime-BOEf47hq.js";
15
15
  var ue = x("chevron-up", [["path", {
16
16
  d: "m18 15-6-6-6 6",
@@ -1,7 +1,7 @@
1
1
  import { t as e } from "./rolldown-runtime-CAFD8bLK.js";
2
2
  import { A as t, M as n, X as r, b as i, d as a, f as o, h as s, l as c, m as l, ot as u, rt as d, st as f } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
3
3
  import { o as p } from "./dist-BzRLLpfq.js";
4
- import { t as m } from "./useI18n-CgmQftNf.js";
4
+ import { t as m } from "./useI18n-PEB8ioi_.js";
5
5
  //#region src/components/blocks/CountdownBlock.vue?vue&type=script&setup=true&lang.ts
6
6
  var h = {
7
7
  key: 0,
@@ -1,7 +1,7 @@
1
1
  import { A as e, M as t, _ as n, at as r, b as i, d as a, f as o, h as s, l as c, p as l, rt as u, st as d, v as f, z as p } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
- import { t as m } from "./useI18n-CgmQftNf.js";
2
+ import { t as m } from "./useI18n-PEB8ioi_.js";
3
3
  import { f as h } from "./styleConstants-fWzlIIwN.js";
4
- import { i as g, n as _, r as v, t as y } from "./NumberWithSuffix-Dw8dN1Pt.js";
4
+ import { i as g, n as _, r as v, t as y } from "./NumberWithSuffix-CLTBb2Rj.js";
5
5
  //#region src/components/toolbar/CheckboxItem.vue?vue&type=script&setup=true&lang.ts
6
6
  var b = { class: "tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-2 tpl:text-[12px] tpl:text-[var(--tpl-text)]" }, x = ["checked"], S = /* @__PURE__ */ i({
7
7
  __name: "CheckboxItem",
@@ -1,13 +1,13 @@
1
1
  import { A as e, B as t, D as n, L as r, X as i, _ as a, a as ee, at as te, b as o, d as ne, f as s, h as c, m as l, ot as u, p as re, rt as d, st as f, t as ie, v as p, z as ae } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
2
  import "./timeouts-BSGxjuUF.js";
3
- import { O as m, i as oe, m as h } from "./keys-Bqs_0du9.js";
3
+ import { A as m, i as oe, m as h } from "./keys-B5SJtPWf.js";
4
4
  import { t as g } from "./createLucideIcon-Di4mqmGn.js";
5
5
  import { t as se } from "./circle-alert-C0L9pUQ4.js";
6
6
  import { t as _ } from "./image-up-1D_3XDdO.js";
7
7
  import { t as v } from "./x-Dlaenqta.js";
8
8
  import { t as ce } from "./LoadingTrack-CFkDkjBb.js";
9
9
  import { t as y } from "./_plugin-vue_export-helper-B0hnzhyu.js";
10
- import { n as le } from "./useCloudI18n-CL_AwWwi.js";
10
+ import { n as le } from "./useCloudI18n-ByEMykjO.js";
11
11
  import { u as ue } from "./cloud-a3VovHva.js";
12
12
  var de = g("file-image", [
13
13
  ["path", {
@@ -0,0 +1,206 @@
1
+ import { A as e, B as t, F as n, L as r, M as i, X as a, a as ee, b as o, c as s, d as c, f as l, h as u, i as te, l as d, m as ne, ot as re, p as f, rt as p, st as m, v as h, y as ie, z as ae } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
+ import "./useEditorCore-uCU9Ny0M.js";
3
+ import { A as g, T as _, m as oe } from "./keys-B5SJtPWf.js";
4
+ import { t as se } from "./useI18n-PEB8ioi_.js";
5
+ import { t as v } from "./createLucideIcon-Di4mqmGn.js";
6
+ import { n as y, t as b } from "./blockTypeIcons-BSf-3RJ-.js";
7
+ import { t as ce } from "./trash-2-424iqbpN.js";
8
+ import { t as le } from "./x-Dlaenqta.js";
9
+ import { n as ue } from "./useCloudI18n-ByEMykjO.js";
10
+ import { t as de } from "./TplModal-BgABm6ju.js";
11
+ var fe = v("search", [["path", {
12
+ d: "m21 21-4.34-4.34",
13
+ key: "14j7rj"
14
+ }], ["circle", {
15
+ cx: "11",
16
+ cy: "11",
17
+ r: "8",
18
+ key: "4ej97u"
19
+ }]]), pe = {
20
+ role: "dialog",
21
+ "aria-modal": "true",
22
+ "aria-labelledby": "tpl-module-browser-title",
23
+ class: "tpl-scale-in tpl:mx-4 tpl:flex tpl:w-full tpl:max-w-[1000px] tpl:flex-col tpl:rounded-[var(--tpl-radius-lg)]",
24
+ style: {
25
+ "background-color": "var(--tpl-bg-elevated)",
26
+ "box-shadow": "var(--tpl-shadow-xl)",
27
+ "max-height": "90vh"
28
+ }
29
+ }, me = { class: "tpl:flex tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-4 tpl:border-[var(--tpl-border)]" }, x = {
30
+ id: "tpl-module-browser-title",
31
+ class: "tpl:text-sm tpl:font-semibold tpl:text-[var(--tpl-text)]"
32
+ }, S = ["aria-label"], C = { class: "tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden" }, w = { class: "tpl:flex tpl:w-[300px] tpl:shrink-0 tpl:flex-col tpl:overflow-hidden" }, T = { class: "tpl:px-4 tpl:pt-4 tpl:pb-3" }, E = { class: "tpl:relative" }, D = ["placeholder"], O = { class: "tpl:flex-1 tpl:overflow-y-auto tpl:px-4 tpl:pb-4" }, k = {
33
+ key: 0,
34
+ class: "tpl:flex tpl:flex-col tpl:gap-1"
35
+ }, A = ["aria-pressed", "onClick"], j = { class: "tpl:flex tpl:items-center tpl:gap-2" }, M = { class: "tpl:flex-1 tpl:truncate tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)]" }, N = { class: "tpl:shrink-0 tpl:rounded-full tpl:px-1.5 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]" }, P = { class: "tpl:mt-1 tpl:flex tpl:items-center tpl:gap-1" }, F = {
36
+ key: 0,
37
+ class: "tpl:text-[10px] tpl:text-[var(--tpl-text-dim)]"
38
+ }, I = ["aria-label", "onClick"], L = [
39
+ "aria-label",
40
+ "title",
41
+ "onClick"
42
+ ], R = {
43
+ key: 1,
44
+ class: "tpl:flex tpl:flex-col tpl:items-center tpl:justify-center tpl:py-12"
45
+ }, z = { class: "tpl:mt-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]" }, he = { class: "tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden tpl:border-l tpl:border-[var(--tpl-border)]" }, ge = {
46
+ key: 0,
47
+ class: "tpl:flex tpl:flex-1 tpl:flex-col tpl:overflow-hidden"
48
+ }, _e = { class: "tpl:flex-1 tpl:overflow-y-auto tpl:p-4" }, ve = {
49
+ key: 1,
50
+ class: "tpl:flex tpl:flex-1 tpl:flex-col tpl:items-center tpl:justify-center tpl:px-4"
51
+ }, ye = { class: "tpl:mt-2 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-dim)]" }, be = { class: "tpl:flex tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3 tpl:border-[var(--tpl-border)]" }, xe = { class: "tpl:flex tpl:items-center tpl:gap-2" }, Se = { class: "tpl:shrink-0 tpl:text-xs tpl:text-[var(--tpl-text-dim)]" }, Ce = ["value"], we = { class: "tpl:flex tpl:gap-2" }, Te = ["disabled"], B = /* @__PURE__ */ o({
52
+ __name: "ModuleBrowserModal",
53
+ props: { visible: { type: Boolean } },
54
+ emits: ["close", "insert"],
55
+ setup(o, { emit: v }) {
56
+ let B = o, V = v, Ee = ie(() => import("./ModulePreviewCanvas-I-uMcK5G.js")), { t: De } = se(), { t: H } = ue(), U = g(_, "ModuleBrowserModal"), W = g(oe, "ModuleBrowserModal"), G = a(""), K = a(null), q = a(null), J = a("end"), Y = c(() => {
57
+ let e = U.modules.value;
58
+ if (!G.value) return e;
59
+ let t = G.value.toLowerCase();
60
+ return e.filter((e) => e.name.toLowerCase().includes(t));
61
+ }), X = c(() => K.value ? U.modules.value.find((e) => e.id === K.value) ?? null : null), Oe = c(() => {
62
+ let e = [{
63
+ value: "beginning",
64
+ label: H.modules.insertAtBeginning
65
+ }], t = W.content.value.blocks;
66
+ for (let n = 0; n < t.length; n++) {
67
+ let r = t[n], i = r.type, a = De.blocks[i] ?? r.type;
68
+ e.push({
69
+ value: r.id,
70
+ label: H.modules.insertAfterBlock.replace("{block}", `${a} ${n + 1}`)
71
+ });
72
+ }
73
+ return e.push({
74
+ value: "end",
75
+ label: H.modules.insertAtEnd
76
+ }), e;
77
+ }), ke = c(() => {
78
+ if (J.value === "end") return;
79
+ if (J.value === "beginning") return 0;
80
+ let e = W.content.value.blocks.findIndex((e) => e.id === J.value);
81
+ if (e !== -1) return e + 1;
82
+ });
83
+ r(() => B.visible, (e) => {
84
+ if (e) {
85
+ G.value = "", K.value = null, q.value = null;
86
+ let e = W.state.selectedBlockId;
87
+ e ? J.value = W.content.value.blocks.findIndex((t) => t.id === e) === -1 ? "end" : e : J.value = "end";
88
+ }
89
+ });
90
+ function Ae(e) {
91
+ let t = [], n = /* @__PURE__ */ new Set();
92
+ for (let r of e.content) if (!n.has(r.type) && b[r.type] && (n.add(r.type), t.push({
93
+ type: r.type,
94
+ icon: b[r.type]
95
+ })), t.length >= 5) break;
96
+ return t;
97
+ }
98
+ function Z(e) {
99
+ let t = new Set(e.content.map((e) => e.type));
100
+ return Math.max(0, t.size - 5);
101
+ }
102
+ async function je(e) {
103
+ try {
104
+ await U.deleteModule(e), K.value === e && (K.value = null);
105
+ } finally {
106
+ q.value = null;
107
+ }
108
+ }
109
+ function Q() {
110
+ X.value && V("insert", X.value, ke.value);
111
+ }
112
+ function $() {
113
+ V("close");
114
+ }
115
+ function Me(e) {
116
+ e.key === "Escape" && $(), e.key === "Enter" && X.value && (e.preventDefault(), Q());
117
+ }
118
+ return (r, a) => (e(), f(de, {
119
+ visible: o.visible,
120
+ onClose: $,
121
+ onKeydown: Me
122
+ }, {
123
+ default: ae(() => [l("div", pe, [
124
+ l("div", me, [l("h3", x, m(p(H).modules.browse), 1), l("button", {
125
+ "aria-label": p(H).modules.close,
126
+ class: "tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-1 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]",
127
+ onClick: $
128
+ }, [h(p(le), {
129
+ size: 16,
130
+ "stroke-width": 2
131
+ })], 8, S)]),
132
+ l("div", C, [l("div", w, [l("div", T, [l("div", E, [h(p(fe), {
133
+ size: 14,
134
+ "stroke-width": 2,
135
+ class: "tpl:pointer-events-none tpl:absolute tpl:left-3 tpl:top-1/2 tpl:-translate-y-1/2 tpl:text-[var(--tpl-text-dim)]"
136
+ }), t(l("input", {
137
+ "onUpdate:modelValue": a[0] ||= (e) => G.value = e,
138
+ type: "text",
139
+ placeholder: p(H).modules.search,
140
+ class: "tpl:h-9 tpl:w-full tpl:rounded-md tpl:border tpl:pl-9 tpl:pr-3 tpl:text-sm tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]"
141
+ }, null, 8, D), [[ee, G.value]])])]), l("div", O, [Y.value.length > 0 ? (e(), u("div", k, [(e(!0), u(d, null, i(Y.value, (t) => (e(), u("button", {
142
+ key: t.id,
143
+ type: "button",
144
+ "aria-pressed": K.value === t.id,
145
+ class: "tpl:group/card tpl:w-full tpl:cursor-pointer tpl:rounded-[var(--tpl-radius-md)] tpl:border tpl:bg-transparent tpl:px-3 tpl:py-2 tpl:text-left tpl:transition-all tpl:duration-[120ms]",
146
+ style: re({
147
+ borderColor: K.value === t.id ? "var(--tpl-primary)" : "var(--tpl-border)",
148
+ backgroundColor: K.value === t.id ? "var(--tpl-primary-light)" : "transparent"
149
+ }),
150
+ onClick: (e) => K.value = t.id
151
+ }, [l("div", j, [l("span", M, m(t.name), 1), l("span", N, m(p(H).modules.blockCount.replace("{count}", String(t.content.length))), 1)]), l("div", P, [
152
+ (e(!0), u(d, null, i(Ae(t), (t) => (e(), f(n(t.icon), {
153
+ key: t.type,
154
+ size: 14,
155
+ "stroke-width": 1.5,
156
+ class: "tpl:text-[var(--tpl-text-dim)]"
157
+ }))), 128)),
158
+ Z(t) > 0 ? (e(), u("span", F, " +" + m(Z(t)), 1)) : ne("", !0),
159
+ q.value === t.id ? (e(), u("button", {
160
+ key: 1,
161
+ "aria-label": p(H).modules.deleteConfirm,
162
+ class: "tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-2 tpl:py-0.5 tpl:text-[10px] tpl:font-medium tpl:transition-colors tpl:duration-100 tpl:border-[var(--tpl-danger)] tpl:text-[var(--tpl-danger)]",
163
+ style: { "background-color": "transparent" },
164
+ onClick: s((e) => je(t.id), ["stop"])
165
+ }, m(p(H).modules.deleteConfirm), 9, I)) : (e(), u("button", {
166
+ key: 2,
167
+ class: "tpl-module-delete-btn tpl:ml-auto tpl:cursor-pointer tpl:rounded-md tpl:border-none tpl:bg-transparent tpl:p-0.5 tpl:transition-colors tpl:duration-100 tpl:text-[var(--tpl-text-dim)]",
168
+ "aria-label": p(H).modules.delete,
169
+ title: p(H).modules.delete,
170
+ onClick: s((e) => q.value = t.id, ["stop"])
171
+ }, [h(p(ce), {
172
+ size: 12,
173
+ "stroke-width": 1.5
174
+ })], 8, L))
175
+ ])], 12, A))), 128))])) : (e(), u("div", R, [h(p(y), {
176
+ size: 32,
177
+ "stroke-width": 1,
178
+ class: "tpl:text-[var(--tpl-text-dim)]"
179
+ }), l("p", z, m(G.value ? p(H).modules.noModules : p(H).modules.noModulesHint), 1)]))])]), l("div", he, [X.value ? (e(), u("div", ge, [l("div", _e, [h(p(Ee), { blocks: X.value.content }, null, 8, ["blocks"])])])) : (e(), u("div", ve, [h(p(y), {
180
+ size: 32,
181
+ "stroke-width": 1,
182
+ class: "tpl:text-[var(--tpl-text-dim)]"
183
+ }), l("p", ye, m(p(H).modules.selectToPreview), 1)]))])]),
184
+ l("div", be, [l("div", xe, [l("label", Se, m(p(H).modules.insertPosition), 1), t(l("select", {
185
+ "onUpdate:modelValue": a[1] ||= (e) => J.value = e,
186
+ class: "tpl:h-7 tpl:max-w-[220px] tpl:rounded-md tpl:border tpl:px-2 tpl:text-xs tpl:outline-none tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:text-[var(--tpl-text)]"
187
+ }, [(e(!0), u(d, null, i(Oe.value, (t) => (e(), u("option", {
188
+ key: t.value,
189
+ value: t.value
190
+ }, m(t.label), 9, Ce))), 128))], 512), [[te, J.value]])]), l("div", we, [l("button", {
191
+ type: "button",
192
+ class: "tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:border-[var(--tpl-border)] tpl:text-[var(--tpl-text)] tpl:bg-[var(--tpl-bg)]",
193
+ onClick: $
194
+ }, m(p(H).modules.close), 1), l("button", {
195
+ type: "button",
196
+ class: "tpl:cursor-pointer tpl:rounded-md tpl:px-3 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50 tpl:bg-[var(--tpl-primary)] tpl:text-[var(--tpl-bg)]",
197
+ disabled: !X.value,
198
+ onClick: Q
199
+ }, m(p(H).modules.insert), 9, Te)])])
200
+ ])]),
201
+ _: 1
202
+ }, 8, ["visible"]));
203
+ }
204
+ });
205
+ //#endregion
206
+ export { B as default };
@@ -1,6 +1,6 @@
1
1
  import { A as e, F as t, M as n, P as r, b as i, d as a, f as o, h as s, l as c, ot as l, p as u, rt as d, w as f } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
- import { N as p, _ as m, a as h, f as g, g as _, h as v, i as y, m as b, n as x, p as S, r as C, u as w, v as T, y as E } from "./useEditorCore-CnXrv71D.js";
3
- import { s as D } from "./keys-Bqs_0du9.js";
2
+ import { N as p, _ as m, a as h, f as g, g as _, h as v, i as y, m as b, n as x, p as S, r as C, u as w, v as T, y as E } from "./useEditorCore-uCU9Ny0M.js";
3
+ import { s as D } from "./keys-B5SJtPWf.js";
4
4
  //#region src/components/blocks/PreviewSectionBlock.vue?vue&type=script&setup=true&lang.ts
5
5
  var O = { class: "tpl:w-full" }, k = { class: "tpl:flex tpl:gap-0" }, A = /* @__PURE__ */ i({
6
6
  name: "PreviewSectionBlock",
@@ -1,6 +1,6 @@
1
1
  import { A as e, F as t, M as n, N as r, X as i, at as a, b as o, d as s, f as c, h as l, l as u, m as d, ot as f, p, rt as m, s as h, st as g, t as ee, v as _, z as te } from "./vue.runtime.esm-bundler-Bxqkjqhc.js";
2
2
  import { t as v } from "./dist-BzRLLpfq.js";
3
- import { t as ne } from "./useI18n-CgmQftNf.js";
3
+ import { t as ne } from "./useI18n-PEB8ioi_.js";
4
4
  import { h as y, i as b, m as x, p as S, u as C } from "./styleConstants-fWzlIIwN.js";
5
5
  //#region ../../node_modules/.pnpm/vanilla-colorful@0.7.2/node_modules/vanilla-colorful/lib/utils/math.js
6
6
  var w = (e, t = 0, n = 1) => e > n ? n : e < t ? t : e, T = (e, t = 0, n = 10 ** t) => Math.round(n * e) / n;