@bikdotai/bik-component-library 0.0.817-beta.12 → 0.0.817-beta.13
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/cjs/components/template-preview/RCS/RCSChatPreview.js +1 -1
- package/dist/cjs/components/template-preview/RCS/RCSChatPreview.js.map +1 -1
- package/dist/cjs/components/template-preview/helpers/TemplateCreatorHelper.js +1 -1
- package/dist/cjs/components/template-preview/helpers/TemplateCreatorHelper.js.map +1 -1
- package/dist/cjs/components/template-preview/models/RCSTemplate.js.map +1 -1
- package/dist/cjs/editor/BikEditor.js +1 -1
- package/dist/cjs/editor/BikEditor.js.map +1 -1
- package/dist/cjs/editor/BikEditor.utils.js +2 -2
- package/dist/cjs/editor/BikEditor.utils.js.map +1 -1
- package/dist/esm/components/template-preview/RCS/RCSChatPreview.js +72 -68
- package/dist/esm/components/template-preview/RCS/RCSChatPreview.js.map +1 -1
- package/dist/esm/components/template-preview/helpers/TemplateCreatorHelper.d.ts +0 -8
- package/dist/esm/components/template-preview/helpers/TemplateCreatorHelper.js +61 -79
- package/dist/esm/components/template-preview/helpers/TemplateCreatorHelper.js.map +1 -1
- package/dist/esm/components/template-preview/models/RCSTemplate.d.ts +0 -7
- package/dist/esm/components/template-preview/models/RCSTemplate.js.map +1 -1
- package/dist/esm/editor/BikEditor.js +60 -54
- package/dist/esm/editor/BikEditor.js.map +1 -1
- package/dist/esm/editor/BikEditor.utils.d.ts +5 -2
- package/dist/esm/editor/BikEditor.utils.js +104 -96
- package/dist/esm/editor/BikEditor.utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../node_modules/prosemirror-model/dist/index.js"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../node_modules/prosemirror-model/dist/index.js"),S=require("./extensions/plainClipboard/pasteUtils.js");function h(e){if(!e||typeof document>"u")return e;const t=document.createElement("div");return t.innerHTML=e,t.querySelectorAll("span").forEach(i=>{if(i.hasAttribute("style")||i.hasAttribute("data-variable"))return;const n=i.parentNode;if(n){for(;i.firstChild;)n.insertBefore(i.firstChild,i);n.removeChild(i)}}),t.querySelectorAll("p").forEach(i=>{i.querySelectorAll("br").length===1&&(i.textContent??"").trim()===""&&(i.innerHTML="")}),t.innerHTML}function u(e){const t=document.createElement("div");t.innerHTML=e;const i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);let n;for(;n=i.nextNode();)n.nodeValue&&n.nodeValue.includes(" ")&&(n.nodeValue=n.nodeValue.replace(/ {2}/g," "));const s=t.querySelectorAll("p");for(const r of Array.from(s)){if(r.childNodes.length===0){r.appendChild(document.createElement("br"));continue}r.lastChild instanceof HTMLBRElement&&r.childNodes.length>1&&r.appendChild(document.createElement("br"))}return t.innerHTML}function A(e,t){const i=h(t),n=document.createElement("div");n.innerHTML=i;const s=a.DOMParser.fromSchema(e.schema).parseSlice(n,{preserveWhitespace:!0});if(s.size===0)return;const{from:r,to:c}=e.state.selection,o=e.state.tr.replaceRange(r,c,s);e.view.dispatch(o)}const d=e=>`<div data-section-divider="${e}" style="display:none;height:0;line-height:0;overflow:hidden;"></div>`;function b(e,t){let i=e;for(const n of t)i+=d(n.id)+n.content;return i}function v(e){return e?g(e).get("body")??e:""}function x(e){if(!e)return"";const t=v(e);return e.substring(t.length)}function g(e){const t=new Map,i=/<div[^>]*data-section-divider="([^"]*)[^>]*>\s*<\/div>/g,n=[];let s;for(;(s=i.exec(e))!==null;)n.push({id:s[1],index:s.index,endIndex:s.index+s[0].length});if(n.length===0)return t.set("body",e),t;t.set("body",e.slice(0,n[0].index));for(let r=0;r<n.length;r++){const c=n[r].endIndex,o=r+1<n.length?n[r+1].index:e.length;t.set(n[r].id,e.slice(c,o))}return t}function p(e,t){const i=f(e,t);if(i===-1)return{html:"",text:"",isEmpty:!0,characterCount:0};const n=m(e,t),s=e.state.doc.slice(i,n),r=document.createElement("div"),c=a.DOMSerializer.fromSchema(e.schema);r.appendChild(c.serializeFragment(s.content));const o=u(r.innerHTML),l=r.textContent??"";return{html:o,text:l,isEmpty:!l.trim(),characterCount:l.length}}function H(e,t){const i=document.createElement("div");return i.innerHTML=t,a.DOMParser.fromSchema(e.schema).parse(i,{preserveWhitespace:!0}).content}function C(e,t,i){const n=f(e,t);if(n===-1){const l=e.state.doc.content.size,y=d(t)+i;e.commands.insertContentAt(l,y,{updateSelection:!1});return}const s=m(e,t),r=H(e,i),{tr:c}=e.state,o=t==="body"?0:n;c.replaceWith(o,s,r),c.setMeta("addToHistory",!1),e.view.dispatch(c)}function E(e){return p(e,"body")}function k(e){return{bold:e.isActive("bold"),italic:e.isActive("italic"),underline:e.isActive("underline"),strike:e.isActive("strike"),bulletList:e.isActive("bulletList"),orderedList:e.isActive("orderedList"),blockquote:e.isActive("blockquote"),codeBlock:e.isActive("codeBlock"),link:(()=>{if(e.isActive("link"))return{href:e.getAttributes("link").href??""};const{$from:t}=e.state.selection;if(t.pos>0){const n=t.doc.resolve(t.pos).marks().find(s=>s.type.name==="link");if(n)return{href:n.attrs.href??""};{const r=t.nodeBefore?.marks.find(c=>c.type.name==="link");if(r)return{href:r.attrs.href??""}}}return null})(),textAlign:e.isActive({textAlign:"center"})?"center":e.isActive({textAlign:"right"})?"right":e.isActive({textAlign:"justify"})?"justify":e.isActive({textAlign:"left"})?"left":null,fontFamily:e.getAttributes("textStyle").fontFamily??null,fontSize:e.getAttributes("textStyle").fontSize??null,color:e.getAttributes("textStyle").color??null,highlight:e.isActive("highlight")?e.getAttributes("highlight").color??"default":null,superscript:e.isActive("superscript"),subscript:e.isActive("subscript")}}function T(e){const t=u(e.getHTML()),i=S.normalizeHardBreaks(e.state.doc.content),n=e.schema.node("doc",null,i),s=n.textBetween(0,n.content.size,`
|
|
2
2
|
|
|
3
3
|
`,`
|
|
4
|
-
`);return{html:
|
|
4
|
+
`);return{html:t,text:s,isEmpty:e.isEmpty,characterCount:s.length}}function f(e,t){if(t==="body")return 1;let i=-1;return e.state.doc.descendants((n,s)=>{if(i!==-1)return!1;n.type.name==="sectionDivider"&&n.attrs.sectionId===t&&(i=s+n.nodeSize)}),i}function m(e,t){const i=e.state.doc,n=i.content.size;if(t==="body"){let c=-1;return i.descendants((o,l)=>{if(c!==-1)return!1;o.type.name==="sectionDivider"&&(c=l)}),c!==-1?c:n}let s=!1,r=-1;return i.descendants((c,o)=>{if(r!==-1)return!1;if(!s)return c.type.name==="sectionDivider"&&c.attrs.sectionId===t&&(s=!0),!1;c.type.name==="sectionDivider"&&(r=o)}),r!==-1?r:n}exports.SECTION_DIVIDER_HTML=d;exports.buildSectionedContent=b;exports.extractActiveFormats=k;exports.extractAllSectionsFromHtml=g;exports.extractBodyContent=E;exports.extractContent=T;exports.extractSectionContent=p;exports.findSectionEndPos=m;exports.findSectionStartPos=f;exports.getBodyHtml=v;exports.getSectionsHtml=x;exports.insertInlineHtml=A;exports.normalizeHtml=h;exports.setSectionContentInEditor=C;exports.toPortableHtml=u;
|
|
5
5
|
//# sourceMappingURL=BikEditor.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BikEditor.utils.js","sources":["../../../src/editor/BikEditor.utils.ts"],"sourcesContent":["import { Editor } from '@tiptap/core';\nimport { DOMParser, DOMSerializer } from 'prosemirror-model';\nimport { EditorSnapshot, FormatState } from './BikEditor.types';\nimport { normalizeHardBreaks } from './extensions/plainClipboard/pasteUtils';\n\n// ---------------------------------------------------------------------------\n// HTML normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Normalise HTML before passing it to TipTap.\n *\n * 1. Unwrap style-less `<span>` wrappers (plain spans, and editor-cursor spans\n * like Quill's `<span class=\"ql-cursor\">`). Spans that carry inline styling\n * (`color` / `font-family` / `font-size` render as styled spans) or that\n * represent a `{{variable}}` token are PRESERVED — otherwise a setContent\n * round-trip would silently drop colour/font formatting that paste keeps.\n * 2. Collapse placeholder paragraphs (`<p><br></p>`) to `<p></p>`. ProseMirror\n * parses `<p></p>` as an empty paragraph and adds its own DOM `<br>` for the\n * cursor — one blank line, correct height. Leaving the source `<br>` would\n * create a `hard_break` child AND the cursor `<br>` → double-height blank line.\n *\n * Uses the DOM (regex cannot selectively pair span tags). `normalizeHtml` runs\n * in the component body for `initialContent`, so it is guarded for SSR: the\n * editor is created lazily on the client (`immediatelyRender: false`), meaning\n * the value is only parsed client-side and passing through on the server is safe.\n */\nexport function normalizeHtml(html: string): string {\n\tif (!html || typeof document === 'undefined') return html;\n\n\tconst container = document.createElement('div');\n\tcontainer.innerHTML = html;\n\n\tcontainer.querySelectorAll('span').forEach((span) => {\n\t\tif (span.hasAttribute('style') || span.hasAttribute('data-variable'))\n\t\t\treturn;\n\t\tconst parent = span.parentNode;\n\t\tif (!parent) return;\n\t\twhile (span.firstChild) parent.insertBefore(span.firstChild, span);\n\t\tparent.removeChild(span);\n\t});\n\n\tcontainer.querySelectorAll('p').forEach((p) => {\n\t\tif (\n\t\t\tp.querySelectorAll('br').length === 1 &&\n\t\t\t(p.textContent ?? '').trim() === ''\n\t\t) {\n\t\t\tp.innerHTML = '';\n\t\t}\n\t});\n\n\treturn container.innerHTML;\n}\n\n/**\n * Make editor HTML portable across email clients and chat renderers.\n *\n * 1. Double a trailing `<br>` in content paragraphs so the blank line is\n * visible. A single trailing `<br>` before `</p>` is swallowed by most\n * email clients; `<br><br>` renders as a visible blank line (matches\n * Gmail's output).\n * 2. Convert empty `<p></p>` to `<p><br></p>` — email clients collapse\n * zero-height paragraphs without a `<br>`.\n */\nexport function toPortableHtml(html: string): string {\n\tconst div = document.createElement('div');\n\tdiv.innerHTML = html;\n\tconst blocks = div.querySelectorAll('p');\n\tfor (const p of Array.from(blocks)) {\n\t\tif (p.childNodes.length === 0) {\n\t\t\tp.appendChild(document.createElement('br'));\n\t\t\tcontinue;\n\t\t}\n\t\tconst last = p.lastChild;\n\t\tif (last instanceof HTMLBRElement && p.childNodes.length > 1) {\n\t\t\tp.appendChild(document.createElement('br'));\n\t\t}\n\t}\n\treturn div.innerHTML;\n}\n\n// ---------------------------------------------------------------------------\n// Inline content insertion\n// ---------------------------------------------------------------------------\n\n/**\n * Insert HTML at the current cursor position, merging the first paragraph\n * inline while preserving the block structure of subsequent paragraphs/lists.\n *\n * Uses `parseSlice` which returns an open-ended Slice — the first block merges\n * at the cursor, middle blocks stay intact, and the last block merges with any\n * text that follows the cursor.\n */\nexport function insertInlineHtml(editor: Editor, html: string): void {\n\tconst normalised = normalizeHtml(html);\n\tconst dom = document.createElement('div');\n\tdom.innerHTML = normalised;\n\tconst slice = DOMParser.fromSchema(editor.schema).parseSlice(dom);\n\n\tif (slice.size === 0) return;\n\n\tconst { from, to } = editor.state.selection;\n\tconst tr = editor.state.tr.replaceRange(from, to, slice);\n\teditor.view.dispatch(tr);\n}\n\n// ---------------------------------------------------------------------------\n// Section divider HTML\n// ---------------------------------------------------------------------------\n\nexport const SECTION_DIVIDER_HTML = (id: string) =>\n\t`<div data-section-divider=\"${id}\" style=\"display:none;height:0;line-height:0;overflow:hidden;\"></div>`;\n\n/**\n * Build initial HTML for an editor with one or more named sections below the body.\n * Each section is separated by an invisible divider node.\n *\n * @example\n * buildSectionedContent('<p>Body</p>', [\n * { id: 'signature', content: '<p>Alice</p>' },\n * { id: 'forwarded', content: '<p>--- fwd ---</p>' },\n * ])\n */\nexport function buildSectionedContent(\n\tbody: string,\n\tsections: Array<{ id: string; content: string }>,\n): string {\n\tlet html = body;\n\tfor (const s of sections) {\n\t\thtml += SECTION_DIVIDER_HTML(s.id) + s.content;\n\t}\n\treturn html;\n}\n\n// ---------------------------------------------------------------------------\n// Section extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Parse the editor HTML into a Map of sectionId → raw HTML string.\n * The special key `'body'` always holds the content before the first divider.\n * Map iteration order matches document order.\n */\nexport function extractAllSections(editor: Editor): Map<string, string> {\n\treturn extractAllSectionsFromHtml(editor.getHTML());\n}\n\n/**\n * Extract just the body portion (everything before the first section divider)\n * from an HTML string produced by BikEditor. Safe to call on plain HTML too —\n * returns the full string when no dividers are present.\n */\nexport function getBodyHtml(html: string): string {\n\tif (!html) return '';\n\tconst sections = extractAllSectionsFromHtml(html);\n\treturn sections.get('body') ?? html;\n}\n\n/**\n * Extract everything from the first section divider onward (dividers + their\n * content). Returns an empty string when there are no sections.\n */\nexport function getSectionsHtml(html: string): string {\n\tif (!html) return '';\n\tconst body = getBodyHtml(html);\n\treturn html.substring(body.length);\n}\n\nexport function extractAllSectionsFromHtml(html: string): Map<string, string> {\n\tconst sections = new Map<string, string>();\n\tconst dividerRegex =\n\t\t/<div[^>]*data-section-divider=\"([^\"]*)[^>]*>\\s*<\\/div>/g;\n\tconst dividers: Array<{ id: string; index: number; endIndex: number }> = [];\n\n\tlet match: RegExpExecArray | null;\n\twhile ((match = dividerRegex.exec(html)) !== null) {\n\t\tdividers.push({\n\t\t\tid: match[1],\n\t\t\tindex: match.index,\n\t\t\tendIndex: match.index + match[0].length,\n\t\t});\n\t}\n\n\tif (dividers.length === 0) {\n\t\tsections.set('body', html);\n\t\treturn sections;\n\t}\n\n\tsections.set('body', html.slice(0, dividers[0].index));\n\tfor (let i = 0; i < dividers.length; i++) {\n\t\tconst start = dividers[i].endIndex;\n\t\tconst end = i + 1 < dividers.length ? dividers[i + 1].index : html.length;\n\t\tsections.set(dividers[i].id, html.slice(start, end));\n\t}\n\n\treturn sections;\n}\n\n/** Returns BikEditorContent for a single named section (or 'body'). */\nexport function extractSectionContent(\n\teditor: Editor,\n\tid: string,\n): EditorSnapshot {\n\tconst startPos = findSectionStartPos(editor, id);\n\tif (startPos === -1)\n\t\treturn { html: '', text: '', isEmpty: true, characterCount: 0 };\n\tconst endPos = findSectionEndPos(editor, id);\n\tconst slice = editor.state.doc.slice(startPos, endPos);\n\tconst container = document.createElement('div');\n\tconst serializer = DOMSerializer.fromSchema(editor.schema);\n\tcontainer.appendChild(serializer.serializeFragment(slice.content));\n\tconst html = toPortableHtml(container.innerHTML);\n\tconst text = container.textContent ?? '';\n\treturn { html, text, isEmpty: !text.trim(), characterCount: text.length };\n}\n\n/**\n * Parse an HTML string into ProseMirror nodes using the editor's schema.\n */\nfunction parseHtmlToNodes(editor: Editor, html: string) {\n\tconst container = document.createElement('div');\n\tcontainer.innerHTML = html;\n\treturn DOMParser.fromSchema(editor.schema).parse(container).content;\n}\n\n/**\n * Replace the content of a single named section without touching others.\n * Uses a ProseMirror transaction to replace only the target range,\n * preserving undo history and other sections' state.\n * If the section doesn't exist yet, it is appended at the end of the document.\n */\nexport function setSectionContentInEditor(\n\teditor: Editor,\n\tid: string,\n\thtml: string,\n): void {\n\tconst startPos = findSectionStartPos(editor, id);\n\tif (startPos === -1) {\n\t\tconst endPos = editor.state.doc.content.size;\n\t\tconst dividerHtml = SECTION_DIVIDER_HTML(id) + html;\n\t\teditor.commands.insertContentAt(endPos, dividerHtml, {\n\t\t\tupdateSelection: false,\n\t\t});\n\t\treturn;\n\t}\n\tconst endPos = findSectionEndPos(editor, id);\n\tconst fragment = parseHtmlToNodes(editor, html);\n\tconst { tr } = editor.state;\n\t// For body, replace from position 0 (before the first paragraph's opening\n\t// boundary) so ProseMirror swaps entire block nodes cleanly. Position 1\n\t// (inside the paragraph) would force ProseMirror to close the open paragraph\n\t// first, creating a ghost empty <p></p>.\n\tconst replaceFrom = id === 'body' ? 0 : startPos;\n\ttr.replaceWith(replaceFrom, endPos, fragment);\n\ttr.setMeta('addToHistory', false);\n\teditor.view.dispatch(tr);\n}\n\n// ---------------------------------------------------------------------------\n// Convenience shorthands (body = first section)\n// ---------------------------------------------------------------------------\n\n/** Extract BikEditorContent for just the body (before the first divider). */\nexport function extractBodyContent(editor: Editor): EditorSnapshot {\n\treturn extractSectionContent(editor, 'body');\n}\n\n// ---------------------------------------------------------------------------\n// Active formats\n// ---------------------------------------------------------------------------\n\nexport function extractActiveFormats(editor: Editor): FormatState {\n\treturn {\n\t\tbold: editor.isActive('bold'),\n\t\titalic: editor.isActive('italic'),\n\t\tunderline: editor.isActive('underline'),\n\t\tstrike: editor.isActive('strike'),\n\t\tbulletList: editor.isActive('bulletList'),\n\t\torderedList: editor.isActive('orderedList'),\n\t\tblockquote: editor.isActive('blockquote'),\n\t\tcodeBlock: editor.isActive('codeBlock'),\n\t\tlink: (() => {\n\t\t\tif (editor.isActive('link')) {\n\t\t\t\treturn { href: editor.getAttributes('link')['href'] ?? '' };\n\t\t\t}\n\t\t\tconst { $from } = editor.state.selection;\n\t\t\tif ($from.pos > 0) {\n\t\t\t\tconst before = $from.doc.resolve($from.pos);\n\t\t\t\tconst linkMark = before.marks().find((m) => m.type.name === 'link');\n\t\t\t\tif (!linkMark) {\n\t\t\t\t\tconst nodeBefore = $from.nodeBefore;\n\t\t\t\t\tconst markOnPrev = nodeBefore?.marks.find(\n\t\t\t\t\t\t(m) => m.type.name === 'link',\n\t\t\t\t\t);\n\t\t\t\t\tif (markOnPrev) {\n\t\t\t\t\t\treturn { href: markOnPrev.attrs['href'] ?? '' };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn { href: linkMark.attrs['href'] ?? '' };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t})(),\n\t\ttextAlign: editor.isActive({ textAlign: 'center' })\n\t\t\t? 'center'\n\t\t\t: editor.isActive({ textAlign: 'right' })\n\t\t\t? 'right'\n\t\t\t: editor.isActive({ textAlign: 'justify' })\n\t\t\t? 'justify'\n\t\t\t: editor.isActive({ textAlign: 'left' })\n\t\t\t? 'left'\n\t\t\t: null,\n\t\tfontFamily: editor.getAttributes('textStyle')['fontFamily'] ?? null,\n\t\tfontSize: editor.getAttributes('textStyle')['fontSize'] ?? null,\n\t\tcolor: editor.getAttributes('textStyle')['color'] ?? null,\n\t\thighlight: editor.isActive('highlight')\n\t\t\t? editor.getAttributes('highlight')['color'] ?? 'default'\n\t\t\t: null,\n\t\tsuperscript: editor.isActive('superscript'),\n\t\tsubscript: editor.isActive('subscript'),\n\t};\n}\n\nexport function extractContent(editor: Editor): EditorSnapshot {\n\tconst html = toPortableHtml(editor.getHTML());\n\tconst normalized = normalizeHardBreaks(editor.state.doc.content);\n\tconst tempDoc = editor.schema.node('doc', null, normalized);\n\t// Paragraph boundary → blank line (\\n\\n), soft line break (hardBreak) → \\n.\n\t// Matches Gmail's plain-text output for the same content.\n\tconst text = tempDoc.textBetween(0, tempDoc.content.size, '\\n\\n', '\\n');\n\treturn {\n\t\thtml,\n\t\ttext,\n\t\tisEmpty: editor.isEmpty,\n\t\tcharacterCount: text.length,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Section position helpers (used by insertAtSectionStart/End and appendBodyContent)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the ProseMirror position immediately after a section's opening divider\n * (i.e. the start of the section's own content).\n * For `'body'`, returns 1 (beginning of the document).\n * Returns -1 if the named section's divider is not found.\n */\nexport function findSectionStartPos(editor: Editor, sectionId: string): number {\n\tif (sectionId === 'body') return 1;\n\tlet startPos = -1;\n\teditor.state.doc.descendants((node, pos) => {\n\t\tif (startPos !== -1) return false;\n\t\tif (\n\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t) {\n\t\t\tstartPos = pos + node.nodeSize; // position right after the divider\n\t\t}\n\t});\n\treturn startPos;\n}\n\n/**\n * Returns the ProseMirror position at the end of a named section's content:\n * - For `'body'`: position of the first section divider, or end of document.\n * - For a named section: position of the next divider, or end of document.\n */\nexport function findSectionEndPos(editor: Editor, sectionId: string): number {\n\tconst doc = editor.state.doc;\n\tconst docSize = doc.content.size;\n\n\tif (sectionId === 'body') {\n\t\tlet firstDividerPos = -1;\n\t\tdoc.descendants((node, pos) => {\n\t\t\tif (firstDividerPos !== -1) return false;\n\t\t\tif (node.type.name === 'sectionDivider') {\n\t\t\t\tfirstDividerPos = pos;\n\t\t\t}\n\t\t});\n\t\treturn firstDividerPos !== -1 ? firstDividerPos : docSize;\n\t}\n\n\tlet passedSection = false;\n\tlet nextDividerPos = -1;\n\tdoc.descendants((node, pos) => {\n\t\tif (nextDividerPos !== -1) return false;\n\t\tif (!passedSection) {\n\t\t\tif (\n\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t) {\n\t\t\t\tpassedSection = true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tif (node.type.name === 'sectionDivider') {\n\t\t\tnextDividerPos = pos;\n\t\t}\n\t});\n\treturn nextDividerPos !== -1 ? nextDividerPos : docSize;\n}\n"],"names":["normalizeHtml","html","container","span","parent","p","toPortableHtml","div","blocks","insertInlineHtml","editor","normalised","dom","slice","DOMParser","from","to","tr","SECTION_DIVIDER_HTML","id","buildSectionedContent","body","sections","s","getBodyHtml","extractAllSectionsFromHtml","getSectionsHtml","dividerRegex","dividers","match","i","start","end","extractSectionContent","startPos","findSectionStartPos","endPos","findSectionEndPos","serializer","DOMSerializer","text","parseHtmlToNodes","setSectionContentInEditor","dividerHtml","fragment","replaceFrom","extractBodyContent","extractActiveFormats","$from","linkMark","m","markOnPrev","extractContent","normalized","normalizeHardBreaks","tempDoc","sectionId","node","pos","doc","docSize","firstDividerPos","passedSection","nextDividerPos"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BikEditor.utils.js","sources":["../../../src/editor/BikEditor.utils.ts"],"sourcesContent":["import { Editor } from '@tiptap/core';\nimport { DOMParser, DOMSerializer } from 'prosemirror-model';\nimport { EditorSnapshot, FormatState } from './BikEditor.types';\nimport { normalizeHardBreaks } from './extensions/plainClipboard/pasteUtils';\n\n// ---------------------------------------------------------------------------\n// HTML normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Normalise HTML before passing it to TipTap.\n *\n * 1. Unwrap style-less `<span>` wrappers (plain spans, and editor-cursor spans\n * like Quill's `<span class=\"ql-cursor\">`). Spans that carry inline styling\n * (`color` / `font-family` / `font-size` render as styled spans) or that\n * represent a `{{variable}}` token are PRESERVED — otherwise a setContent\n * round-trip would silently drop colour/font formatting that paste keeps.\n * 2. Collapse placeholder paragraphs (`<p><br></p>`) to `<p></p>`. ProseMirror\n * parses `<p></p>` as an empty paragraph and adds its own DOM `<br>` for the\n * cursor — one blank line, correct height. Leaving the source `<br>` would\n * create a `hard_break` child AND the cursor `<br>` → double-height blank line.\n *\n * Uses the DOM (regex cannot selectively pair span tags). `normalizeHtml` runs\n * in the component body for `initialContent`, so it is guarded for SSR: the\n * editor is created lazily on the client (`immediatelyRender: false`), meaning\n * the value is only parsed client-side and passing through on the server is safe.\n */\nexport function normalizeHtml(html: string): string {\n\tif (!html || typeof document === 'undefined') return html;\n\n\tconst container = document.createElement('div');\n\tcontainer.innerHTML = html;\n\n\tcontainer.querySelectorAll('span').forEach((span) => {\n\t\tif (span.hasAttribute('style') || span.hasAttribute('data-variable'))\n\t\t\treturn;\n\t\tconst parent = span.parentNode;\n\t\tif (!parent) return;\n\t\twhile (span.firstChild) parent.insertBefore(span.firstChild, span);\n\t\tparent.removeChild(span);\n\t});\n\n\tcontainer.querySelectorAll('p').forEach((p) => {\n\t\tif (\n\t\t\tp.querySelectorAll('br').length === 1 &&\n\t\t\t(p.textContent ?? '').trim() === ''\n\t\t) {\n\t\t\tp.innerHTML = '';\n\t\t}\n\t});\n\n\treturn container.innerHTML;\n}\n\n/**\n * Make editor HTML portable across email clients and chat renderers.\n *\n * 1. Preserve consecutive spaces by converting every second space in a run\n * to ` ` (U+00A0). Standard HTML collapses adjacent regular spaces;\n * alternating with ` ` prevents that — same convention Gmail uses.\n * 2. Double a trailing `<br>` in content paragraphs so the blank line is\n * visible. A single trailing `<br>` before `</p>` is swallowed by most\n * email clients; `<br><br>` renders as a visible blank line (matches\n * Gmail's output).\n * 3. Convert empty `<p></p>` to `<p><br></p>` — email clients collapse\n * zero-height paragraphs without a `<br>`.\n */\nexport function toPortableHtml(html: string): string {\n\tconst div = document.createElement('div');\n\tdiv.innerHTML = html;\n\n\tconst walker = document.createTreeWalker(div, NodeFilter.SHOW_TEXT);\n\tlet textNode: Text | null;\n\twhile ((textNode = walker.nextNode() as Text | null)) {\n\t\tif (textNode.nodeValue && textNode.nodeValue.includes(' ')) {\n\t\t\ttextNode.nodeValue = textNode.nodeValue.replace(/ {2}/g, ' ');\n\t\t}\n\t}\n\n\tconst blocks = div.querySelectorAll('p');\n\tfor (const p of Array.from(blocks)) {\n\t\tif (p.childNodes.length === 0) {\n\t\t\tp.appendChild(document.createElement('br'));\n\t\t\tcontinue;\n\t\t}\n\t\tconst last = p.lastChild;\n\t\tif (last instanceof HTMLBRElement && p.childNodes.length > 1) {\n\t\t\tp.appendChild(document.createElement('br'));\n\t\t}\n\t}\n\treturn div.innerHTML;\n}\n\n// ---------------------------------------------------------------------------\n// Inline content insertion\n// ---------------------------------------------------------------------------\n\n/**\n * Insert HTML at the current cursor position, merging the first paragraph\n * inline while preserving the block structure of subsequent paragraphs/lists.\n *\n * Uses `parseSlice` which returns an open-ended Slice — the first block merges\n * at the cursor, middle blocks stay intact, and the last block merges with any\n * text that follows the cursor.\n */\nexport function insertInlineHtml(editor: Editor, html: string): void {\n\tconst normalised = normalizeHtml(html);\n\tconst dom = document.createElement('div');\n\tdom.innerHTML = normalised;\n\tconst slice = DOMParser.fromSchema(editor.schema).parseSlice(dom, {\n\t\tpreserveWhitespace: true,\n\t});\n\n\tif (slice.size === 0) return;\n\n\tconst { from, to } = editor.state.selection;\n\tconst tr = editor.state.tr.replaceRange(from, to, slice);\n\teditor.view.dispatch(tr);\n}\n\n// ---------------------------------------------------------------------------\n// Section divider HTML\n// ---------------------------------------------------------------------------\n\nexport const SECTION_DIVIDER_HTML = (id: string) =>\n\t`<div data-section-divider=\"${id}\" style=\"display:none;height:0;line-height:0;overflow:hidden;\"></div>`;\n\n/**\n * Build initial HTML for an editor with one or more named sections below the body.\n * Each section is separated by an invisible divider node.\n *\n * @example\n * buildSectionedContent('<p>Body</p>', [\n * { id: 'signature', content: '<p>Alice</p>' },\n * { id: 'forwarded', content: '<p>--- fwd ---</p>' },\n * ])\n */\nexport function buildSectionedContent(\n\tbody: string,\n\tsections: Array<{ id: string; content: string }>,\n): string {\n\tlet html = body;\n\tfor (const s of sections) {\n\t\thtml += SECTION_DIVIDER_HTML(s.id) + s.content;\n\t}\n\treturn html;\n}\n\n// ---------------------------------------------------------------------------\n// Section extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Parse the editor HTML into a Map of sectionId → raw HTML string.\n * The special key `'body'` always holds the content before the first divider.\n * Map iteration order matches document order.\n */\nexport function extractAllSections(editor: Editor): Map<string, string> {\n\treturn extractAllSectionsFromHtml(editor.getHTML());\n}\n\n/**\n * Extract just the body portion (everything before the first section divider)\n * from an HTML string produced by BikEditor. Safe to call on plain HTML too —\n * returns the full string when no dividers are present.\n */\nexport function getBodyHtml(html: string): string {\n\tif (!html) return '';\n\tconst sections = extractAllSectionsFromHtml(html);\n\treturn sections.get('body') ?? html;\n}\n\n/**\n * Extract everything from the first section divider onward (dividers + their\n * content). Returns an empty string when there are no sections.\n */\nexport function getSectionsHtml(html: string): string {\n\tif (!html) return '';\n\tconst body = getBodyHtml(html);\n\treturn html.substring(body.length);\n}\n\nexport function extractAllSectionsFromHtml(html: string): Map<string, string> {\n\tconst sections = new Map<string, string>();\n\tconst dividerRegex =\n\t\t/<div[^>]*data-section-divider=\"([^\"]*)[^>]*>\\s*<\\/div>/g;\n\tconst dividers: Array<{ id: string; index: number; endIndex: number }> = [];\n\n\tlet match: RegExpExecArray | null;\n\twhile ((match = dividerRegex.exec(html)) !== null) {\n\t\tdividers.push({\n\t\t\tid: match[1],\n\t\t\tindex: match.index,\n\t\t\tendIndex: match.index + match[0].length,\n\t\t});\n\t}\n\n\tif (dividers.length === 0) {\n\t\tsections.set('body', html);\n\t\treturn sections;\n\t}\n\n\tsections.set('body', html.slice(0, dividers[0].index));\n\tfor (let i = 0; i < dividers.length; i++) {\n\t\tconst start = dividers[i].endIndex;\n\t\tconst end = i + 1 < dividers.length ? dividers[i + 1].index : html.length;\n\t\tsections.set(dividers[i].id, html.slice(start, end));\n\t}\n\n\treturn sections;\n}\n\n/** Returns BikEditorContent for a single named section (or 'body'). */\nexport function extractSectionContent(\n\teditor: Editor,\n\tid: string,\n): EditorSnapshot {\n\tconst startPos = findSectionStartPos(editor, id);\n\tif (startPos === -1)\n\t\treturn { html: '', text: '', isEmpty: true, characterCount: 0 };\n\tconst endPos = findSectionEndPos(editor, id);\n\tconst slice = editor.state.doc.slice(startPos, endPos);\n\tconst container = document.createElement('div');\n\tconst serializer = DOMSerializer.fromSchema(editor.schema);\n\tcontainer.appendChild(serializer.serializeFragment(slice.content));\n\tconst html = toPortableHtml(container.innerHTML);\n\tconst text = container.textContent ?? '';\n\treturn { html, text, isEmpty: !text.trim(), characterCount: text.length };\n}\n\n/**\n * Parse an HTML string into ProseMirror nodes using the editor's schema.\n */\nfunction parseHtmlToNodes(editor: Editor, html: string) {\n\tconst container = document.createElement('div');\n\tcontainer.innerHTML = html;\n\treturn DOMParser.fromSchema(editor.schema).parse(container, {\n\t\tpreserveWhitespace: true,\n\t}).content;\n}\n\n/**\n * Replace the content of a single named section without touching others.\n * Uses a ProseMirror transaction to replace only the target range,\n * preserving undo history and other sections' state.\n * If the section doesn't exist yet, it is appended at the end of the document.\n */\nexport function setSectionContentInEditor(\n\teditor: Editor,\n\tid: string,\n\thtml: string,\n): void {\n\tconst startPos = findSectionStartPos(editor, id);\n\tif (startPos === -1) {\n\t\tconst endPos = editor.state.doc.content.size;\n\t\tconst dividerHtml = SECTION_DIVIDER_HTML(id) + html;\n\t\teditor.commands.insertContentAt(endPos, dividerHtml, {\n\t\t\tupdateSelection: false,\n\t\t});\n\t\treturn;\n\t}\n\tconst endPos = findSectionEndPos(editor, id);\n\tconst fragment = parseHtmlToNodes(editor, html);\n\tconst { tr } = editor.state;\n\t// For body, replace from position 0 (before the first paragraph's opening\n\t// boundary) so ProseMirror swaps entire block nodes cleanly. Position 1\n\t// (inside the paragraph) would force ProseMirror to close the open paragraph\n\t// first, creating a ghost empty <p></p>.\n\tconst replaceFrom = id === 'body' ? 0 : startPos;\n\ttr.replaceWith(replaceFrom, endPos, fragment);\n\ttr.setMeta('addToHistory', false);\n\teditor.view.dispatch(tr);\n}\n\n// ---------------------------------------------------------------------------\n// Convenience shorthands (body = first section)\n// ---------------------------------------------------------------------------\n\n/** Extract BikEditorContent for just the body (before the first divider). */\nexport function extractBodyContent(editor: Editor): EditorSnapshot {\n\treturn extractSectionContent(editor, 'body');\n}\n\n// ---------------------------------------------------------------------------\n// Active formats\n// ---------------------------------------------------------------------------\n\nexport function extractActiveFormats(editor: Editor): FormatState {\n\treturn {\n\t\tbold: editor.isActive('bold'),\n\t\titalic: editor.isActive('italic'),\n\t\tunderline: editor.isActive('underline'),\n\t\tstrike: editor.isActive('strike'),\n\t\tbulletList: editor.isActive('bulletList'),\n\t\torderedList: editor.isActive('orderedList'),\n\t\tblockquote: editor.isActive('blockquote'),\n\t\tcodeBlock: editor.isActive('codeBlock'),\n\t\tlink: (() => {\n\t\t\tif (editor.isActive('link')) {\n\t\t\t\treturn { href: editor.getAttributes('link')['href'] ?? '' };\n\t\t\t}\n\t\t\tconst { $from } = editor.state.selection;\n\t\t\tif ($from.pos > 0) {\n\t\t\t\tconst before = $from.doc.resolve($from.pos);\n\t\t\t\tconst linkMark = before.marks().find((m) => m.type.name === 'link');\n\t\t\t\tif (!linkMark) {\n\t\t\t\t\tconst nodeBefore = $from.nodeBefore;\n\t\t\t\t\tconst markOnPrev = nodeBefore?.marks.find(\n\t\t\t\t\t\t(m) => m.type.name === 'link',\n\t\t\t\t\t);\n\t\t\t\t\tif (markOnPrev) {\n\t\t\t\t\t\treturn { href: markOnPrev.attrs['href'] ?? '' };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn { href: linkMark.attrs['href'] ?? '' };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t})(),\n\t\ttextAlign: editor.isActive({ textAlign: 'center' })\n\t\t\t? 'center'\n\t\t\t: editor.isActive({ textAlign: 'right' })\n\t\t\t? 'right'\n\t\t\t: editor.isActive({ textAlign: 'justify' })\n\t\t\t? 'justify'\n\t\t\t: editor.isActive({ textAlign: 'left' })\n\t\t\t? 'left'\n\t\t\t: null,\n\t\tfontFamily: editor.getAttributes('textStyle')['fontFamily'] ?? null,\n\t\tfontSize: editor.getAttributes('textStyle')['fontSize'] ?? null,\n\t\tcolor: editor.getAttributes('textStyle')['color'] ?? null,\n\t\thighlight: editor.isActive('highlight')\n\t\t\t? editor.getAttributes('highlight')['color'] ?? 'default'\n\t\t\t: null,\n\t\tsuperscript: editor.isActive('superscript'),\n\t\tsubscript: editor.isActive('subscript'),\n\t};\n}\n\nexport function extractContent(editor: Editor): EditorSnapshot {\n\tconst html = toPortableHtml(editor.getHTML());\n\tconst normalized = normalizeHardBreaks(editor.state.doc.content);\n\tconst tempDoc = editor.schema.node('doc', null, normalized);\n\t// Paragraph boundary → blank line (\\n\\n), soft line break (hardBreak) → \\n.\n\t// Matches Gmail's plain-text output for the same content.\n\tconst text = tempDoc.textBetween(0, tempDoc.content.size, '\\n\\n', '\\n');\n\treturn {\n\t\thtml,\n\t\ttext,\n\t\tisEmpty: editor.isEmpty,\n\t\tcharacterCount: text.length,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Section position helpers (used by insertAtSectionStart/End and appendBodyContent)\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the ProseMirror position immediately after a section's opening divider\n * (i.e. the start of the section's own content).\n * For `'body'`, returns 1 (beginning of the document).\n * Returns -1 if the named section's divider is not found.\n */\nexport function findSectionStartPos(editor: Editor, sectionId: string): number {\n\tif (sectionId === 'body') return 1;\n\tlet startPos = -1;\n\teditor.state.doc.descendants((node, pos) => {\n\t\tif (startPos !== -1) return false;\n\t\tif (\n\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t) {\n\t\t\tstartPos = pos + node.nodeSize; // position right after the divider\n\t\t}\n\t});\n\treturn startPos;\n}\n\n/**\n * Returns the ProseMirror position at the end of a named section's content:\n * - For `'body'`: position of the first section divider, or end of document.\n * - For a named section: position of the next divider, or end of document.\n */\nexport function findSectionEndPos(editor: Editor, sectionId: string): number {\n\tconst doc = editor.state.doc;\n\tconst docSize = doc.content.size;\n\n\tif (sectionId === 'body') {\n\t\tlet firstDividerPos = -1;\n\t\tdoc.descendants((node, pos) => {\n\t\t\tif (firstDividerPos !== -1) return false;\n\t\t\tif (node.type.name === 'sectionDivider') {\n\t\t\t\tfirstDividerPos = pos;\n\t\t\t}\n\t\t});\n\t\treturn firstDividerPos !== -1 ? firstDividerPos : docSize;\n\t}\n\n\tlet passedSection = false;\n\tlet nextDividerPos = -1;\n\tdoc.descendants((node, pos) => {\n\t\tif (nextDividerPos !== -1) return false;\n\t\tif (!passedSection) {\n\t\t\tif (\n\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t) {\n\t\t\t\tpassedSection = true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tif (node.type.name === 'sectionDivider') {\n\t\t\tnextDividerPos = pos;\n\t\t}\n\t});\n\treturn nextDividerPos !== -1 ? nextDividerPos : docSize;\n}\n"],"names":["normalizeHtml","html","container","span","parent","p","toPortableHtml","div","walker","textNode","blocks","insertInlineHtml","editor","normalised","dom","slice","DOMParser","from","to","tr","SECTION_DIVIDER_HTML","id","buildSectionedContent","body","sections","s","getBodyHtml","extractAllSectionsFromHtml","getSectionsHtml","dividerRegex","dividers","match","i","start","end","extractSectionContent","startPos","findSectionStartPos","endPos","findSectionEndPos","serializer","DOMSerializer","text","parseHtmlToNodes","setSectionContentInEditor","dividerHtml","fragment","replaceFrom","extractBodyContent","extractActiveFormats","$from","linkMark","m","markOnPrev","extractContent","normalized","normalizeHardBreaks","tempDoc","sectionId","node","pos","doc","docSize","firstDividerPos","passedSection","nextDividerPos"],"mappings":"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"}
|
|
@@ -1,103 +1,107 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useMemo as
|
|
3
|
-
import { useTemplateModalContext as
|
|
4
|
-
import { isRichAndCarouselCards as
|
|
5
|
-
import { VariableEditorHelper as
|
|
6
|
-
import { HEADER_TYPES as
|
|
7
|
-
import { ChatBtn as
|
|
8
|
-
import { RCSButtons as
|
|
9
|
-
import { RCSMediaCard as
|
|
10
|
-
import {
|
|
11
|
-
const
|
|
1
|
+
import { jsxs as h, jsx as e, Fragment as n } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo as H } from "react";
|
|
3
|
+
import { useTemplateModalContext as B } from "../../template-context-mapper/context/templateModalContext.js";
|
|
4
|
+
import { isRichAndCarouselCards as v } from "../helpers/templateMiscHelper.js";
|
|
5
|
+
import { VariableEditorHelper as D } from "../helpers/VariableEditorHelper.js";
|
|
6
|
+
import { HEADER_TYPES as a } from "../models/TemplateMeta.js";
|
|
7
|
+
import { ChatBtn as V } from "../WhatsApp/ChatBtn.js";
|
|
8
|
+
import { RCSButtons as z } from "./RCSButtons.js";
|
|
9
|
+
import { RCSMediaCard as E, PdfMediaCard as U } from "./RCSMediaCard.js";
|
|
10
|
+
import { RCSPreviewContainer as j, HeaderTextContainer as G, TitleTextContainer as k, RcsHtmlContainer as F, RCSChatBtnContainer as W } from "./RCSPreview.styled.js";
|
|
11
|
+
const T = new D(), re = (M) => {
|
|
12
12
|
const {
|
|
13
|
-
bodyText:
|
|
13
|
+
bodyText: u,
|
|
14
14
|
titleText: m,
|
|
15
15
|
headerMediaType: t,
|
|
16
|
-
headerText:
|
|
17
|
-
headerAssetLink:
|
|
16
|
+
headerText: S,
|
|
17
|
+
headerAssetLink: i,
|
|
18
18
|
headerAssetName: p,
|
|
19
19
|
imagePreviewStyles: g,
|
|
20
|
-
size:
|
|
21
|
-
bodyVariableList:
|
|
22
|
-
headerVariableList:
|
|
23
|
-
buttons:
|
|
20
|
+
size: y,
|
|
21
|
+
bodyVariableList: w,
|
|
22
|
+
headerVariableList: N,
|
|
23
|
+
buttons: s,
|
|
24
24
|
carouselCardIndex: r,
|
|
25
|
-
isWhatsappCarousel:
|
|
26
|
-
isPreview:
|
|
27
|
-
titleVariableList:
|
|
25
|
+
isWhatsappCarousel: R,
|
|
26
|
+
isPreview: b,
|
|
27
|
+
titleVariableList: I,
|
|
28
28
|
templateConfiguration: o
|
|
29
|
-
} =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
), O =
|
|
29
|
+
} = M, L = T.format(
|
|
30
|
+
u?.replace(/</g, "<").replace(/>/g, ">"),
|
|
31
|
+
w
|
|
32
|
+
), P = T.format(
|
|
33
|
+
S?.replace(/</g, "<").replace(/>/g, ">"),
|
|
34
|
+
N
|
|
35
|
+
), O = T.format(
|
|
36
36
|
m?.replace(/</g, "<").replace(/>/g, ">"),
|
|
37
|
-
|
|
37
|
+
I
|
|
38
38
|
), {
|
|
39
|
-
selectedCarouselIndex:
|
|
39
|
+
selectedCarouselIndex: d,
|
|
40
40
|
isProductCarouselType: x,
|
|
41
|
-
errorIndexes:
|
|
42
|
-
isCarouselHovered:
|
|
43
|
-
} =
|
|
41
|
+
errorIndexes: A,
|
|
42
|
+
isCarouselHovered: _
|
|
43
|
+
} = B(), f = H(() => v(
|
|
44
44
|
o?.templateType
|
|
45
|
-
), [o?.templateType]),
|
|
46
|
-
S,
|
|
47
|
-
{
|
|
48
|
-
headerAssetLink: l,
|
|
49
|
-
headerAssetName: p,
|
|
50
|
-
mediaType: t,
|
|
51
|
-
imagePreviewStyles: t === i.IMAGE ? g : {}
|
|
52
|
-
}
|
|
53
|
-
) : null;
|
|
45
|
+
), [o?.templateType]), l = H(() => o?.orientation == "HORIZONTAL", [o]);
|
|
54
46
|
return /* @__PURE__ */ h(
|
|
55
|
-
|
|
47
|
+
j,
|
|
56
48
|
{
|
|
57
49
|
isCarouselCard: r != null && r > -1,
|
|
58
|
-
showBorder: r != null && r ===
|
|
59
|
-
hasError:
|
|
60
|
-
isWhatsappCarousel:
|
|
61
|
-
isPreview:
|
|
62
|
-
showDashedBorder: x &&
|
|
63
|
-
needBorder:
|
|
64
|
-
isHorizontalOrientation:
|
|
50
|
+
showBorder: r != null && r === d || x && r != null && r > -1 && d != null && d > -1,
|
|
51
|
+
hasError: A?.includes(r ?? -2),
|
|
52
|
+
isWhatsappCarousel: R,
|
|
53
|
+
isPreview: b,
|
|
54
|
+
showDashedBorder: x && _ && (d ?? -1) < 0 && (r ?? -1) > -1,
|
|
55
|
+
needBorder: f,
|
|
56
|
+
isHorizontalOrientation: l,
|
|
65
57
|
children: [
|
|
66
|
-
!
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
!l && /* @__PURE__ */ e(n, { children: t === a.TEXT ? /* @__PURE__ */ e(
|
|
59
|
+
G,
|
|
60
|
+
{
|
|
61
|
+
dangerouslySetInnerHTML: { __html: P }
|
|
62
|
+
}
|
|
63
|
+
) : t !== a.NONE && i && t !== a.DOCUMENT ? /* @__PURE__ */ e(
|
|
64
|
+
E,
|
|
65
|
+
{
|
|
66
|
+
headerAssetLink: i,
|
|
67
|
+
headerAssetName: p,
|
|
68
|
+
mediaType: t,
|
|
69
|
+
imagePreviewStyles: t === a.IMAGE ? g : {}
|
|
70
|
+
}
|
|
71
|
+
) : null }),
|
|
72
|
+
/* @__PURE__ */ h("div", { style: { width: l ? "50%" : "" }, children: [
|
|
73
|
+
/* @__PURE__ */ h("div", { className: f ? "" : "text--template", children: [
|
|
74
|
+
!!m && /* @__PURE__ */ e(n, { children: /* @__PURE__ */ e(
|
|
75
|
+
k,
|
|
71
76
|
{
|
|
72
77
|
dangerouslySetInnerHTML: {
|
|
73
78
|
__html: O
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
) }),
|
|
77
|
-
!!
|
|
78
|
-
|
|
82
|
+
!!u && /* @__PURE__ */ e(n, { children: /* @__PURE__ */ e(
|
|
83
|
+
F,
|
|
79
84
|
{
|
|
80
85
|
dangerouslySetInnerHTML: {
|
|
81
|
-
__html:
|
|
86
|
+
__html: L
|
|
82
87
|
},
|
|
83
88
|
style: { paddingTop: m ? 0 : 12 }
|
|
84
89
|
}
|
|
85
90
|
) }),
|
|
86
|
-
t ===
|
|
91
|
+
t === a.DOCUMENT ? /* @__PURE__ */ e(U, { headerAssetLink: i, headerAssetName: p }) : /* @__PURE__ */ e(n, {})
|
|
87
92
|
] }),
|
|
88
|
-
|
|
89
|
-
n && n.length > 0 ? E(
|
|
93
|
+
s && s.length > 0 ? v(
|
|
90
94
|
o?.templateType
|
|
91
|
-
) ? /* @__PURE__ */ e(
|
|
95
|
+
) ? /* @__PURE__ */ e(n, { children: s.map((c, C) => /* @__PURE__ */ e(V, { text: c.text, size: y }, C)) }) : /* @__PURE__ */ e(W, { children: s.map((c, C) => /* @__PURE__ */ e(z, { text: c.text, size: y }, C)) }) : null
|
|
92
96
|
] }),
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
l && t !== a.NONE && i && t !== a.DOCUMENT && /* @__PURE__ */ e(
|
|
98
|
+
E,
|
|
95
99
|
{
|
|
96
|
-
headerAssetLink:
|
|
100
|
+
headerAssetLink: i,
|
|
97
101
|
headerAssetName: p,
|
|
98
102
|
mediaType: t,
|
|
99
|
-
imagePreviewStyles: t ===
|
|
100
|
-
isHorizontal:
|
|
103
|
+
imagePreviewStyles: t === a.IMAGE ? g : {},
|
|
104
|
+
isHorizontal: l
|
|
101
105
|
}
|
|
102
106
|
)
|
|
103
107
|
]
|
|
@@ -105,6 +109,6 @@ const u = new z(), ie = (w) => {
|
|
|
105
109
|
);
|
|
106
110
|
};
|
|
107
111
|
export {
|
|
108
|
-
|
|
112
|
+
re as RCSChatPreview
|
|
109
113
|
};
|
|
110
114
|
//# sourceMappingURL=RCSChatPreview.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RCSChatPreview.js","sources":["../../../../../src/components/template-preview/RCS/RCSChatPreview.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useTemplateModalContext } from '@src/components/template-context-mapper/context/templateModalContext';\nimport { isRichAndCarouselCards } from '../helpers/templateMiscHelper';\nimport { VariableEditorHelper } from '../helpers/VariableEditorHelper';\nimport { RCS_TEMPLATE_TYPE, RCSPreviewPropsV2 } from '../models/RCSTemplate';\nimport { HEADER_TYPES } from '../models/TemplateMeta';\nimport { ChatBtn } from '../WhatsApp/ChatBtn';\nimport { RCSButtons } from './RCSButtons';\nimport { PdfMediaCard, RCSMediaCard } from './RCSMediaCard';\nimport {\n\tHeaderTextContainer,\n\tRCSChatBtnContainer,\n\tRcsHtmlContainer,\n\tRCSPreviewContainer,\n\tTitleTextContainer,\n} from './RCSPreview.styled';\n\nconst variableEditorHelper = new VariableEditorHelper();\n\nexport const RCSChatPreview = (props: RCSPreviewPropsV2) => {\n\tconst {\n\t\tbodyText,\n\t\ttitleText,\n\t\theaderMediaType,\n\t\theaderText,\n\t\theaderAssetLink,\n\t\theaderAssetName,\n\t\timagePreviewStyles,\n\t\tsize,\n\t\tbodyVariableList,\n\t\theaderVariableList,\n\t\tbuttons,\n\t\tcarouselCardIndex,\n\t\tisWhatsappCarousel,\n\t\tisPreview,\n\t\ttitleVariableList,\n\t\ttemplateConfiguration,\n\t} = props;\n\n\tconst bodyHTML = variableEditorHelper.format(\n\t\tbodyText?.replace(/</g, '<').replace(/>/g, '>'),\n\t\tbodyVariableList,\n\t);\n\tconst headerHtml = variableEditorHelper.format(\n\t\theaderText?.replace(/</g, '<').replace(/>/g, '>'),\n\t\theaderVariableList,\n\t);\n\tconst titleHtml = variableEditorHelper.format(\n\t\ttitleText?.replace(/</g, '<').replace(/>/g, '>'),\n\t\ttitleVariableList,\n\t);\n\tconst {\n\t\tselectedCarouselIndex,\n\t\tisProductCarouselType,\n\t\terrorIndexes,\n\t\tisCarouselHovered,\n\t} = useTemplateModalContext();\n\n\tconst isRichCardTypeTemplate = useMemo(() => {\n\t\treturn isRichAndCarouselCards(\n\t\t\ttemplateConfiguration?.templateType as RCS_TEMPLATE_TYPE,\n\t\t);\n\t}, [templateConfiguration?.templateType]);\n\n\tconst isHorizontalOrientation = useMemo(() => {\n\t\treturn templateConfiguration?.orientation == 'HORIZONTAL';\n\t}, [templateConfiguration]);\n\n\t// For VERTICAL templates whose original `components[]` order is\n\t// body-then-media, render the media after the body instead of the default\n\t// media-first layout. Defaults to false → unchanged behaviour.\n\tconst isMediaAfterBody = useMemo(() => {\n\t\treturn (\n\t\t\t!isHorizontalOrientation && !!templateConfiguration?.isMediaAfterBody\n\t\t);\n\t}, [isHorizontalOrientation, templateConfiguration]);\n\n\tconst verticalMediaHeader =\n\t\theaderMediaType === HEADER_TYPES.TEXT ? (\n\t\t\t<HeaderTextContainer dangerouslySetInnerHTML={{ __html: headerHtml }} />\n\t\t) : headerMediaType !== HEADER_TYPES.NONE &&\n\t\t headerAssetLink &&\n\t\t headerMediaType !== HEADER_TYPES.DOCUMENT ? (\n\t\t\t<RCSMediaCard\n\t\t\t\theaderAssetLink={headerAssetLink}\n\t\t\t\theaderAssetName={headerAssetName}\n\t\t\t\tmediaType={headerMediaType}\n\t\t\t\timagePreviewStyles={\n\t\t\t\t\theaderMediaType === HEADER_TYPES.IMAGE ? imagePreviewStyles : {}\n\t\t\t\t}\n\t\t\t/>\n\t\t) : null;\n\n\treturn (\n\t\t<RCSPreviewContainer\n\t\t\tisCarouselCard={carouselCardIndex != undefined && carouselCardIndex > -1}\n\t\t\tshowBorder={\n\t\t\t\t(carouselCardIndex != undefined &&\n\t\t\t\t\tcarouselCardIndex === selectedCarouselIndex) ||\n\t\t\t\t(isProductCarouselType &&\n\t\t\t\t\tcarouselCardIndex != undefined &&\n\t\t\t\t\tcarouselCardIndex > -1 &&\n\t\t\t\t\tselectedCarouselIndex != undefined &&\n\t\t\t\t\tselectedCarouselIndex > -1)\n\t\t\t}\n\t\t\thasError={errorIndexes?.includes(carouselCardIndex ?? -2)}\n\t\t\tisWhatsappCarousel={isWhatsappCarousel}\n\t\t\tisPreview={isPreview}\n\t\t\tshowDashedBorder={\n\t\t\t\tisProductCarouselType &&\n\t\t\t\tisCarouselHovered &&\n\t\t\t\t(selectedCarouselIndex ?? -1) < 0 &&\n\t\t\t\t(carouselCardIndex ?? -1) > -1\n\t\t\t}\n\t\t\tneedBorder={isRichCardTypeTemplate}\n\t\t\tisHorizontalOrientation={isHorizontalOrientation}\n\t\t>\n\t\t\t{!isHorizontalOrientation && !isMediaAfterBody && verticalMediaHeader}\n\t\t\t<div style={{ width: isHorizontalOrientation ? '50%' : '' }}>\n\t\t\t\t<div className={isRichCardTypeTemplate ? '' : 'text--template'}>\n\t\t\t\t\t{!!titleText && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<TitleTextContainer\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t__html: titleHtml,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{!!bodyText && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<RcsHtmlContainer\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t__html: bodyHTML,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tstyle={{ paddingTop: titleText ? 0 : 12 }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t\t{headerMediaType === HEADER_TYPES.DOCUMENT ? (\n\t\t\t\t\t\t<PdfMediaCard {...{ headerAssetLink, headerAssetName }} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<></>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t{!isHorizontalOrientation && isMediaAfterBody && verticalMediaHeader}\n\n\t\t\t\t{buttons && buttons.length > 0 ? (\n\t\t\t\t\tisRichAndCarouselCards(\n\t\t\t\t\t\ttemplateConfiguration?.templateType as RCS_TEMPLATE_TYPE,\n\t\t\t\t\t) ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{buttons.map((button, i) => (\n\t\t\t\t\t\t\t\t<ChatBtn key={i} text={button.text} size={size} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<RCSChatBtnContainer>\n\t\t\t\t\t\t\t{buttons.map((button, i) => (\n\t\t\t\t\t\t\t\t<RCSButtons key={i} text={button.text} size={size} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</RCSChatBtnContainer>\n\t\t\t\t\t)\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{isHorizontalOrientation &&\n\t\t\t\theaderMediaType !== HEADER_TYPES.NONE &&\n\t\t\t\theaderAssetLink &&\n\t\t\t\theaderMediaType !== HEADER_TYPES.DOCUMENT && (\n\t\t\t\t\t<RCSMediaCard\n\t\t\t\t\t\theaderAssetLink={headerAssetLink}\n\t\t\t\t\t\theaderAssetName={headerAssetName}\n\t\t\t\t\t\tmediaType={headerMediaType}\n\t\t\t\t\t\timagePreviewStyles={\n\t\t\t\t\t\t\theaderMediaType === HEADER_TYPES.IMAGE ? imagePreviewStyles : {}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tisHorizontal={isHorizontalOrientation}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t</RCSPreviewContainer>\n\t);\n};\n"],"names":["variableEditorHelper","VariableEditorHelper","RCSChatPreview","props","bodyText","titleText","headerMediaType","headerText","headerAssetLink","headerAssetName","imagePreviewStyles","size","bodyVariableList","headerVariableList","buttons","carouselCardIndex","isWhatsappCarousel","isPreview","titleVariableList","templateConfiguration","bodyHTML","headerHtml","titleHtml","selectedCarouselIndex","isProductCarouselType","errorIndexes","isCarouselHovered","useTemplateModalContext","isRichCardTypeTemplate","useMemo","isRichAndCarouselCards","isHorizontalOrientation","isMediaAfterBody","verticalMediaHeader","HEADER_TYPES","jsx","HeaderTextContainer","RCSMediaCard","jsxs","RCSPreviewContainer","Fragment","TitleTextContainer","RcsHtmlContainer","PdfMediaCard","button","i","ChatBtn","RCSChatBtnContainer","RCSButtons"],"mappings":";;;;;;;;;;AAiBA,MAAMA,IAAuB,IAAIC,EAAA,GAEpBC,KAAiB,CAACC,MAA6B;AAC3D,QAAM;AAAA,IACL,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,YAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,MAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,SAAAC;AAAA,IACA,mBAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,WAAAC;AAAA,IACA,mBAAAC;AAAA,IACA,uBAAAC;AAAA,EAAA,IACGhB,GAEEiB,IAAWpB,EAAqB;AAAA,IACrCI,GAAU,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM;AAAA,IACpDQ;AAAA,EAAA,GAEKS,IAAarB,EAAqB;AAAA,IACvCO,GAAY,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM;AAAA,IACtDM;AAAA,EAAA,GAEKS,IAAYtB,EAAqB;AAAA,IACtCK,GAAW,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM;AAAA,IACrDa;AAAA,EAAA,GAEK;AAAA,IACL,uBAAAK;AAAA,IACA,uBAAAC;AAAA,IACA,cAAAC;AAAA,IACA,mBAAAC;AAAA,EAAA,IACGC,EAAA,GAEEC,IAAyBC,EAAQ,MAC/BC;AAAA,IACNX,GAAuB;AAAA,EAAA,GAEtB,CAACA,GAAuB,YAAY,CAAC,GAElCY,IAA0BF,EAAQ,MAChCV,GAAuB,eAAe,cAC3C,CAACA,CAAqB,CAAC,GAKpBa,IAAmBH,EAAQ,MAE/B,CAACE,KAA2B,CAAC,CAACZ,GAAuB,kBAEpD,CAACY,GAAyBZ,CAAqB,CAAC,GAE7Cc,IACL3B,MAAoB4B,EAAa,OAChC,gBAAAC,EAACC,GAAA,EAAoB,yBAAyB,EAAE,QAAQf,EAAA,GAAc,IACnEf,MAAoB4B,EAAa,QACnC1B,KACAF,MAAoB4B,EAAa,WAClC,gBAAAC;AAAA,IAACE;AAAA,IAAA;AAAA,MACA,iBAAA7B;AAAA,MACA,iBAAAC;AAAA,MACA,WAAWH;AAAA,MACX,oBACCA,MAAoB4B,EAAa,QAAQxB,IAAqB,CAAA;AAAA,IAAC;AAAA,EAAA,IAG9D;AAEL,SACC,gBAAA4B;AAAA,IAACC;AAAA,IAAA;AAAA,MACA,gBAAgBxB,KAAqB,QAAaA,IAAoB;AAAA,MACtE,YACEA,KAAqB,QACrBA,MAAsBQ,KACtBC,KACAT,KAAqB,QACrBA,IAAoB,MACpBQ,KAAyB,QACzBA,IAAwB;AAAA,MAE1B,UAAUE,GAAc,SAASV,KAAqB,EAAE;AAAA,MACxD,oBAAAC;AAAA,MACA,WAAAC;AAAA,MACA,kBACCO,KACAE,MACCH,KAAyB,MAAM,MAC/BR,KAAqB,MAAM;AAAA,MAE7B,YAAYa;AAAA,MACZ,yBAAAG;AAAA,MAEC,UAAA;AAAA,QAAA,CAACA,KAA2B,CAACC,KAAoBC;AAAA,QAClD,gBAAAK,EAAC,SAAI,OAAO,EAAE,OAAOP,IAA0B,QAAQ,MACtD,UAAA;AAAA,UAAA,gBAAAO,EAAC,OAAA,EAAI,WAAWV,IAAyB,KAAK,kBAC5C,UAAA;AAAA,YAAA,CAAC,CAACvB,KACF,gBAAA8B,EAAAK,GAAA,EACC,UAAA,gBAAAL;AAAA,cAACM;AAAA,cAAA;AAAA,gBACA,yBAAyB;AAAA,kBACxB,QAAQnB;AAAA,gBAAA;AAAA,cACT;AAAA,YAAA,GAEF;AAAA,YAGA,CAAC,CAAClB,KACF,gBAAA+B,EAAAK,GAAA,EACC,UAAA,gBAAAL;AAAA,cAACO;AAAA,cAAA;AAAA,gBACA,yBAAyB;AAAA,kBACxB,QAAQtB;AAAA,gBAAA;AAAA,gBAET,OAAO,EAAE,YAAYf,IAAY,IAAI,GAAA;AAAA,cAAG;AAAA,YAAA,GAE1C;AAAA,YAEAC,MAAoB4B,EAAa,WACjC,gBAAAC,EAACQ,GAAA,EAAmB,iBAAAnC,GAAiB,iBAAAC,EAAgB,CAAG,IAExD,gBAAA0B,EAAAK,GAAA,CAAA,CAAE;AAAA,UAAA,GAEJ;AAAA,UAEC,CAACT,KAA2BC,KAAoBC;AAAA,UAEhDnB,KAAWA,EAAQ,SAAS,IAC5BgB;AAAA,YACCX,GAAuB;AAAA,UAAA,IAEvB,gBAAAgB,EAAAK,GAAA,EACE,UAAA1B,EAAQ,IAAI,CAAC8B,GAAQC,MACrB,gBAAAV,EAACW,GAAA,EAAgB,MAAMF,EAAO,MAAM,MAAAjC,EAAA,GAAtBkC,CAAkC,CAChD,EAAA,CACF,IAEA,gBAAAV,EAACY,GAAA,EACC,UAAAjC,EAAQ,IAAI,CAAC8B,GAAQC,MACrB,gBAAAV,EAACa,GAAA,EAAmB,MAAMJ,EAAO,MAAM,MAAAjC,EAAA,GAAtBkC,CAAkC,CACnD,GACF,IAEE;AAAA,QAAA,GACL;AAAA,QACCd,KACAzB,MAAoB4B,EAAa,QACjC1B,KACAF,MAAoB4B,EAAa,YAChC,gBAAAC;AAAA,UAACE;AAAA,UAAA;AAAA,YACA,iBAAA7B;AAAA,YACA,iBAAAC;AAAA,YACA,WAAWH;AAAA,YACX,oBACCA,MAAoB4B,EAAa,QAAQxB,IAAqB,CAAA;AAAA,YAE/D,cAAcqB;AAAA,UAAA;AAAA,QAAA;AAAA,MACf;AAAA,IAAA;AAAA,EAAA;AAIL;"}
|
|
1
|
+
{"version":3,"file":"RCSChatPreview.js","sources":["../../../../../src/components/template-preview/RCS/RCSChatPreview.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useTemplateModalContext } from '@src/components/template-context-mapper/context/templateModalContext';\nimport { isRichAndCarouselCards } from '../helpers/templateMiscHelper';\nimport { VariableEditorHelper } from '../helpers/VariableEditorHelper';\nimport { RCS_TEMPLATE_TYPE, RCSPreviewPropsV2 } from '../models/RCSTemplate';\nimport { HEADER_TYPES } from '../models/TemplateMeta';\nimport { ChatBtn } from '../WhatsApp/ChatBtn';\nimport { RCSButtons } from './RCSButtons';\nimport { PdfMediaCard, RCSMediaCard } from './RCSMediaCard';\nimport {\n\tHeaderTextContainer,\n\tRCSChatBtnContainer,\n\tRcsHtmlContainer,\n\tRCSPreviewContainer,\n\tTitleTextContainer,\n} from './RCSPreview.styled';\n\nconst variableEditorHelper = new VariableEditorHelper();\n\nexport const RCSChatPreview = (props: RCSPreviewPropsV2) => {\n\tconst {\n\t\tbodyText,\n\t\ttitleText,\n\t\theaderMediaType,\n\t\theaderText,\n\t\theaderAssetLink,\n\t\theaderAssetName,\n\t\timagePreviewStyles,\n\t\tsize,\n\t\tbodyVariableList,\n\t\theaderVariableList,\n\t\tbuttons,\n\t\tcarouselCardIndex,\n\t\tisWhatsappCarousel,\n\t\tisPreview,\n\t\ttitleVariableList,\n\t\ttemplateConfiguration,\n\t} = props;\n\n\tconst bodyHTML = variableEditorHelper.format(\n\t\tbodyText?.replace(/</g, '<').replace(/>/g, '>'),\n\t\tbodyVariableList,\n\t);\n\tconst headerHtml = variableEditorHelper.format(\n\t\theaderText?.replace(/</g, '<').replace(/>/g, '>'),\n\t\theaderVariableList,\n\t);\n\tconst titleHtml = variableEditorHelper.format(\n\t\ttitleText?.replace(/</g, '<').replace(/>/g, '>'),\n\t\ttitleVariableList,\n\t);\n\tconst {\n\t\tselectedCarouselIndex,\n\t\tisProductCarouselType,\n\t\terrorIndexes,\n\t\tisCarouselHovered,\n\t} = useTemplateModalContext();\n\n\tconst isRichCardTypeTemplate = useMemo(() => {\n\t\treturn isRichAndCarouselCards(\n\t\t\ttemplateConfiguration?.templateType as RCS_TEMPLATE_TYPE,\n\t\t);\n\t}, [templateConfiguration?.templateType]);\n\n\tconst isHorizontalOrientation = useMemo(() => {\n\t\treturn templateConfiguration?.orientation == 'HORIZONTAL';\n\t}, [templateConfiguration]);\n\n\treturn (\n\t\t<RCSPreviewContainer\n\t\t\tisCarouselCard={carouselCardIndex != undefined && carouselCardIndex > -1}\n\t\t\tshowBorder={\n\t\t\t\t(carouselCardIndex != undefined &&\n\t\t\t\t\tcarouselCardIndex === selectedCarouselIndex) ||\n\t\t\t\t(isProductCarouselType &&\n\t\t\t\t\tcarouselCardIndex != undefined &&\n\t\t\t\t\tcarouselCardIndex > -1 &&\n\t\t\t\t\tselectedCarouselIndex != undefined &&\n\t\t\t\t\tselectedCarouselIndex > -1)\n\t\t\t}\n\t\t\thasError={errorIndexes?.includes(carouselCardIndex ?? -2)}\n\t\t\tisWhatsappCarousel={isWhatsappCarousel}\n\t\t\tisPreview={isPreview}\n\t\t\tshowDashedBorder={\n\t\t\t\tisProductCarouselType &&\n\t\t\t\tisCarouselHovered &&\n\t\t\t\t(selectedCarouselIndex ?? -1) < 0 &&\n\t\t\t\t(carouselCardIndex ?? -1) > -1\n\t\t\t}\n\t\t\tneedBorder={isRichCardTypeTemplate}\n\t\t\tisHorizontalOrientation={isHorizontalOrientation}\n\t\t>\n\t\t\t{!isHorizontalOrientation && (\n\t\t\t\t<>\n\t\t\t\t\t{headerMediaType === HEADER_TYPES.TEXT ? (\n\t\t\t\t\t\t<HeaderTextContainer\n\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: headerHtml }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : headerMediaType !== HEADER_TYPES.NONE &&\n\t\t\t\t\t headerAssetLink &&\n\t\t\t\t\t headerMediaType !== HEADER_TYPES.DOCUMENT ? (\n\t\t\t\t\t\t<RCSMediaCard\n\t\t\t\t\t\t\theaderAssetLink={headerAssetLink}\n\t\t\t\t\t\t\theaderAssetName={headerAssetName}\n\t\t\t\t\t\t\tmediaType={headerMediaType}\n\t\t\t\t\t\t\timagePreviewStyles={\n\t\t\t\t\t\t\t\theaderMediaType === HEADER_TYPES.IMAGE ? imagePreviewStyles : {}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t)}\n\t\t\t<div style={{ width: isHorizontalOrientation ? '50%' : '' }}>\n\t\t\t\t<div className={isRichCardTypeTemplate ? '' : 'text--template'}>\n\t\t\t\t\t{!!titleText && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<TitleTextContainer\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t__html: titleHtml,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{!!bodyText && (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<RcsHtmlContainer\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t__html: bodyHTML,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tstyle={{ paddingTop: titleText ? 0 : 12 }}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t\t{headerMediaType === HEADER_TYPES.DOCUMENT ? (\n\t\t\t\t\t\t<PdfMediaCard {...{ headerAssetLink, headerAssetName }} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<></>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t{buttons && buttons.length > 0 ? (\n\t\t\t\t\tisRichAndCarouselCards(\n\t\t\t\t\t\ttemplateConfiguration?.templateType as RCS_TEMPLATE_TYPE,\n\t\t\t\t\t) ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{buttons.map((button, i) => (\n\t\t\t\t\t\t\t\t<ChatBtn key={i} text={button.text} size={size} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<RCSChatBtnContainer>\n\t\t\t\t\t\t\t{buttons.map((button, i) => (\n\t\t\t\t\t\t\t\t<RCSButtons key={i} text={button.text} size={size} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</RCSChatBtnContainer>\n\t\t\t\t\t)\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{isHorizontalOrientation &&\n\t\t\t\theaderMediaType !== HEADER_TYPES.NONE &&\n\t\t\t\theaderAssetLink &&\n\t\t\t\theaderMediaType !== HEADER_TYPES.DOCUMENT && (\n\t\t\t\t\t<RCSMediaCard\n\t\t\t\t\t\theaderAssetLink={headerAssetLink}\n\t\t\t\t\t\theaderAssetName={headerAssetName}\n\t\t\t\t\t\tmediaType={headerMediaType}\n\t\t\t\t\t\timagePreviewStyles={\n\t\t\t\t\t\t\theaderMediaType === HEADER_TYPES.IMAGE ? imagePreviewStyles : {}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tisHorizontal={isHorizontalOrientation}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t</RCSPreviewContainer>\n\t);\n};\n"],"names":["variableEditorHelper","VariableEditorHelper","RCSChatPreview","props","bodyText","titleText","headerMediaType","headerText","headerAssetLink","headerAssetName","imagePreviewStyles","size","bodyVariableList","headerVariableList","buttons","carouselCardIndex","isWhatsappCarousel","isPreview","titleVariableList","templateConfiguration","bodyHTML","headerHtml","titleHtml","selectedCarouselIndex","isProductCarouselType","errorIndexes","isCarouselHovered","useTemplateModalContext","isRichCardTypeTemplate","useMemo","isRichAndCarouselCards","isHorizontalOrientation","jsxs","RCSPreviewContainer","jsx","Fragment","HEADER_TYPES","HeaderTextContainer","RCSMediaCard","TitleTextContainer","RcsHtmlContainer","PdfMediaCard","button","i","ChatBtn","RCSChatBtnContainer","RCSButtons"],"mappings":"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"}
|
|
@@ -30,12 +30,4 @@ export declare class TemplateCreatorHelper {
|
|
|
30
30
|
pod?: string;
|
|
31
31
|
}): Promise<CreateTemplateType>;
|
|
32
32
|
parseTemplateConfiguration(template: RCSTemplateType): RCSTemplateConfig;
|
|
33
|
-
/**
|
|
34
|
-
* Determines, from the original `components[]` order, whether a non-TEXT
|
|
35
|
-
* media header appears AFTER the body component. The library preview
|
|
36
|
-
* otherwise always renders the media first; honouring this keeps
|
|
37
|
-
* body-then-media templates (the third-party ordering for some
|
|
38
|
-
* `text_message_with_media` templates) correct in the preview.
|
|
39
|
-
*/
|
|
40
|
-
isRcsMediaAfterBody(template: RCSTemplateType): boolean;
|
|
41
33
|
}
|