@templatical/editor 0.34.3 → 0.35.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.
- package/dist/{AiChatSidebar-CkHJ28sf.js → AiChatSidebar-DPHbCGu4.js} +29 -21
- package/dist/{AiFeatureMenu-DWdKguDN.js → AiFeatureMenu--8z7qvg1.js} +4 -4
- package/dist/{BlockIssueBadge-DcyHTAqw.js → BlockIssueBadge-BGCsJqqM.js} +2 -2
- package/dist/BlockPreviewCanvas-DKspIy8V.js +131 -0
- package/dist/{CloudHeaderExtras-BJ3Cebhv.js → CloudHeaderExtras-CRUQvgSV.js} +2 -2
- package/dist/{CloudPanels-BGz9ygo6.js → CloudPanels-Bp5gFtaL.js} +3 -3
- package/dist/{CollaboratorBar-KphmSQeZ.js → CollaboratorBar-DvwZm5u7.js} +57 -49
- package/dist/{ColorPicker-C6EOwtHC.js → ColorPicker-DtozuN75.js} +1 -1
- package/dist/{CommentsPanel-DmWh8f08.js → CommentsPanel-3C-DsEjy.js} +1 -1
- package/dist/{CommentsSidebar-CL_tffzT.js → CommentsSidebar-go1FnjDW.js} +34 -25
- package/dist/{CountdownToolbar-B8J4i5Xp.js → CountdownToolbar-SLBuij7Q.js} +1 -1
- package/dist/{DesignReferenceSidebar-BDhEeaAh.js → DesignReferenceSidebar-rcE_BvUd.js} +55 -47
- package/dist/{IssuesPanel-CiOjeRFI.js → IssuesPanel-Cig46N1i.js} +23 -15
- package/dist/{MergeTagInput-RytOlh1A.js → MergeTagInput-D1hzsn2b.js} +42 -33
- package/dist/{MergeTagModeToggle-Bi-FydXj.js → MergeTagModeToggle-CH9wR5YF.js} +70 -58
- package/dist/{ParagraphEditor-C87tkmtE.js → ParagraphEditor-CT2AdMdZ.js} +365 -323
- package/dist/{RestoreVersionDialog-Db5rZRMA.js → RestoreVersionDialog-mdqgQxFR.js} +3 -3
- package/dist/{RichTextEditorContent-BmTcV2-a.js → RichTextEditorContent-riOB-rKD.js} +48 -36
- package/dist/{SaveBlockDialog-CDCzx6Bo.js → SaveBlockDialog-Cn2v4Lpj.js} +6 -6
- package/dist/{SavedBlocksBrowserModal-DQR6kJB1.js → SavedBlocksBrowserModal-BORqqASb.js} +7 -7
- package/dist/{SavedBlocksPanels-DFzV0CRD.js → SavedBlocksPanels-ffBnWuVU.js} +1 -1
- package/dist/{SavedBlocksPickBar-XyXmnSnO.js → SavedBlocksPickBar-BmQC2tWN.js} +2 -2
- package/dist/{TemplateScoringPanel-CpyEKMzC.js → TemplateScoringPanel-CxAtdreR.js} +36 -27
- package/dist/{TestEmailModal-DIfJy9eE.js → TestEmailModal-Cjn1padY.js} +7 -7
- package/dist/{TestEmailPanel-C8Wx5yPS.js → TestEmailPanel-Bf3XZ1jn.js} +1 -1
- package/dist/{TitleEditor-iNFOisr4.js → TitleEditor-pYEUX6lR.js} +5 -5
- package/dist/{TplModal-CowM3o_F.js → TplModal-DRx4ytx8.js} +1 -1
- package/dist/{VersionHistoryMenu-CV90OhXs.js → VersionHistoryMenu-CrNrGsaa.js} +21 -13
- package/dist/{VersionHistoryPanels-BE3pplJG.js → VersionHistoryPanels-CsuQk6W3.js} +1 -1
- package/dist/{VersionPreviewBanner-BwUWBtlH.js → VersionPreviewBanner-BqbO0Zss.js} +1 -1
- package/dist/blockTypeIcons-D_4HdaY9.js +175 -0
- package/dist/bundle-stats.json +6 -6
- package/dist/{ca-C0hfqt4U.js → ca-D9S-UCfZ.js} +2 -0
- package/dist/cdn/chunks/{AiChatSidebar-BEnIWn6s.js → AiChatSidebar-D0f74_nS.js} +3 -3
- package/dist/cdn/chunks/{AiChatSidebar-BEnIWn6s.js.map → AiChatSidebar-D0f74_nS.js.map} +1 -1
- package/dist/cdn/chunks/{AiFeatureMenu-DMl23akc.js → AiFeatureMenu-DwGb3eF9.js} +3 -3
- package/dist/cdn/chunks/{AiFeatureMenu-DMl23akc.js.map → AiFeatureMenu-DwGb3eF9.js.map} +1 -1
- package/dist/cdn/chunks/{BlockIssueBadge-CloK4k3M.js → BlockIssueBadge-CosQgeJ-.js} +2 -2
- package/dist/cdn/chunks/{BlockIssueBadge-CloK4k3M.js.map → BlockIssueBadge-CosQgeJ-.js.map} +1 -1
- package/dist/cdn/chunks/BlockPreviewCanvas-CIpZ2a6g.js +133 -0
- package/dist/cdn/chunks/BlockPreviewCanvas-CIpZ2a6g.js.map +1 -0
- package/dist/cdn/chunks/{CloudHeaderExtras-b4KpVeUN.js → CloudHeaderExtras-CQzQwKFB.js} +3 -3
- package/dist/cdn/chunks/{CloudHeaderExtras-b4KpVeUN.js.map → CloudHeaderExtras-CQzQwKFB.js.map} +1 -1
- package/dist/cdn/chunks/{CloudPanels-DzwOq9lp.js → CloudPanels-BmexuLOU.js} +4 -4
- package/dist/cdn/chunks/{CloudPanels-DzwOq9lp.js.map → CloudPanels-BmexuLOU.js.map} +1 -1
- package/dist/cdn/chunks/{CollaboratorBar-WXKvpoGK.js → CollaboratorBar-DEICobpp.js} +3 -3
- package/dist/cdn/chunks/{CollaboratorBar-WXKvpoGK.js.map → CollaboratorBar-DEICobpp.js.map} +1 -1
- package/dist/cdn/chunks/{ColorPicker-BubTDiS1.js → ColorPicker-C7yC58FK.js} +2 -2
- package/dist/cdn/chunks/{ColorPicker-BubTDiS1.js.map → ColorPicker-C7yC58FK.js.map} +1 -1
- package/dist/cdn/chunks/{CommentsPanel-DAA2VqX4.js → CommentsPanel-OjmKxLL7.js} +2 -2
- package/dist/cdn/chunks/{CommentsPanel-DAA2VqX4.js.map → CommentsPanel-OjmKxLL7.js.map} +1 -1
- package/dist/cdn/chunks/{CommentsSidebar-Ci0M2ePp.js → CommentsSidebar-C4pWZGpy.js} +2 -2
- package/dist/cdn/chunks/{CommentsSidebar-Ci0M2ePp.js.map → CommentsSidebar-C4pWZGpy.js.map} +1 -1
- package/dist/cdn/chunks/{CountdownToolbar-CzZq26Vp.js → CountdownToolbar-wlJOxyAl.js} +2 -2
- package/dist/cdn/chunks/{CountdownToolbar-CzZq26Vp.js.map → CountdownToolbar-wlJOxyAl.js.map} +1 -1
- package/dist/cdn/chunks/{DesignReferenceSidebar-C_ehdX5C.js → DesignReferenceSidebar-DELhnh8h.js} +3 -3
- package/dist/cdn/chunks/{DesignReferenceSidebar-C_ehdX5C.js.map → DesignReferenceSidebar-DELhnh8h.js.map} +1 -1
- package/dist/cdn/chunks/{IssuesPanel-BXAN2_al.js → IssuesPanel-C9i3o8aE.js} +2 -2
- package/dist/cdn/chunks/{IssuesPanel-BXAN2_al.js.map → IssuesPanel-C9i3o8aE.js.map} +1 -1
- package/dist/cdn/chunks/{MergeTagInput-1vcI9uQH.js → MergeTagInput-D76Kyvgu.js} +5 -5
- package/dist/cdn/chunks/{MergeTagInput-1vcI9uQH.js.map → MergeTagInput-D76Kyvgu.js.map} +1 -1
- package/dist/cdn/chunks/{MergeTagModeToggle-B_mUYJo4.js → MergeTagModeToggle-Dz3gxN2y.js} +3 -3
- package/dist/cdn/chunks/{MergeTagModeToggle-B_mUYJo4.js.map → MergeTagModeToggle-Dz3gxN2y.js.map} +1 -1
- package/dist/cdn/chunks/{ParagraphEditor-DCDHMcmx.js → ParagraphEditor-DQn0HMfV.js} +176 -172
- package/dist/cdn/chunks/{ParagraphEditor-DCDHMcmx.js.map → ParagraphEditor-DQn0HMfV.js.map} +1 -1
- package/dist/cdn/chunks/{RestoreVersionDialog-BkSSwf-Q.js → RestoreVersionDialog-BdjOL8Oy.js} +3 -3
- package/dist/cdn/chunks/{RestoreVersionDialog-BkSSwf-Q.js.map → RestoreVersionDialog-BdjOL8Oy.js.map} +1 -1
- package/dist/cdn/chunks/{RichTextEditorContent-S4KogjIj.js → RichTextEditorContent-Drzwgh0J.js} +4 -4
- package/dist/cdn/chunks/{RichTextEditorContent-S4KogjIj.js.map → RichTextEditorContent-Drzwgh0J.js.map} +1 -1
- package/dist/cdn/chunks/{SaveBlockDialog-BH774Nt0.js → SaveBlockDialog-B3rbmXSM.js} +5 -5
- package/dist/cdn/chunks/{SaveBlockDialog-BH774Nt0.js.map → SaveBlockDialog-B3rbmXSM.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksBrowserModal-CSUqw_dD.js → SavedBlocksBrowserModal-CkUXlnd2.js} +6 -6
- package/dist/cdn/chunks/{SavedBlocksBrowserModal-CSUqw_dD.js.map → SavedBlocksBrowserModal-CkUXlnd2.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksPanels-B6ApbCjG.js → SavedBlocksPanels-BPi3PZKP.js} +2 -2
- package/dist/cdn/chunks/{SavedBlocksPanels-B6ApbCjG.js.map → SavedBlocksPanels-BPi3PZKP.js.map} +1 -1
- package/dist/cdn/chunks/{SavedBlocksPickBar-C9MXSRcR.js → SavedBlocksPickBar-BvB9A5W2.js} +3 -3
- package/dist/cdn/chunks/{SavedBlocksPickBar-C9MXSRcR.js.map → SavedBlocksPickBar-BvB9A5W2.js.map} +1 -1
- package/dist/cdn/chunks/{TemplateScoringPanel-QVOxc9TZ.js → TemplateScoringPanel-BBCyLnOi.js} +2 -2
- package/dist/cdn/chunks/{TemplateScoringPanel-QVOxc9TZ.js.map → TemplateScoringPanel-BBCyLnOi.js.map} +1 -1
- package/dist/cdn/chunks/{TestEmailModal-_CZvaO58.js → TestEmailModal-DAGTsBqi.js} +7 -7
- package/dist/cdn/chunks/{TestEmailModal-_CZvaO58.js.map → TestEmailModal-DAGTsBqi.js.map} +1 -1
- package/dist/cdn/chunks/{TestEmailPanel-DXLxvyrD.js → TestEmailPanel-BfenVvfx.js} +2 -2
- package/dist/cdn/chunks/{TestEmailPanel-DXLxvyrD.js.map → TestEmailPanel-BfenVvfx.js.map} +1 -1
- package/dist/cdn/chunks/{TitleEditor-BuCOahW3.js → TitleEditor-oQ4gr6wS.js} +5 -5
- package/dist/cdn/chunks/{TitleEditor-BuCOahW3.js.map → TitleEditor-oQ4gr6wS.js.map} +1 -1
- package/dist/cdn/chunks/{TplModal-CqY8R3hn.js → TplModal-DxOMcVwp.js} +2 -2
- package/dist/cdn/chunks/{TplModal-CqY8R3hn.js.map → TplModal-DxOMcVwp.js.map} +1 -1
- package/dist/cdn/chunks/{VersionHistoryMenu-DDjIBvad.js → VersionHistoryMenu-BfVUvWHT.js} +4 -4
- package/dist/cdn/chunks/{VersionHistoryMenu-DDjIBvad.js.map → VersionHistoryMenu-BfVUvWHT.js.map} +1 -1
- package/dist/cdn/chunks/{VersionHistoryPanels-BuTw04T5.js → VersionHistoryPanels-NpDb641L.js} +2 -2
- package/dist/cdn/chunks/{VersionHistoryPanels-BuTw04T5.js.map → VersionHistoryPanels-NpDb641L.js.map} +1 -1
- package/dist/cdn/chunks/{VersionPreviewBanner-fGAv20qI.js → VersionPreviewBanner-Cpgt4xHc.js} +2 -2
- package/dist/cdn/chunks/{VersionPreviewBanner-fGAv20qI.js.map → VersionPreviewBanner-Cpgt4xHc.js.map} +1 -1
- package/dist/cdn/chunks/{blockTypeIcons-ZEzEpCti.js → blockTypeIcons-t9vvaiuH.js} +2 -2
- package/dist/cdn/chunks/{blockTypeIcons-ZEzEpCti.js.map → blockTypeIcons-t9vvaiuH.js.map} +1 -1
- package/dist/cdn/chunks/{ca-C0hfqt4U.js → ca-D9S-UCfZ.js} +3 -1
- package/dist/cdn/chunks/{ca-C0hfqt4U.js.map → ca-D9S-UCfZ.js.map} +1 -1
- package/dist/cdn/chunks/{cloud-BP5-6__d.js → cloud-CullB76F.js} +2 -2
- package/dist/cdn/chunks/{cloud-BP5-6__d.js.map → cloud-CullB76F.js.map} +1 -1
- package/dist/cdn/chunks/{createCloudRuntime-JFE-sxbT.js → createCloudRuntime-Cx2JpUYU.js} +4 -4
- package/dist/cdn/chunks/{createCloudRuntime-JFE-sxbT.js.map → createCloudRuntime-Cx2JpUYU.js.map} +1 -1
- package/dist/{de-C6J2Iae8.js → cdn/chunks/de-BUPszLpi.js} +4 -0
- package/dist/cdn/chunks/{de-C6J2Iae8.js.map → de-BUPszLpi.js.map} +1 -1
- package/dist/cdn/chunks/{en-BaUYOQi8.js → en-BbOC5x3w.js} +3 -1
- package/dist/cdn/chunks/en-BbOC5x3w.js.map +1 -0
- package/dist/cdn/chunks/en-rGHphLWo.js +2 -0
- package/dist/cdn/chunks/{es-CKDYfJYn.js → es-0bCDcT9p.js} +3 -1
- package/dist/cdn/chunks/{es-CKDYfJYn.js.map → es-0bCDcT9p.js.map} +1 -1
- package/dist/cdn/chunks/{extensions-7z04EIGg.js → extensions-BpXY7jO5.js} +3 -3
- package/dist/cdn/chunks/{extensions-7z04EIGg.js.map → extensions-BpXY7jO5.js.map} +1 -1
- package/dist/{fr-L8DR73mK.js → cdn/chunks/fr-Brr8mJ9e.js} +4 -0
- package/dist/cdn/chunks/fr-Brr8mJ9e.js.map +1 -0
- package/dist/cdn/chunks/icons-BLxcQUck.js +1675 -0
- package/dist/cdn/chunks/icons-BLxcQUck.js.map +1 -0
- package/dist/cdn/chunks/{nl-GDWeuX18.js → nl-Co3_RL0M.js} +3 -1
- package/dist/cdn/chunks/nl-Co3_RL0M.js.map +1 -0
- package/dist/cdn/chunks/{preRenderCustomBlocks-LFB-e-0m.js → preRenderCustomBlocks-Bdpiiw4A.js} +2 -2
- package/dist/cdn/chunks/{preRenderCustomBlocks-LFB-e-0m.js.map → preRenderCustomBlocks-Bdpiiw4A.js.map} +1 -1
- package/dist/cdn/chunks/{pt-BR-B1AVVhWj.js → pt-BR-BECez5b0.js} +3 -1
- package/dist/cdn/chunks/{pt-BR-B1AVVhWj.js.map → pt-BR-BECez5b0.js.map} +1 -1
- package/dist/cdn/chunks/{src-BDvZrpFH.js → src-BC-eolWY.js} +161 -160
- package/dist/cdn/chunks/src-BC-eolWY.js.map +1 -0
- package/dist/cdn/chunks/{src-BM3f9I7t.js → src-CUvZWL6Y.js} +83 -83
- package/dist/cdn/chunks/src-CUvZWL6Y.js.map +1 -0
- package/dist/cdn/chunks/{src-Cxl-9O-L.js → src-CaXeO-gG.js} +17 -17
- package/dist/cdn/chunks/{src-Cxl-9O-L.js.map → src-CaXeO-gG.js.map} +1 -1
- package/dist/cdn/chunks/{src-CLoCCDfs.js → src-Dwgq7hf4.js} +71 -48
- package/dist/cdn/chunks/src-Dwgq7hf4.js.map +1 -0
- package/dist/cdn/chunks/{useEditorCore-ehUSEsbw.js → useEditorCore-D4MytYB9.js} +495 -485
- package/dist/cdn/chunks/useEditorCore-D4MytYB9.js.map +1 -0
- package/dist/cdn/chunks/{useMergeTag-TLhF2fGK.js → useMergeTag-CSocWpxV.js} +2 -2
- package/dist/cdn/chunks/{useMergeTag-TLhF2fGK.js.map → useMergeTag-CSocWpxV.js.map} +1 -1
- package/dist/cdn/editor.css +1 -1
- package/dist/cdn/editor.js +920 -907
- package/dist/cdn/editor.js.map +1 -1
- package/dist/check-CY-Ec6FV.js +11 -0
- package/dist/chevron-down-BghbWA9p.js +11 -0
- package/dist/chevron-up-n3qFAPS3.js +11 -0
- package/dist/circle-alert-L5uGGFRP.js +30 -0
- package/dist/clock-Dgnwp18n.js +16 -0
- package/dist/{cloud-BMzRKCbk.js → cloud-B1c4XIsn.js} +1 -1
- package/dist/{createCloudRuntime-DbTFm1ES.js → createCloudRuntime-PevFSH74.js} +2 -2
- package/dist/createLucideIcon-05lB8iWe.js +96 -0
- package/dist/{cdn/chunks/de-C6J2Iae8.js → de-BUPszLpi.js} +2 -2
- package/dist/{dist-PL6vP4SC.js → dist-tGkjkX-v.js} +143 -122
- package/dist/{en-BaUYOQi8.js → en-BbOC5x3w.js} +2 -0
- package/dist/{es-CKDYfJYn.js → es-0bCDcT9p.js} +2 -0
- package/dist/{extensions-Mf8iHey9.js → extensions-Bawm4BOM.js} +2 -2
- package/dist/{cdn/chunks/fr-L8DR73mK.js → fr-Brr8mJ9e.js} +2 -2
- package/dist/image-up-ovhjl9u9.js +27 -0
- package/dist/info-c3KI927I.js +23 -0
- package/dist/loader-circle-B2Y8xZQb.js +12 -0
- package/dist/message-circle-B7K-naUa.js +11 -0
- package/dist/{nl-GDWeuX18.js → nl-Co3_RL0M.js} +2 -0
- package/dist/pencil-BhWTFcp4.js +14 -0
- package/dist/{preRenderCustomBlocks-CSIF-HyJ.js → preRenderCustomBlocks-DFXH54Zr.js} +1 -1
- package/dist/{pt-BR-B1AVVhWj.js → pt-BR-BECez5b0.js} +2 -0
- package/dist/refresh-cw-BqUR5vgO.js +37 -0
- package/dist/send-D1vvuW79.js +14 -0
- package/dist/shield-check-DjK54PnW.js +14 -0
- package/dist/sparkles-DNdS9V_3.js +28 -0
- package/dist/style.css +1 -1
- package/dist/templatical-editor.js +1238 -1167
- package/dist/text-align-start-Bcmo_VUY.js +58 -0
- package/dist/trash-C9bMXvw4.js +30 -0
- package/dist/triangle-alert-Bn8Bd2Yv.js +22 -0
- package/dist/upload-DKgg1gno.js +21 -0
- package/dist/{useEditorCore-DdkQuTHl.js → useEditorCore-CYGvurZa.js} +1089 -1026
- package/dist/{useMergeTag-gSuYus-M.js → useMergeTag-C9GEpljB.js} +1 -1
- package/dist/{useScrollToBlock-CdI8fGqt.js → useScrollToBlock-oUx1HIZ2.js} +27 -23
- package/dist/x-BPKoRPTG.js +14 -0
- package/package.json +9 -9
- package/dist/BlockPreviewCanvas-B621ANn9.js +0 -129
- package/dist/blockTypeIcons-DQsKtHik.js +0 -134
- package/dist/cdn/chunks/BlockPreviewCanvas-DSiJFJa0.js +0 -131
- package/dist/cdn/chunks/BlockPreviewCanvas-DSiJFJa0.js.map +0 -1
- package/dist/cdn/chunks/en-BaUYOQi8.js.map +0 -1
- package/dist/cdn/chunks/en-mEKGL1PX.js +0 -2
- package/dist/cdn/chunks/fr-L8DR73mK.js.map +0 -1
- package/dist/cdn/chunks/icons-SP5Itd-A.js +0 -1218
- package/dist/cdn/chunks/icons-SP5Itd-A.js.map +0 -1
- package/dist/cdn/chunks/nl-GDWeuX18.js.map +0 -1
- package/dist/cdn/chunks/src-BDvZrpFH.js.map +0 -1
- package/dist/cdn/chunks/src-BM3f9I7t.js.map +0 -1
- package/dist/cdn/chunks/src-CLoCCDfs.js.map +0 -1
- package/dist/cdn/chunks/useEditorCore-ehUSEsbw.js.map +0 -1
- package/dist/check-JK8Uacq0.js +0 -7
- package/dist/chevron-down-a-fb_Ijn.js +0 -7
- package/dist/chevron-up-x4l0et_Y.js +0 -7
- package/dist/circle-alert-CJDW5LZo.js +0 -25
- package/dist/clock-BW6rXk2f.js +0 -12
- package/dist/createLucideIcon-Bvw1Zx56.js +0 -43
- package/dist/image-up-CuzFc1mu.js +0 -23
- package/dist/info-DybAwcA3.js +0 -19
- package/dist/loader-circle-t-SVgmJ3.js +0 -7
- package/dist/message-circle-DtwKrlhN.js +0 -7
- package/dist/pencil-2qhC-Y4q.js +0 -10
- package/dist/refresh-cw-C8SBuPdg.js +0 -29
- package/dist/send-BoqJliF6.js +0 -10
- package/dist/shield-check-D0dMaHtE.js +0 -10
- package/dist/sparkles-Dy2BJjiX.js +0 -23
- package/dist/text-align-start-DrxjxvIy.js +0 -43
- package/dist/trash-rYMzzHZd.js +0 -25
- package/dist/triangle-alert-DxnFj4-B.js +0 -17
- package/dist/upload-DZu1adQz.js +0 -17
- package/dist/x-DJOd1hS4.js +0 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { S as e, X as t } from "./vue.runtime.esm-bundler-D9JUcKrV.js";
|
|
2
|
-
import { I as n, k as r, o as i } from "./dist-
|
|
2
|
+
import { I as n, k as r, o as i } from "./dist-tGkjkX-v.js";
|
|
3
3
|
import { D as a, E as o, O as s, P as c, j as l, k as u } from "./keys-C3P1yxnr.js";
|
|
4
4
|
//#region src/composables/useMergeTag.ts
|
|
5
5
|
function d() {
|
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import { T as e } from "./vue.runtime.esm-bundler-D9JUcKrV.js";
|
|
2
|
-
import { t } from "./createLucideIcon-
|
|
2
|
+
import { t } from "./createLucideIcon-05lB8iWe.js";
|
|
3
3
|
import { t as n } from "./useEditorRoot-DkRGTQRs.js";
|
|
4
|
-
var r = t(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
4
|
+
var r = t({
|
|
5
|
+
name: "list-checks",
|
|
6
|
+
size: 24,
|
|
7
|
+
node: [
|
|
8
|
+
["path", {
|
|
9
|
+
d: "M13 5h8",
|
|
10
|
+
key: "a7qcls"
|
|
11
|
+
}],
|
|
12
|
+
["path", {
|
|
13
|
+
d: "M13 12h8",
|
|
14
|
+
key: "h98zly"
|
|
15
|
+
}],
|
|
16
|
+
["path", {
|
|
17
|
+
d: "M13 19h8",
|
|
18
|
+
key: "c3s6r1"
|
|
19
|
+
}],
|
|
20
|
+
["path", {
|
|
21
|
+
d: "m3 17 2 2 4-4",
|
|
22
|
+
key: "1jhpwq"
|
|
23
|
+
}],
|
|
24
|
+
["path", {
|
|
25
|
+
d: "m3 7 2 2 4-4",
|
|
26
|
+
key: "1obspn"
|
|
27
|
+
}]
|
|
28
|
+
]
|
|
29
|
+
});
|
|
26
30
|
//#endregion
|
|
27
31
|
//#region src/composables/useScrollToBlock.ts
|
|
28
32
|
function i() {
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@templatical/editor",
|
|
3
3
|
"description": "Vue 3 visual drag-and-drop email editor powered by Templatical",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.35.0",
|
|
5
5
|
"bugs": "https://github.com/templatical/sdk/issues",
|
|
6
6
|
"devDependencies": {
|
|
7
|
-
"@lucide/vue": "^1.
|
|
8
|
-
"@templatical/core": "0.
|
|
9
|
-
"@templatical/quality": "0.
|
|
10
|
-
"@templatical/types": "0.
|
|
7
|
+
"@lucide/vue": "^1.42.0",
|
|
8
|
+
"@templatical/core": "0.35.0",
|
|
9
|
+
"@templatical/quality": "0.35.0",
|
|
10
|
+
"@templatical/types": "0.35.0",
|
|
11
11
|
"@tiptap/core": "^3.31.3",
|
|
12
12
|
"@tiptap/extension-color": "^3.31.3",
|
|
13
13
|
"@tiptap/extension-font-family": "^3.31.3",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
25
25
|
"@vue/test-utils": "^2.5.0",
|
|
26
26
|
"@vueuse/core": "^14.4.0",
|
|
27
|
-
"es-module-lexer": "^
|
|
27
|
+
"es-module-lexer": "^3.0.1",
|
|
28
28
|
"happy-dom": "^20.14.0",
|
|
29
29
|
"jsdom": "30.0.1",
|
|
30
30
|
"liquidjs": "^10.29.0",
|
|
@@ -63,9 +63,9 @@
|
|
|
63
63
|
"license": "FSL-1.1-MIT",
|
|
64
64
|
"module": "./dist/templatical-editor.js",
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@templatical/media-library": "0.
|
|
67
|
-
"@templatical/quality": "0.
|
|
68
|
-
"@templatical/renderer": "0.
|
|
66
|
+
"@templatical/media-library": "0.35.0",
|
|
67
|
+
"@templatical/quality": "0.35.0",
|
|
68
|
+
"@templatical/renderer": "0.35.0"
|
|
69
69
|
},
|
|
70
70
|
"peerDependenciesMeta": {
|
|
71
71
|
"@templatical/renderer": {
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
|
|
2
|
-
import { A as t, N as n, Ot as r, P as i, S as a, c as o, d as s, j as c, k as l, l as u, r as d, rt as f, s as p, v as m } from "./vue.runtime.esm-bundler-D9JUcKrV.js";
|
|
3
|
-
import { R as h, a as g, b as _, d as v, f as y, g as b, h as x, i as S, l as C, m as w, n as T, p as E, r as D, v as O, y as k } from "./useEditorCore-DdkQuTHl.js";
|
|
4
|
-
import { A, d as j, h as M, q as N, s as P } from "./keys-C3P1yxnr.js";
|
|
5
|
-
import { n as F, t as I } from "./emailFrameWidth-BmFCN2dp.js";
|
|
6
|
-
//#region src/components/blocks/PreviewSectionBlock.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
-
var L = { class: "tpl:w-full" }, R = { class: "tpl:flex tpl:gap-0" }, z = /* @__PURE__ */ m({
|
|
8
|
-
name: "PreviewSectionBlock",
|
|
9
|
-
__name: "PreviewSectionBlock",
|
|
10
|
-
props: {
|
|
11
|
-
block: {},
|
|
12
|
-
viewport: {}
|
|
13
|
-
},
|
|
14
|
-
setup(e) {
|
|
15
|
-
let t = {
|
|
16
|
-
title: C,
|
|
17
|
-
paragraph: w,
|
|
18
|
-
image: b,
|
|
19
|
-
video: T,
|
|
20
|
-
button: h,
|
|
21
|
-
divider: k,
|
|
22
|
-
social: g,
|
|
23
|
-
menu: x,
|
|
24
|
-
table: D,
|
|
25
|
-
spacer: S,
|
|
26
|
-
html: O,
|
|
27
|
-
custom: _
|
|
28
|
-
}, m = e, y = a(P, null), A = p(() => {
|
|
29
|
-
switch (m.block.columns) {
|
|
30
|
-
case "2": return ["50%", "50%"];
|
|
31
|
-
case "3": return [
|
|
32
|
-
"33.33%",
|
|
33
|
-
"33.33%",
|
|
34
|
-
"33.33%"
|
|
35
|
-
];
|
|
36
|
-
case "1-2": return ["33.33%", "66.67%"];
|
|
37
|
-
case "2-1": return ["66.67%", "33.33%"];
|
|
38
|
-
default: return ["100%"];
|
|
39
|
-
}
|
|
40
|
-
}), j = p(() => {
|
|
41
|
-
let e = A.value.length, t = [...m.block.children];
|
|
42
|
-
for (; t.length < e;) t.push([]);
|
|
43
|
-
return t.slice(0, e);
|
|
44
|
-
});
|
|
45
|
-
function M(e) {
|
|
46
|
-
return j.value[e] || [];
|
|
47
|
-
}
|
|
48
|
-
function N(e) {
|
|
49
|
-
return E(e, y, t);
|
|
50
|
-
}
|
|
51
|
-
return (e, t) => {
|
|
52
|
-
let a = n("PreviewSectionBlock", !0);
|
|
53
|
-
return l(), s("div", L, [o("div", R, [(l(!0), s(d, null, c(j.value, (e, t) => (l(), s("div", {
|
|
54
|
-
key: t,
|
|
55
|
-
style: r({ width: A.value[t] })
|
|
56
|
-
}, [(l(!0), s(d, null, c(M(t), (e) => (l(), s("div", {
|
|
57
|
-
key: e.id,
|
|
58
|
-
style: r(f(v)(e))
|
|
59
|
-
}, [e.type === "section" ? (l(), u(a, {
|
|
60
|
-
key: 0,
|
|
61
|
-
block: e,
|
|
62
|
-
viewport: "desktop"
|
|
63
|
-
}, null, 8, ["block"])) : (l(), u(i(N(e)), {
|
|
64
|
-
key: 1,
|
|
65
|
-
block: e,
|
|
66
|
-
viewport: "desktop"
|
|
67
|
-
}, null, 8, ["block"]))], 4))), 128))], 4))), 128))])]);
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}), B = ["lang"], V = /*@__PURE__*/ m({
|
|
71
|
-
__name: "BlockPreviewCanvas",
|
|
72
|
-
props: {
|
|
73
|
-
blocks: {},
|
|
74
|
-
viewport: { default: "desktop" },
|
|
75
|
-
applyConditionFilter: {
|
|
76
|
-
type: Boolean,
|
|
77
|
-
default: !0
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
setup(e) {
|
|
81
|
-
let n = e, m = a(P), L = a(M, null), R = a(j, null), V = a(A, null);
|
|
82
|
-
t(N, p(() => V?.value ?? !1));
|
|
83
|
-
let H = p(() => n.applyConditionFilter ? n.blocks.filter((e) => !R?.isHidden(e.id)) : n.blocks), U = p(() => F(L?.content.value.settings, n.viewport)), W = p(() => L ? y(L.content.value.settings) : {}), G = p(() => L?.content.value.settings?.locale?.trim() || void 0), K = p(() => L?.content.value.settings.backgroundColor || "var(--tpl-canvas-bg)"), q = p(() => U.value + 192), J = {
|
|
84
|
-
section: z,
|
|
85
|
-
title: C,
|
|
86
|
-
paragraph: w,
|
|
87
|
-
image: b,
|
|
88
|
-
video: T,
|
|
89
|
-
button: h,
|
|
90
|
-
divider: k,
|
|
91
|
-
social: g,
|
|
92
|
-
menu: x,
|
|
93
|
-
table: D,
|
|
94
|
-
spacer: S,
|
|
95
|
-
html: O,
|
|
96
|
-
custom: _
|
|
97
|
-
};
|
|
98
|
-
function Y(e) {
|
|
99
|
-
return E(e, m, J);
|
|
100
|
-
}
|
|
101
|
-
return (t, n) => (l(), s("div", {
|
|
102
|
-
"data-testid": "block-preview-stage",
|
|
103
|
-
class: "tpl:pointer-events-none tpl:mx-auto tpl:flex tpl:select-none tpl:justify-center tpl:rounded-lg",
|
|
104
|
-
style: r({
|
|
105
|
-
width: `${q.value}px`,
|
|
106
|
-
minWidth: `${U.value}px`,
|
|
107
|
-
maxWidth: "100%",
|
|
108
|
-
backgroundColor: K.value,
|
|
109
|
-
boxShadow: "var(--tpl-shadow-sm)"
|
|
110
|
-
})
|
|
111
|
-
}, [o("div", {
|
|
112
|
-
"data-testid": "block-preview-canvas",
|
|
113
|
-
lang: G.value,
|
|
114
|
-
style: r({
|
|
115
|
-
width: `${U.value}px`,
|
|
116
|
-
transition: f(I),
|
|
117
|
-
...W.value
|
|
118
|
-
})
|
|
119
|
-
}, [(l(!0), s(d, null, c(H.value, (t) => (l(), s("div", {
|
|
120
|
-
key: t.id,
|
|
121
|
-
style: r(f(v)(t))
|
|
122
|
-
}, [(l(), u(i(Y(t)), {
|
|
123
|
-
block: t,
|
|
124
|
-
viewport: e.viewport
|
|
125
|
-
}, null, 8, ["block", "viewport"]))], 4))), 128))], 12, B)], 4));
|
|
126
|
-
}
|
|
127
|
-
}), H = /* @__PURE__ */ e({ default: () => U }), U = V;
|
|
128
|
-
//#endregion
|
|
129
|
-
export { H as n, U as t };
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { A as e, I as t, M as n, j as r, k as i } from "./useEditorCore-DdkQuTHl.js";
|
|
2
|
-
import { t as a } from "./createLucideIcon-Bvw1Zx56.js";
|
|
3
|
-
var o = a("columns-3", [
|
|
4
|
-
["rect", {
|
|
5
|
-
width: "18",
|
|
6
|
-
height: "18",
|
|
7
|
-
x: "3",
|
|
8
|
-
y: "3",
|
|
9
|
-
rx: "2",
|
|
10
|
-
key: "afitv7"
|
|
11
|
-
}],
|
|
12
|
-
["path", {
|
|
13
|
-
d: "M9 3v18",
|
|
14
|
-
key: "fh3hqa"
|
|
15
|
-
}],
|
|
16
|
-
["path", {
|
|
17
|
-
d: "M15 3v18",
|
|
18
|
-
key: "14nvp0"
|
|
19
|
-
}]
|
|
20
|
-
]), s = a("heading", [
|
|
21
|
-
["path", {
|
|
22
|
-
d: "M6 12h12",
|
|
23
|
-
key: "8npq4p"
|
|
24
|
-
}],
|
|
25
|
-
["path", {
|
|
26
|
-
d: "M6 20V4",
|
|
27
|
-
key: "1w1bmo"
|
|
28
|
-
}],
|
|
29
|
-
["path", {
|
|
30
|
-
d: "M18 20V4",
|
|
31
|
-
key: "o2hl4u"
|
|
32
|
-
}]
|
|
33
|
-
]), c = a("minus", [["path", {
|
|
34
|
-
d: "M5 12h14",
|
|
35
|
-
key: "1ays0h"
|
|
36
|
-
}]]), l = a("move-vertical", [
|
|
37
|
-
["path", {
|
|
38
|
-
d: "M12 2v20",
|
|
39
|
-
key: "t6zp3m"
|
|
40
|
-
}],
|
|
41
|
-
["path", {
|
|
42
|
-
d: "m8 18 4 4 4-4",
|
|
43
|
-
key: "bh5tu3"
|
|
44
|
-
}],
|
|
45
|
-
["path", {
|
|
46
|
-
d: "m8 6 4-4 4 4",
|
|
47
|
-
key: "ybng9g"
|
|
48
|
-
}]
|
|
49
|
-
]), u = a("package", [
|
|
50
|
-
["path", {
|
|
51
|
-
d: "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",
|
|
52
|
-
key: "1a0edw"
|
|
53
|
-
}],
|
|
54
|
-
["path", {
|
|
55
|
-
d: "M12 22V12",
|
|
56
|
-
key: "d0xqtd"
|
|
57
|
-
}],
|
|
58
|
-
["polyline", {
|
|
59
|
-
points: "3.29 7 12 12 20.71 7",
|
|
60
|
-
key: "ousv84"
|
|
61
|
-
}],
|
|
62
|
-
["path", {
|
|
63
|
-
d: "m7.5 4.27 9 5.15",
|
|
64
|
-
key: "1c824w"
|
|
65
|
-
}]
|
|
66
|
-
]), d = a("pilcrow", [
|
|
67
|
-
["path", {
|
|
68
|
-
d: "M13 4v16",
|
|
69
|
-
key: "8vvj80"
|
|
70
|
-
}],
|
|
71
|
-
["path", {
|
|
72
|
-
d: "M17 4v16",
|
|
73
|
-
key: "7dpous"
|
|
74
|
-
}],
|
|
75
|
-
["path", {
|
|
76
|
-
d: "M19 4H9.5a4.5 4.5 0 0 0 0 9H13",
|
|
77
|
-
key: "sh4n9v"
|
|
78
|
-
}]
|
|
79
|
-
]), f = a("play", [["path", {
|
|
80
|
-
d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",
|
|
81
|
-
key: "10ikf1"
|
|
82
|
-
}]]), p = a("rectangle-horizontal", [["rect", {
|
|
83
|
-
width: "20",
|
|
84
|
-
height: "12",
|
|
85
|
-
x: "2",
|
|
86
|
-
y: "6",
|
|
87
|
-
rx: "2",
|
|
88
|
-
key: "9lu3g6"
|
|
89
|
-
}]]), m = a("search", [["path", {
|
|
90
|
-
d: "m21 21-4.34-4.34",
|
|
91
|
-
key: "14j7rj"
|
|
92
|
-
}], ["circle", {
|
|
93
|
-
cx: "11",
|
|
94
|
-
cy: "11",
|
|
95
|
-
r: "8",
|
|
96
|
-
key: "4ej97u"
|
|
97
|
-
}]]), h = a("timer", [
|
|
98
|
-
["line", {
|
|
99
|
-
x1: "10",
|
|
100
|
-
x2: "14",
|
|
101
|
-
y1: "2",
|
|
102
|
-
y2: "2",
|
|
103
|
-
key: "14vaq8"
|
|
104
|
-
}],
|
|
105
|
-
["line", {
|
|
106
|
-
x1: "12",
|
|
107
|
-
x2: "15",
|
|
108
|
-
y1: "14",
|
|
109
|
-
y2: "11",
|
|
110
|
-
key: "17fdiu"
|
|
111
|
-
}],
|
|
112
|
-
["circle", {
|
|
113
|
-
cx: "12",
|
|
114
|
-
cy: "14",
|
|
115
|
-
r: "8",
|
|
116
|
-
key: "1e1u0o"
|
|
117
|
-
}]
|
|
118
|
-
]), g = {
|
|
119
|
-
section: o,
|
|
120
|
-
title: s,
|
|
121
|
-
paragraph: d,
|
|
122
|
-
image: n,
|
|
123
|
-
button: p,
|
|
124
|
-
divider: c,
|
|
125
|
-
video: f,
|
|
126
|
-
social: e,
|
|
127
|
-
menu: r,
|
|
128
|
-
table: i,
|
|
129
|
-
spacer: l,
|
|
130
|
-
countdown: h,
|
|
131
|
-
html: t
|
|
132
|
-
};
|
|
133
|
-
//#endregion
|
|
134
|
-
export { c as i, m as n, u as r, g as t };
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { n as e } from "./rolldown-runtime-B0aSnxlc.js";
|
|
2
|
-
import { E as t, F as n, L as r, N as i, P as a, R as o, S as s, at as c, f as l, g as u, lt as d, m as f, p, u as m } from "./draggable-kbOhCgnk.js";
|
|
3
|
-
import { O as h, _ as g, a as _, c as v, d as y, f as b, h as x, i as S, m as C, n as w, p as T, r as E, u as D, v as O, y as k } from "./useEditorCore-ehUSEsbw.js";
|
|
4
|
-
import { A, d as j, h as M, q as N, s as P } from "./keys-DQp8x7Nx.js";
|
|
5
|
-
import { n as F, t as I } from "./emailFrameWidth-BmFCN2dp.js";
|
|
6
|
-
//#region src/components/blocks/PreviewSectionBlock.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
-
var L = { class: "tpl:w-full" }, R = { class: "tpl:flex tpl:gap-0" }, z = /* @__PURE__ */ s({
|
|
8
|
-
name: "PreviewSectionBlock",
|
|
9
|
-
__name: "PreviewSectionBlock",
|
|
10
|
-
props: {
|
|
11
|
-
block: {},
|
|
12
|
-
viewport: {}
|
|
13
|
-
},
|
|
14
|
-
setup(e) {
|
|
15
|
-
let a = {
|
|
16
|
-
title: v,
|
|
17
|
-
paragraph: T,
|
|
18
|
-
image: x,
|
|
19
|
-
video: w,
|
|
20
|
-
button: h,
|
|
21
|
-
divider: O,
|
|
22
|
-
social: _,
|
|
23
|
-
menu: C,
|
|
24
|
-
table: E,
|
|
25
|
-
spacer: S,
|
|
26
|
-
html: g,
|
|
27
|
-
custom: k
|
|
28
|
-
}, s = e, y = t(P, null), A = l(() => {
|
|
29
|
-
switch (s.block.columns) {
|
|
30
|
-
case "2": return ["50%", "50%"];
|
|
31
|
-
case "3": return [
|
|
32
|
-
"33.33%",
|
|
33
|
-
"33.33%",
|
|
34
|
-
"33.33%"
|
|
35
|
-
];
|
|
36
|
-
case "1-2": return ["33.33%", "66.67%"];
|
|
37
|
-
case "2-1": return ["66.67%", "33.33%"];
|
|
38
|
-
default: return ["100%"];
|
|
39
|
-
}
|
|
40
|
-
}), j = l(() => {
|
|
41
|
-
let e = A.value.length, t = [...s.block.children];
|
|
42
|
-
for (; t.length < e;) t.push([]);
|
|
43
|
-
return t.slice(0, e);
|
|
44
|
-
});
|
|
45
|
-
function M(e) {
|
|
46
|
-
return j.value[e] || [];
|
|
47
|
-
}
|
|
48
|
-
function N(e) {
|
|
49
|
-
return b(e, y, a);
|
|
50
|
-
}
|
|
51
|
-
return (e, t) => {
|
|
52
|
-
let a = r("PreviewSectionBlock", !0);
|
|
53
|
-
return i(), u("div", L, [p("div", R, [(i(!0), u(m, null, n(j.value, (e, t) => (i(), u("div", {
|
|
54
|
-
key: t,
|
|
55
|
-
style: d({ width: A.value[t] })
|
|
56
|
-
}, [(i(!0), u(m, null, n(M(t), (e) => (i(), u("div", {
|
|
57
|
-
key: e.id,
|
|
58
|
-
style: d(c(D)(e))
|
|
59
|
-
}, [e.type === "section" ? (i(), f(a, {
|
|
60
|
-
key: 0,
|
|
61
|
-
block: e,
|
|
62
|
-
viewport: "desktop"
|
|
63
|
-
}, null, 8, ["block"])) : (i(), f(o(N(e)), {
|
|
64
|
-
key: 1,
|
|
65
|
-
block: e,
|
|
66
|
-
viewport: "desktop"
|
|
67
|
-
}, null, 8, ["block"]))], 4))), 128))], 4))), 128))])]);
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}), B = ["lang"], V = /*@__PURE__*/ s({
|
|
71
|
-
__name: "BlockPreviewCanvas",
|
|
72
|
-
props: {
|
|
73
|
-
blocks: {},
|
|
74
|
-
viewport: { default: "desktop" },
|
|
75
|
-
applyConditionFilter: {
|
|
76
|
-
type: Boolean,
|
|
77
|
-
default: !0
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
setup(e) {
|
|
81
|
-
let r = e, s = t(P), L = t(M, null), R = t(j, null), V = t(A, null);
|
|
82
|
-
a(N, l(() => V?.value ?? !1));
|
|
83
|
-
let H = l(() => r.applyConditionFilter ? r.blocks.filter((e) => !R?.isHidden(e.id)) : r.blocks), U = l(() => F(L?.content.value.settings, r.viewport)), W = l(() => L ? y(L.content.value.settings) : {}), G = l(() => L?.content.value.settings?.locale?.trim() || void 0), K = l(() => L?.content.value.settings.backgroundColor || "var(--tpl-canvas-bg)"), q = l(() => U.value + 192), J = {
|
|
84
|
-
section: z,
|
|
85
|
-
title: v,
|
|
86
|
-
paragraph: T,
|
|
87
|
-
image: x,
|
|
88
|
-
video: w,
|
|
89
|
-
button: h,
|
|
90
|
-
divider: O,
|
|
91
|
-
social: _,
|
|
92
|
-
menu: C,
|
|
93
|
-
table: E,
|
|
94
|
-
spacer: S,
|
|
95
|
-
html: g,
|
|
96
|
-
custom: k
|
|
97
|
-
};
|
|
98
|
-
function Y(e) {
|
|
99
|
-
return b(e, s, J);
|
|
100
|
-
}
|
|
101
|
-
return (t, r) => (i(), u("div", {
|
|
102
|
-
"data-testid": "block-preview-stage",
|
|
103
|
-
class: "tpl:pointer-events-none tpl:mx-auto tpl:flex tpl:select-none tpl:justify-center tpl:rounded-lg",
|
|
104
|
-
style: d({
|
|
105
|
-
width: `${q.value}px`,
|
|
106
|
-
minWidth: `${U.value}px`,
|
|
107
|
-
maxWidth: "100%",
|
|
108
|
-
backgroundColor: K.value,
|
|
109
|
-
boxShadow: "var(--tpl-shadow-sm)"
|
|
110
|
-
})
|
|
111
|
-
}, [p("div", {
|
|
112
|
-
"data-testid": "block-preview-canvas",
|
|
113
|
-
lang: G.value,
|
|
114
|
-
style: d({
|
|
115
|
-
width: `${U.value}px`,
|
|
116
|
-
transition: c(I),
|
|
117
|
-
...W.value
|
|
118
|
-
})
|
|
119
|
-
}, [(i(!0), u(m, null, n(H.value, (t) => (i(), u("div", {
|
|
120
|
-
key: t.id,
|
|
121
|
-
style: d(c(D)(t))
|
|
122
|
-
}, [(i(), f(o(Y(t)), {
|
|
123
|
-
block: t,
|
|
124
|
-
viewport: e.viewport
|
|
125
|
-
}, null, 8, ["block", "viewport"]))], 4))), 128))], 12, B)], 4));
|
|
126
|
-
}
|
|
127
|
-
}), H = /* @__PURE__ */ e({ default: () => U }), U = V;
|
|
128
|
-
//#endregion
|
|
129
|
-
export { H as n, U as t };
|
|
130
|
-
|
|
131
|
-
//# sourceMappingURL=BlockPreviewCanvas-DSiJFJa0.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BlockPreviewCanvas-DSiJFJa0.js","names":[],"sources":["../../../src/components/blocks/PreviewSectionBlock.vue","../../../src/components/blocks/PreviewSectionBlock.vue","../../../src/components/BlockPreviewCanvas.vue","../../../src/components/BlockPreviewCanvas.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport ButtonBlock from \"./ButtonBlock.vue\";\nimport CustomBlock from \"./CustomBlock.vue\";\nimport DividerBlock from \"./DividerBlock.vue\";\nimport HtmlBlock from \"./HtmlBlock.vue\";\nimport ImageBlock from \"./ImageBlock.vue\";\nimport MenuBlock from \"./MenuBlock.vue\";\nimport SocialIconsBlock from \"./SocialIconsBlock.vue\";\nimport SpacerBlock from \"./SpacerBlock.vue\";\nimport TableBlock from \"./TableBlock.vue\";\nimport TitleBlock from \"./TitleBlock.vue\";\nimport ParagraphBlock from \"./ParagraphBlock.vue\";\nimport VideoBlock from \"./VideoBlock.vue\";\nimport {\n resolveBlockComponent,\n getBlockWrapperStyle,\n} from \"../../utils/blockComponentResolver\";\nimport type {\n Block,\n SectionBlock as SectionBlockType,\n} from \"@templatical/types\";\nimport { computed, inject, type Component } from \"vue\";\nimport { BLOCK_REGISTRY_KEY } from \"../../keys\";\n\nconst previewBlockComponentMap: Record<string, Component> = {\n title: TitleBlock,\n paragraph: ParagraphBlock,\n image: ImageBlock,\n video: VideoBlock,\n button: ButtonBlock,\n divider: DividerBlock,\n social: SocialIconsBlock,\n menu: MenuBlock,\n table: TableBlock,\n spacer: SpacerBlock,\n html: HtmlBlock,\n custom: CustomBlock,\n};\n\nconst props = defineProps<{\n block: SectionBlockType;\n viewport: \"desktop\";\n}>();\n\ndefineOptions({ name: \"PreviewSectionBlock\" });\n\nconst blockRegistry = inject(BLOCK_REGISTRY_KEY, null);\n\nconst columnWidths = computed(() => {\n switch (props.block.columns) {\n case \"2\":\n return [\"50%\", \"50%\"];\n case \"3\":\n return [\"33.33%\", \"33.33%\", \"33.33%\"];\n case \"1-2\":\n return [\"33.33%\", \"66.67%\"];\n case \"2-1\":\n return [\"66.67%\", \"33.33%\"];\n default:\n return [\"100%\"];\n }\n});\n\nconst columns = computed(() => {\n const count = columnWidths.value.length;\n const children = [...props.block.children];\n while (children.length < count) {\n children.push([]);\n }\n return children.slice(0, count);\n});\n\nfunction getColumnBlocks(colIndex: number): Block[] {\n return columns.value[colIndex] || [];\n}\n\nfunction getBlockComponent(block: Block): Component | null {\n return resolveBlockComponent(block, blockRegistry, previewBlockComponentMap);\n}\n</script>\n\n<template>\n <div class=\"tpl:w-full\">\n <div class=\"tpl:flex tpl:gap-0\">\n <div\n v-for=\"(_, colIndex) in columns\"\n :key=\"colIndex\"\n :style=\"{ width: columnWidths[colIndex] }\"\n >\n <div\n v-for=\"childBlock in getColumnBlocks(colIndex)\"\n :key=\"childBlock.id\"\n :style=\"getBlockWrapperStyle(childBlock)\"\n >\n <!-- Recursive self-reference for nested sections -->\n <PreviewSectionBlock\n v-if=\"childBlock.type === 'section'\"\n :block=\"childBlock\"\n viewport=\"desktop\"\n />\n <component\n :is=\"getBlockComponent(childBlock)\"\n v-else\n :block=\"childBlock\"\n viewport=\"desktop\"\n />\n </div>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport ButtonBlock from \"./ButtonBlock.vue\";\nimport CustomBlock from \"./CustomBlock.vue\";\nimport DividerBlock from \"./DividerBlock.vue\";\nimport HtmlBlock from \"./HtmlBlock.vue\";\nimport ImageBlock from \"./ImageBlock.vue\";\nimport MenuBlock from \"./MenuBlock.vue\";\nimport SocialIconsBlock from \"./SocialIconsBlock.vue\";\nimport SpacerBlock from \"./SpacerBlock.vue\";\nimport TableBlock from \"./TableBlock.vue\";\nimport TitleBlock from \"./TitleBlock.vue\";\nimport ParagraphBlock from \"./ParagraphBlock.vue\";\nimport VideoBlock from \"./VideoBlock.vue\";\nimport {\n resolveBlockComponent,\n getBlockWrapperStyle,\n} from \"../../utils/blockComponentResolver\";\nimport type {\n Block,\n SectionBlock as SectionBlockType,\n} from \"@templatical/types\";\nimport { computed, inject, type Component } from \"vue\";\nimport { BLOCK_REGISTRY_KEY } from \"../../keys\";\n\nconst previewBlockComponentMap: Record<string, Component> = {\n title: TitleBlock,\n paragraph: ParagraphBlock,\n image: ImageBlock,\n video: VideoBlock,\n button: ButtonBlock,\n divider: DividerBlock,\n social: SocialIconsBlock,\n menu: MenuBlock,\n table: TableBlock,\n spacer: SpacerBlock,\n html: HtmlBlock,\n custom: CustomBlock,\n};\n\nconst props = defineProps<{\n block: SectionBlockType;\n viewport: \"desktop\";\n}>();\n\ndefineOptions({ name: \"PreviewSectionBlock\" });\n\nconst blockRegistry = inject(BLOCK_REGISTRY_KEY, null);\n\nconst columnWidths = computed(() => {\n switch (props.block.columns) {\n case \"2\":\n return [\"50%\", \"50%\"];\n case \"3\":\n return [\"33.33%\", \"33.33%\", \"33.33%\"];\n case \"1-2\":\n return [\"33.33%\", \"66.67%\"];\n case \"2-1\":\n return [\"66.67%\", \"33.33%\"];\n default:\n return [\"100%\"];\n }\n});\n\nconst columns = computed(() => {\n const count = columnWidths.value.length;\n const children = [...props.block.children];\n while (children.length < count) {\n children.push([]);\n }\n return children.slice(0, count);\n});\n\nfunction getColumnBlocks(colIndex: number): Block[] {\n return columns.value[colIndex] || [];\n}\n\nfunction getBlockComponent(block: Block): Component | null {\n return resolveBlockComponent(block, blockRegistry, previewBlockComponentMap);\n}\n</script>\n\n<template>\n <div class=\"tpl:w-full\">\n <div class=\"tpl:flex tpl:gap-0\">\n <div\n v-for=\"(_, colIndex) in columns\"\n :key=\"colIndex\"\n :style=\"{ width: columnWidths[colIndex] }\"\n >\n <div\n v-for=\"childBlock in getColumnBlocks(colIndex)\"\n :key=\"childBlock.id\"\n :style=\"getBlockWrapperStyle(childBlock)\"\n >\n <!-- Recursive self-reference for nested sections -->\n <PreviewSectionBlock\n v-if=\"childBlock.type === 'section'\"\n :block=\"childBlock\"\n viewport=\"desktop\"\n />\n <component\n :is=\"getBlockComponent(childBlock)\"\n v-else\n :block=\"childBlock\"\n viewport=\"desktop\"\n />\n </div>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport ButtonBlock from \"./blocks/ButtonBlock.vue\";\nimport CustomBlock from \"./blocks/CustomBlock.vue\";\nimport DividerBlock from \"./blocks/DividerBlock.vue\";\nimport HtmlBlock from \"./blocks/HtmlBlock.vue\";\nimport ImageBlock from \"./blocks/ImageBlock.vue\";\nimport MenuBlock from \"./blocks/MenuBlock.vue\";\nimport PreviewSectionBlock from \"./blocks/PreviewSectionBlock.vue\";\nimport SocialIconsBlock from \"./blocks/SocialIconsBlock.vue\";\nimport SpacerBlock from \"./blocks/SpacerBlock.vue\";\nimport TableBlock from \"./blocks/TableBlock.vue\";\nimport TitleBlock from \"./blocks/TitleBlock.vue\";\nimport ParagraphBlock from \"./blocks/ParagraphBlock.vue\";\nimport VideoBlock from \"./blocks/VideoBlock.vue\";\nimport {\n BLOCK_REGISTRY_KEY,\n CONDITION_PREVIEW_KEY,\n EDITOR_KEY,\n MERGE_TAG_SAMPLE_MODE_KEY,\n USE_MERGE_TAG_SAMPLES_KEY,\n} from \"../keys\";\nimport {\n resolveBlockComponent,\n getBlockWrapperStyle,\n getDocumentStyle,\n} from \"../utils/blockComponentResolver\";\nimport {\n EMAIL_FRAME_WIDTH_TRANSITION,\n EMAIL_GUTTER,\n getEmailFrameWidth,\n} from \"../utils/emailFrameWidth\";\nimport type { Block, ViewportSize } from \"@templatical/types\";\nimport { computed, inject, provide, type Component } from \"vue\";\n\nconst props = withDefaults(\n defineProps<{\n blocks: Block[];\n /**\n * Which viewport to render. Defaults to `desktop`, so the saved-blocks\n * surfaces — which have no viewport control — behave exactly as before.\n * The test-email dialog passes the user's choice so responsive blocks show\n * the variant a recipient on that device would receive.\n */\n viewport?: ViewportSize;\n /**\n * Whether the hand-toggled display-condition filter still applies here.\n * `false` where a resolver owns the preview: it has already evaluated every\n * condition against real data, so layering a manual hide on top would veto\n * the answer that was asked for.\n *\n * A prop rather than an injected `PREVIEW_RESOLUTION_KEY` read, because the\n * test-email dialog builds its *own* resolution instance (keyed to the\n * selected recipient) — injecting would consult the shared canvas instance\n * and get the wrong answer.\n */\n applyConditionFilter?: boolean;\n }>(),\n { viewport: \"desktop\", applyConditionFilter: true },\n);\n\nconst blockRegistry = inject(BLOCK_REGISTRY_KEY);\nconst editor = inject(EDITOR_KEY, null);\nconst conditionPreview = inject(CONDITION_PREVIEW_KEY, null);\n\n/**\n * This canvas is only ever a preview — nothing here is editable — so it honours\n * the user's mode directly, with no `previewMode` gate of the kind `Canvas.vue`\n * needs. Re-provided rather than left to inherit, because a `BlockPreviewCanvas`\n * inside a dialog may sit under an editing `Canvas` that provides `false`.\n */\nconst mergeTagSampleMode = inject(MERGE_TAG_SAMPLE_MODE_KEY, null);\nprovide(\n USE_MERGE_TAG_SAMPLES_KEY,\n computed(() => mergeTagSampleMode?.value ?? false),\n);\n\n/**\n * Blocks a display condition currently excludes, so a preview never shows\n * content the recipient won't get. The canvas does the same via\n * `v-show=\"!conditionPreview?.isHidden(block.id)\"`.\n *\n * A no-op for the saved-blocks browser: entries there carry their *stored* ids,\n * which aren't in the current template, so nothing is tracked as hidden. It\n * bites where it should — the save dialog and the test-email preview, both of\n * which show blocks that are live on the canvas.\n *\n * Skipped entirely when `applyConditionFilter` is false — see the prop.\n */\nconst visibleBlocks = computed(() =>\n props.applyConditionFilter\n ? props.blocks.filter((block) => !conditionPreview?.isHidden(block.id))\n : props.blocks,\n);\n\n/**\n * Frame width, from the one helper the canvas and the scaled preview rows also\n * use — so all three agree by construction rather than by three constants that\n * happen to match. A template with a custom body width now previews at that\n * width instead of a flat 600.\n */\nconst frameWidth = computed(() =>\n getEmailFrameWidth(editor?.content.value.settings, props.viewport),\n);\n\n/**\n * The same document-level style the canvas applies, so a previewed block\n * renders identically to the canvas one: without it the font falls back to the\n * editor UI's and the link rules hit their unset defaults, dropping the\n * underline and the link colour.\n *\n * Read from the *current* template even in the saved-blocks browser, where the\n * previewed content came from elsewhere — a saved block stores only `Block[]`,\n * and the current settings are what it will actually look like once inserted.\n */\nconst documentStyle = computed(() =>\n editor ? getDocumentStyle(editor.content.value.settings) : {},\n);\n\n/**\n * The email's own language, for the browser's spellchecker and hyphenation —\n * the same binding the editing canvas carries, so a preview is checked by the\n * same rules as the block it mirrors.\n *\n * From `settings.locale`, never `config.locale`: the chrome's language says\n * nothing about the content's. Read from the *current* template for the same\n * reason `documentStyle` is — a saved block stores only `Block[]`. Undefined\n * rather than `\"\"`, which would declare \"unknown language\" and suppress\n * spellcheck instead of falling back.\n */\nconst contentLang = computed(\n () => editor?.content.value.settings?.locale?.trim() || undefined,\n);\n\n/**\n * The email's body background — `mj-body background-color` when sent, and the\n * `.tpl-canvas-bg` layer on the editing canvas.\n *\n * Deliberately NOT part of `getDocumentStyle`: the canvas applies that helper\n * to `.tpl-canvas`, which must stay transparent so the invertible background\n * layer beneath it shows through. A background there would double-paint and\n * defeat the dark-mode preview.\n *\n * Truthiness, not `??`: the colour pickers clear to an empty string to mean\n * \"unset\", which as an inline style renders the frame transparent rather than\n * falling back to the neutral preview surface.\n */\nconst emailBackground = computed(\n () =>\n editor?.content.value.settings.backgroundColor || \"var(--tpl-canvas-bg)\",\n);\n\n/**\n * Width the stage asks for: the content column plus a full gutter on each side,\n * the same stage the canvas builds. It is an ask rather than a fixed size —\n * paired with `max-width: 100%` below, so a container with less room hands over\n * what it has and shows a narrower band instead of overflowing.\n *\n * It has to be a specified width, not `100%`: `TplModal`'s wrapper is\n * shrink-to-fit, so a percentage there resolves against a container whose size\n * the stage is itself supposed to influence, and the stage collapses to its\n * `min-width` — no gutters, on the one surface this exists for.\n */\nconst stageWidth = computed(() => frameWidth.value + EMAIL_GUTTER * 2);\n\nconst previewComponentMap: Record<string, Component> = {\n section: PreviewSectionBlock,\n title: TitleBlock,\n paragraph: ParagraphBlock,\n image: ImageBlock,\n video: VideoBlock,\n button: ButtonBlock,\n divider: DividerBlock,\n social: SocialIconsBlock,\n menu: MenuBlock,\n table: TableBlock,\n spacer: SpacerBlock,\n html: HtmlBlock,\n custom: CustomBlock,\n};\n\nfunction getBlockComponent(block: Block): Component | null {\n return resolveBlockComponent(block, blockRegistry, previewComponentMap);\n}\n</script>\n\n<template>\n <!-- STAGE — the email body, holding the background and a gutter of it on\n each side of the content column, the same shape `Canvas.vue` builds.\n `max-width: 100%` is what makes it fit anywhere: a roomy surface shows\n the full band, a dialog shows as much as it has, and a container sized to\n the content column shows none. `min-width` keeps it from squeezing the\n column, so a cramped surface clips exactly as it did when the frame\n carried the width itself. -->\n <div\n data-testid=\"block-preview-stage\"\n class=\"tpl:pointer-events-none tpl:mx-auto tpl:flex tpl:select-none tpl:justify-center tpl:rounded-lg\"\n :style=\"{\n width: `${stageWidth}px`,\n minWidth: `${frameWidth}px`,\n maxWidth: '100%',\n backgroundColor: emailBackground,\n boxShadow: 'var(--tpl-shadow-sm)',\n }\"\n >\n <!-- CONTENT COLUMN — the blocks at their true email width. Keeps the\n testid: this is the element whose width *is* the email width, which is\n what every viewport assertion measures. -->\n <div\n data-testid=\"block-preview-canvas\"\n :lang=\"contentLang\"\n :style=\"{\n width: `${frameWidth}px`,\n transition: EMAIL_FRAME_WIDTH_TRANSITION,\n ...documentStyle,\n }\"\n >\n <div\n v-for=\"block in visibleBlocks\"\n :key=\"block.id\"\n :style=\"getBlockWrapperStyle(block)\"\n >\n <component\n :is=\"getBlockComponent(block)\"\n :block=\"block\"\n :viewport=\"viewport\"\n />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport ButtonBlock from \"./blocks/ButtonBlock.vue\";\nimport CustomBlock from \"./blocks/CustomBlock.vue\";\nimport DividerBlock from \"./blocks/DividerBlock.vue\";\nimport HtmlBlock from \"./blocks/HtmlBlock.vue\";\nimport ImageBlock from \"./blocks/ImageBlock.vue\";\nimport MenuBlock from \"./blocks/MenuBlock.vue\";\nimport PreviewSectionBlock from \"./blocks/PreviewSectionBlock.vue\";\nimport SocialIconsBlock from \"./blocks/SocialIconsBlock.vue\";\nimport SpacerBlock from \"./blocks/SpacerBlock.vue\";\nimport TableBlock from \"./blocks/TableBlock.vue\";\nimport TitleBlock from \"./blocks/TitleBlock.vue\";\nimport ParagraphBlock from \"./blocks/ParagraphBlock.vue\";\nimport VideoBlock from \"./blocks/VideoBlock.vue\";\nimport {\n BLOCK_REGISTRY_KEY,\n CONDITION_PREVIEW_KEY,\n EDITOR_KEY,\n MERGE_TAG_SAMPLE_MODE_KEY,\n USE_MERGE_TAG_SAMPLES_KEY,\n} from \"../keys\";\nimport {\n resolveBlockComponent,\n getBlockWrapperStyle,\n getDocumentStyle,\n} from \"../utils/blockComponentResolver\";\nimport {\n EMAIL_FRAME_WIDTH_TRANSITION,\n EMAIL_GUTTER,\n getEmailFrameWidth,\n} from \"../utils/emailFrameWidth\";\nimport type { Block, ViewportSize } from \"@templatical/types\";\nimport { computed, inject, provide, type Component } from \"vue\";\n\nconst props = withDefaults(\n defineProps<{\n blocks: Block[];\n /**\n * Which viewport to render. Defaults to `desktop`, so the saved-blocks\n * surfaces — which have no viewport control — behave exactly as before.\n * The test-email dialog passes the user's choice so responsive blocks show\n * the variant a recipient on that device would receive.\n */\n viewport?: ViewportSize;\n /**\n * Whether the hand-toggled display-condition filter still applies here.\n * `false` where a resolver owns the preview: it has already evaluated every\n * condition against real data, so layering a manual hide on top would veto\n * the answer that was asked for.\n *\n * A prop rather than an injected `PREVIEW_RESOLUTION_KEY` read, because the\n * test-email dialog builds its *own* resolution instance (keyed to the\n * selected recipient) — injecting would consult the shared canvas instance\n * and get the wrong answer.\n */\n applyConditionFilter?: boolean;\n }>(),\n { viewport: \"desktop\", applyConditionFilter: true },\n);\n\nconst blockRegistry = inject(BLOCK_REGISTRY_KEY);\nconst editor = inject(EDITOR_KEY, null);\nconst conditionPreview = inject(CONDITION_PREVIEW_KEY, null);\n\n/**\n * This canvas is only ever a preview — nothing here is editable — so it honours\n * the user's mode directly, with no `previewMode` gate of the kind `Canvas.vue`\n * needs. Re-provided rather than left to inherit, because a `BlockPreviewCanvas`\n * inside a dialog may sit under an editing `Canvas` that provides `false`.\n */\nconst mergeTagSampleMode = inject(MERGE_TAG_SAMPLE_MODE_KEY, null);\nprovide(\n USE_MERGE_TAG_SAMPLES_KEY,\n computed(() => mergeTagSampleMode?.value ?? false),\n);\n\n/**\n * Blocks a display condition currently excludes, so a preview never shows\n * content the recipient won't get. The canvas does the same via\n * `v-show=\"!conditionPreview?.isHidden(block.id)\"`.\n *\n * A no-op for the saved-blocks browser: entries there carry their *stored* ids,\n * which aren't in the current template, so nothing is tracked as hidden. It\n * bites where it should — the save dialog and the test-email preview, both of\n * which show blocks that are live on the canvas.\n *\n * Skipped entirely when `applyConditionFilter` is false — see the prop.\n */\nconst visibleBlocks = computed(() =>\n props.applyConditionFilter\n ? props.blocks.filter((block) => !conditionPreview?.isHidden(block.id))\n : props.blocks,\n);\n\n/**\n * Frame width, from the one helper the canvas and the scaled preview rows also\n * use — so all three agree by construction rather than by three constants that\n * happen to match. A template with a custom body width now previews at that\n * width instead of a flat 600.\n */\nconst frameWidth = computed(() =>\n getEmailFrameWidth(editor?.content.value.settings, props.viewport),\n);\n\n/**\n * The same document-level style the canvas applies, so a previewed block\n * renders identically to the canvas one: without it the font falls back to the\n * editor UI's and the link rules hit their unset defaults, dropping the\n * underline and the link colour.\n *\n * Read from the *current* template even in the saved-blocks browser, where the\n * previewed content came from elsewhere — a saved block stores only `Block[]`,\n * and the current settings are what it will actually look like once inserted.\n */\nconst documentStyle = computed(() =>\n editor ? getDocumentStyle(editor.content.value.settings) : {},\n);\n\n/**\n * The email's own language, for the browser's spellchecker and hyphenation —\n * the same binding the editing canvas carries, so a preview is checked by the\n * same rules as the block it mirrors.\n *\n * From `settings.locale`, never `config.locale`: the chrome's language says\n * nothing about the content's. Read from the *current* template for the same\n * reason `documentStyle` is — a saved block stores only `Block[]`. Undefined\n * rather than `\"\"`, which would declare \"unknown language\" and suppress\n * spellcheck instead of falling back.\n */\nconst contentLang = computed(\n () => editor?.content.value.settings?.locale?.trim() || undefined,\n);\n\n/**\n * The email's body background — `mj-body background-color` when sent, and the\n * `.tpl-canvas-bg` layer on the editing canvas.\n *\n * Deliberately NOT part of `getDocumentStyle`: the canvas applies that helper\n * to `.tpl-canvas`, which must stay transparent so the invertible background\n * layer beneath it shows through. A background there would double-paint and\n * defeat the dark-mode preview.\n *\n * Truthiness, not `??`: the colour pickers clear to an empty string to mean\n * \"unset\", which as an inline style renders the frame transparent rather than\n * falling back to the neutral preview surface.\n */\nconst emailBackground = computed(\n () =>\n editor?.content.value.settings.backgroundColor || \"var(--tpl-canvas-bg)\",\n);\n\n/**\n * Width the stage asks for: the content column plus a full gutter on each side,\n * the same stage the canvas builds. It is an ask rather than a fixed size —\n * paired with `max-width: 100%` below, so a container with less room hands over\n * what it has and shows a narrower band instead of overflowing.\n *\n * It has to be a specified width, not `100%`: `TplModal`'s wrapper is\n * shrink-to-fit, so a percentage there resolves against a container whose size\n * the stage is itself supposed to influence, and the stage collapses to its\n * `min-width` — no gutters, on the one surface this exists for.\n */\nconst stageWidth = computed(() => frameWidth.value + EMAIL_GUTTER * 2);\n\nconst previewComponentMap: Record<string, Component> = {\n section: PreviewSectionBlock,\n title: TitleBlock,\n paragraph: ParagraphBlock,\n image: ImageBlock,\n video: VideoBlock,\n button: ButtonBlock,\n divider: DividerBlock,\n social: SocialIconsBlock,\n menu: MenuBlock,\n table: TableBlock,\n spacer: SpacerBlock,\n html: HtmlBlock,\n custom: CustomBlock,\n};\n\nfunction getBlockComponent(block: Block): Component | null {\n return resolveBlockComponent(block, blockRegistry, previewComponentMap);\n}\n</script>\n\n<template>\n <!-- STAGE — the email body, holding the background and a gutter of it on\n each side of the content column, the same shape `Canvas.vue` builds.\n `max-width: 100%` is what makes it fit anywhere: a roomy surface shows\n the full band, a dialog shows as much as it has, and a container sized to\n the content column shows none. `min-width` keeps it from squeezing the\n column, so a cramped surface clips exactly as it did when the frame\n carried the width itself. -->\n <div\n data-testid=\"block-preview-stage\"\n class=\"tpl:pointer-events-none tpl:mx-auto tpl:flex tpl:select-none tpl:justify-center tpl:rounded-lg\"\n :style=\"{\n width: `${stageWidth}px`,\n minWidth: `${frameWidth}px`,\n maxWidth: '100%',\n backgroundColor: emailBackground,\n boxShadow: 'var(--tpl-shadow-sm)',\n }\"\n >\n <!-- CONTENT COLUMN — the blocks at their true email width. Keeps the\n testid: this is the element whose width *is* the email width, which is\n what every viewport assertion measures. -->\n <div\n data-testid=\"block-preview-canvas\"\n :lang=\"contentLang\"\n :style=\"{\n width: `${frameWidth}px`,\n transition: EMAIL_FRAME_WIDTH_TRANSITION,\n ...documentStyle,\n }\"\n >\n <div\n v-for=\"block in visibleBlocks\"\n :key=\"block.id\"\n :style=\"getBlockWrapperStyle(block)\"\n >\n <component\n :is=\"getBlockComponent(block)\"\n :block=\"block\"\n :viewport=\"viewport\"\n />\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"en-BaUYOQi8.js","names":[],"sources":["../../../src/i18n/locales/en.ts"],"sourcesContent":["export default {\n // Footer (OSS only)\n footer: {\n poweredBy: \"Powered by\",\n openSource: \"Open Source\",\n },\n\n // Header — template name + save state. Shown only when a templates provider\n // is configured.\n header: {\n save: \"Save\",\n saving: \"Saving...\",\n saved: \"Saved\",\n unsaved: \"Unsaved\",\n saveFailed: \"Save failed\",\n saveNoTemplate: \"Load or create a template first\",\n templateName: \"Template name\",\n rename: \"Rename template\",\n untitled: \"Untitled\",\n updatedAt: \"Updated {time}\",\n createdAt: \"Created {time}\",\n updatedJustNow: \"Updated just now\",\n createdJustNow: \"Created just now\",\n },\n\n // Relative timestamps, shared by every surface that shows one: the header's\n // updated line, saved blocks, comments and version history.\n time: {\n justNow: \"Just now\",\n minutesAgo: \"{minutes}m ago\",\n hoursAgo: \"{hours}h ago\",\n daysAgo: \"{days}d ago\",\n },\n\n // History (undo/redo)\n history: {\n collabWarning: \"Undo may affect collaborators' recent changes\",\n undo: \"Undo\",\n redo: \"Redo\",\n },\n\n // Viewport toggle\n viewport: {\n label: \"Viewport\",\n desktop: \"Desktop\",\n mobile: \"Mobile\",\n },\n\n // Dark mode preview\n darkMode: {\n enable: \"Dark Mode Preview\",\n disable: \"Light Mode Preview\",\n },\n\n // Preview mode\n previewMode: {\n enable: \"Preview Mode\",\n disable: \"Exit Preview\",\n },\n\n // Sidebar - Block types\n blocks: {\n section: \"Section\",\n image: \"Image\",\n title: \"Title\",\n paragraph: \"Paragraph\",\n button: \"Button\",\n divider: \"Divider\",\n video: \"Video\",\n social: \"Social\",\n spacer: \"Spacer\",\n html: \"HTML\",\n menu: \"Menu\",\n table: \"Table\",\n countdown: \"Countdown\",\n },\n\n // Placeholder text a newly inserted block starts with. Author-facing\n // prompts, meant to be overwritten — so they follow the editor UI locale.\n // Recipient-facing defaults live in `i18n/contentDefaults.ts` and follow\n // the template's own `settings.locale` instead.\n blockDefaults: {\n title: \"Enter your title\",\n paragraph: \"Enter your text here\",\n button: \"Click Here\",\n },\n\n // Right sidebar\n sidebar: {\n content: \"Content\",\n settings: \"Settings\",\n noSelection: \"No element selected\",\n noSelectionHint: \"Select a block on the canvas to edit it\",\n },\n\n // Toolbar - Common\n toolbar: {\n duplicate: \"Duplicate\",\n delete: \"Delete\",\n },\n\n // Title editor toolbar\n titleEditor: {\n toolbar: \"Title formatting\",\n bold: \"Bold (Ctrl+B)\",\n italic: \"Italic (Ctrl+I)\",\n addLink: \"Add Link\",\n },\n\n // Paragraph editor toolbar\n paragraphEditor: {\n toolbar: \"Text formatting\",\n bold: \"Bold (Ctrl+B)\",\n italic: \"Italic (Ctrl+I)\",\n underline: \"Underline (Ctrl+U)\",\n strikethrough: \"Strikethrough\",\n subscript: \"Subscript\",\n superscript: \"Superscript\",\n addLink: \"Add Link\",\n bulletList: \"Bullet List\",\n numberedList: \"Numbered List\",\n alignLeft: \"Align Left\",\n alignCenter: \"Align Center\",\n alignRight: \"Align Right\",\n alignJustify: \"Justify\",\n clearFormatting: \"Clear Formatting\",\n insertEmoji: \"Insert Emoji\",\n fontFamily: \"Font Family\",\n defaultFont: \"Default\",\n fontSize: \"Font Size\",\n defaultSize: \"Default\",\n textColor: \"Text Color\",\n highlightColor: \"Highlight Color\",\n lineHeight: \"Line Height\",\n letterSpacing: \"Letter Spacing\",\n emojiItemLabel: \"Insert emoji {emoji}\",\n },\n\n // Block actions (BlockWrapper)\n blockActions: {\n drag: \"Drag to reorder, or press Space to move with keyboard\",\n dragLifted:\n \"Moving {block}. Use up and down arrow keys to reposition, Space or Enter to drop, Escape to cancel.\",\n duplicate: \"Duplicate block\",\n delete: \"Delete block\",\n hiddenOnViewport: \"Hidden on {viewport}\",\n saveAsBlock: \"Save as Block\",\n conditionToggle: \"Toggle display condition\",\n comments: \"Comments ({count})\",\n lifted: \"{block} lifted. Position {position} of {total}.\",\n moved: \"{block} moved to position {position} of {total}.\",\n dropped: \"{block} dropped at position {position} of {total}.\",\n cancelled: \"Move cancelled. {block} returned to position {position}.\",\n },\n\n // Toolbar - Section\n section: {\n dropHere: \"Drop blocks here\",\n columns: \"Columns\",\n column1: \"1 Column\",\n column2: \"2 Columns\",\n column3: \"3 Columns\",\n ratio12: \"1:2 Ratio\",\n ratio21: \"2:1 Ratio\",\n borderRadius: \"Border Radius\",\n wrapperEnable: \"Add wrapper\",\n stackOnMobile: \"Stack on mobile\",\n },\n\n // Text editor link dialog\n linkDialog: {\n editLink: \"Edit Link\",\n insertLink: \"Insert Link\",\n updateLink: \"Update Link\",\n removeLink: \"Remove Link\",\n cancel: \"Cancel\",\n urlPlaceholder: \"https://example.com\",\n urlLabel: \"URL\",\n colorLabel: \"Link Color\",\n },\n\n // Toolbar - Title\n title: {\n level: \"Heading Level\",\n heading1: \"Heading 1 (36px)\",\n heading2: \"Heading 2 (28px)\",\n heading3: \"Heading 3 (22px)\",\n heading4: \"Heading 4 (18px)\",\n fontFamily: \"Font Family\",\n inheritFont: \"Use template font\",\n color: \"Color\",\n align: \"Align\",\n alignLeft: \"Left\",\n alignCenter: \"Center\",\n alignRight: \"Right\",\n },\n\n // Emoji picker\n emoji: {\n smileys: \"Smileys\",\n gestures: \"Gestures\",\n objects: \"Objects\",\n },\n\n // Toolbar - Image\n image: {\n imageUrl: \"Image URL\",\n imageUrlPlaceholder: \"https://...\",\n altText: \"Alt Text\",\n altTextPlaceholder: \"Image description\",\n width: \"Width\",\n fullWidth: \"Full Width\",\n widthCustom: \"Custom\",\n height: \"Height\",\n heightAuto: \"Auto\",\n heightCustom: \"Custom\",\n borderRadius: \"Border Radius\",\n linkUrl: \"Link URL\",\n openInNewTab: \"Open in new tab\",\n placeholderUrl: \"Placeholder Image\",\n optional: \"(optional)\",\n placeholderUrlPlaceholder: \"https://... (design-time only)\",\n placeholderUrlTooltip:\n \"Since the image URL uses a merge tag, you can provide a real image here to preview the layout while designing. This is not included in the final output.\",\n clickToAdd: \"Click to add image URL\",\n browseMedia: \"Browse Media\",\n dropToUpload: \"Drop image to upload\",\n uploading: \"Uploading…\",\n decorative: \"Decorative image\",\n decorativeHint:\n \"Hidden from screen readers. Use only for spacers and visual flourishes.\",\n },\n\n // Toolbar - Video\n video: {\n videoUrl: \"Video URL\",\n videoUrlPlaceholder: \"https://youtube.com/...\",\n openInNewTab: \"Open in new tab\",\n customThumbnail: \"Custom Thumbnail\",\n optional: \"(optional)\",\n thumbnailPlaceholder: \"Auto-generated from video URL\",\n altText: \"Alt Text\",\n altTextPlaceholder: \"Video description\",\n width: \"Width\",\n fullWidth: \"Full Width\",\n height: \"Height\",\n heightAuto: \"Auto\",\n heightCustom: \"Custom\",\n placeholderUrl: \"Placeholder Thumbnail\",\n placeholderUrlPlaceholder: \"https://... (design-time only)\",\n placeholderUrlTooltip:\n \"Since the video URL uses a merge tag, you can provide a real thumbnail here to preview the layout while designing. This is not included in the final output.\",\n addVideo: \"Add a video URL\",\n },\n\n // Toolbar - Button\n button: {\n fontFamily: \"Font Family\",\n inheritFont: \"Use template font\",\n text: \"Text\",\n url: \"URL\",\n urlPlaceholder: \"https://...\",\n openInNewTab: \"Open in new tab\",\n background: \"Background\",\n textColor: \"Text Color\",\n borderRadius: \"Border Radius\",\n fontSize: \"Font Size\",\n width: \"Width\",\n widthAuto: \"Fit to content\",\n fullWidth: \"Full Width\",\n widthCustom: \"Custom\",\n },\n\n // Toolbar - Divider\n divider: {\n style: \"Style\",\n solid: \"Solid\",\n dashed: \"Dashed\",\n dotted: \"Dotted\",\n color: \"Color\",\n thickness: \"Thickness\",\n },\n\n // Toolbar - Social Icons\n social: {\n icons: \"Icons\",\n addIcon: \"Add Icon\",\n addIcons: \"Add social icons\",\n removeIcon: \"Remove\",\n urlPlaceholder: \"https://...\",\n style: \"Style\",\n styleSolid: \"Solid\",\n styleOutlined: \"Outlined\",\n styleRounded: \"Rounded\",\n styleSquare: \"Square\",\n styleCircle: \"Circle\",\n size: \"Size\",\n sizeSmall: \"S\",\n sizeMedium: \"M\",\n sizeLarge: \"L\",\n spacing: \"Spacing\",\n align: \"Alignment\",\n platforms: {\n facebook: \"Facebook\",\n twitter: \"X (Twitter)\",\n instagram: \"Instagram\",\n linkedin: \"LinkedIn\",\n youtube: \"YouTube\",\n tiktok: \"TikTok\",\n pinterest: \"Pinterest\",\n email: \"Email\",\n website: \"Website\",\n whatsapp: \"WhatsApp\",\n telegram: \"Telegram\",\n discord: \"Discord\",\n snapchat: \"Snapchat\",\n reddit: \"Reddit\",\n github: \"GitHub\",\n dribbble: \"Dribbble\",\n behance: \"Behance\",\n },\n },\n\n // Toolbar - Menu\n menu: {\n items: \"Menu Items\",\n addItem: \"Add Item\",\n removeItem: \"Remove\",\n text: \"Text\",\n urlPlaceholder: \"https://example.com\",\n openInNewTab: \"Open in new tab\",\n bold: \"Bold\",\n underline: \"Underline\",\n color: \"Color\",\n linkColor: \"Link Color\",\n fontSize: \"Font Size\",\n fontFamily: \"Font Family\",\n separator: \"Separator\",\n separatorColor: \"Separator Color\",\n spacing: \"Spacing\",\n textAlign: \"Alignment\",\n addLinks: \"Add menu links\",\n },\n\n // Toolbar - Table\n table: {\n dimensions: \"Dimensions\",\n rows: \"Rows\",\n columns: \"Columns\",\n hasHeaderRow: \"Header row\",\n headerBackgroundColor: \"Header Background\",\n noHeaderBg: \"No background\",\n borderColor: \"Border Color\",\n borderWidth: \"Border Width\",\n cellPadding: \"Cell Padding\",\n fontFamily: \"Font Family\",\n fontSize: \"Font Size\",\n color: \"Text Color\",\n textAlign: \"Alignment\",\n cellPlaceholder: \"Enter text...\",\n empty: \"Add a table\",\n },\n\n // Toolbar - Paragraph\n paragraph: {\n paragraphSpacing: \"Paragraph Spacing\",\n },\n\n // Toolbar - Spacer\n spacer: {\n height: \"Height\",\n },\n\n // Toolbar - Countdown\n countdown: {\n targetDate: \"Target Date\",\n timezone: \"Timezone\",\n display: \"Display\",\n days: \"Days\",\n hours: \"Hours\",\n minutes: \"Minutes\",\n seconds: \"Seconds\",\n separator: \"Separator\",\n fontFamily: \"Font Family\",\n inheritFont: \"Default\",\n digitFontSize: \"Digit Size\",\n digitColor: \"Digit Color\",\n labelColor: \"Label Color\",\n labelFontSize: \"Label Size\",\n background: \"Background\",\n labels: \"Labels\",\n expiry: \"Expired Message\",\n expiredMessagePlaceholder: \"This offer has expired\",\n expiredImageUrl: \"Expired Image URL\",\n hideOnExpiry: \"Hide when expired\",\n setDate: \"Set a target date in the settings panel\",\n hidden: \"Hidden (expired)\",\n },\n\n // Custom Blocks\n customBlocks: {\n definitionNotFound: \"Unknown block type — this block is not registered\",\n renderError:\n \"This block could not be rendered. Check the block template for errors.\",\n fields: {\n required: \"Required\",\n addItem: \"Add item\",\n removeItem: \"Remove\",\n maxItemsReached: \"Maximum items reached\",\n minItemsRequired: \"Minimum {count} items required\",\n },\n toolbar: {\n noDefinition:\n \"Register this block type in your SDK configuration to edit its properties\",\n },\n dataSource: {\n fetchButton: \"Load content\",\n changeButton: \"Change\",\n fetching: \"Loading...\",\n readOnlyTooltip: \"This value is loaded from your data source\",\n fetchError: \"Failed to load content\",\n },\n },\n\n // Toolbar - HTML\n html: {\n content: \"HTML Content\",\n preview: \"Custom HTML block\",\n empty: \"Add HTML content in the panel\",\n sanitizationHint:\n \"HTML is exported as-is and isn't sanitized — make sure the content is safe.\",\n },\n\n // Toolbar - Common block settings\n blockSettings: {\n spacing: \"Spacing\",\n padding: \"Padding\",\n background: \"Background\",\n color: \"Color\",\n display: \"Display\",\n showOnDesktop: \"Show on desktop\",\n showOnMobile: \"Show on mobile\",\n hiddenOnDevice: \"Hidden on {device}\",\n displayCondition: \"Display Condition\",\n selectCondition: \"Select condition\",\n removeCondition: \"Remove condition\",\n noCondition: \"Always visible\",\n conditionApplied: \"Condition applied\",\n customCondition: \"Custom condition\",\n customConditionLabel: \"Condition name\",\n customConditionBefore: \"Before (opening logic)\",\n customConditionAfter: \"After (closing logic)\",\n applyCondition: \"Apply\",\n cancelCondition: \"Cancel\",\n customBadge: \"Custom\",\n restoreHiddenBlocks: \"Show all hidden blocks\",\n },\n\n // Template settings\n templateSettings: {\n layout: \"Layout\",\n widthPreset: \"Width Preset\",\n customWidth: \"Custom Width\",\n appearance: \"Appearance\",\n backgroundColor: \"Background Color\",\n textColor: \"Text Color\",\n linkColor: \"Link Color\",\n linkUnderline: \"Underline Links\",\n fontFamily: \"Font Family\",\n preheaderText: \"Preheader Text\",\n preheaderTextPlaceholder:\n \"Preview text shown after subject line in inbox...\",\n preheaderTextHint:\n \"This text appears after the subject line in email client previews. Supports merge tags.\",\n language: \"Language\",\n contentLocale: \"Content language\",\n contentLocaleHint:\n \"BCP 47 code (e.g. en, de, pt-BR). Sets the rendered email's lang attribute so screen readers pronounce content correctly.\",\n tips: \"Tips\",\n tip1: \"600px is the standard width for email templates\",\n tip2: \"Use web-safe fonts for best compatibility\",\n tip3: \"Light backgrounds work best for readability\",\n },\n\n // Spacing control\n spacingControl: {\n lockAll: \"Lock all sides\",\n unlock: \"Unlock sides\",\n top: \"Top\",\n right: \"Right\",\n bottom: \"Bottom\",\n left: \"Left\",\n decreaseTop: \"Decrease top\",\n increaseTop: \"Increase top\",\n decreaseLeft: \"Decrease left\",\n increaseLeft: \"Increase left\",\n decreaseRight: \"Decrease right\",\n increaseRight: \"Increase right\",\n decreaseBottom: \"Decrease bottom\",\n increaseBottom: \"Increase bottom\",\n },\n\n // Color Picker\n colorPicker: {\n pickColor: \"Pick a color\",\n hexValue: \"Hex color value\",\n notSet: \"Not set\",\n clear: \"Clear color\",\n presetColors: \"Preset colors\",\n },\n\n // Merge Tag\n mergeTag: {\n clickToEdit: \"Click to edit\",\n remove: \"Remove merge tag\",\n insert: \"Insert merge tag\",\n insertShort: \"Merge tag\",\n editValue: \"Edit merge tag value\",\n deleteMergeTag: \"Delete merge tag\",\n suggestionEmpty: \"No matching merge tags\",\n picker: {\n title: \"Insert merge tag\",\n searchPlaceholder: \"Search merge tags\",\n searchAriaLabel: \"Search merge tags\",\n noResults: \"No matching merge tags\",\n empty: \"No merge tags configured\",\n otherGroup: \"Other\",\n close: \"Close\",\n groupCount: \"{count}\",\n sample: \"Preview: {sample}\",\n },\n },\n\n // Logic tags (standalone, separate from merge tags)\n logicTag: {\n insert: \"Insert logic\",\n insertShort: \"Logic\",\n picker: {\n title: \"Insert logic\",\n searchPlaceholder: \"Search logic tags\",\n searchAriaLabel: \"Search logic tags\",\n noResults: \"No matching logic tags\",\n empty: \"No logic tags configured\",\n otherGroup: \"Other\",\n close: \"Close\",\n },\n },\n\n // Canvas\n canvas: {\n noBlocks: \"No blocks yet\",\n dragHint: \"Start from scratch by dragging blocks from the sidebar\",\n dropHere: \"Drop here\",\n aiHintChat: \"or let\",\n aiHintChatSuffix: \"generate a complete template for you in seconds\",\n aiHintDesign:\n \"Have an existing design? Upload a screenshot, image, or PDF and\",\n aiHintDesignSuffix: \"will instantly recreate it\",\n },\n\n // Sidebar\n savedBlocks: {\n title: \"Saved Blocks\",\n saveAsBlock: \"Save as Block\",\n name: \"Name\",\n namePlaceholder: \"e.g. Header, Footer, CTA...\",\n save: \"Save Block\",\n saving: \"Saving...\",\n cancel: \"Cancel\",\n empty: \"No saved blocks yet\",\n emptyHint: \"Save blocks from your templates to reuse them later.\",\n noResults: \"No saved blocks match your search\",\n search: \"Search saved blocks...\",\n loading: \"Loading saved blocks…\",\n category: \"Category\",\n categoryPlaceholder: \"e.g. Headers, Promos... (optional)\",\n allCategories: \"All categories\",\n filterByCategory: \"Filter by category\",\n insert: \"Insert\",\n rename: \"Rename\",\n delete: \"Delete\",\n deleteConfirm: \"Delete this saved block?\",\n blockCount: \"{count} block(s)\",\n browse: \"Browse Saved Blocks\",\n selectToPreview: \"Select a saved block to preview\",\n insertAtBeginning: \"At beginning\",\n insertAfterBlock: \"After {block}\",\n insertAtEnd: \"At end\",\n insertPosition: \"Insert position\",\n close: \"Close\",\n pickToolbar: \"Saved block selection\",\n pickCount: \"{count} block(s) selected\",\n pickHint: \"Click blocks to add or remove them\",\n savingCount: \"Saving {count} block(s):\",\n reorderHint: \"Drag to reorder — blocks are saved in this order\",\n reorderHandle: \"Reorder {block}, position {position} of {total}\",\n reorderAnnouncement: \"{block} moved to position {position} of {total}\",\n expand: \"Expand\",\n collapse: \"Collapse\",\n expandPreview: \"Expand {block} preview\",\n collapsePreview: \"Collapse {block} preview\",\n },\n comments: {\n button: \"Comments\",\n title: \"Comments\",\n placeholder: \"Write a comment...\",\n replyPlaceholder: \"Write a reply...\",\n reply: \"Reply\",\n resolve: \"Resolve\",\n unresolve: \"Unresolve\",\n delete: \"Delete\",\n edit: \"Edit\",\n cancel: \"Cancel\",\n save: \"Save\",\n noComments: \"No comments yet\",\n noCommentsHint:\n \"Start a conversation by adding a comment to the template or a specific block.\",\n deleteConfirm: \"Delete this comment?\",\n filterAll: \"All\",\n filterUnresolved: \"Unresolved\",\n filterBlock: \"This block\",\n jumpToBlock: \"Block\",\n ownedByYou: \"You\",\n edited: \"edited\",\n resolvedBy: \"Resolved by {name}\",\n replyOne: \"{count} Reply\",\n replyMany: \"{count} Replies\",\n missingBlock: \"Missing block\",\n saveTemplateFirst: \"Save the template before commenting on this block.\",\n },\n versionHistory: {\n tooltip: \"Version history\",\n dropdownTitle: \"Version history\",\n empty: \"No versions yet\",\n auto: \"auto\",\n olderVersion: \"Older version\",\n newerVersion: \"Newer version\",\n },\n versionPreview: {\n message: \"You are previewing an earlier version of this template.\",\n cancel: \"Cancel\",\n restore: \"Restore this version\",\n restoreConfirm: {\n title: \"Restore this version?\",\n unsavedWithSave:\n \"You have unsaved changes. Save them first and they stay in your history — restore without saving and they are lost.\",\n unsavedNoSave:\n \"You have unsaved changes and nowhere to save them. Restoring this version will lose them.\",\n saveAndRestore: \"Save, then restore\",\n restoreAnyway: \"Restore anyway\",\n cancel: \"Cancel\",\n },\n },\n previewResolution: {\n resolving: \"Resolving preview…\",\n failed: \"Preview couldn't be resolved — showing the unresolved template.\",\n hint: \"Preview uses resolved data from your backend.\",\n },\n mergeTagPreview: {\n label: \"Merge tag view\",\n sample: \"Sample\",\n labelView: \"Label\",\n },\n testEmail: {\n title: \"Send Test Email\",\n recipientLabel: \"Recipient\",\n recipientPlaceholder: \"you@example.com\",\n invalidAddress: \"Enter a valid email address.\",\n preview: \"Preview\",\n previewHint:\n \"Merge tags are shown unresolved — your backend fills them in.\",\n previewHintSample:\n \"Merge tags show example values — your backend fills in the real data.\",\n recipientNotAllowed: \"That address isn't in the allowed list.\",\n send: \"Send\",\n sending: \"Sending...\",\n cancel: \"Cancel\",\n success: \"Test email sent successfully\",\n button: \"Test\",\n },\n sidebarNav: {\n browseSavedBlocks: \"Browse saved blocks\",\n palette: \"Block palette\",\n insertBlock: \"Insert {block} block\",\n },\n\n // Landmark region labels for assistive technology\n landmarks: {\n canvas: \"Email canvas\",\n blockToolbar: \"Block properties\",\n rightSidebar: \"Block properties and template settings\",\n reorderAnnouncements: \"Block reorder announcements\",\n },\n\n // Design Reference (cloud)\n errors: {\n editorLoading: \"Loading editor...\",\n editorLoadFailed: \"Failed to load editor.\",\n retry: \"Retry\",\n },\n\n issues: {\n panelTitle: \"Issues\",\n panelTabLabel: \"Issues\",\n groupErrors: \"Errors\",\n groupWarnings: \"Warnings\",\n groupInfo: \"Info\",\n jump: \"Jump to block\",\n fix: \"Fix\",\n emptyState: \"No issues — looking good.\",\n badgeError: \"Has errors\",\n badgeWarning: \"Has warnings\",\n issueCountTooltip: \"{count} issue(s)\",\n },\n\n smallScreen: {\n title: \"Larger screen required\",\n message:\n \"The editor needs more space than this screen offers. Open it on a tablet or desktop to start editing.\",\n },\n};\n"],"mappings":"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"}
|