nuxt-generation-emails 1.1.0 → 1.2.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/cli/index.mjs
CHANGED
|
@@ -46,15 +46,11 @@ const props = withDefaults(defineProps<{
|
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* useNgeTemplate auto-loads the sibling .mjml file, compiles it with
|
|
49
|
-
* Handlebars, and
|
|
49
|
+
* Handlebars, and sets the render function \u2014 no <template> block needed.
|
|
50
50
|
* MJML components from components/ are registered automatically.
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
useNgeTemplate('${templatePath}', props)
|
|
53
53
|
${scriptClose}
|
|
54
|
-
|
|
55
|
-
<template>
|
|
56
|
-
<div v-html="html" />
|
|
57
|
-
</template>
|
|
58
54
|
`;
|
|
59
55
|
}
|
|
60
56
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -789,8 +789,8 @@ export function registerMjmlComponents(): void {
|
|
|
789
789
|
addTemplate({
|
|
790
790
|
filename: "nge/use-template.ts",
|
|
791
791
|
write: true,
|
|
792
|
-
getContents: () => `import { ref, watch, toRef } from 'vue'
|
|
793
|
-
import type { Ref } from 'vue'
|
|
792
|
+
getContents: () => `import { h, ref, watch, toRef, getCurrentInstance } from 'vue'
|
|
793
|
+
import type { Ref, VNode } from 'vue'
|
|
794
794
|
import Handlebars from 'handlebars'
|
|
795
795
|
import { registerMjmlComponents } from './register-components'
|
|
796
796
|
|
|
@@ -823,26 +823,37 @@ let _componentsRegistered = false
|
|
|
823
823
|
/**
|
|
824
824
|
* Load and render an MJML email template by name.
|
|
825
825
|
* Registers MJML components (Handlebars partials) automatically on first call.
|
|
826
|
+
* Sets the current component's render function \u2014 no <template> block needed.
|
|
826
827
|
*
|
|
827
828
|
* @param name - Template name relative to the emails directory (e.g. 'example', 'v1/test')
|
|
828
829
|
* @param props - Reactive props object from defineProps
|
|
829
|
-
* @returns Ref<string> containing the rendered HTML \u2014 use with v-html in your template
|
|
830
830
|
*/
|
|
831
|
-
export function useNgeTemplate(name: string, props: Record<string, unknown>):
|
|
831
|
+
export function useNgeTemplate(name: string, props: Record<string, unknown>): void {
|
|
832
832
|
if (!_componentsRegistered) {
|
|
833
833
|
registerMjmlComponents()
|
|
834
834
|
_componentsRegistered = true
|
|
835
835
|
}
|
|
836
836
|
|
|
837
|
+
const instance = getCurrentInstance()
|
|
838
|
+
const renderedHtml = ref('')
|
|
839
|
+
|
|
837
840
|
const source = templateMap[name]
|
|
838
841
|
if (!source) {
|
|
839
842
|
const available = Object.keys(templateMap).join(', ')
|
|
840
843
|
console.error(\`[nuxt-generation-emails] Template "\${name}" not found. Available: \${available}\`)
|
|
841
|
-
|
|
844
|
+
renderedHtml.value = \`<pre style="color:red;">Template "\${name}" not found</pre>\`
|
|
845
|
+
if (instance) {
|
|
846
|
+
instance.render = (): VNode => h('div', { innerHTML: renderedHtml.value })
|
|
847
|
+
}
|
|
848
|
+
return
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Set the render function on the component instance so Vue renders the HTML directly.
|
|
852
|
+
if (instance) {
|
|
853
|
+
instance.render = (): VNode => h('div', { innerHTML: renderedHtml.value })
|
|
842
854
|
}
|
|
843
855
|
|
|
844
856
|
const compiled = Handlebars.compile(source)
|
|
845
|
-
const renderedHtml = ref('')
|
|
846
857
|
|
|
847
858
|
// mjml-browser v5 returns a Promise \u2014 use watch to resolve async results reactively.
|
|
848
859
|
// Tracks both the mjml2html loader ref AND all accessed props (via the Handlebars compile spread).
|
|
@@ -862,8 +873,6 @@ export function useNgeTemplate(name: string, props: Record<string, unknown>): Re
|
|
|
862
873
|
},
|
|
863
874
|
{ immediate: true, deep: true },
|
|
864
875
|
)
|
|
865
|
-
|
|
866
|
-
return renderedHtml
|
|
867
876
|
}
|
|
868
877
|
`
|
|
869
878
|
});
|
|
@@ -157,5 +157,5 @@ onUnmounted(() => {
|
|
|
157
157
|
</template>
|
|
158
158
|
|
|
159
159
|
<style scoped>
|
|
160
|
-
.nge-template-selector{position:relative}.nge-template-selector__trigger{align-items:center;backdrop-filter:blur(10px);background:hsla(0,0%,100%,.15);border:1px solid hsla(0,0%,100%,.25);border-radius:8px;color:#fff;cursor:pointer;display:flex;font-family:DM Sans,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:13px;font-weight:500;gap:8px;justify-content:space-between;letter-spacing:-.01em;min-width:200px;padding:8px 16px;transition:all .2s cubic-bezier(.4,0,.2,1)}.nge-template-selector__trigger:hover{background:hsla(0,0%,100%,.25)}.nge-template-selector__label{flex:1;overflow:hidden;text-align:left;text-overflow:ellipsis;white-space:nowrap}.nge-template-selector__icon{flex-shrink:0;transition:transform .2s cubic-bezier(.4,0,.2,1)}.nge-template-selector__icon--open{transform:rotate(180deg)}.nge-template-selector__dropdown{animation:slideDown .2s cubic-bezier(.4,0,.2,1);background:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 10px 25px rgba(0,0,0,.1),0 4px 10px rgba(0,0,0,.05);left:0;max-height:300px;overflow-y:auto;position:absolute;
|
|
160
|
+
.nge-template-selector{position:relative}.nge-template-selector__trigger{align-items:center;backdrop-filter:blur(10px);background:hsla(0,0%,100%,.15);border:1px solid hsla(0,0%,100%,.25);border-radius:8px;color:#fff;cursor:pointer;display:flex;font-family:DM Sans,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:13px;font-weight:500;gap:8px;justify-content:space-between;letter-spacing:-.01em;min-width:200px;padding:8px 16px;transition:all .2s cubic-bezier(.4,0,.2,1)}.nge-template-selector__trigger:hover{background:hsla(0,0%,100%,.25)}.nge-template-selector__label{flex:1;overflow:hidden;text-align:left;text-overflow:ellipsis;white-space:nowrap}.nge-template-selector__icon{flex-shrink:0;transition:transform .2s cubic-bezier(.4,0,.2,1)}.nge-template-selector__icon--open{transform:rotate(180deg)}.nge-template-selector__dropdown{animation:slideDown .2s cubic-bezier(.4,0,.2,1);background:#fff;border:1px solid #e5e7eb;border-radius:8px;box-shadow:0 10px 25px rgba(0,0,0,.1),0 4px 10px rgba(0,0,0,.05);left:0;max-height:300px;min-width:100%;overflow-y:auto;position:absolute;top:calc(100% + 8px);width:-moz-max-content;width:max-content;z-index:1000}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.nge-template-selector__item{border-bottom:1px solid #f3f4f6;color:#374151;cursor:pointer;font-family:DM Sans,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:13px;font-weight:450;letter-spacing:-.01em;padding:10px 16px;transition:all .15s ease}.nge-template-selector__item:last-child{border-bottom:none}.nge-template-selector__item:hover{background:#f9fafb;color:#00dc82}.nge-template-selector__item--active{background:#f0fdf4;color:#00dc82;font-weight:500}.nge-template-selector__item--active:before{color:#00dc82;content:"✓";margin-right:8px}.nge-template-selector__directory{border-bottom:1px solid #f3f4f6}.nge-template-selector__directory:last-child{border-bottom:none}.nge-template-selector__dir-header{align-items:center;background:#fafafa;color:#111827;cursor:pointer;display:flex;font-family:DM Sans,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-size:13px;font-weight:600;gap:8px;letter-spacing:-.01em;padding:10px 16px;transition:all .15s ease}.nge-template-selector__dir-header:hover{background:#f3f4f6}.nge-template-selector__dir-icon{color:#6b7280;flex-shrink:0;transition:transform .2s cubic-bezier(.4,0,.2,1)}.nge-template-selector__dir-icon--open{transform:rotate(90deg)}.nge-template-selector__dir-content{background:#fff}.nge-template-selector__dir-content .nge-template-selector__item{border-bottom:1px solid #f9fafb;padding-left:36px}.nge-template-selector__dir-content .nge-template-selector__item:last-child{border-bottom:none;color:#00dc82}
|
|
161
161
|
</style>
|
package/package.json
CHANGED