@maildeno/editor 0.1.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/LICENSE +21 -0
- package/README.md +426 -0
- package/dist/RowPreviewLegacyComponent-CXsY4P-R.js +439 -0
- package/dist/RowPreviewLegacyComponent-osWbuByc.js +439 -0
- package/dist/RowPreviewRow-D-U1mV4v.js +107 -0
- package/dist/RowPreviewRow-MSc_unf3.js +107 -0
- package/dist/adapters/index.d.ts +7 -0
- package/dist/adapters/localStorageAdapter.d.ts +6 -0
- package/dist/adapters/types.d.ts +83 -0
- package/dist/baseStyles.d.ts +13 -0
- package/dist/blocks/canvasStyleHelpers.d.ts +17 -0
- package/dist/blocks/definitions/anchor.d.ts +2 -0
- package/dist/blocks/definitions/button.d.ts +2 -0
- package/dist/blocks/definitions/divider.d.ts +2 -0
- package/dist/blocks/definitions/heading.d.ts +2 -0
- package/dist/blocks/definitions/image.d.ts +2 -0
- package/dist/blocks/definitions/list.d.ts +2 -0
- package/dist/blocks/definitions/menu.d.ts +2 -0
- package/dist/blocks/definitions/paragraph.d.ts +2 -0
- package/dist/blocks/definitions/socials.d.ts +2 -0
- package/dist/blocks/definitions/spacer.d.ts +2 -0
- package/dist/blocks/definitions/video.d.ts +2 -0
- package/dist/blocks/index.d.ts +8 -0
- package/dist/blocks/registry.d.ts +23 -0
- package/dist/blocks/types.d.ts +73 -0
- package/dist/composables/emailBuilder/components/useComponentStyleEditor.d.ts +72 -0
- package/dist/composables/emailBuilder/components/useProductRowActions.d.ts +3 -0
- package/dist/composables/emailBuilder/components/useProductRows.d.ts +59 -0
- package/dist/composables/emailBuilder/core/config/componentConfig.d.ts +29 -0
- package/dist/composables/emailBuilder/core/link-tags/useLinkTagInsert.d.ts +13 -0
- package/dist/composables/emailBuilder/core/merge-tags/mergeTagDefinitions.d.ts +64 -0
- package/dist/composables/emailBuilder/core/merge-tags/resolveMergeTags.d.ts +27 -0
- package/dist/composables/emailBuilder/core/ui/useLayerHoverScroll.d.ts +20 -0
- package/dist/composables/emailBuilder/core/ui/useLayoutDrag.d.ts +85 -0
- package/dist/composables/emailBuilder/core/ui/useRichTextEditors.d.ts +6 -0
- package/dist/composables/emailBuilder/core/ui/visibilityBadgeHelpers.d.ts +22 -0
- package/dist/composables/emailBuilder/core/useEmailBuilder.d.ts +274 -0
- package/dist/composables/emailBuilder/core/useEmailBuilderDefault.d.ts +507 -0
- package/dist/composables/emailBuilder/core/useEmailBuilderOperations.d.ts +31 -0
- package/dist/composables/emailBuilder/core/useEmailBuilderVisibility.d.ts +31 -0
- package/dist/composables/emailBuilder/export/actions/download.d.ts +24 -0
- package/dist/composables/emailBuilder/export/generators/html.d.ts +3 -0
- package/dist/composables/emailBuilder/export/generators/mjml.d.ts +6 -0
- package/dist/composables/emailBuilder/export/generators/react-email.d.ts +61 -0
- package/dist/composables/emailBuilder/export/helpers/generatorHelpers.d.ts +53 -0
- package/dist/composables/emailBuilder/export/logic/espLogicWrapper.d.ts +76 -0
- package/dist/composables/emailBuilder/export/logic/reactLogicWrapper.d.ts +31 -0
- package/dist/composables/emailBuilder/export/merge-tags/mergeTagMapper.d.ts +42 -0
- package/dist/composables/emailBuilder/export/merge-tags/reactMergeTagMapper.d.ts +26 -0
- package/dist/composables/emailBuilder/export/shared/containers.d.ts +18 -0
- package/dist/composables/emailBuilder/export/shared/styles.d.ts +12 -0
- package/dist/composables/emailBuilder/export/shared/tagIdentifier.d.ts +1 -0
- package/dist/composables/emailBuilder/export/targets/htmlExport.d.ts +20 -0
- package/dist/composables/emailBuilder/export/targets/jsonExport.d.ts +28 -0
- package/dist/composables/emailBuilder/export/targets/mjmlExport.d.ts +19 -0
- package/dist/composables/emailBuilder/export/targets/reactEmailExport.d.ts +20 -0
- package/dist/composables/emailBuilder/export/transformers/espWrapper.d.ts +2 -0
- package/dist/composables/emailBuilder/export/transformers/formatting.d.ts +3 -0
- package/dist/composables/emailBuilder/export/transformers/minify.d.ts +33 -0
- package/dist/composables/emailBuilder/export/transformers/tagMapper.d.ts +29 -0
- package/dist/composables/emailBuilder/export/types/export.d.ts +24 -0
- package/dist/composables/emailBuilder/export/useEmailExportEngine.d.ts +63 -0
- package/dist/composables/emailBuilder/export/useEmailExportMobileStyles.d.ts +3 -0
- package/dist/composables/emailBuilder/export/useExportSettings.d.ts +5 -0
- package/dist/composables/emailBuilder/health/accessibilityChecker.d.ts +64 -0
- package/dist/composables/emailBuilder/health/healthIndicator.d.ts +19 -0
- package/dist/composables/emailBuilder/history/useEmailBuilderHistory.d.ts +26 -0
- package/dist/composables/emailBuilder/history/useHistory.d.ts +16 -0
- package/dist/composables/emailBuilder/persistence/useEmailBuilderPersistence.d.ts +38 -0
- package/dist/composables/emailBuilder/preview/useClientPreview.d.ts +127 -0
- package/dist/composables/emailBuilder/transform/pipeline/hydrate.d.ts +54 -0
- package/dist/composables/emailBuilder/transform/pipeline/optimize.d.ts +101 -0
- package/dist/composables/emailBuilder/transform/pipeline/optimizeAI.d.ts +125 -0
- package/dist/composables/emailBuilder/types/emailBuilder.d.ts +79 -0
- package/dist/composables/system/useColor.d.ts +26 -0
- package/dist/composables/system/useDeviceDetection.d.ts +5 -0
- package/dist/composables/system/useGoogleFonts.d.ts +11 -0
- package/dist/composables/system/useImageUpload.d.ts +23 -0
- package/dist/composables/system/useSavedRowsPanel.d.ts +35 -0
- package/dist/composables/ui/useConfirm.d.ts +33 -0
- package/dist/composables/ui/useInfoDialog.d.ts +22 -0
- package/dist/composables/ui/useTeleportTarget.d.ts +49 -0
- package/dist/composables/ui/useToast.d.ts +32 -0
- package/dist/devStyleMirror.d.ts +20 -0
- package/dist/documentScopedStyles.d.ts +39 -0
- package/dist/editor.css +2411 -0
- package/dist/element-DN22fZmQ.js +72000 -0
- package/dist/element-scoped-styles.css +2411 -0
- package/dist/element.d.ts +6 -0
- package/dist/element.js +2 -0
- package/dist/esp/registry.d.ts +33 -0
- package/dist/estree-C12ASyI-.js +7993 -0
- package/dist/html-DGrfikay.js +7353 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +71955 -0
- package/dist/init.d.ts +85 -0
- package/dist/init.js +130 -0
- package/dist/lightDom.d.ts +30 -0
- package/dist/merge-tags/registry.d.ts +33 -0
- package/dist/shadowStyles.d.ts +8 -0
- package/dist/standalone-Bd2oQFm3.js +3639 -0
- package/dist/theme.d.ts +132 -0
- package/dist/typescript-D-z2dDu9.js +23190 -0
- package/dist/utils/generateId.d.ts +1 -0
- package/dist/utils/shadowDom.d.ts +30 -0
- package/dist/vue.runtime.esm-bundler-DwQEK7WO.js +9028 -0
- package/package.json +99 -0
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { PartialStorageAdapter } from './adapters/types';
|
|
2
|
+
import { ThemeOptions } from './theme';
|
|
3
|
+
/**
|
|
4
|
+
* The ergonomic, no-Vue-knowledge entry point. element.ts already provides
|
|
5
|
+
* everything this composes — a real custom element, complete CSS bundling,
|
|
6
|
+
* live theming via CSS variables — init() just wires it up with a plain
|
|
7
|
+
* options object and hands back a small handle instead of requiring the
|
|
8
|
+
* caller to know defineCustomElement, prop reflection, or DOM CustomEvent
|
|
9
|
+
* details themselves.
|
|
10
|
+
*/
|
|
11
|
+
export interface InitOptions {
|
|
12
|
+
/** A DOM element, or a CSS selector resolved via document.querySelector. */
|
|
13
|
+
container: HTMLElement | string;
|
|
14
|
+
templateId?: string;
|
|
15
|
+
storageAdapter?: PartialStorageAdapter;
|
|
16
|
+
theme?: ThemeOptions;
|
|
17
|
+
capabilities?: {
|
|
18
|
+
export?: Array<"html" | "mjml" | "react" | "json">;
|
|
19
|
+
};
|
|
20
|
+
onSendTestEmail?: (payload: {
|
|
21
|
+
to: string;
|
|
22
|
+
subject: string;
|
|
23
|
+
html: string;
|
|
24
|
+
}) => Promise<void> | void;
|
|
25
|
+
/**
|
|
26
|
+
* Render inside a shadow root (default) or directly in the page.
|
|
27
|
+
*
|
|
28
|
+
* Shadow DOM isolates the editor's styles from the host page, which is
|
|
29
|
+
* usually what you want. Set false when you'd rather have predictable
|
|
30
|
+
* DOM behaviour than isolation: inside a shadow root `event.target` is
|
|
31
|
+
* retargeted to the host, `document.activeElement` returns the host,
|
|
32
|
+
* `document.querySelector` can't see in, and `@font-face`/`@property`
|
|
33
|
+
* are ignored. This package handles all of that internally, but a host
|
|
34
|
+
* page's own scripts — or a third-party library — may not, and that is
|
|
35
|
+
* not fixable from inside the editor. Light DOM is the escape hatch.
|
|
36
|
+
*
|
|
37
|
+
* The trade-off is real in both directions: with `shadowDom: false`,
|
|
38
|
+
* the host page's CSS can reach the editor and vice versa.
|
|
39
|
+
*/
|
|
40
|
+
shadowDom?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface EditorHandle {
|
|
43
|
+
/** The underlying <maildeno-editor> element, for anything this handle
|
|
44
|
+
* doesn't wrap directly — it's a real DOM element, nothing hidden. */
|
|
45
|
+
readonly element: HTMLElement;
|
|
46
|
+
/** Vue's defineCustomElement dispatches emits as real DOM CustomEvents
|
|
47
|
+
* on the host element, with the emit payload in event.detail — this is
|
|
48
|
+
* just addEventListener with that unwrapping done for you. */
|
|
49
|
+
on(event: "save", handler: (payload: {
|
|
50
|
+
templateId: string | null;
|
|
51
|
+
}) => void): void;
|
|
52
|
+
off(event: "save", handler: (payload: {
|
|
53
|
+
templateId: string | null;
|
|
54
|
+
}) => void): void;
|
|
55
|
+
/** Re-themes live — sets the theme prop, which EmailEditor.vue's own
|
|
56
|
+
* watch(..., {immediate: true}) picks up via useHost(), the same
|
|
57
|
+
* mechanism that applies it on initial mount. Calling this again after
|
|
58
|
+
* mount is the actual "live" part, not just initial configuration. */
|
|
59
|
+
setTheme(theme: ThemeOptions): void;
|
|
60
|
+
/** These four call EmailEditor.vue's defineExpose'd methods, which Vue's
|
|
61
|
+
* own defineCustomElement implementation forwards directly onto the
|
|
62
|
+
* custom element instance (confirmed: _instance.exposed is read and
|
|
63
|
+
* redefined as properties on the element itself, not something Vue-
|
|
64
|
+
* internal or requiring a $refs-style lookup). "prune" (default)
|
|
65
|
+
* evaluates against the current preview context; "wrap" always
|
|
66
|
+
* includes every ESP-conditional branch, matching the same two modes
|
|
67
|
+
* the Export dropdown itself offers. */
|
|
68
|
+
getHtml(mode?: "prune" | "wrap"): string | null;
|
|
69
|
+
getMjml(mode?: "prune" | "wrap"): string | null;
|
|
70
|
+
getReactEmail(mode?: "prune" | "wrap"): string | null;
|
|
71
|
+
getJson(): Record<string, unknown> | null;
|
|
72
|
+
/** Removes the element from the DOM. Vue's custom element wrapper
|
|
73
|
+
* handles unmounting the internal app and cleaning up watchers/effects
|
|
74
|
+
* as part of its own disconnectedCallback — not reimplemented here. */
|
|
75
|
+
destroy(): void;
|
|
76
|
+
}
|
|
77
|
+
export declare function init(options: InitOptions): Promise<EditorHandle>;
|
|
78
|
+
export { registerBlock, getBlock, getAllBlocks, } from './blocks/registry';
|
|
79
|
+
export { registerESPSyntax, getRegisteredCustomESPs, } from './esp/registry';
|
|
80
|
+
export { registerMergeTags, getRegisteredMergeTagIds, } from './merge-tags/registry';
|
|
81
|
+
export { setEditorTheme, palette } from './theme';
|
|
82
|
+
export { createLocalStorageAdapter } from './adapters/localStorageAdapter';
|
|
83
|
+
export type { BlockDefinition } from './blocks/types';
|
|
84
|
+
export type { ThemeOptions, ThemeTokens } from './theme';
|
|
85
|
+
export type { EditorStorageAdapter, PartialStorageAdapter, TemplateSnapshot, TemplateSummary, SavedRow, } from './adapters/types';
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { D as h, at as ref, i as createApp, rt as reactive } from "./vue.runtime.esm-bundler-DwQEK7WO.js";
|
|
2
|
+
import { a as setEditorTheme, c as createLocalStorageAdapter, d as getRegisteredMergeTagIds, f as registerMergeTags, h as registerBlock, i as palette, l as getRegisteredCustomESPs, m as getBlock, n as registerMaildenoEditorElement, p as getAllBlocks, r as EmailEditor_default, s as buildShadowStyles, u as registerESPSyntax } from "./element-DN22fZmQ.js";
|
|
3
|
+
//#region src/lightDom.ts
|
|
4
|
+
var stylesInjected = false;
|
|
5
|
+
/**
|
|
6
|
+
* The shadow path hands these strings to defineCustomElement, which turns
|
|
7
|
+
* them into <style> tags inside the shadow root. Here they go to
|
|
8
|
+
* document.head instead — same content, different destination. Guarded so
|
|
9
|
+
* multiple editors on one page inject once.
|
|
10
|
+
*/
|
|
11
|
+
function injectStylesIntoHead() {
|
|
12
|
+
if (stylesInjected || typeof document === "undefined") return;
|
|
13
|
+
stylesInjected = true;
|
|
14
|
+
for (const css of buildShadowStyles()) {
|
|
15
|
+
if (!css) continue;
|
|
16
|
+
const style = document.createElement("style");
|
|
17
|
+
style.setAttribute("data-maildeno-light-dom", "");
|
|
18
|
+
style.textContent = css;
|
|
19
|
+
document.head.appendChild(style);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function mountLightDom(container, initialProps) {
|
|
23
|
+
injectStylesIntoHead();
|
|
24
|
+
const props = reactive({ ...initialProps });
|
|
25
|
+
const saveHandlers = /* @__PURE__ */ new Set();
|
|
26
|
+
const editorRef = ref(null);
|
|
27
|
+
const mountEl = document.createElement("div");
|
|
28
|
+
mountEl.style.height = "100%";
|
|
29
|
+
container.appendChild(mountEl);
|
|
30
|
+
const app = createApp({ setup() {
|
|
31
|
+
return () => h(EmailEditor_default, {
|
|
32
|
+
...props,
|
|
33
|
+
ref: editorRef,
|
|
34
|
+
onSave: (payload) => saveHandlers.forEach((fn) => fn(payload))
|
|
35
|
+
});
|
|
36
|
+
} });
|
|
37
|
+
app.mount(mountEl);
|
|
38
|
+
return {
|
|
39
|
+
element: mountEl,
|
|
40
|
+
exposed: () => editorRef.value ?? null,
|
|
41
|
+
setProp: (key, value) => {
|
|
42
|
+
props[key] = value;
|
|
43
|
+
},
|
|
44
|
+
addSaveHandler: (fn) => saveHandlers.add(fn),
|
|
45
|
+
removeSaveHandler: (fn) => saveHandlers.delete(fn),
|
|
46
|
+
destroy: () => {
|
|
47
|
+
app.unmount();
|
|
48
|
+
mountEl.remove();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/init.ts
|
|
54
|
+
function toDomEventName(event) {
|
|
55
|
+
return event;
|
|
56
|
+
}
|
|
57
|
+
async function init(options) {
|
|
58
|
+
const container = typeof options.container === "string" ? document.querySelector(options.container) : options.container;
|
|
59
|
+
if (!container) throw new Error(`[maildeno-editor] init() couldn't find a container${typeof options.container === "string" ? ` matching "${options.container}"` : ""}.`);
|
|
60
|
+
if (options.shadowDom === false) {
|
|
61
|
+
const mount = mountLightDom(container, {
|
|
62
|
+
templateId: options.templateId,
|
|
63
|
+
storageAdapter: options.storageAdapter,
|
|
64
|
+
theme: options.theme,
|
|
65
|
+
capabilities: options.capabilities,
|
|
66
|
+
onSendTestEmail: options.onSendTestEmail
|
|
67
|
+
});
|
|
68
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
69
|
+
const call = (name, ...args) => {
|
|
70
|
+
const fn = mount.exposed()?.[name];
|
|
71
|
+
return typeof fn === "function" ? fn(...args) : null;
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
element: mount.element,
|
|
75
|
+
on: (_event, handler) => mount.addSaveHandler(handler),
|
|
76
|
+
off: (_event, handler) => mount.removeSaveHandler(handler),
|
|
77
|
+
setTheme: (theme) => mount.setProp("theme", theme),
|
|
78
|
+
getHtml: (mode = "prune") => call("getHtml", mode),
|
|
79
|
+
getMjml: (mode = "prune") => call("getMjml", mode),
|
|
80
|
+
getReactEmail: (mode = "prune") => call("getReactEmail", mode),
|
|
81
|
+
getJson: () => call("getJson"),
|
|
82
|
+
destroy: () => mount.destroy()
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
registerMaildenoEditorElement();
|
|
86
|
+
const el = document.createElement("maildeno-editor");
|
|
87
|
+
if (options.templateId !== void 0) el.templateId = options.templateId;
|
|
88
|
+
if (options.storageAdapter) el.storageAdapter = options.storageAdapter;
|
|
89
|
+
if (options.theme) el.theme = options.theme;
|
|
90
|
+
if (options.capabilities) el.capabilities = options.capabilities;
|
|
91
|
+
if (options.onSendTestEmail) el.onSendTestEmail = options.onSendTestEmail;
|
|
92
|
+
container.appendChild(el);
|
|
93
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
94
|
+
const listenerWrappers = /* @__PURE__ */ new WeakMap();
|
|
95
|
+
return {
|
|
96
|
+
element: el,
|
|
97
|
+
on(event, handler) {
|
|
98
|
+
const wrapped = ((e) => handler(Array.isArray(e.detail) ? e.detail[0] : e.detail));
|
|
99
|
+
listenerWrappers.set(handler, wrapped);
|
|
100
|
+
el.addEventListener(toDomEventName(event), wrapped);
|
|
101
|
+
},
|
|
102
|
+
off(event, handler) {
|
|
103
|
+
const wrapped = listenerWrappers.get(handler);
|
|
104
|
+
if (wrapped) {
|
|
105
|
+
el.removeEventListener(toDomEventName(event), wrapped);
|
|
106
|
+
listenerWrappers.delete(handler);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
setTheme(theme) {
|
|
110
|
+
el.theme = theme;
|
|
111
|
+
},
|
|
112
|
+
getHtml(mode = "prune") {
|
|
113
|
+
return el.getHtml ? el.getHtml(mode) : null;
|
|
114
|
+
},
|
|
115
|
+
getMjml(mode = "prune") {
|
|
116
|
+
return el.getMjml ? el.getMjml(mode) : null;
|
|
117
|
+
},
|
|
118
|
+
getReactEmail(mode = "prune") {
|
|
119
|
+
return el.getReactEmail ? el.getReactEmail(mode) : null;
|
|
120
|
+
},
|
|
121
|
+
getJson() {
|
|
122
|
+
return el.getJson ? el.getJson() : null;
|
|
123
|
+
},
|
|
124
|
+
destroy() {
|
|
125
|
+
el.remove();
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
130
|
+
export { createLocalStorageAdapter, getAllBlocks, getBlock, getRegisteredCustomESPs, getRegisteredMergeTagIds, init, palette, registerBlock, registerESPSyntax, registerMergeTags, setEditorTheme };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mounts the editor directly into the page, with no shadow root.
|
|
3
|
+
*
|
|
4
|
+
* This is the `shadowDom: false` path. Shadow DOM buys style isolation,
|
|
5
|
+
* but it costs real behaviour: `event.target` is retargeted to the host,
|
|
6
|
+
* `document.activeElement` returns the host rather than the focused
|
|
7
|
+
* element, `document.querySelector` cannot see inside, and `@font-face`
|
|
8
|
+
* and `@property` are ignored entirely. Every one of those has caused a
|
|
9
|
+
* concrete bug in this package, and third-party libraries hit them too —
|
|
10
|
+
* Reka UI's own internals use `document.activeElement` and never
|
|
11
|
+
* `composedPath()`, so anything built on it can misbehave inside a shadow
|
|
12
|
+
* root in ways that cannot be fixed from the outside.
|
|
13
|
+
*
|
|
14
|
+
* Light DOM trades isolation for predictability: the host page's CSS can
|
|
15
|
+
* reach the editor (and vice versa), but every browser API behaves
|
|
16
|
+
* normally. It is the right choice when the host page's styles are known
|
|
17
|
+
* and controlled, and the escape hatch when something in the shadow path
|
|
18
|
+
* misbehaves.
|
|
19
|
+
*/
|
|
20
|
+
export interface LightDomMount {
|
|
21
|
+
/** The element the editor was mounted into. */
|
|
22
|
+
element: HTMLElement;
|
|
23
|
+
/** Reads EmailEditor.vue's defineExpose'd methods. */
|
|
24
|
+
exposed: () => Record<string, any> | null;
|
|
25
|
+
setProp: (key: string, value: unknown) => void;
|
|
26
|
+
addSaveHandler: (fn: (payload: any) => void) => void;
|
|
27
|
+
removeSaveHandler: (fn: (payload: any) => void) => void;
|
|
28
|
+
destroy: () => void;
|
|
29
|
+
}
|
|
30
|
+
export declare function mountLightDom(container: HTMLElement, initialProps: Record<string, unknown>): LightDomMount;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confirmed against the real pipeline (mergeTagMapper.ts's transformToken):
|
|
3
|
+
* any tag ID not in the hardcoded SYSTEM_TAG_MAP already falls through to
|
|
4
|
+
* transformCustomTag, which handles arbitrary tag names generically for
|
|
5
|
+
* all known ESP syntaxes — this was already true before this registry
|
|
6
|
+
* existed (see the "Zero Vendor Lock-in" note in mergeTagMapper.ts).
|
|
7
|
+
*
|
|
8
|
+
* So registering a merge tag isn't fixing a correctness gap the way the
|
|
9
|
+
* ESP registry was. It solves a narrower, real problem: getSystemTagIds()
|
|
10
|
+
* only returns SYSTEM_TAG_MAP's hardcoded keys, so a host's own fields
|
|
11
|
+
* (order_total, loyalty_points, ...) never show up in the "Common tags"
|
|
12
|
+
* picker UI — a user would have to already know to type {{ order_total }}
|
|
13
|
+
* by hand. This registry makes registered tags discoverable there.
|
|
14
|
+
*
|
|
15
|
+
* Optional per-ESP token overrides exist for the rare case a custom tag
|
|
16
|
+
* needs something other than the generic transform (e.g. a genuinely
|
|
17
|
+
* ESP-specific system-level token) — most registrations won't need them.
|
|
18
|
+
*/
|
|
19
|
+
export interface MergeTagRegistration {
|
|
20
|
+
key: string;
|
|
21
|
+
/** Optional — omit to use the existing generic transformCustomTag path
|
|
22
|
+
* for every ESP syntax, which is already correct for ordinary data
|
|
23
|
+
* fields. Only provide this for a tag that needs ESP-specific hardcoded
|
|
24
|
+
* tokens, the same category SYSTEM_TAG_MAP covers for built-ins. */
|
|
25
|
+
tokens?: Partial<Record<string, string>>;
|
|
26
|
+
}
|
|
27
|
+
export declare function registerMergeTags(tags: MergeTagRegistration[]): void;
|
|
28
|
+
/** Custom-registered IDs, appended after the built-ins for the picker UI. */
|
|
29
|
+
export declare function getRegisteredMergeTagIds(): string[];
|
|
30
|
+
/** Only returns a value for tags that were registered WITH explicit token
|
|
31
|
+
* overrides — most registered tags return undefined here on purpose, so
|
|
32
|
+
* transformToken's existing transformCustomTag fallback handles them. */
|
|
33
|
+
export declare function getRegisteredMergeTagToken(tagId: string, syntax: string): string | undefined;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* False when running from source, where the build-time substitution above
|
|
3
|
+
* never ran and the shadow root therefore has no component CSS. Used to
|
|
4
|
+
* decide whether the dev style mirror is needed — a capability check rather
|
|
5
|
+
* than an environment guess, so it self-corrects in either direction.
|
|
6
|
+
*/
|
|
7
|
+
export declare function hasExtractedScopedCss(): boolean;
|
|
8
|
+
export declare function buildShadowStyles(): string[];
|