@templatical/editor 0.42.0 → 0.42.1

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 (272) hide show
  1. package/dist/{AiChatSidebar-DqSoJAXx.js → AiChatSidebar-DOCvzGBe.js} +7 -7
  2. package/dist/{AiFeatureMenu-CoBvE72q.js → AiFeatureMenu-CfijAx4G.js} +4 -4
  3. package/dist/{BlockIssueBadge-D8KsGWY6.js → BlockIssueBadge-BJ3A6mqh.js} +2 -2
  4. package/dist/{BlockPreviewCanvas-W6-MRpWz.js → BlockPreviewCanvas-DggfBaoJ.js} +2 -2
  5. package/dist/{CloudHeaderExtras-AbsNuL9T.js → CloudHeaderExtras-dFbdqBr5.js} +2 -2
  6. package/dist/{CloudPanels-BNL6rSeB.js → CloudPanels-DmMxhzzZ.js} +4 -4
  7. package/dist/{CollaboratorBar-DlZ-wOL_.js → CollaboratorBar-XXk1tOC5.js} +2 -2
  8. package/dist/{CommentsPanel-9k1q-79y.js → CommentsPanel-CGEhbjx0.js} +1 -1
  9. package/dist/{CommentsSidebar-Bc7nORmD.js → CommentsSidebar-CUpst9ou.js} +10 -10
  10. package/dist/{CountdownToolbar-Bnq25sR-.js → CountdownToolbar-B1a_UIuB.js} +3 -3
  11. package/dist/{DesignReferenceSidebar-Cl5eE8Kn.js → DesignReferenceSidebar-DkAmsBgM.js} +5 -5
  12. package/dist/{IssuesPanel-Dnns3O9z.js → IssuesPanel-lTpsCV4a.js} +5 -5
  13. package/dist/{LogicTagInsertButton-SI6irEtn.js → LogicTagInsertButton-B5YymR4U.js} +3 -3
  14. package/dist/{MediaEditModal-C-InB-H2.js → MediaEditModal-B1X8qtJb.js} +1 -1
  15. package/dist/{MediaPanels-CTosUpeo.js → MediaPanels-DO30L1KS.js} +1 -1
  16. package/dist/{MergeTagInput-BMQGNh1k.js → MergeTagInput-B0M_-X0K.js} +1 -1
  17. package/dist/{MergeTagModeToggle-Cm9s-w6o.js → MergeTagModeToggle-B-8W1tK7.js} +3 -3
  18. package/dist/{ParagraphEditor-CnBPQCVo.js → ParagraphEditor-BhhpXgoO.js} +20 -20
  19. package/dist/{RestoreVersionDialog-B13whpxH.js → RestoreVersionDialog-DE8aqmdi.js} +3 -3
  20. package/dist/{RichTextEditorContent-DOvhgc-7.js → RichTextEditorContent-AaLAArA0.js} +4 -4
  21. package/dist/{SaveBlockDialog-b5yrQfoN.js → SaveBlockDialog-BJ-hEwLv.js} +8 -8
  22. package/dist/{SavedBlocksBrowserModal-DpqK4Zqp.js → SavedBlocksBrowserModal-nLI8aAQ5.js} +9 -9
  23. package/dist/{SavedBlocksPanels-C2wURIlT.js → SavedBlocksPanels-RnzUMUJI.js} +1 -1
  24. package/dist/{SavedBlocksPickBar-Bx9_SXVA.js → SavedBlocksPickBar-D3QA3Tgy.js} +2 -2
  25. package/dist/{TemplateScoringPanel-Cs0TGtRF.js → TemplateScoringPanel-C6ellAcs.js} +11 -11
  26. package/dist/{TemplateSettings-Gn9ps1R6.js → TemplateSettings-C_0qK-zs.js} +5 -5
  27. package/dist/{TestEmailModal-DaIaklcg.js → TestEmailModal-CnyxLhWJ.js} +6 -6
  28. package/dist/{TestEmailPanel-CKSvzakC.js → TestEmailPanel-BRisIL4G.js} +1 -1
  29. package/dist/{TitleEditor-C66Jk73n.js → TitleEditor-lPITPzw6.js} +9 -9
  30. package/dist/{ToggleSwitch-BqttX9lY.js → ToggleSwitch-CtZ6adlX.js} +1 -1
  31. package/dist/{Toolbar-DVsKYQaC.js → Toolbar-B6dG5_IP.js} +20 -20
  32. package/dist/{TplModal-DRQln7xH.js → TplModal-BiAf7tWe.js} +1 -1
  33. package/dist/{VersionHistoryMenu-b0A8mS2_.js → VersionHistoryMenu-DdspCRSA.js} +5 -5
  34. package/dist/{VersionHistoryPanels-Df5WjNah.js → VersionHistoryPanels-C589Jm_B.js} +1 -1
  35. package/dist/{VersionPreviewBanner-xB9r83r0.js → VersionPreviewBanner-XUuLe36h.js} +1 -1
  36. package/dist/{WrapperBlock-B0cUORGz.js → WrapperBlock-CVQ4t1tY.js} +1 -1
  37. package/dist/{blockTypeIcons-DfQNZnl7.js → blockTypeIcons-Sg8SY1NQ.js} +2 -2
  38. package/dist/bundle-stats.json +6 -6
  39. package/dist/cdn/chunks/{AiChatSidebar-DD17BwXn.js → AiChatSidebar-DiG-EQ-E.js} +4 -4
  40. package/dist/cdn/chunks/AiChatSidebar-DiG-EQ-E.js.map +1 -0
  41. package/dist/cdn/chunks/{AiFeatureMenu-Di381OsL.js → AiFeatureMenu-BXSPgOzA.js} +3 -3
  42. package/dist/cdn/chunks/AiFeatureMenu-BXSPgOzA.js.map +1 -0
  43. package/dist/cdn/chunks/{BlockIssueBadge-BR_N3nRh.js → BlockIssueBadge-ChQ0mPf5.js} +2 -2
  44. package/dist/cdn/chunks/BlockIssueBadge-ChQ0mPf5.js.map +1 -0
  45. package/dist/cdn/chunks/{BlockPreviewCanvas-BXpcAiiY.js → BlockPreviewCanvas-CMmv1FTA.js} +3 -3
  46. package/dist/cdn/chunks/BlockPreviewCanvas-CMmv1FTA.js.map +1 -0
  47. package/dist/cdn/chunks/{CloudHeaderExtras-BEM2eWfF.js → CloudHeaderExtras-yvFz2_e-.js} +3 -3
  48. package/dist/cdn/chunks/CloudHeaderExtras-yvFz2_e-.js.map +1 -0
  49. package/dist/cdn/chunks/{CloudPanels-D7nK1-bm.js → CloudPanels-DpKck9Na.js} +4 -4
  50. package/dist/cdn/chunks/CloudPanels-DpKck9Na.js.map +1 -0
  51. package/dist/cdn/chunks/{CollaboratorBar-D1SUwahw.js → CollaboratorBar-Clm1ZVXQ.js} +3 -3
  52. package/dist/cdn/chunks/CollaboratorBar-Clm1ZVXQ.js.map +1 -0
  53. package/dist/cdn/chunks/{CommentsPanel-qsLMAlJU.js → CommentsPanel-CjhxGMjL.js} +2 -2
  54. package/dist/cdn/chunks/CommentsPanel-CjhxGMjL.js.map +1 -0
  55. package/dist/cdn/chunks/{CommentsSidebar-CTwEE-s_.js → CommentsSidebar-D9bqMnlt.js} +2 -2
  56. package/dist/cdn/chunks/CommentsSidebar-D9bqMnlt.js.map +1 -0
  57. package/dist/cdn/chunks/CountdownBlock-sVDjKkRw.js.map +1 -1
  58. package/dist/cdn/chunks/{CountdownToolbar-BJTcnIQ-.js → CountdownToolbar-CIRx5w1U.js} +4 -4
  59. package/dist/cdn/chunks/CountdownToolbar-CIRx5w1U.js.map +1 -0
  60. package/dist/cdn/chunks/{DesignReferenceSidebar-Dl3eEGtS.js → DesignReferenceSidebar-C1-SbE_R.js} +2 -2
  61. package/dist/cdn/chunks/DesignReferenceSidebar-C1-SbE_R.js.map +1 -0
  62. package/dist/cdn/chunks/{IssuesPanel-L9Gq_T8n.js → IssuesPanel-qKY6UDd-.js} +2 -2
  63. package/dist/cdn/chunks/IssuesPanel-qKY6UDd-.js.map +1 -0
  64. package/dist/cdn/chunks/LoadingTrack-_7DH_5aw.js.map +1 -1
  65. package/dist/cdn/chunks/{LogicTagInsertButton-3pIbVE9p.js → LogicTagInsertButton-CItDS_U1.js} +2 -2
  66. package/dist/cdn/chunks/LogicTagInsertButton-CItDS_U1.js.map +1 -0
  67. package/dist/cdn/chunks/{MediaEditModal-rTjYl-fV.js → MediaEditModal-CzUtXkpk.js} +2 -2
  68. package/dist/cdn/chunks/MediaEditModal-CzUtXkpk.js.map +1 -0
  69. package/dist/cdn/chunks/{MediaPanels-DMXRQVqg.js → MediaPanels-DOLsh7WC.js} +2 -2
  70. package/dist/cdn/chunks/MediaPanels-DOLsh7WC.js.map +1 -0
  71. package/dist/cdn/chunks/{MergeTagInput-JcBzr77a.js → MergeTagInput-B33u3nxj.js} +2 -2
  72. package/dist/cdn/chunks/MergeTagInput-B33u3nxj.js.map +1 -0
  73. package/dist/cdn/chunks/{MergeTagModeToggle-CYmueXS2.js → MergeTagModeToggle-Bz1CH3NT.js} +2 -2
  74. package/dist/cdn/chunks/MergeTagModeToggle-Bz1CH3NT.js.map +1 -0
  75. package/dist/cdn/chunks/{ParagraphEditor-DbjFDnYm.js → ParagraphEditor-J74SIn-m.js} +24 -24
  76. package/dist/cdn/chunks/ParagraphEditor-J74SIn-m.js.map +1 -0
  77. package/dist/cdn/chunks/{RestoreVersionDialog-pANCWcce.js → RestoreVersionDialog-CFE7jqDB.js} +3 -3
  78. package/dist/cdn/chunks/RestoreVersionDialog-CFE7jqDB.js.map +1 -0
  79. package/dist/cdn/chunks/{RichTextEditorContent-BtM1or8A.js → RichTextEditorContent-dOg1xFqv.js} +4 -4
  80. package/dist/cdn/chunks/RichTextEditorContent-dOg1xFqv.js.map +1 -0
  81. package/dist/cdn/chunks/{SaveBlockDialog-CGM3mrGj.js → SaveBlockDialog-DZOmDCC8.js} +6 -6
  82. package/dist/cdn/chunks/SaveBlockDialog-DZOmDCC8.js.map +1 -0
  83. package/dist/cdn/chunks/{SavedBlocksBrowserModal-C6Z8AvtD.js → SavedBlocksBrowserModal-B43H5zKA.js} +6 -6
  84. package/dist/cdn/chunks/SavedBlocksBrowserModal-B43H5zKA.js.map +1 -0
  85. package/dist/cdn/chunks/{SavedBlocksPanels-DNwKmnhp.js → SavedBlocksPanels-uTSb2xO_.js} +2 -2
  86. package/dist/cdn/chunks/SavedBlocksPanels-uTSb2xO_.js.map +1 -0
  87. package/dist/cdn/chunks/{SavedBlocksPickBar-D2p1ufB4.js → SavedBlocksPickBar-BUvmGqHK.js} +3 -3
  88. package/dist/cdn/chunks/SavedBlocksPickBar-BUvmGqHK.js.map +1 -0
  89. package/dist/cdn/chunks/{TemplateScoringPanel-BDB4RErx.js → TemplateScoringPanel-ebsrVge3.js} +2 -2
  90. package/dist/cdn/chunks/TemplateScoringPanel-ebsrVge3.js.map +1 -0
  91. package/dist/cdn/chunks/{TemplateSettings-DVN1t3yF.js → TemplateSettings-BaEVdUTM.js} +4 -4
  92. package/dist/cdn/chunks/TemplateSettings-BaEVdUTM.js.map +1 -0
  93. package/dist/cdn/chunks/{TestEmailModal-DZBCmBtT.js → TestEmailModal-ide7UP_H.js} +6 -6
  94. package/dist/cdn/chunks/TestEmailModal-ide7UP_H.js.map +1 -0
  95. package/dist/cdn/chunks/{TestEmailPanel-1ibwYCUl.js → TestEmailPanel-Cqdsnufx.js} +2 -2
  96. package/dist/cdn/chunks/TestEmailPanel-Cqdsnufx.js.map +1 -0
  97. package/dist/cdn/chunks/{TitleEditor-BRl2qKbd.js → TitleEditor-CoFzxLPA.js} +8 -8
  98. package/dist/cdn/chunks/TitleEditor-CoFzxLPA.js.map +1 -0
  99. package/dist/cdn/chunks/{ToggleSwitch-niSL2uog.js → ToggleSwitch-D-8dCEbI.js} +2 -2
  100. package/dist/cdn/chunks/ToggleSwitch-D-8dCEbI.js.map +1 -0
  101. package/dist/cdn/chunks/{Toolbar-tTl0P-rr.js → Toolbar-BDzhrmGV.js} +32 -32
  102. package/dist/cdn/chunks/Toolbar-BDzhrmGV.js.map +1 -0
  103. package/dist/cdn/chunks/{TplModal-C_eIPykE.js → TplModal-mLMmolQp.js} +2 -2
  104. package/dist/cdn/chunks/TplModal-mLMmolQp.js.map +1 -0
  105. package/dist/cdn/chunks/{VersionHistoryMenu-Ww57XAzj.js → VersionHistoryMenu-C_bBKOYU.js} +2 -2
  106. package/dist/cdn/chunks/VersionHistoryMenu-C_bBKOYU.js.map +1 -0
  107. package/dist/cdn/chunks/{VersionHistoryPanels-w0EG_qVW.js → VersionHistoryPanels-B9LwOKxm.js} +2 -2
  108. package/dist/cdn/chunks/VersionHistoryPanels-B9LwOKxm.js.map +1 -0
  109. package/dist/cdn/chunks/{VersionPreviewBanner-Bbd4C-AN.js → VersionPreviewBanner-CKyrcgxJ.js} +2 -2
  110. package/dist/cdn/chunks/VersionPreviewBanner-CKyrcgxJ.js.map +1 -0
  111. package/dist/cdn/chunks/{WrapperBlock-Ch4KeMIb.js → WrapperBlock-DI8vSvTO.js} +2 -2
  112. package/dist/cdn/chunks/WrapperBlock-DI8vSvTO.js.map +1 -0
  113. package/dist/cdn/chunks/{blockTypeIcons-CyPXFh7L.js → blockTypeIcons-CdfCfqHE.js} +2 -2
  114. package/dist/cdn/chunks/blockTypeIcons-CdfCfqHE.js.map +1 -0
  115. package/dist/cdn/chunks/ca--zGWn9AU.js.map +1 -1
  116. package/dist/cdn/chunks/ca-BTf1Zbqb.js.map +1 -1
  117. package/dist/cdn/chunks/cloud-De-eh1u6.js.map +1 -1
  118. package/dist/cdn/chunks/createCloudRuntime-DsaUaWvr.js.map +1 -1
  119. package/dist/cdn/chunks/de-BRNLKcDl.js.map +1 -1
  120. package/dist/cdn/chunks/de-mMY5yQJu.js.map +1 -1
  121. package/dist/cdn/chunks/de-xzrh9PA3.js.map +1 -1
  122. package/dist/cdn/chunks/dist-BRZhN8qJ.js.map +1 -1
  123. package/dist/cdn/chunks/dist-CXB2_kBa.js.map +1 -1
  124. package/dist/cdn/chunks/draggable-IB4x6w2O.js.map +1 -1
  125. package/dist/cdn/chunks/{editor-modal-BdI0iA5r.js → editor-modal-CZQArGNj.js} +4 -4
  126. package/dist/cdn/chunks/editor-modal-CZQArGNj.js.map +1 -0
  127. package/dist/cdn/chunks/emojiData-6m0DBh7O.js.map +1 -1
  128. package/dist/cdn/chunks/en-9unxBjV8.js +2 -0
  129. package/dist/cdn/chunks/en-ChVeGQBY.js.map +1 -1
  130. package/dist/cdn/chunks/en-JJjqHMjy.js.map +1 -1
  131. package/dist/cdn/chunks/es-BIh8BxV9.js.map +1 -1
  132. package/dist/cdn/chunks/es-BT4LSpE2.js.map +1 -1
  133. package/dist/cdn/chunks/{extensions-DK_9-6Bd.js → extensions-Dy251lPd.js} +3 -3
  134. package/dist/cdn/chunks/extensions-Dy251lPd.js.map +1 -0
  135. package/dist/cdn/chunks/formatAbsoluteDateTime-DMmop3C-.js.map +1 -1
  136. package/dist/cdn/chunks/formatRelativeTime-CtUU-QZ8.js.map +1 -1
  137. package/dist/cdn/chunks/fr-C5VUZogP.js.map +1 -1
  138. package/dist/cdn/chunks/fr-CI7OJoql.js.map +1 -1
  139. package/dist/cdn/chunks/htmlparser-ClUZ6waR.js.map +1 -1
  140. package/dist/cdn/chunks/{icons-Bad3WZ3G.js → icons-CQnjugjy.js} +38 -38
  141. package/dist/cdn/chunks/icons-CQnjugjy.js.map +1 -0
  142. package/dist/cdn/chunks/ja-DhlWUfke.js.map +1 -1
  143. package/dist/cdn/chunks/ja-x5JYxaCW.js.map +1 -1
  144. package/dist/cdn/chunks/keys-DCWeHkSF.js.map +1 -1
  145. package/dist/cdn/chunks/liquid.browser-BypTT2oc.js.map +1 -1
  146. package/dist/cdn/chunks/logger-ByvdoAwq.js.map +1 -1
  147. package/dist/cdn/chunks/nl-D8y5OWGB.js.map +1 -1
  148. package/dist/cdn/chunks/nl-UXxFyXV6.js.map +1 -1
  149. package/dist/cdn/chunks/preRenderCustomBlocks-h4ZFBKbD.js.map +1 -1
  150. package/dist/cdn/chunks/pt-BR-CoCwRUi0.js.map +1 -1
  151. package/dist/cdn/chunks/pt-BR-DHm3SP6W.js.map +1 -1
  152. package/dist/cdn/chunks/pt-BR-DMCbUBvJ.js.map +1 -1
  153. package/dist/cdn/chunks/pusher-BbIHJKf3.js.map +1 -1
  154. package/dist/cdn/chunks/readableTextColor-f8Kykfnh.js.map +1 -1
  155. package/dist/cdn/chunks/socialIcons-ZOCwCCyn.js.map +1 -1
  156. package/dist/cdn/chunks/src-BR3I3gOW.js.map +1 -1
  157. package/dist/cdn/chunks/src-fZSLjhjy.js.map +1 -1
  158. package/dist/cdn/chunks/{src-BxoLKnkl.js → src-nhIF5-mf.js} +3 -3
  159. package/dist/cdn/chunks/src-nhIF5-mf.js.map +1 -0
  160. package/dist/cdn/chunks/styleConstants-C_YAPdQS.js.map +1 -1
  161. package/dist/cdn/chunks/templateSettingsFields-YCFVBVYh.js.map +1 -1
  162. package/dist/cdn/chunks/timeouts-DHPZQ0G3.js.map +1 -1
  163. package/dist/cdn/chunks/{tiptap-DhLuKyDc.js → tiptap-D1u8JIUW.js} +1916 -1917
  164. package/dist/cdn/chunks/tiptap-D1u8JIUW.js.map +1 -0
  165. package/dist/cdn/chunks/useAliveFlag-DAlQLbM2.js.map +1 -1
  166. package/dist/cdn/chunks/useCloudI18n-CrjWbpbu.js.map +1 -1
  167. package/dist/cdn/chunks/{useEditorCore-yd40TFKy.js → useEditorCore-D4kzTMtQ.js} +5 -5
  168. package/dist/cdn/chunks/useEditorCore-D4kzTMtQ.js.map +1 -0
  169. package/dist/cdn/chunks/useEditorRoot-CshefZLP.js.map +1 -1
  170. package/dist/cdn/chunks/useI18n-CyO_Nmca.js.map +1 -1
  171. package/dist/cdn/chunks/useLogicTag-J_i_hvZg.js.map +1 -1
  172. package/dist/cdn/chunks/useMergeTag-C5MyHYxJ.js.map +1 -1
  173. package/dist/cdn/chunks/usePopoverPosition-DGXjXKjM.js.map +1 -1
  174. package/dist/cdn/chunks/useScrollToBlock-DgHZJvID.js.map +1 -1
  175. package/dist/cdn/editor.css +1 -1
  176. package/dist/cdn/editor.js +495 -466
  177. package/dist/cdn/editor.js.map +1 -1
  178. package/dist/{check-eqb2JhqU.js → check-BMx_TLAS.js} +1 -1
  179. package/dist/{chevron-down-Dkr-7Ywl.js → chevron-down-KZf5mh9_.js} +1 -1
  180. package/dist/{chevron-right-Bge4XF_B.js → chevron-right-BLZ60Vxw.js} +1 -1
  181. package/dist/{chevron-up-CQAyl0kC.js → chevron-up-B9ynB8eU.js} +1 -1
  182. package/dist/{circle-alert-CYgTHKWr.js → circle-alert-pjvFFDrF.js} +1 -1
  183. package/dist/{clock-BgSJZJP5.js → clock-CiiTBfF3.js} +1 -1
  184. package/dist/{copy-mw6PVnOJ.js → copy-BF0_pQjH.js} +1 -1
  185. package/dist/{createLucideIcon-BxY5yz5u.js → createLucideIcon-C2YOVVWx.js} +8 -8
  186. package/dist/{dist-CQSVro7b.js → dist-B0dkvy7z.js} +1 -1
  187. package/dist/{dist-BJM3eFyT.js → dist-BPWuzECC.js} +1 -1
  188. package/dist/{dist-EDkj3Ub1.js → dist-BUHovM4k.js} +1 -1
  189. package/dist/{dist-BmsLcnrO.js → dist-BwoEME8p.js} +1 -1
  190. package/dist/{dist-DerFNpDY.js → dist-C2Ge44fD.js} +760 -761
  191. package/dist/{dist-BdHF7nyq.js → dist-CIxmOOSG.js} +5 -5
  192. package/dist/{dist-wyXxj3R1.js → dist-CJ7RZARo.js} +1 -1
  193. package/dist/{dist-Bl4rxpX9.js → dist-CxmLZQso.js} +1 -1
  194. package/dist/{dist-DyrEOKEJ.js → dist-DRmafAUz.js} +1 -1
  195. package/dist/{dist-Djmzp6wi.js → dist-DdOAotfz.js} +1 -1
  196. package/dist/{dist-BxVnMgXZ.js → dist-W_ERo6c_.js} +1 -1
  197. package/dist/{dist-DQbOebGW.js → dist-p-LkiWIQ.js} +1 -1
  198. package/dist/{editor-modal-qzmEVcIk.js → editor-modal-99FB40dl.js} +16 -16
  199. package/dist/en-BvOjRLiw.js +2 -0
  200. package/dist/{extensions-DoT2-_pz.js → extensions-DqQXxrvP.js} +3 -3
  201. package/dist/{eye-DphkRtAD.js → eye-RdXYgrQZ.js} +1 -1
  202. package/dist/{image-up-Qi2BXD7T.js → image-up-BwdoReQt.js} +1 -1
  203. package/dist/{info-VSyAs02q.js → info-zFMSGrL1.js} +1 -1
  204. package/dist/{link-CNuozGqD.js → link-D7orqFBT.js} +1 -1
  205. package/dist/{list-BA0I5Wmu.js → list-BGt4Pgxc.js} +1 -1
  206. package/dist/{loader-circle-z5eeqasv.js → loader-circle-BVBgkRGz.js} +1 -1
  207. package/dist/{message-circle-BsQ9hEup.js → message-circle-D8YLsarv.js} +1 -1
  208. package/dist/{package-OkXfuRoO.js → package-CuFvk0L5.js} +1 -1
  209. package/dist/{pencil-DFVFA7Dj.js → pencil-DRYbmZW7.js} +1 -1
  210. package/dist/{plus-D8bkVjZ7.js → plus-Dv0b3kh0.js} +1 -1
  211. package/dist/{refresh-cw-DPB7YFuz.js → refresh-cw-gYTIS5bJ.js} +1 -1
  212. package/dist/{search-C-dCgqIa.js → search-D84_Ki_a.js} +1 -1
  213. package/dist/{send-Cm2fy2zm.js → send-Cn-8_H_U.js} +1 -1
  214. package/dist/{shield-check-COgBYFDF.js → shield-check-BOoVWJtD.js} +1 -1
  215. package/dist/{smartphone-v0u_MOEV.js → smartphone-4Ej3PBw5.js} +1 -1
  216. package/dist/{socialIcons-CACVa6m_.js → socialIcons-CzRJskEk.js} +1 -1
  217. package/dist/{sparkles-Ds0RF8Iu.js → sparkles-D3vnNe7O.js} +1 -1
  218. package/dist/style.css +1 -1
  219. package/dist/templatical-editor.js +404 -375
  220. package/dist/{text-align-start-DiavaIm6.js → text-align-start-Ci2h_Xly.js} +1 -1
  221. package/dist/{trash-DnOkfu2V.js → trash-wmi4UKvv.js} +1 -1
  222. package/dist/{triangle-alert-DGLAyXnh.js → triangle-alert-DJ0r2wmQ.js} +1 -1
  223. package/dist/{upload-BBDme2cy.js → upload-XMde-TXf.js} +1 -1
  224. package/dist/{useEditorCore-LyNoGs0m.js → useEditorCore-Dhit8Ygg.js} +11 -11
  225. package/dist/{useScrollToBlock-Dj4v3rxr.js → useScrollToBlock-B4F7KCrf.js} +1 -1
  226. package/dist/{x-3BHV3Q6K.js → x-BWrtpVl-.js} +1 -1
  227. package/package.json +10 -10
  228. package/dist/cdn/chunks/AiChatSidebar-DD17BwXn.js.map +0 -1
  229. package/dist/cdn/chunks/AiFeatureMenu-Di381OsL.js.map +0 -1
  230. package/dist/cdn/chunks/BlockIssueBadge-BR_N3nRh.js.map +0 -1
  231. package/dist/cdn/chunks/BlockPreviewCanvas-BXpcAiiY.js.map +0 -1
  232. package/dist/cdn/chunks/CloudHeaderExtras-BEM2eWfF.js.map +0 -1
  233. package/dist/cdn/chunks/CloudPanels-D7nK1-bm.js.map +0 -1
  234. package/dist/cdn/chunks/CollaboratorBar-D1SUwahw.js.map +0 -1
  235. package/dist/cdn/chunks/CommentsPanel-qsLMAlJU.js.map +0 -1
  236. package/dist/cdn/chunks/CommentsSidebar-CTwEE-s_.js.map +0 -1
  237. package/dist/cdn/chunks/CountdownToolbar-BJTcnIQ-.js.map +0 -1
  238. package/dist/cdn/chunks/DesignReferenceSidebar-Dl3eEGtS.js.map +0 -1
  239. package/dist/cdn/chunks/IssuesPanel-L9Gq_T8n.js.map +0 -1
  240. package/dist/cdn/chunks/LogicTagInsertButton-3pIbVE9p.js.map +0 -1
  241. package/dist/cdn/chunks/MediaEditModal-rTjYl-fV.js.map +0 -1
  242. package/dist/cdn/chunks/MediaPanels-DMXRQVqg.js.map +0 -1
  243. package/dist/cdn/chunks/MergeTagInput-JcBzr77a.js.map +0 -1
  244. package/dist/cdn/chunks/MergeTagModeToggle-CYmueXS2.js.map +0 -1
  245. package/dist/cdn/chunks/ParagraphEditor-DbjFDnYm.js.map +0 -1
  246. package/dist/cdn/chunks/RestoreVersionDialog-pANCWcce.js.map +0 -1
  247. package/dist/cdn/chunks/RichTextEditorContent-BtM1or8A.js.map +0 -1
  248. package/dist/cdn/chunks/SaveBlockDialog-CGM3mrGj.js.map +0 -1
  249. package/dist/cdn/chunks/SavedBlocksBrowserModal-C6Z8AvtD.js.map +0 -1
  250. package/dist/cdn/chunks/SavedBlocksPanels-DNwKmnhp.js.map +0 -1
  251. package/dist/cdn/chunks/SavedBlocksPickBar-D2p1ufB4.js.map +0 -1
  252. package/dist/cdn/chunks/TemplateScoringPanel-BDB4RErx.js.map +0 -1
  253. package/dist/cdn/chunks/TemplateSettings-DVN1t3yF.js.map +0 -1
  254. package/dist/cdn/chunks/TestEmailModal-DZBCmBtT.js.map +0 -1
  255. package/dist/cdn/chunks/TestEmailPanel-1ibwYCUl.js.map +0 -1
  256. package/dist/cdn/chunks/TitleEditor-BRl2qKbd.js.map +0 -1
  257. package/dist/cdn/chunks/ToggleSwitch-niSL2uog.js.map +0 -1
  258. package/dist/cdn/chunks/Toolbar-tTl0P-rr.js.map +0 -1
  259. package/dist/cdn/chunks/TplModal-C_eIPykE.js.map +0 -1
  260. package/dist/cdn/chunks/VersionHistoryMenu-Ww57XAzj.js.map +0 -1
  261. package/dist/cdn/chunks/VersionHistoryPanels-w0EG_qVW.js.map +0 -1
  262. package/dist/cdn/chunks/VersionPreviewBanner-Bbd4C-AN.js.map +0 -1
  263. package/dist/cdn/chunks/WrapperBlock-Ch4KeMIb.js.map +0 -1
  264. package/dist/cdn/chunks/blockTypeIcons-CyPXFh7L.js.map +0 -1
  265. package/dist/cdn/chunks/editor-modal-BdI0iA5r.js.map +0 -1
  266. package/dist/cdn/chunks/en-Cs-nw16K.js +0 -2
  267. package/dist/cdn/chunks/extensions-DK_9-6Bd.js.map +0 -1
  268. package/dist/cdn/chunks/icons-Bad3WZ3G.js.map +0 -1
  269. package/dist/cdn/chunks/src-BxoLKnkl.js.map +0 -1
  270. package/dist/cdn/chunks/tiptap-DhLuKyDc.js.map +0 -1
  271. package/dist/cdn/chunks/useEditorCore-yd40TFKy.js.map +0 -1
  272. package/dist/en-1tgLzB8q.js +0 -2
@@ -1 +0,0 @@
1
- {"version":3,"file":"TplModal-C_eIPykE.js","names":[],"sources":["../../../src/components/TplModal.vue","../../../src/components/TplModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useFocusTrap } from \"../composables\";\nimport { usePopoverRoot } from \"../composables/usePopoverRoot\";\nimport { THEME_STYLES_KEY, UI_THEME_KEY } from \"../keys\";\nimport { computed, inject, ref } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"keydown\", event: KeyboardEvent): void;\n}>();\n\nconst dialogRef = ref<HTMLElement | null>(null);\nconst isVisible = computed(() => props.visible);\nuseFocusTrap(dialogRef, isVisible);\n\nconst tplUiTheme = inject(UI_THEME_KEY);\n\n// The backdrop below carries the bare `tpl` class, which re-declares every\n// `--tpl-*` token from the base `.tpl` rule. A custom property declared on an\n// element beats one inherited from an ancestor, so that re-declaration shadows\n// the consumer's `theme` config — which lives as inline styles on the editor\n// root — for this whole teleported subtree. Re-applying `themeStyles` here is\n// what restores it, and doing it on the backdrop covers every dialog rendered\n// through this wrapper rather than each one remembering to. `data-tpl-theme`\n// does the same job for the dark token block. See the invariant in\n// `tests/theme-token-scope.test.ts` (issue #487).\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst popoverRoot = usePopoverRoot();\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n emit(\"close\");\n }\n emit(\"keydown\", event);\n}\n</script>\n\n<template>\n <Teleport v-if=\"popoverRoot\" :to=\"popoverRoot\">\n <Transition\n enter-active-class=\"tpl:transition\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <!-- The backdrop is the reference box every slotted panel caps against,\n which is why it owns the gutter (`p-4`) rather than each panel\n carrying its own margin. `inset-0` gives it a definite height; the\n wrapper below spans that height so a panel's percentage cap\n (`max-h-[90%]` / `max-h-[80%]`) has an unbroken chain to resolve\n through. Those numbers are the `vh` values they replaced, so an\n untrapped editor renders exactly as before.\n\n Panels must never cap in `vh`. `fixed` covers the viewport only while\n nothing traps it, and an ancestor with `transform`, `filter`,\n `backdrop-filter`, `will-change: transform`, `contain: paint`,\n `container-type` or a transform animation becomes the containing\n block for fixed descendants. The editor is embedded in someone\n else's page, so any of those can sit above it: `inset-0` then\n resolves to that ancestor's box while a `vh` cap still resolves to\n the viewport, and the panel overflows a container that usually also\n has `overflow: hidden`. That is issue #575 — in a 420px host inside a\n 720px viewport, a 648px panel clipped ~113px off both the top and the\n bottom, with no scrollbar to reach the buttons. Capping against the\n backdrop is self-correcting whether or not the trap is present.\n Locked by `tests/overlay-height-scope.test.ts`.\n\n The padding belongs here and not on the wrapper: preflight is\n omitted, so non-form elements keep `content-box` and padding on an\n `h-full` element would add to 100% and overflow by exactly the\n padding (the trap behind issue #115). Insets size the backdrop's\n border box, so padding here safely shrinks the content box instead. -->\n <!-- `z-10` is the one z-index inside `.tpl-popover-root` that has to be\n real. The root is a single stacking context, so its residents\n otherwise paint in teleport-anchor order — and this modal's anchor is\n established when the editor mounts, while a link dialog's is\n established later, when a paragraph enters edit mode. Without a\n number, a picker opened FROM that dialog renders behind it. Any\n positive value beats the `auto` siblings; 10 stays far below the\n suggestion popup (9999) and `SmallScreenNotice` (10001), and cannot\n escape the root's own 10000 either way. -->\n <div\n v-if=\"visible\"\n :data-tpl-theme=\"tplUiTheme\"\n class=\"tpl tpl:fixed tpl:inset-0 tpl:z-10 tpl:flex tpl:items-center tpl:justify-center tpl:p-4\"\n style=\"\n background-color: var(--tpl-overlay);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n :style=\"themeStyles\"\n @click.self=\"emit('close')\"\n @keydown=\"handleKeydown\"\n >\n <!-- `h-full` only, deliberately no `w-full`: height is what has to\n become definite, and widening this element would change what\n `w-full` on a panel resolves against. Panels are shrink-to-fit\n horizontally — the test-email dialog stays compact until its\n preview opens, and the saved-blocks browser pins an explicit width\n precisely because this wrapper is shrink-to-fit. Constraining one\n axis leaves all of that intact.\n\n It repeats `@click.self` because it now covers the backdrop's full\n height: clicks in the gap above or below the panel land here, so\n without it click-outside-to-close would only work on the padding\n ring and the columns either side. -->\n <div\n ref=\"dialogRef\"\n class=\"tpl:flex tpl:h-full tpl:items-center tpl:justify-center\"\n @click.self=\"emit('close')\"\n >\n <slot />\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { useFocusTrap } from \"../composables\";\nimport { usePopoverRoot } from \"../composables/usePopoverRoot\";\nimport { THEME_STYLES_KEY, UI_THEME_KEY } from \"../keys\";\nimport { computed, inject, ref } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"keydown\", event: KeyboardEvent): void;\n}>();\n\nconst dialogRef = ref<HTMLElement | null>(null);\nconst isVisible = computed(() => props.visible);\nuseFocusTrap(dialogRef, isVisible);\n\nconst tplUiTheme = inject(UI_THEME_KEY);\n\n// The backdrop below carries the bare `tpl` class, which re-declares every\n// `--tpl-*` token from the base `.tpl` rule. A custom property declared on an\n// element beats one inherited from an ancestor, so that re-declaration shadows\n// the consumer's `theme` config — which lives as inline styles on the editor\n// root — for this whole teleported subtree. Re-applying `themeStyles` here is\n// what restores it, and doing it on the backdrop covers every dialog rendered\n// through this wrapper rather than each one remembering to. `data-tpl-theme`\n// does the same job for the dark token block. See the invariant in\n// `tests/theme-token-scope.test.ts` (issue #487).\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst popoverRoot = usePopoverRoot();\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n emit(\"close\");\n }\n emit(\"keydown\", event);\n}\n</script>\n\n<template>\n <Teleport v-if=\"popoverRoot\" :to=\"popoverRoot\">\n <Transition\n enter-active-class=\"tpl:transition\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <!-- The backdrop is the reference box every slotted panel caps against,\n which is why it owns the gutter (`p-4`) rather than each panel\n carrying its own margin. `inset-0` gives it a definite height; the\n wrapper below spans that height so a panel's percentage cap\n (`max-h-[90%]` / `max-h-[80%]`) has an unbroken chain to resolve\n through. Those numbers are the `vh` values they replaced, so an\n untrapped editor renders exactly as before.\n\n Panels must never cap in `vh`. `fixed` covers the viewport only while\n nothing traps it, and an ancestor with `transform`, `filter`,\n `backdrop-filter`, `will-change: transform`, `contain: paint`,\n `container-type` or a transform animation becomes the containing\n block for fixed descendants. The editor is embedded in someone\n else's page, so any of those can sit above it: `inset-0` then\n resolves to that ancestor's box while a `vh` cap still resolves to\n the viewport, and the panel overflows a container that usually also\n has `overflow: hidden`. That is issue #575 — in a 420px host inside a\n 720px viewport, a 648px panel clipped ~113px off both the top and the\n bottom, with no scrollbar to reach the buttons. Capping against the\n backdrop is self-correcting whether or not the trap is present.\n Locked by `tests/overlay-height-scope.test.ts`.\n\n The padding belongs here and not on the wrapper: preflight is\n omitted, so non-form elements keep `content-box` and padding on an\n `h-full` element would add to 100% and overflow by exactly the\n padding (the trap behind issue #115). Insets size the backdrop's\n border box, so padding here safely shrinks the content box instead. -->\n <!-- `z-10` is the one z-index inside `.tpl-popover-root` that has to be\n real. The root is a single stacking context, so its residents\n otherwise paint in teleport-anchor order — and this modal's anchor is\n established when the editor mounts, while a link dialog's is\n established later, when a paragraph enters edit mode. Without a\n number, a picker opened FROM that dialog renders behind it. Any\n positive value beats the `auto` siblings; 10 stays far below the\n suggestion popup (9999) and `SmallScreenNotice` (10001), and cannot\n escape the root's own 10000 either way. -->\n <div\n v-if=\"visible\"\n :data-tpl-theme=\"tplUiTheme\"\n class=\"tpl tpl:fixed tpl:inset-0 tpl:z-10 tpl:flex tpl:items-center tpl:justify-center tpl:p-4\"\n style=\"\n background-color: var(--tpl-overlay);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n :style=\"themeStyles\"\n @click.self=\"emit('close')\"\n @keydown=\"handleKeydown\"\n >\n <!-- `h-full` only, deliberately no `w-full`: height is what has to\n become definite, and widening this element would change what\n `w-full` on a panel resolves against. Panels are shrink-to-fit\n horizontally — the test-email dialog stays compact until its\n preview opens, and the saved-blocks browser pins an explicit width\n precisely because this wrapper is shrink-to-fit. Constraining one\n axis leaves all of that intact.\n\n It repeats `@click.self` because it now covers the backdrop's full\n height: clicks in the gap above or below the panel land here, so\n without it click-outside-to-close would only work on the padding\n ring and the columns either side. -->\n <div\n ref=\"dialogRef\"\n class=\"tpl:flex tpl:h-full tpl:items-center tpl:justify-center\"\n @click.self=\"emit('close')\"\n >\n <slot />\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n"],"mappings":";;;;;;;;;;EAMA,IAAM,IAAQ,GAIR,IAAO,GAKP,IAAY,EAAwB,IAAI,GACxC,IAAY,QAAe,EAAM,OAAO;EAC9C,EAAa,GAAW,CAAS;EAEjC,IAAM,IAAa,EAAO,CAAY,GAWhC,IAAc,EAAO,GAAkB,IAAI,GAC3C,IAAc,EAAe;EAEnC,SAAS,EAAc,GAA4B;GAIjD,AAHI,EAAM,QAAQ,YAChB,EAAK,OAAO,GAEd,EAAK,WAAW,CAAK;EACvB;mBAIkB,EAAA,CAAA,KAAhB,EAAA,GAAA,EA+EW,GAAA;;GA/EmB,IAAI,EAAA,CAAA;EAChC,GAAA,CAAA,EA6Ea,GAAA;GA5EX,sBAAmB;GACnB,oBAAiB;GACjB,kBAAe;GACf,sBAAmB;GACnB,oBAAiB;GACjB,kBAAe;;GAsCf,SAAA,QAgCM,CA/BE,EAAA,WADR,EAAA,GAAA,EAgCM,OAAA;;IA9BH,kBAAgB,EAAA,CAAA;IACjB,OAAM;IACN,OAIC,EAAA,CAJD;KAAA,oBAAA;KAAA,mBAAA;KAAA,2BAAA;IAAA,GAKQ,EAAA,CAAA,CAAW,CAAA;IAClB,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAI,OAAA,GAAA,CAAA,MAAA,CAAA;IAChB,WAAS;GAcV,GAAA,CAAA,EAMM,OAAA;IALA,SAAA;IAAJ,KAAI;IACJ,OAAM;IACL,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAI,OAAA,GAAA,CAAA,MAAA,CAAA;GAEjB,GAAA,CAAA,EAAQ,EAAA,QAAA,SAAA,CAAA,GAAA,GAAA,CAAA,GAAA,IAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"VersionHistoryMenu-Ww57XAzj.js","names":[],"sources":["../../../src/components/VersionHistoryMenu.vue","../../../src/components/VersionHistoryMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The header's version-history control: step older / newer through the list, or\n * open the dropdown and jump straight to one.\n *\n * Shared by both editors. Reads the `TemplateVersion` contract, so any\n * provider drives it.\n */\nimport { computed, inject, ref } from \"vue\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Clock,\n LoaderCircle,\n} from \"@lucide/vue\";\nimport type { TemplateVersion } from \"@templatical/types\";\nimport { useI18n } from \"../composables/useI18n\";\nimport { formatAbsoluteDateTime } from \"../utils/formatAbsoluteDateTime\";\nimport { formatRelativeTime } from \"../utils/formatRelativeTime\";\nimport { UI_LOCALE_KEY } from \"../keys\";\n\nconst props = defineProps<{\n versions: TemplateVersion[];\n isLoading: boolean;\n isRestoring: boolean;\n /** Which version is on the canvas, or `null` while editing normally. */\n previewingId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"open\"): void;\n (e: \"navigate\", version: TemplateVersion): void;\n}>();\n\nconst { t, format } = useI18n();\nconst uiLocale = inject(UI_LOCALE_KEY, undefined);\n\nconst isOpen = ref(false);\nconst dropdownRef = ref<HTMLElement | null>(null);\n\n/**\n * Position in the list (0 = newest), derived from what is actually previewed\n * rather than tracked locally. A local index went stale the moment the user\n * cancelled a preview — the arrows then stepped from wherever they had left off\n * instead of from the top.\n */\nconst currentIndex = computed(() =>\n props.previewingId === null\n ? -1\n : props.versions.findIndex((v) => v.id === props.previewingId),\n);\n\nconst canGoNewer = computed(\n () => currentIndex.value > 0 && !props.isRestoring && !props.isLoading,\n);\n\nconst canGoOlder = computed(\n () =>\n currentIndex.value < props.versions.length - 1 &&\n props.versions.length > 0 &&\n !props.isRestoring &&\n !props.isLoading,\n);\n\nfunction goNewer(): void {\n if (!canGoNewer.value) return;\n emit(\"navigate\", props.versions[currentIndex.value - 1]);\n}\n\nfunction goOlder(): void {\n if (!canGoOlder.value) return;\n emit(\"navigate\", props.versions[currentIndex.value + 1]);\n}\n\nfunction toggleDropdown(): void {\n isOpen.value = !isOpen.value;\n // Always on open, never only when empty: history grows behind the user's back\n // (every save may record one), so a list fetched once would go stale silently.\n if (isOpen.value) emit(\"open\");\n}\n\nfunction selectVersion(version: TemplateVersion): void {\n emit(\"navigate\", version);\n isOpen.value = false;\n}\n\nfunction formatDate(dateString: string): string {\n const result = formatRelativeTime(dateString, t.time, format, 7);\n if (result !== null) return result;\n\n // Past the relative window, `Intl` builds the label — in the EDITOR's locale,\n // not the browser's, which is what put \"Mar 4\" in a German menu.\n return formatAbsoluteDateTime(dateString, uiLocale, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nonClickOutside(dropdownRef, () => {\n isOpen.value = false;\n});\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n class=\"tpl:relative tpl:flex tpl:items-center tpl:gap-0.5\"\n data-testid=\"version-history\"\n >\n <!-- Step to an older version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-older\"\n :disabled=\"!canGoOlder\"\n :title=\"t.versionHistory.olderVersion\"\n :aria-label=\"t.versionHistory.olderVersion\"\n @click.stop=\"goOlder\"\n >\n <ChevronLeft :size=\"14\" :stroke-width=\"2\" />\n </button>\n\n <!-- History dropdown toggle -->\n <button\n class=\"tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-toggle\"\n :aria-expanded=\"isOpen\"\n :title=\"t.versionHistory.tooltip\"\n :aria-label=\"t.versionHistory.tooltip\"\n @click.stop=\"toggleDropdown\"\n >\n <Clock :size=\"16\" :stroke-width=\"1.5\" />\n <ChevronDown\n class=\"tpl:transition-transform\"\n :class=\"{ 'tpl:rotate-180': isOpen }\"\n :size=\"10\"\n :stroke-width=\"2\"\n />\n </button>\n\n <Transition name=\"tpl-dropdown\">\n <div\n v-if=\"isOpen\"\n class=\"tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]\"\n data-testid=\"version-history-dropdown\"\n >\n <div\n class=\"tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]\"\n >\n {{ t.versionHistory.dropdownTitle }}\n </div>\n\n <div\n v-if=\"isLoading && versions.length === 0\"\n class=\"tpl:flex tpl:items-center tpl:justify-center tpl:py-8\"\n role=\"status\"\n aria-busy=\"true\"\n >\n <LoaderCircle\n class=\"tpl:animate-spin tpl:text-[var(--tpl-primary)]\"\n :size=\"20\"\n :stroke-width=\"2\"\n />\n </div>\n\n <div\n v-else-if=\"versions.length === 0\"\n class=\"tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-empty\"\n >\n {{ t.versionHistory.empty }}\n </div>\n\n <div v-else class=\"tpl:max-h-64 tpl:overflow-y-auto\">\n <button\n v-for=\"version in versions\"\n :key=\"version.id\"\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-l-2 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:hover:border-l-[var(--tpl-primary)] tpl:hover:bg-[var(--tpl-bg-hover)]\"\n :class=\"\n version.id === previewingId\n ? 'tpl:border-l-[var(--tpl-primary)] tpl:bg-[var(--tpl-bg-active)]'\n : 'tpl:border-l-transparent'\n \"\n style=\"background-color: transparent\"\n data-testid=\"version-history-entry\"\n :data-version-id=\"version.id\"\n :disabled=\"isRestoring\"\n @click=\"selectVersion(version)\"\n >\n <div class=\"tpl:flex tpl:flex-col tpl:gap-0.5\">\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n <span>{{\n version.label ?? formatDate(version.createdAt)\n }}</span>\n <span\n v-if=\"version.isAutomatic\"\n class=\"tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-xs tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ t.versionHistory.auto }}\n </span>\n </div>\n <!-- A labelled version still shows when it was taken, and by whom\n if the store tracks that; an unlabelled one already leads with\n the date, so the line would repeat it. -->\n <div\n v-if=\"version.label || version.author?.name\"\n class=\"tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n >\n <template v-if=\"version.label\">{{\n formatDate(version.createdAt)\n }}</template>\n <template v-if=\"version.label && version.author?.name\">\n ·\n </template>\n <template v-if=\"version.author?.name\">{{\n version.author.name\n }}</template>\n </div>\n </div>\n </button>\n </div>\n </div>\n </Transition>\n\n <!-- Step to a newer version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-newer\"\n :disabled=\"!canGoNewer\"\n :title=\"t.versionHistory.newerVersion\"\n :aria-label=\"t.versionHistory.newerVersion\"\n @click.stop=\"goNewer\"\n >\n <ChevronRight :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * The header's version-history control: step older / newer through the list, or\n * open the dropdown and jump straight to one.\n *\n * Shared by both editors. Reads the `TemplateVersion` contract, so any\n * provider drives it.\n */\nimport { computed, inject, ref } from \"vue\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Clock,\n LoaderCircle,\n} from \"@lucide/vue\";\nimport type { TemplateVersion } from \"@templatical/types\";\nimport { useI18n } from \"../composables/useI18n\";\nimport { formatAbsoluteDateTime } from \"../utils/formatAbsoluteDateTime\";\nimport { formatRelativeTime } from \"../utils/formatRelativeTime\";\nimport { UI_LOCALE_KEY } from \"../keys\";\n\nconst props = defineProps<{\n versions: TemplateVersion[];\n isLoading: boolean;\n isRestoring: boolean;\n /** Which version is on the canvas, or `null` while editing normally. */\n previewingId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"open\"): void;\n (e: \"navigate\", version: TemplateVersion): void;\n}>();\n\nconst { t, format } = useI18n();\nconst uiLocale = inject(UI_LOCALE_KEY, undefined);\n\nconst isOpen = ref(false);\nconst dropdownRef = ref<HTMLElement | null>(null);\n\n/**\n * Position in the list (0 = newest), derived from what is actually previewed\n * rather than tracked locally. A local index went stale the moment the user\n * cancelled a preview — the arrows then stepped from wherever they had left off\n * instead of from the top.\n */\nconst currentIndex = computed(() =>\n props.previewingId === null\n ? -1\n : props.versions.findIndex((v) => v.id === props.previewingId),\n);\n\nconst canGoNewer = computed(\n () => currentIndex.value > 0 && !props.isRestoring && !props.isLoading,\n);\n\nconst canGoOlder = computed(\n () =>\n currentIndex.value < props.versions.length - 1 &&\n props.versions.length > 0 &&\n !props.isRestoring &&\n !props.isLoading,\n);\n\nfunction goNewer(): void {\n if (!canGoNewer.value) return;\n emit(\"navigate\", props.versions[currentIndex.value - 1]);\n}\n\nfunction goOlder(): void {\n if (!canGoOlder.value) return;\n emit(\"navigate\", props.versions[currentIndex.value + 1]);\n}\n\nfunction toggleDropdown(): void {\n isOpen.value = !isOpen.value;\n // Always on open, never only when empty: history grows behind the user's back\n // (every save may record one), so a list fetched once would go stale silently.\n if (isOpen.value) emit(\"open\");\n}\n\nfunction selectVersion(version: TemplateVersion): void {\n emit(\"navigate\", version);\n isOpen.value = false;\n}\n\nfunction formatDate(dateString: string): string {\n const result = formatRelativeTime(dateString, t.time, format, 7);\n if (result !== null) return result;\n\n // Past the relative window, `Intl` builds the label — in the EDITOR's locale,\n // not the browser's, which is what put \"Mar 4\" in a German menu.\n return formatAbsoluteDateTime(dateString, uiLocale, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nonClickOutside(dropdownRef, () => {\n isOpen.value = false;\n});\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n class=\"tpl:relative tpl:flex tpl:items-center tpl:gap-0.5\"\n data-testid=\"version-history\"\n >\n <!-- Step to an older version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-older\"\n :disabled=\"!canGoOlder\"\n :title=\"t.versionHistory.olderVersion\"\n :aria-label=\"t.versionHistory.olderVersion\"\n @click.stop=\"goOlder\"\n >\n <ChevronLeft :size=\"14\" :stroke-width=\"2\" />\n </button>\n\n <!-- History dropdown toggle -->\n <button\n class=\"tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-toggle\"\n :aria-expanded=\"isOpen\"\n :title=\"t.versionHistory.tooltip\"\n :aria-label=\"t.versionHistory.tooltip\"\n @click.stop=\"toggleDropdown\"\n >\n <Clock :size=\"16\" :stroke-width=\"1.5\" />\n <ChevronDown\n class=\"tpl:transition-transform\"\n :class=\"{ 'tpl:rotate-180': isOpen }\"\n :size=\"10\"\n :stroke-width=\"2\"\n />\n </button>\n\n <Transition name=\"tpl-dropdown\">\n <div\n v-if=\"isOpen\"\n class=\"tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]\"\n data-testid=\"version-history-dropdown\"\n >\n <div\n class=\"tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]\"\n >\n {{ t.versionHistory.dropdownTitle }}\n </div>\n\n <div\n v-if=\"isLoading && versions.length === 0\"\n class=\"tpl:flex tpl:items-center tpl:justify-center tpl:py-8\"\n role=\"status\"\n aria-busy=\"true\"\n >\n <LoaderCircle\n class=\"tpl:animate-spin tpl:text-[var(--tpl-primary)]\"\n :size=\"20\"\n :stroke-width=\"2\"\n />\n </div>\n\n <div\n v-else-if=\"versions.length === 0\"\n class=\"tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-empty\"\n >\n {{ t.versionHistory.empty }}\n </div>\n\n <div v-else class=\"tpl:max-h-64 tpl:overflow-y-auto\">\n <button\n v-for=\"version in versions\"\n :key=\"version.id\"\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-l-2 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:hover:border-l-[var(--tpl-primary)] tpl:hover:bg-[var(--tpl-bg-hover)]\"\n :class=\"\n version.id === previewingId\n ? 'tpl:border-l-[var(--tpl-primary)] tpl:bg-[var(--tpl-bg-active)]'\n : 'tpl:border-l-transparent'\n \"\n style=\"background-color: transparent\"\n data-testid=\"version-history-entry\"\n :data-version-id=\"version.id\"\n :disabled=\"isRestoring\"\n @click=\"selectVersion(version)\"\n >\n <div class=\"tpl:flex tpl:flex-col tpl:gap-0.5\">\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n <span>{{\n version.label ?? formatDate(version.createdAt)\n }}</span>\n <span\n v-if=\"version.isAutomatic\"\n class=\"tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-xs tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ t.versionHistory.auto }}\n </span>\n </div>\n <!-- A labelled version still shows when it was taken, and by whom\n if the store tracks that; an unlabelled one already leads with\n the date, so the line would repeat it. -->\n <div\n v-if=\"version.label || version.author?.name\"\n class=\"tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n >\n <template v-if=\"version.label\">{{\n formatDate(version.createdAt)\n }}</template>\n <template v-if=\"version.label && version.author?.name\">\n ·\n </template>\n <template v-if=\"version.author?.name\">{{\n version.author.name\n }}</template>\n </div>\n </div>\n </button>\n </div>\n </div>\n </Transition>\n\n <!-- Step to a newer version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-newer\"\n :disabled=\"!canGoNewer\"\n :title=\"t.versionHistory.newerVersion\"\n :aria-label=\"t.versionHistory.newerVersion\"\n @click.stop=\"goNewer\"\n >\n <ChevronRight :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"VersionHistoryPanels-w0EG_qVW.js","names":[],"sources":["../../../src/components/VersionHistoryPanels.vue","../../../src/components/VersionHistoryPanels.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Mount point for the version-history chrome that sits outside the header,\n * shared by the OSS and Cloud editors.\n *\n * Same shape as `SavedBlocksPanels.vue` / `TestEmailPanel.vue`: everything here\n * is `defineAsyncComponent` behind a `v-if` on its own state, and the editors in\n * turn lazy-load *this* wrapper and render it only when a\n * `VersionHistoryProvider` is configured — so a consumer without one downloads\n * none of it.\n *\n * The header's dropdown control is not here for one reason only: it has to sit\n * in the header's centre column. It is lazily imported at those two sites\n * instead, and covered by the same CDN chunk guard.\n */\nimport { defineAsyncComponent } from \"vue\";\nimport type { UseVersionHistoryFeatureReturn } from \"../composables/useVersionHistoryFeature\";\n\nconst props = defineProps<{\n feature: UseVersionHistoryFeatureReturn;\n}>();\n\nconst VersionPreviewBanner = defineAsyncComponent(\n () => import(\"./VersionPreviewBanner.vue\"),\n);\n// Its own chunk, fetched only if a restore is attempted with unsaved work —\n// which for a Cloud session (autosave on) is the uncommon case.\nconst RestoreVersionDialog = defineAsyncComponent(\n () => import(\"./RestoreVersionDialog.vue\"),\n);\n\n/**\n * Every action here swallows its rejection: the feature already reported it\n * through `onError` and rolled the canvas back, and an unhandled rejection out\n * of a DOM event binding helps nobody.\n */\nasync function handleRequestRestore(): Promise<void> {\n try {\n await props.feature.requestRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleSaveAndRestore(): Promise<void> {\n try {\n await props.feature.saveAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleDiscardAndRestore(): Promise<void> {\n try {\n await props.feature.discardAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n</script>\n\n<template>\n <VersionPreviewBanner\n v-if=\"feature.isPreviewing.value\"\n :visible=\"feature.isPreviewing.value\"\n :can-restore=\"feature.canRestore.value\"\n @cancel=\"feature.cancelPreview()\"\n @confirm=\"handleRequestRestore\"\n />\n\n <RestoreVersionDialog\n v-if=\"feature.isConfirmingRestore.value\"\n :visible=\"feature.isConfirmingRestore.value\"\n :can-save=\"feature.canSaveBeforeRestore.value\"\n :is-busy=\"feature.isConfirmBusy.value\"\n @cancel=\"feature.cancelRestoreConfirm()\"\n @save-and-restore=\"handleSaveAndRestore\"\n @discard-and-restore=\"handleDiscardAndRestore\"\n />\n</template>\n","<script setup lang=\"ts\">\n/**\n * Mount point for the version-history chrome that sits outside the header,\n * shared by the OSS and Cloud editors.\n *\n * Same shape as `SavedBlocksPanels.vue` / `TestEmailPanel.vue`: everything here\n * is `defineAsyncComponent` behind a `v-if` on its own state, and the editors in\n * turn lazy-load *this* wrapper and render it only when a\n * `VersionHistoryProvider` is configured — so a consumer without one downloads\n * none of it.\n *\n * The header's dropdown control is not here for one reason only: it has to sit\n * in the header's centre column. It is lazily imported at those two sites\n * instead, and covered by the same CDN chunk guard.\n */\nimport { defineAsyncComponent } from \"vue\";\nimport type { UseVersionHistoryFeatureReturn } from \"../composables/useVersionHistoryFeature\";\n\nconst props = defineProps<{\n feature: UseVersionHistoryFeatureReturn;\n}>();\n\nconst VersionPreviewBanner = defineAsyncComponent(\n () => import(\"./VersionPreviewBanner.vue\"),\n);\n// Its own chunk, fetched only if a restore is attempted with unsaved work —\n// which for a Cloud session (autosave on) is the uncommon case.\nconst RestoreVersionDialog = defineAsyncComponent(\n () => import(\"./RestoreVersionDialog.vue\"),\n);\n\n/**\n * Every action here swallows its rejection: the feature already reported it\n * through `onError` and rolled the canvas back, and an unhandled rejection out\n * of a DOM event binding helps nobody.\n */\nasync function handleRequestRestore(): Promise<void> {\n try {\n await props.feature.requestRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleSaveAndRestore(): Promise<void> {\n try {\n await props.feature.saveAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleDiscardAndRestore(): Promise<void> {\n try {\n await props.feature.discardAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n</script>\n\n<template>\n <VersionPreviewBanner\n v-if=\"feature.isPreviewing.value\"\n :visible=\"feature.isPreviewing.value\"\n :can-restore=\"feature.canRestore.value\"\n @cancel=\"feature.cancelPreview()\"\n @confirm=\"handleRequestRestore\"\n />\n\n <RestoreVersionDialog\n v-if=\"feature.isConfirmingRestore.value\"\n :visible=\"feature.isConfirmingRestore.value\"\n :can-save=\"feature.canSaveBeforeRestore.value\"\n :is-busy=\"feature.isConfirmBusy.value\"\n @cancel=\"feature.cancelRestoreConfirm()\"\n @save-and-restore=\"handleSaveAndRestore\"\n @discard-and-restore=\"handleDiscardAndRestore\"\n />\n</template>\n"],"mappings":";;;;;;;EAkBA,IAAM,IAAQ,GAIR,IAAuB,QACrB,OAAO,qCACf,GAGM,IAAuB,QACrB,OAAO,qCACf;EAOA,eAAe,IAAsC;GACnD,IAAI;IACF,MAAM,EAAM,QAAQ,eAAe;GACrC,QAAQ,CAER;EACF;EAEA,eAAe,IAAsC;GACnD,IAAI;IACF,MAAM,EAAM,QAAQ,eAAe;GACrC,QAAQ,CAER;EACF;EAEA,eAAe,IAAyC;GACtD,IAAI;IACF,MAAM,EAAM,QAAQ,kBAAkB;GACxC,QAAQ,CAER;EACF;oBAKU,EAAA,GAAA,EAAA,GAAA,MAAA,CAAA,EAAA,QAAQ,aAAa,SAD7B,EAAA,GAAA,EAME,EAAA,CAAA,GAAA;;GAJC,SAAS,EAAA,QAAQ,aAAa;GAC9B,eAAa,EAAA,QAAQ,WAAW;GAChC,UAAM,AAAA,EAAA,QAAA,MAAE,EAAA,QAAQ,cAAa;GAC7B,WAAS;EAIJ,GAAA,MAAA,GAAA,CAAA,WAAA,aAAA,CAAA,KAAA,EAAA,IAAA,EAAA,GAAA,EAAA,QAAQ,oBAAoB,SADpC,EAAA,GAAA,EAQE,EAAA,CAAA,GAAA;;GANC,SAAS,EAAA,QAAQ,oBAAoB;GACrC,YAAU,EAAA,QAAQ,qBAAqB;GACvC,WAAS,EAAA,QAAQ,cAAc;GAC/B,UAAM,AAAA,EAAA,QAAA,MAAE,EAAA,QAAQ,qBAAoB;GACpC,kBAAkB;GAClB,qBAAqB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"VersionPreviewBanner-Bbd4C-AN.js","names":[],"sources":["../../../src/components/VersionPreviewBanner.vue","../../../src/components/VersionPreviewBanner.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ghostBtnClass, primaryBtnClass } from \"../constants/styleConstants\";\n/**\n * Shown while a past version is on the canvas instead of the user's own work.\n * Cancel puts the pre-preview content back; Restore makes the version current.\n *\n * Lives outside `src/cloud/` because version history is a BYO provider, not a\n * Cloud feature — a consumer's own `versionHistory` provider drives this banner\n * with no Cloud involved.\n */\nimport { Clock } from \"@lucide/vue\";\nimport { useI18n } from \"../composables/useI18n\";\n\ndefineProps<{\n visible: boolean;\n /**\n * Whether the provider supplied `restore`. When it didn't, history is\n * browse-and-preview only, so the confirm action does not render at all\n * rather than rendering disabled — the same discipline saved blocks uses.\n */\n canRestore: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"cancel\"): void;\n (e: \"confirm\"): void;\n}>();\n\nconst { t } = useI18n();\n</script>\n\n<template>\n <div\n v-if=\"visible\"\n class=\"tpl-preview-banner tpl:absolute tpl:top-14 tpl:right-0 tpl:left-0 tpl:z-40 tpl:flex tpl:items-center tpl:justify-center tpl:gap-4 tpl:px-4 tpl:py-3 tpl:bg-[var(--tpl-primary-light)] tpl:border-b tpl:border-[var(--tpl-primary)]\"\n data-testid=\"version-preview-banner\"\n role=\"status\"\n >\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:text-sm tpl:text-[var(--tpl-text)]\"\n >\n <Clock\n :size=\"18\"\n :stroke-width=\"2\"\n class=\"tpl:text-[var(--tpl-primary)]\"\n />\n <span>{{ t.versionPreview.message }}</span>\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n :class=\"ghostBtnClass\"\n style=\"background-color: transparent\"\n data-testid=\"version-preview-cancel\"\n @click=\"emit('cancel')\"\n >\n {{ t.versionPreview.cancel }}\n </button>\n <button\n v-if=\"canRestore\"\n :class=\"primaryBtnClass\"\n data-testid=\"version-preview-restore\"\n @click=\"emit('confirm')\"\n >\n {{ t.versionPreview.restore }}\n </button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ghostBtnClass, primaryBtnClass } from \"../constants/styleConstants\";\n/**\n * Shown while a past version is on the canvas instead of the user's own work.\n * Cancel puts the pre-preview content back; Restore makes the version current.\n *\n * Lives outside `src/cloud/` because version history is a BYO provider, not a\n * Cloud feature — a consumer's own `versionHistory` provider drives this banner\n * with no Cloud involved.\n */\nimport { Clock } from \"@lucide/vue\";\nimport { useI18n } from \"../composables/useI18n\";\n\ndefineProps<{\n visible: boolean;\n /**\n * Whether the provider supplied `restore`. When it didn't, history is\n * browse-and-preview only, so the confirm action does not render at all\n * rather than rendering disabled — the same discipline saved blocks uses.\n */\n canRestore: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"cancel\"): void;\n (e: \"confirm\"): void;\n}>();\n\nconst { t } = useI18n();\n</script>\n\n<template>\n <div\n v-if=\"visible\"\n class=\"tpl-preview-banner tpl:absolute tpl:top-14 tpl:right-0 tpl:left-0 tpl:z-40 tpl:flex tpl:items-center tpl:justify-center tpl:gap-4 tpl:px-4 tpl:py-3 tpl:bg-[var(--tpl-primary-light)] tpl:border-b tpl:border-[var(--tpl-primary)]\"\n data-testid=\"version-preview-banner\"\n role=\"status\"\n >\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:text-sm tpl:text-[var(--tpl-text)]\"\n >\n <Clock\n :size=\"18\"\n :stroke-width=\"2\"\n class=\"tpl:text-[var(--tpl-primary)]\"\n />\n <span>{{ t.versionPreview.message }}</span>\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n :class=\"ghostBtnClass\"\n style=\"background-color: transparent\"\n data-testid=\"version-preview-cancel\"\n @click=\"emit('cancel')\"\n >\n {{ t.versionPreview.cancel }}\n </button>\n <button\n v-if=\"canRestore\"\n :class=\"primaryBtnClass\"\n data-testid=\"version-preview-restore\"\n @click=\"emit('confirm')\"\n >\n {{ t.versionPreview.restore }}\n </button>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAuBA,IAAM,IAAO,GAKP,EAAE,SAAM,EAAQ;mBAKZ,EAAA,WADR,EAAA,GAAA,EAkCM,OAlCN,GAkCM,CA5BJ,EASM,OATN,GASM,CANJ,EAIE,EAAA,CAAA,GAAA;GAHC,MAAM;GACN,gBAAc;GACf,OAAM;EAER,CAAA,GAAA,EAA2C,QAAA,MAAA,EAAlC,EAAA,CAAA,CAAC,CAAC,eAAe,OAAO,GAAA,CAAA,CAAA,CAAA,GAEnC,EAiBM,OAjBN,GAiBM,CAhBJ,EAOS,UAAA;GANN,OAAK,EAAE,EAAA,CAAA,CAAa;GACrB,OAAA,EAAA,oBAAA,cAAA;GACA,eAAY;GACX,SAAK,AAAA,EAAA,QAAA,MAAE,EAAI,QAAA;EAET,GAAA,EAAA,EAAA,CAAA,CAAC,CAAC,eAAe,MAAM,GAAA,CAAA,GAGpB,EAAA,cADR,EAAA,GAAA,EAOS,UAAA;;GALN,OAAK,EAAE,EAAA,CAAA,CAAe;GACvB,eAAY;GACX,SAAK,AAAA,EAAA,QAAA,MAAE,EAAI,SAAA;EAET,GAAA,EAAA,EAAA,CAAA,CAAC,CAAC,eAAe,OAAO,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"WrapperBlock-Ch4KeMIb.js","names":[],"sources":["../../../src/utils/emailFrameWidth.ts","../../../src/components/blocks/WrapperBlock.vue","../../../src/components/blocks/WrapperBlock.vue"],"sourcesContent":["import type { TemplateSettings, ViewportSize } from \"@templatical/types\";\n\n/**\n * Width a mobile preview renders at. Not the template's own width — a phone\n * viewport is narrower than any sensible email body, so every viewport-aware\n * surface clamps to this.\n */\nexport const MOBILE_EMAIL_WIDTH = 375;\n\n/**\n * Fallback body width when no template settings are available — headless mounts\n * and tests. Matches `createDefaultTemplateContent`'s default.\n */\nexport const DEFAULT_EMAIL_WIDTH = 600;\n\n/**\n * The width an email body lays itself out against, for a given viewport.\n *\n * **The single source of truth for every surface that renders blocks**: the\n * canvas, the preview canvas, and the save dialog's scaled preview rows. They\n * have to agree — `SavedBlockPreviewRow` divides by this number to compute its\n * `transform: scale()`, so if it and the canvas disagreed the rows would be\n * scaled by the wrong factor and overflow or under-fill their frame. Sharing one\n * function makes that agreement structural instead of three constants that happen\n * to match today.\n *\n * Pass the *current* template's settings even when previewing content from\n * elsewhere (a saved block stores only `Block[]`): the current settings are what\n * the content will actually be rendered at.\n */\nexport function getEmailFrameWidth(\n settings: TemplateSettings | undefined,\n viewport: ViewportSize = \"desktop\",\n): number {\n if (viewport === \"mobile\") return MOBILE_EMAIL_WIDTH;\n return settings?.width ?? DEFAULT_EMAIL_WIDTH;\n}\n\n/**\n * Band of email background shown on each side of the content column.\n *\n * A surface that renders blocks at exactly the body width has nowhere for\n * `settings.backgroundColor` to show: a full-width section's own background\n * covers every pixel of it, so the body colour reads as unset even though the\n * sent email paints it across the whole client viewport. The gutter is what\n * makes it visible, mirroring how `mj-body background-color` renders beside the\n * centred content.\n *\n * Fixed rather than \"fill the container\" so the band never overwhelms the\n * content on a wide monitor. `Canvas.vue` adds it to both sides of a fixed\n * stage; `BlockPreviewCanvas` treats it as the cap on a fluid one, because a\n * fixed 792px stage overflows every dialog it lives in.\n */\nexport const EMAIL_GUTTER = 96;\n\n/**\n * How a viewport switch animates the frame.\n *\n * Lives here rather than being written out per call site so every surface that\n * switches viewport eases identically — the canvas's toggle and the test-email\n * dialog's should feel like the same control, not two similar ones. The slight\n * overshoot in the curve is deliberate and matches the editor's other viewport\n * transitions.\n *\n * Only `width` transitions: block content re-flows for the new viewport in the\n * same frame, exactly as it does on the canvas, so animating height as well would\n * lag the reflow behind the frame.\n */\nexport const EMAIL_FRAME_WIDTH_TRANSITION =\n \"width 300ms cubic-bezier(0.34, 1.56, 0.64, 1)\";\n","<script setup lang=\"ts\">\nimport {\n getBlockWrapperStyle,\n getWrapperStyle,\n resolveBlockComponent,\n} from \"../../utils/blockComponentResolver\";\nimport type {\n Block,\n ViewportSize,\n WrapperBlock as WrapperBlockType,\n} from \"@templatical/types\";\nimport { computed, inject } from \"vue\";\nimport { BLOCK_REGISTRY_KEY } from \"../../keys\";\n\ndefineOptions({ name: \"WrapperBlock\" });\n\nconst props = defineProps<{\n block: WrapperBlockType;\n viewport: ViewportSize;\n}>();\n\nconst blockRegistry = inject(BLOCK_REGISTRY_KEY, null);\n\nconst wrapperStyle = computed(() => getWrapperStyle(props.block) ?? {});\n\nfunction getBlockComponent(block: Block) {\n // Children resolve through the registry (title, section, …). No local\n // fallback map: a Canvas import of PreviewSectionBlock (or a preview import\n // of SectionBlock) would pull the other surface's tree into this band.\n return resolveBlockComponent(block, blockRegistry, {});\n}\n</script>\n\n<template>\n <div data-testid=\"layout-wrapper\" class=\"tpl:w-full\" :style=\"wrapperStyle\">\n <div\n v-for=\"child in block.children\"\n :key=\"child.id\"\n :data-block-id=\"child.id\"\n :style=\"getBlockWrapperStyle(child)\"\n >\n <component\n :is=\"getBlockComponent(child)\"\n :block=\"child\"\n :viewport=\"viewport\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n getBlockWrapperStyle,\n getWrapperStyle,\n resolveBlockComponent,\n} from \"../../utils/blockComponentResolver\";\nimport type {\n Block,\n ViewportSize,\n WrapperBlock as WrapperBlockType,\n} from \"@templatical/types\";\nimport { computed, inject } from \"vue\";\nimport { BLOCK_REGISTRY_KEY } from \"../../keys\";\n\ndefineOptions({ name: \"WrapperBlock\" });\n\nconst props = defineProps<{\n block: WrapperBlockType;\n viewport: ViewportSize;\n}>();\n\nconst blockRegistry = inject(BLOCK_REGISTRY_KEY, null);\n\nconst wrapperStyle = computed(() => getWrapperStyle(props.block) ?? {});\n\nfunction getBlockComponent(block: Block) {\n // Children resolve through the registry (title, section, …). No local\n // fallback map: a Canvas import of PreviewSectionBlock (or a preview import\n // of SectionBlock) would pull the other surface's tree into this band.\n return resolveBlockComponent(block, blockRegistry, {});\n}\n</script>\n\n<template>\n <div data-testid=\"layout-wrapper\" class=\"tpl:w-full\" :style=\"wrapperStyle\">\n <div\n v-for=\"child in block.children\"\n :key=\"child.id\"\n :data-block-id=\"child.id\"\n :style=\"getBlockWrapperStyle(child)\"\n >\n <component\n :is=\"getBlockComponent(child)\"\n :block=\"child\"\n :viewport=\"viewport\"\n />\n </div>\n </div>\n</template>\n"],"mappings":";;;AA8BA,SAAgB,EACd,GACA,IAAyB,WACjB;CAER,OADI,MAAa,WAAU,MACpB,GAAU,SAAA;AACnB;AAgCA,IAAa,IACX;;;;;;;;ECrDF,IAAM,IAAQ,GAKR,IAAgB,EAAO,GAAoB,IAAI,GAE/C,IAAe,QAAe,EAAgB,EAAM,KAAK,KAAK,CAAC,CAAC;EAEtE,SAAS,EAAkB,GAAc;GAIvC,OAAO,EAAsB,GAAO,GAAe,CAAC,CAAC;EACvD;oBAIE,EAAA,GAAA,EAaM,OAAA;GAbD,eAAY;GAAiB,OAAM;GAAc,OAAK,EAAE,EAAA,KAAY;EACvE,GAAA,EAAA,EAAA,EAAA,GAAA,EAWM,GAAA,MAAA,EAVY,EAAA,MAAM,WAAf,OADT,EAAA,GAAA,EAWM,OAAA;GATH,KAAK,EAAM;GACX,iBAAe,EAAM;GACrB,OAAK,EAAE,EAAA,CAAA,CAAoB,CAAC,CAAK,CAAA;EAElC,GAAA,EAAA,EAAA,GAAA,EAIE,EAHK,EAAkB,CAAK,CAAA,GAAA;GAC3B,OAAO;GACP,UAAU,EAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"blockTypeIcons-CyPXFh7L.js","names":[],"sources":["../../../src/utils/blockTypeIcons.ts"],"sourcesContent":["import {\n Code,\n Columns3,\n Heading,\n Image,\n Minus,\n MoveVertical,\n Navigation,\n Pilcrow,\n Play,\n RectangleHorizontal,\n Share2,\n Table,\n Timer,\n} from \"@lucide/vue\";\nimport type { Component } from \"vue\";\n\nexport const blockTypeIcons: Record<string, Component> = {\n section: Columns3,\n title: Heading,\n paragraph: Pilcrow,\n image: Image,\n button: RectangleHorizontal,\n divider: Minus,\n video: Play,\n social: Share2,\n menu: Navigation,\n table: Table,\n spacer: MoveVertical,\n countdown: Timer,\n html: Code,\n};\n"],"mappings":";;AAiBA,IAAa,IAA4C;CACvD,SAAS;CACT,OAAO;CACP,WAAW;CACX,OAAO;CACP,QAAQ;CACR,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,WAAW;CACX,MAAM;AACR"}