@bikdotai/bik-component-library 0.0.811-beta.1 → 0.0.811-beta.3

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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react/jsx-runtime"),e=require("../node_modules/@tiptap/core/dist/index.js"),n=require("@tiptap/react"),o=require("react"),i=require("./BikEditor.styles.js"),r=require("./BikEditor.types.js"),l=require("./BikEditor.utils.js"),s=require("./extensions/buildExtensions.js"),c=require("./floating/LinkBubbleMenu.js");function a(t){return Object.entries(t).map((t=>{let[e,n]=t;return`${e.replace(/([A-Z])/g,(t=>`-${t.toLowerCase()}`))}:${n}`})).join(";")}const u=(u,d)=>{var m,g,v,h,f,C,p;const{initialContent:S,sections:x,features:k,disabled:y,maxCharacters:H,shortcuts:B,sendShortcut:b,mentions:z,slashCommands:A,link:E,onPaste:I,onReady:R,onChange:j,onSend:L,onFocus:T,onBlur:F,onSelectionChange:M,minHeight:O,maxHeight:q,style:P,className:w,editorClassName:D,editorStyle:U}=u,N=(null==x?void 0:x.length)?l.buildSectionedContent(l.normalizeHtml(null!=S?S:""),x.map((t=>Object.assign(Object.assign({},t),{content:l.normalizeHtml(t.content)})))):l.normalizeHtml(null!=S?S:""),_=o.useRef([]),$=o.useRef(!1),J=o.useRef(R);J.current=R;const V=o.useRef(j);V.current=j;const W=o.useRef(M);W.current=M;const Z=o.useRef(T);Z.current=T;const G=o.useRef(F);G.current=F;const K=o.useRef(L);K.current=L;const Q=o.useRef(null!==(m=null==z?void 0:z.agents)&&void 0!==m?m:[]);Q.current=null!==(g=null==z?void 0:z.agents)&&void 0!==g?g:[];const X=o.useRef(null!==(v=null==z?void 0:z.teams)&&void 0!==v?v:[]);X.current=null!==(h=null==z?void 0:z.teams)&&void 0!==h?h:[];const Y=o.useRef(null!==(f=null==A?void 0:A.items)&&void 0!==f?f:[]);Y.current=null!==(C=null==A?void 0:A.items)&&void 0!==C?C:[];const tt=n.useEditor({extensions:s.buildExtensions({features:k,placeholder:u.placeholder,maxCharacters:H,hasSections:(null!==(p=null==x?void 0:x.length)&&void 0!==p?p:0)>0,mentions:{agents:z?Q:void 0,teams:z?X:void 0},slashCommands:A?Y:void 0,onPaste:I,onSend:L?t=>{var e;return null===(e=K.current)||void 0===e?void 0:e.call(K,t)}:void 0,sendShortcut:b,shortcuts:B,onMentionSelected:null==z?void 0:z.onSelect,onSlashCommandSelected:null==A?void 0:A.onSelect,renderMentionItem:null==z?void 0:z.renderItem,renderMentionDropdown:null==z?void 0:z.renderDropdown,renderSlashCommandItem:null==A?void 0:A.renderItem,renderSlashCommandDropdown:null==A?void 0:A.renderDropdown}),content:N,editable:!y,immediatelyRender:!1,editorProps:{attributes:Object.assign(Object.assign({},D?{class:D}:{}),U?{style:a(U)}:{})},onUpdate:t=>{let{editor:e}=t;var n;null===(n=V.current)||void 0===n||n.call(V,l.extractContent(e))},onTransaction:t=>{let{editor:e}=t;var n;null===(n=W.current)||void 0===n||n.call(W,l.extractActiveFormats(e))},onFocus:()=>{var t;return null===(t=Z.current)||void 0===t?void 0:t.call(Z)},onBlur:()=>{var t;return null===(t=G.current)||void 0===t?void 0:t.call(G)}});function et(t){tt?t(tt):_.current.push(t)}return o.useEffect((()=>{var t;if(tt){if(_.current.length>0){_.current.splice(0).forEach((t=>t(tt)))}$.current||($.current=!0,null===(t=J.current)||void 0===t||t.call(J))}}),[tt]),o.useImperativeHandle(d,(()=>({focus:t=>et((e=>e.commands.focus(t))),blur:()=>et((t=>t.commands.blur())),clearContent:()=>et((t=>t.commands.clearContent(!0))),setContent:t=>{const e=l.normalizeHtml(t);et((t=>t.commands.setContent(e,{emitUpdate:!0})))},insertContent:t=>{const e=l.normalizeHtml(t);et((t=>t.commands.insertContent(e)))},insertInlineContent:t=>{et((e=>l.insertInlineHtml(e,t)))},insertAtStart:t=>{const e=l.normalizeHtml(t);et((t=>t.commands.insertContentAt(1,e)))},insertBlock:t=>{const e=l.normalizeHtml(t);et((t=>t.commands.insertContentAt(t.state.doc.content.size,e)))},appendInline:t=>{const e=l.normalizeHtml(t);et((t=>t.commands.insertContentAt(t.state.doc.content.size-1,e)))},insertAtEnd(t){this.insertBlock(t)},appendContent(t){this.appendInline(t)},getContent:()=>tt?l.extractContent(tt):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>{var t;return null!==(t=null==tt?void 0:tt.getJSON())&&void 0!==t?t:null},getMentions:()=>{const t=new Set,e=new Set;return tt?(tt.state.doc.descendants((n=>{"mentionAgent"===n.type.name&&null!=n.attrs.id?t.add(String(n.attrs.id)):"mentionTeam"===n.type.name&&null!=n.attrs.id&&e.add(String(n.attrs.id))})),{agentIds:Array.from(t),teamIds:Array.from(e)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!tt)return{from:0,to:0};const{from:t,to:e}=tt.state.selection;return{from:t,to:e}},insertAtPosition:(t,e)=>{const n=l.normalizeHtml(e);et((e=>e.commands.insertContentAt(t,n)))},getSelectedText:()=>{if(!tt)return"";const{state:t}=tt,{from:n,to:o,empty:i}=t.selection;if(!i)return t.doc.textBetween(n,o," ");const r=t.schema.marks.link;if(r){const o=e.getMarkRange(t.doc.resolve(n),r);if(o)return t.doc.textBetween(o.from,o.to," ")}return""},getCharacterCount:()=>{var t,e,n,o;return{count:null!==(o=null!==(n=null===(e=null===(t=null==tt?void 0:tt.storage.characterCount)||void 0===t?void 0:t.characters)||void 0===e?void 0:e.call(t))&&void 0!==n?n:null==tt?void 0:tt.getText().length)&&void 0!==o?o:0,limit:null!=H?H:null}},getSectionContent:t=>tt?l.extractSectionContent(tt,t):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(t,e)=>{const n=l.normalizeHtml(e);et((e=>l.setSectionContentInEditor(e,t,n)))},focusSection:t=>{et((e=>{if("body"===t){let t=e.state.doc.content.size-1;return e.state.doc.descendants(((n,o)=>("sectionDivider"===n.type.name&&t===e.state.doc.content.size-1&&(t=o-1),t===e.state.doc.content.size-1))),t<1&&(t=1),void e.chain().focus().setTextSelection(t).run()}let n=-1;e.state.doc.descendants(((e,o)=>{if(-1!==n)return!1;"sectionDivider"===e.type.name&&e.attrs.sectionId===t&&(n=o+e.nodeSize+1)})),-1!==n&&e.chain().focus().setTextSelection(n).run()}))},clearSection:t=>{et((e=>l.setSectionContentInEditor(e,t,"<p></p>")))},getBodyContent:()=>tt?l.extractBodyContent(tt):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:t=>{const e=l.normalizeHtml(t);et((t=>l.setSectionContentInEditor(t,"body",e)))},setBodyAndSections:(t,e)=>{const n=l.buildSectionedContent(l.normalizeHtml(t),e.map((t=>({id:t.id,content:l.normalizeHtml(t.content)}))));et((t=>t.commands.setContent(n,{emitUpdate:!0})))},appendBodyContent:t=>{const e=l.normalizeHtml(t);et((t=>{const n=l.findSectionEndPos(t,"body");t.commands.insertContentAt(n-1,e)}))},insertAtSectionStart:(t,e)=>{const n=l.normalizeHtml(e);et((e=>{const o=l.findSectionStartPos(e,t);-1!==o&&e.commands.insertContentAt(o,n)}))},insertAtSectionEnd:(t,e)=>{const n=l.normalizeHtml(e);et((e=>{const o=l.findSectionEndPos(e,t);e.commands.insertContentAt(o,n)}))},getActiveFormats:()=>tt?l.extractActiveFormats(tt):r.DEFAULT_FORMAT_STATE,actions:{toggleBold:()=>null==tt?void 0:tt.chain().focus().toggleBold().run(),toggleItalic:()=>null==tt?void 0:tt.chain().focus().toggleItalic().run(),toggleUnderline:()=>null==tt?void 0:tt.chain().focus().toggleUnderline().run(),toggleStrike:()=>null==tt?void 0:tt.chain().focus().toggleStrike().run(),toggleBulletList:()=>null==tt?void 0:tt.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>null==tt?void 0:tt.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>null==tt?void 0:tt.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>null==tt?void 0:tt.chain().focus().toggleCodeBlock().run(),setTextAlign:t=>null==tt?void 0:tt.chain().focus().setTextAlign(t).run(),setFontFamily:t=>null==tt?void 0:tt.chain().focus().setFontFamily(t).run(),setFontSize:t=>null==tt?void 0:tt.chain().focus().setFontSize(t).run(),setColor:t=>null==tt?void 0:tt.chain().focus().setColor(t).run(),setHighlight:t=>null==tt?void 0:tt.chain().focus().toggleHighlight({color:t}).run(),unsetColor:()=>null==tt?void 0:tt.chain().focus().unsetColor().run(),unsetHighlight:()=>null==tt?void 0:tt.chain().focus().unsetHighlight().run(),setLink:(t,e)=>{tt&&(void 0!==e?tt.chain().focus().extendMarkRange("link").command((n=>{let{tr:o,state:i}=n;const{from:r,to:l}=o.selection,s=i.schema.marks.link;if(!s)return!1;const c=i.schema.text(e,[s.create({href:t})]),a=i.schema.text(" ");return o.replaceWith(r,l,[c,a]),!0})).run():tt.chain().focus().extendMarkRange("link").setLink({href:t}).insertContent(" ").run())},updateLink:t=>null==tt?void 0:tt.chain().focus().extendMarkRange("link").setLink({href:t}).run(),removeLink:()=>null==tt?void 0:tt.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:t=>null==tt?void 0:tt.chain().focus().insertContent(t).run(),insertVariable:t=>null==tt?void 0:tt.chain().focus().insertContent(`{{${t}}}`).run(),insertHtml:t=>null==tt?void 0:tt.commands.insertContent(l.normalizeHtml(t)),undo:()=>null==tt?void 0:tt.chain().focus().undo().run(),redo:()=>null==tt?void 0:tt.chain().focus().redo().run(),canUndo:()=>{var t;return null!==(t=null==tt?void 0:tt.can().undo())&&void 0!==t&&t},canRedo:()=>{var t;return null!==(t=null==tt?void 0:tt.can().redo())&&void 0!==t&&t},toggleSuperscript:()=>null==tt?void 0:tt.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>null==tt?void 0:tt.chain().focus().toggleSubscript().run(),insertImage:t=>null==tt?void 0:tt.chain().focus().setImage({src:t}).run()}})),[tt]),tt?t.jsxs(i.BikEditorShell,Object.assign({minHeight:O,maxHeight:q,tightParagraphs:!(null==k?void 0:k.richPaste),style:P,className:w},{children:[t.jsx(n.EditorContent,{editor:tt}),t.jsx(c.LinkBubbleMenu,{editor:tt,renderLinkTooltip:null==E?void 0:E.renderTooltip})]})):null},d=o.forwardRef(u);d.displayName="BikEditor",exports.BikEditor=d;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react/jsx-runtime"),e=require("../node_modules/@tiptap/core/dist/index.js"),n=require("@tiptap/react"),o=require("react"),i=require("./BikEditor.styles.js"),r=require("./BikEditor.types.js"),l=require("./BikEditor.utils.js"),s=require("./extensions/buildExtensions.js"),c=require("./floating/LinkBubbleMenu.js");function u(t){return Object.entries(t).map((t=>{let[e,n]=t;return`${e.replace(/([A-Z])/g,(t=>`-${t.toLowerCase()}`))}:${n}`})).join(";")}const a=(a,d)=>{var m,g,v,h,f,p,C;const{initialContent:S,sections:k,features:x,disabled:b,maxCharacters:y,shortcuts:A,sendShortcut:B,mentions:H,slashCommands:z,link:E,onPaste:R,onReady:I,onChange:L,onSend:j,onFocus:T,onBlur:F,onSelectionChange:M,minHeight:q,maxHeight:O,style:P,className:w,editorClassName:D,editorStyle:U}=a,_=(null==k?void 0:k.length)?l.buildSectionedContent(l.normalizeHtml(null!=S?S:""),k.map((t=>Object.assign(Object.assign({},t),{content:l.normalizeHtml(t.content)})))):l.normalizeHtml(null!=S?S:""),N=o.useRef([]),$=o.useRef(!1),J=o.useRef(I);J.current=I;const V=o.useRef(L);V.current=L;const W=o.useRef(M);W.current=M;const Z=o.useRef(r.DEFAULT_FORMAT_STATE),G=o.useRef(T);G.current=T;const K=o.useRef(F);K.current=F;const Q=o.useRef(j);Q.current=j;const X=o.useRef(null!==(m=null==H?void 0:H.agents)&&void 0!==m?m:[]);X.current=null!==(g=null==H?void 0:H.agents)&&void 0!==g?g:[];const Y=o.useRef(null!==(v=null==H?void 0:H.teams)&&void 0!==v?v:[]);Y.current=null!==(h=null==H?void 0:H.teams)&&void 0!==h?h:[];const tt=o.useRef(null!==(f=null==z?void 0:z.items)&&void 0!==f?f:[]);tt.current=null!==(p=null==z?void 0:z.items)&&void 0!==p?p:[];const et=n.useEditor({extensions:s.buildExtensions({features:x,placeholder:a.placeholder,maxCharacters:y,hasSections:(null!==(C=null==k?void 0:k.length)&&void 0!==C?C:0)>0,mentions:{agents:H?X:void 0,teams:H?Y:void 0},slashCommands:z?tt:void 0,onPaste:R,onSend:j?t=>{var e;return null===(e=Q.current)||void 0===e?void 0:e.call(Q,t)}:void 0,sendShortcut:B,shortcuts:A,onMentionSelected:null==H?void 0:H.onSelect,onSlashCommandSelected:null==z?void 0:z.onSelect,renderMentionItem:null==H?void 0:H.renderItem,renderMentionDropdown:null==H?void 0:H.renderDropdown,renderSlashCommandItem:null==z?void 0:z.renderItem,renderSlashCommandDropdown:null==z?void 0:z.renderDropdown}),content:_,editable:!b,immediatelyRender:!1,editorProps:{attributes:Object.assign(Object.assign({},D?{class:D}:{}),U?{style:u(U)}:{})},onUpdate:t=>{let{editor:e}=t;var n;null===(n=V.current)||void 0===n||n.call(V,l.extractContent(e))},onTransaction:t=>{let{editor:e}=t;var n,o,i;const r=l.extractActiveFormats(e),s=Z.current;(s.bold!==r.bold||s.italic!==r.italic||s.underline!==r.underline||s.strike!==r.strike||s.bulletList!==r.bulletList||s.orderedList!==r.orderedList||s.blockquote!==r.blockquote||s.codeBlock!==r.codeBlock||s.superscript!==r.superscript||s.subscript!==r.subscript||s.textAlign!==r.textAlign||s.fontFamily!==r.fontFamily||s.fontSize!==r.fontSize||s.color!==r.color||s.highlight!==r.highlight||(null===(n=s.link)||void 0===n?void 0:n.href)!==(null===(o=r.link)||void 0===o?void 0:o.href))&&(Z.current=r,null===(i=W.current)||void 0===i||i.call(W,r))},onFocus:()=>{var t;return null===(t=G.current)||void 0===t?void 0:t.call(G)},onBlur:()=>{var t;return null===(t=K.current)||void 0===t?void 0:t.call(K)}});function nt(t){et?t(et):N.current.push(t)}return o.useEffect((()=>{var t;if(et){if(N.current.length>0){N.current.splice(0).forEach((t=>t(et)))}$.current||($.current=!0,null===(t=J.current)||void 0===t||t.call(J))}}),[et]),o.useImperativeHandle(d,(()=>({focus:t=>nt((e=>e.commands.focus(t))),blur:()=>nt((t=>t.commands.blur())),clearContent:()=>nt((t=>t.commands.clearContent(!0))),setContent:t=>{const e=l.normalizeHtml(t);nt((t=>t.commands.setContent(e,{emitUpdate:!0})))},insertContent:t=>{const e=l.normalizeHtml(t);nt((t=>t.commands.insertContent(e)))},insertInlineContent:t=>{nt((e=>l.insertInlineHtml(e,t)))},insertAtStart:t=>{const e=l.normalizeHtml(t);nt((t=>t.commands.insertContentAt(1,e)))},insertBlock:t=>{const e=l.normalizeHtml(t);nt((t=>t.commands.insertContentAt(t.state.doc.content.size,e)))},appendInline:t=>{const e=l.normalizeHtml(t);nt((t=>t.commands.insertContentAt(t.state.doc.content.size-1,e)))},insertAtEnd(t){this.insertBlock(t)},appendContent(t){this.appendInline(t)},getContent:()=>et?l.extractContent(et):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>{var t;return null!==(t=null==et?void 0:et.getJSON())&&void 0!==t?t:null},getMentions:()=>{const t=new Set,e=new Set;return et?(et.state.doc.descendants((n=>{"mentionAgent"===n.type.name&&null!=n.attrs.id?t.add(String(n.attrs.id)):"mentionTeam"===n.type.name&&null!=n.attrs.id&&e.add(String(n.attrs.id))})),{agentIds:Array.from(t),teamIds:Array.from(e)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!et)return{from:0,to:0};const{from:t,to:e}=et.state.selection;return{from:t,to:e}},insertAtPosition:(t,e)=>{const n=l.normalizeHtml(e);nt((e=>e.commands.insertContentAt(t,n)))},getSelectedText:()=>{if(!et)return"";const{state:t}=et,{from:n,to:o,empty:i}=t.selection;if(!i)return t.doc.textBetween(n,o," ");const r=t.schema.marks.link;if(r){const o=e.getMarkRange(t.doc.resolve(n),r);if(o)return t.doc.textBetween(o.from,o.to," ")}return""},getCharacterCount:()=>{var t,e,n,o;return{count:null!==(o=null!==(n=null===(e=null===(t=null==et?void 0:et.storage.characterCount)||void 0===t?void 0:t.characters)||void 0===e?void 0:e.call(t))&&void 0!==n?n:null==et?void 0:et.getText().length)&&void 0!==o?o:0,limit:null!=y?y:null}},getSectionContent:t=>et?l.extractSectionContent(et,t):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(t,e)=>{const n=l.normalizeHtml(e);nt((e=>l.setSectionContentInEditor(e,t,n)))},focusSection:t=>{nt((e=>{if("body"===t){let t=e.state.doc.content.size-1;return e.state.doc.descendants(((n,o)=>("sectionDivider"===n.type.name&&t===e.state.doc.content.size-1&&(t=o-1),t===e.state.doc.content.size-1))),t<1&&(t=1),void e.chain().focus().setTextSelection(t).run()}let n=-1;e.state.doc.descendants(((e,o)=>{if(-1!==n)return!1;"sectionDivider"===e.type.name&&e.attrs.sectionId===t&&(n=o+e.nodeSize+1)})),-1!==n&&e.chain().focus().setTextSelection(n).run()}))},clearSection:t=>{nt((e=>l.setSectionContentInEditor(e,t,"<p></p>")))},getBodyContent:()=>et?l.extractBodyContent(et):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:t=>{const e=l.normalizeHtml(t);nt((t=>l.setSectionContentInEditor(t,"body",e)))},setBodyAndSections:(t,e)=>{const n=l.buildSectionedContent(l.normalizeHtml(t),e.map((t=>({id:t.id,content:l.normalizeHtml(t.content)}))));nt((t=>t.commands.setContent(n,{emitUpdate:!0})))},appendBodyContent:t=>{const e=l.normalizeHtml(t);nt((t=>{const n=l.findSectionEndPos(t,"body");t.commands.insertContentAt(n-1,e)}))},insertAtSectionStart:(t,e)=>{const n=l.normalizeHtml(e);nt((e=>{const o=l.findSectionStartPos(e,t);-1!==o&&e.commands.insertContentAt(o,n)}))},insertAtSectionEnd:(t,e)=>{const n=l.normalizeHtml(e);nt((e=>{const o=l.findSectionEndPos(e,t);e.commands.insertContentAt(o,n)}))},getActiveFormats:()=>et?l.extractActiveFormats(et):r.DEFAULT_FORMAT_STATE,actions:{toggleBold:()=>null==et?void 0:et.chain().focus().toggleBold().run(),toggleItalic:()=>null==et?void 0:et.chain().focus().toggleItalic().run(),toggleUnderline:()=>null==et?void 0:et.chain().focus().toggleUnderline().run(),toggleStrike:()=>null==et?void 0:et.chain().focus().toggleStrike().run(),toggleBulletList:()=>null==et?void 0:et.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>null==et?void 0:et.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>null==et?void 0:et.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>null==et?void 0:et.chain().focus().toggleCodeBlock().run(),setTextAlign:t=>null==et?void 0:et.chain().focus().setTextAlign(t).run(),setFontFamily:t=>null==et?void 0:et.chain().focus().setFontFamily(t).run(),setFontSize:t=>null==et?void 0:et.chain().focus().setFontSize(t).run(),setColor:t=>null==et?void 0:et.chain().focus().setColor(t).run(),setHighlight:t=>null==et?void 0:et.chain().focus().toggleHighlight({color:t}).run(),unsetColor:()=>null==et?void 0:et.chain().focus().unsetColor().run(),unsetHighlight:()=>null==et?void 0:et.chain().focus().unsetHighlight().run(),setLink:(t,e)=>{et&&(void 0!==e?et.chain().focus().extendMarkRange("link").command((n=>{let{tr:o,state:i}=n;const{from:r,to:l}=o.selection,s=i.schema.marks.link;if(!s)return!1;const c=i.schema.text(e,[s.create({href:t})]),u=i.schema.text(" ");return o.replaceWith(r,l,[c,u]),!0})).run():et.chain().focus().extendMarkRange("link").setLink({href:t}).insertContent(" ").run())},updateLink:t=>null==et?void 0:et.chain().focus().extendMarkRange("link").setLink({href:t}).run(),removeLink:()=>null==et?void 0:et.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:t=>null==et?void 0:et.chain().focus().insertContent(t).run(),insertVariable:t=>null==et?void 0:et.chain().focus().insertContent(`{{${t}}}`).run(),insertHtml:t=>null==et?void 0:et.commands.insertContent(l.normalizeHtml(t)),undo:()=>null==et?void 0:et.chain().focus().undo().run(),redo:()=>null==et?void 0:et.chain().focus().redo().run(),canUndo:()=>{var t;return null!==(t=null==et?void 0:et.can().undo())&&void 0!==t&&t},canRedo:()=>{var t;return null!==(t=null==et?void 0:et.can().redo())&&void 0!==t&&t},toggleSuperscript:()=>null==et?void 0:et.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>null==et?void 0:et.chain().focus().toggleSubscript().run(),insertImage:t=>null==et?void 0:et.chain().focus().setImage({src:t}).run()}})),[et]),et?t.jsxs(i.BikEditorShell,Object.assign({minHeight:q,maxHeight:O,tightParagraphs:!(null==x?void 0:x.richPaste),style:P,className:w},{children:[t.jsx(n.EditorContent,{editor:et}),t.jsx(c.LinkBubbleMenu,{editor:et,renderLinkTooltip:null==E?void 0:E.renderTooltip})]})):null},d=o.forwardRef(a);d.displayName="BikEditor",exports.BikEditor=d;
2
2
  //# sourceMappingURL=BikEditor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from 'react';\nimport { BikEditorShell } from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n} from './BikEditor.types';\nimport {\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t} = props;\n\n\tconst initialEditorContent = sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tonSelectionChangeRef.current?.(extractActiveFormats(e));\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t}, [editor]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1) e.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","Object","entries","map","_ref","k","v","replace","c","toLowerCase","join","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","initialEditorContent","length","buildSectionedContent","normalizeHtml","s","assign","content","pendingQueue","useRef","hasCalledOnReady","onReadyRef","current","onChangeRef","onSelectionChangeRef","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","agents","_a","_b","teamMentionsRef","teams","_c","_d","slashCommandsRef","items","_e","_f","editor","useEditor","extensions","buildExtensions","placeholder","hasSections","_g","undefined","snapshot","call","onMentionSelected","onSelect","onSlashCommandSelected","renderMentionItem","renderItem","renderMentionDropdown","renderDropdown","renderSlashCommandItem","renderSlashCommandDropdown","editable","immediatelyRender","editorProps","attributes","class","onUpdate","_ref2","e","extractContent","onTransaction","_ref3","extractActiveFormats","enqueue","op","push","useEffect","splice","forEach","useImperativeHandle","focus","position","commands","blur","clearContent","setContent","html","normalised","emitUpdate","insertContent","insertInlineContent","insertInlineHtml","insertAtStart","insertContentAt","insertBlock","state","doc","size","appendInline","insertAtEnd","this","appendContent","getContent","text","isEmpty","characterCount","getJSON","getMentions","agentIds","Set","teamIds","descendants","node","type","name","attrs","add","String","Array","from","getCursorPosition","to","selection","insertAtPosition","pos","getSelectedText","empty","textBetween","linkMarkType","schema","marks","range","getMarkRange","resolve","getCharacterCount","count","storage","characters","getText","limit","getSectionContent","sectionId","extractSectionContent","setSectionContent","setSectionContentInEditor","focusSection","endOfBody","chain","setTextSelection","run","targetPos","nodeSize","clearSection","getBodyContent","extractBodyContent","setBodyContent","setBodyAndSections","body","id","appendBodyContent","boundaryPos","findSectionEndPos","insertAtSectionStart","findSectionStartPos","insertAtSectionEnd","getActiveFormats","DEFAULT_FORMAT_STATE","actions","toggleBold","toggleItalic","toggleUnderline","toggleStrike","toggleBulletList","toggleOrderedList","toggleBlockquote","toggleCodeBlock","setTextAlign","align","setFontFamily","font","setFontSize","setColor","color","setHighlight","toggleHighlight","unsetColor","unsetHighlight","setLink","href","extendMarkRange","command","_ref4","tr","linkNode","create","space","replaceWith","updateLink","removeLink","unsetLink","insertEmoji","emoji","insertVariable","variableName","insertHtml","undo","redo","canUndo","can","canRedo","toggleSuperscript","toggleSubscript","insertImage","src","setImage","_jsxs","BikEditorShell","tightParagraphs","richPaste","children","_jsx","jsx","EditorContent","LinkBubbleMenu","renderLinkTooltip","renderTooltip","BikEditor","forwardRef","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from 'react';\nimport { BikEditorShell } from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n} from './BikEditor.types';\nimport {\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t} = props;\n\n\tconst initialEditorContent = sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t}, [editor]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1) e.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","Object","entries","map","_ref","k","v","replace","c","toLowerCase","join","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","initialEditorContent","length","buildSectionedContent","normalizeHtml","s","assign","content","pendingQueue","useRef","hasCalledOnReady","onReadyRef","current","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","agents","_a","_b","teamMentionsRef","teams","_c","_d","slashCommandsRef","items","_e","_f","editor","useEditor","extensions","buildExtensions","placeholder","hasSections","_g","undefined","snapshot","call","onMentionSelected","onSelect","onSlashCommandSelected","renderMentionItem","renderItem","renderMentionDropdown","renderDropdown","renderSlashCommandItem","renderSlashCommandDropdown","editable","immediatelyRender","editorProps","attributes","class","onUpdate","_ref2","e","extractContent","onTransaction","_ref3","next","extractActiveFormats","prev","bold","italic","underline","strike","bulletList","orderedList","blockquote","codeBlock","superscript","subscript","textAlign","fontFamily","fontSize","color","highlight","href","enqueue","op","push","useEffect","splice","forEach","useImperativeHandle","focus","position","commands","blur","clearContent","setContent","html","normalised","emitUpdate","insertContent","insertInlineContent","insertInlineHtml","insertAtStart","insertContentAt","insertBlock","state","doc","size","appendInline","insertAtEnd","this","appendContent","getContent","text","isEmpty","characterCount","getJSON","getMentions","agentIds","Set","teamIds","descendants","node","type","name","attrs","add","String","Array","from","getCursorPosition","to","selection","insertAtPosition","pos","getSelectedText","empty","textBetween","linkMarkType","schema","marks","range","getMarkRange","resolve","getCharacterCount","count","storage","characters","getText","limit","getSectionContent","sectionId","extractSectionContent","setSectionContent","setSectionContentInEditor","focusSection","endOfBody","chain","setTextSelection","run","targetPos","nodeSize","clearSection","getBodyContent","extractBodyContent","setBodyContent","setBodyAndSections","body","id","appendBodyContent","boundaryPos","findSectionEndPos","insertAtSectionStart","findSectionStartPos","insertAtSectionEnd","getActiveFormats","actions","toggleBold","toggleItalic","toggleUnderline","toggleStrike","toggleBulletList","toggleOrderedList","toggleBlockquote","toggleCodeBlock","setTextAlign","align","setFontFamily","font","setFontSize","setColor","setHighlight","toggleHighlight","unsetColor","unsetHighlight","setLink","extendMarkRange","command","_ref4","tr","linkNode","create","space","replaceWith","updateLink","removeLink","unsetLink","insertEmoji","emoji","insertVariable","variableName","insertHtml","undo","redo","canUndo","can","canRedo","toggleSuperscript","toggleSubscript","insertImage","src","setImage","_jsxs","BikEditorShell","tightParagraphs","richPaste","children","_jsx","jsx","EditorContent","LinkBubbleMenu","renderLinkTooltip","renderTooltip","BikEditor","forwardRef","displayName"],"mappings":"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"}
@@ -26,18 +26,6 @@
26
26
  padding: 0;
27
27
  }
28
28
 
29
- /* ProseMirror appends an invisible trailing <br> after a paragraph that
30
- ends in a hard break, so the cursor can sit on that final line. A plain
31
- HTML viewer (Gmail, our email shadow DOM) doesn't add one, so the editor
32
- would show one phantom empty line MORE than the sent HTML per such
33
- paragraph. Hide it when the paragraph has other content (the break is
34
- NOT the first child — e.g. a paragraph ending in <br>, even when the
35
- <br> is nested inside a mark <span>); keep it for truly empty paragraphs
36
- where it is the only child and provides the blank line. Editor == output. */
37
- .ProseMirror-trailingBreak:not(:first-child) {
38
- display: none;
39
- }
40
-
41
29
  ul,
42
30
  ol {
43
31
  margin: 0;
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\ttightParagraphs?: boolean;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '80px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tpadding: 8px 12px;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\t/* Paragraph spacing.\n\t\t Email/signature (rich): paragraphs carry the browser-default 1em block\n\t\t margin — the SAME spacing the sent HTML gets (we emit plain <p>, which\n\t\t renders against the default <p> margin in Gmail and our email viewer),\n\t\t so editor view == emitted HTML == Gmail. A single Enter = a new\n\t\t paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.\n\t\t Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with\n\t\t no paragraph-gap concept — paragraphs are tight (margin:0) regardless of\n\t\t typed vs pasted. (A margin:0 attr still overrides to tight either way.) */\n\t\tp {\n\t\t\tmargin: ${({ tightParagraphs }) => (tightParagraphs ? '0' : '1em 0')};\n\t\t\tpadding: 0;\n\t\t}\n\n\t\t/* ProseMirror appends an invisible trailing <br> after a paragraph that\n\t\t ends in a hard break, so the cursor can sit on that final line. A plain\n\t\t HTML viewer (Gmail, our email shadow DOM) doesn't add one, so the editor\n\t\t would show one phantom empty line MORE than the sent HTML per such\n\t\t paragraph. Hide it when the paragraph has other content (the break is\n\t\t NOT the first child — e.g. a paragraph ending in <br>, even when the\n\t\t <br> is nested inside a mark <span>); keep it for truly empty paragraphs\n\t\t where it is the only child and provides the blank line. Editor == output. */\n\t\t.ProseMirror-trailingBreak:not(:first-child) {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t.bik-variable {\n\t}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n"],"names":["BikEditorShell","div","_ref","minHeight","_ref2","maxHeight","_ref3","tightParagraphs","COLORS","content","brand"],"mappings":"kNAGaA,MAAAA,OAAuB,QAACC,GAInC;;;;;gBAKcC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;gBACtCC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;;;;;;;;;;;;;;;;;;aAkBzCC,IAAA,IAACC,gBAAEA,GAAiBD,EAAA,OAAMC,EAAkB,IAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAoC3DC,EAAMA,OAACC,QAAQC;;;;WAIfF,EAAMA,OAACC,QAAQC;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\ttightParagraphs?: boolean;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '80px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tpadding: 8px 12px;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\t/* Paragraph spacing.\n\t\t Email/signature (rich): paragraphs carry the browser-default 1em block\n\t\t margin — the SAME spacing the sent HTML gets (we emit plain <p>, which\n\t\t renders against the default <p> margin in Gmail and our email viewer),\n\t\t so editor view == emitted HTML == Gmail. A single Enter = a new\n\t\t paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.\n\t\t Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with\n\t\t no paragraph-gap concept — paragraphs are tight (margin:0) regardless of\n\t\t typed vs pasted. (A margin:0 attr still overrides to tight either way.) */\n\t\tp {\n\t\t\tmargin: ${({ tightParagraphs }) => (tightParagraphs ? '0' : '1em 0')};\n\t\t\tpadding: 0;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t.bik-variable {\n\t}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n"],"names":["BikEditorShell","div","_ref","minHeight","_ref2","maxHeight","_ref3","tightParagraphs","COLORS","content","brand"],"mappings":"kNAGaA,MAAAA,OAAuB,QAACC,GAInC;;;;;gBAKcC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;gBACtCC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;;;;;;;;;;;;;;;;;;aAkBzCC,IAAA,IAACC,gBAAEA,GAAiBD,EAAA,OAAMC,EAAkB,IAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;WAwB3DC,EAAMA,OAACC,QAAQC;;;;WAIfF,EAAMA,OAACC,QAAQC;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../../node_modules/@tiptap/core/dist/index.js"),t=require("@tiptap/pm/model"),r=require("@tiptap/pm/state"),n=require("./pasteUtils.js");const a=e.Extension.create({name:"pasteNormalization",addOptions:()=>({preserveMarks:!1,plainOnly:!1}),addProseMirrorPlugins(){const e=this.options.preserveMarks,a=this.options.plainOnly;let s;const i=e=>{var t;const r=e.firstChild;s=r&&"paragraph"===r.type.name?null!==(t=r.attrs.margin)&&void 0!==t?t:null:void 0};return[new r.Plugin({appendTransaction(e,t,r){var n;if(!e.some((e=>e.docChanged)))return s=void 0,null;const a=r.tr;let i=!1;if(void 0!==s){const o=s;let l=t.selection.from;for(const t of e)l=t.mapping.map(l);const p=r.doc.resolve(Math.max(0,Math.min(l,r.doc.content.size)));for(let e=p.depth;e>=1;e--){const t=p.node(e);if("paragraph"===t.type.name){(null!==(n=t.attrs.margin)&&void 0!==n?n:null)!==o&&(a.setNodeMarkup(p.before(e),void 0,Object.assign(Object.assign({},t.attrs),{margin:o})),i=!0);break}}}s=void 0;const o=a.doc;let l=null;return o.forEach(((e,t)=>{var r;if("paragraph"!==e.type.name)return void(l=null);let n=null!==(r=e.attrs.margin)&&void 0!==r?r:null;0===e.childCount&&"0"!==n&&"0"===l&&(a.setNodeMarkup(t,void 0,Object.assign(Object.assign({},e.attrs),{margin:"0"})),n="0",i=!0),l=n})),i?a.setMeta("addToHistory",!1):null},props:Object.assign(Object.assign({},a?{handlePaste(e,t){var r,a;const s=null!==(a=null===(r=t.clipboardData)||void 0===r?void 0:r.getData("text/plain"))&&void 0!==a?a:"";if(!s)return!1;const o=n.parseClipboardTextAsBreaks(s,e.state.schema);return i(o.content),e.dispatch(e.state.tr.replaceSelection(o)),!0}}:{}),{clipboardTextParser(e,t,r,a){const s=n.parseClipboardTextAsBreaks(e,a.state.schema);return i(s.content),s},transformPastedHTML(e){if(e.includes("data-pm-slice"))return e;const t=document.createElement("div");return t.innerHTML=e,n.wrapInlineContent(t),n.cleanBlockBrs(t),n.stripTrailingBrs(t),t.innerHTML},transformPasted(r){let a=n.normalizeHardBreaks(r.content);return e||(a=n.stripRichMarks(a)),a=n.mirrorParagraphMargins(a),i(a),new t.Slice(a,r.openStart,r.openEnd)}})})]}});exports.PasteNormalizationExtension=a;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../../node_modules/@tiptap/core/dist/index.js"),t=require("@tiptap/pm/model"),r=require("@tiptap/pm/state"),n=require("./pasteUtils.js");const a=e.Extension.create({name:"pasteNormalization",addOptions:()=>({preserveMarks:!1,plainOnly:!1}),addProseMirrorPlugins(){const e=this.options.preserveMarks,a=this.options.plainOnly;let s;const i=e=>{var t;const r=e.firstChild;s=r&&"paragraph"===r.type.name?null!==(t=r.attrs.margin)&&void 0!==t?t:null:void 0};return[new r.Plugin({appendTransaction(e,t,r){var n;if(!e.some((e=>e.docChanged)))return s=void 0,null;const a=r.tr;let i=!1;if(void 0!==s){const o=s;let l=t.selection.from;for(const t of e)l=t.mapping.map(l);const p=r.doc.resolve(Math.max(0,Math.min(l,r.doc.content.size)));for(let e=p.depth;e>=1;e--){const t=p.node(e);if("paragraph"===t.type.name){(null!==(n=t.attrs.margin)&&void 0!==n?n:null)!==o&&(a.setNodeMarkup(p.before(e),void 0,Object.assign(Object.assign({},t.attrs),{margin:o})),i=!0);break}}}s=void 0;const o=a.doc;let l=null;return o.forEach(((e,t)=>{var r;if("paragraph"!==e.type.name)return void(l=null);let n=null!==(r=e.attrs.margin)&&void 0!==r?r:null;0===e.childCount&&"0"!==n&&"0"===l&&(a.setNodeMarkup(t,void 0,Object.assign(Object.assign({},e.attrs),{margin:"0"})),n="0",i=!0),l=n})),i?a.setMeta("addToHistory",!1):null},props:Object.assign(Object.assign({},a?{handlePaste(e,t){var r,a;const s=null!==(a=null===(r=t.clipboardData)||void 0===r?void 0:r.getData("text/plain"))&&void 0!==a?a:"";if(!s)return!1;const o=n.parseClipboardTextAsBreaks(s,e.state.schema);return i(o.content),e.dispatch(e.state.tr.replaceSelection(o)),!0}}:{}),{clipboardTextParser(e,t,r,a){const s=n.parseClipboardTextAsBreaks(e,a.state.schema);return i(s.content),s},transformPastedHTML(e){if(e.includes("data-pm-slice"))return e;const t=document.createElement("div");return t.innerHTML=e,t.querySelectorAll("br.Apple-interchange-newline").forEach((e=>e.remove())),n.wrapInlineContent(t),n.cleanBlockBrs(t),n.stripTrailingBrs(t),t.innerHTML},transformPasted(r){let a=n.normalizeHardBreaks(r.content);return e||(a=n.stripRichMarks(a)),a=n.mirrorParagraphMargins(a),i(a),new t.Slice(a,r.openStart,r.openEnd)}})})]}});exports.PasteNormalizationExtension=a;
2
2
  //# sourceMappingURL=PasteNormalizationExtension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PasteNormalizationExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PasteNormalizationExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport {\n\tcleanBlockBrs,\n\tmirrorParagraphMargins,\n\tnormalizeHardBreaks,\n\tparseClipboardTextAsBreaks,\n\tstripRichMarks,\n\tstripTrailingBrs,\n\twrapInlineContent,\n} from './pasteUtils';\n\n/**\n * Unified paste normalizer for all editor channels.\n *\n * Uses ProseMirror's recommended hooks instead of overriding handlePaste:\n * - clipboardTextParser: plain text → Slice (one block, <br> per line)\n * - transformPastedHTML: HTML → HTML (cleans Google Docs / Word artifacts)\n * - transformPasted: Slice → Slice (normalize hardBreaks, strip marks,\n * mirror the source paragraph-margin convention)\n *\n * Margins MIRROR the source (like Gmail): they are not added structurally, so\n * ChatGPT-pasted `<p>` keeps its default margin (gaps) while Google-Docs and\n * plain/paste-without-formatting content stays margin:0 (tight).\n *\n * `appendTransaction` does two bounded touch-ups:\n * 1. Repairs the FIRST pasted paragraph — ProseMirror merges it into the\n * cursor's paragraph at paste time, dropping its margin attr; we record that\n * margin (in transformPasted / the plain handlePaste) and reapply it at the\n * paste position.\n * 2. Typed-Enter inheritance — splitBlock gives a paragraph created at a block\n * end DEFAULT attrs, so an empty paragraph that follows a margin:0 paragraph\n * is set to margin:0 too. Typing inside tight content stays tight; default\n * content stays default; non-empty (pasted) paragraphs are never touched.\n *\n * `plainOnly` (channels with no rich formatting — WhatsApp, IG, FB, comments)\n * forces EVERY paste through the plain-text path: even Cmd/Ctrl+V ignores the\n * clipboard HTML and pastes text only, since those channels don't support\n * formatting anyway. Email and the signature editor (richPaste) keep the full\n * HTML pipeline.\n */\nexport const PasteNormalizationExtension = Extension.create({\n\tname: 'pasteNormalization',\n\taddOptions() {\n\t\treturn {\n\t\t\tpreserveMarks: false,\n\t\t\tplainOnly: false,\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\tconst preserveMarks = this.options.preserveMarks;\n\t\tconst plainOnly = this.options.plainOnly;\n\n\t\t// Margin of the first pasted paragraph, recorded at paste time so the\n\t\t// appendTransaction can restore it after ProseMirror merges that\n\t\t// paragraph into the destination (losing its attrs). `undefined` means\n\t\t// \"no paste pending\".\n\t\tlet pastedFirstMargin: string | null | undefined;\n\n\t\tconst recordFirstMargin = (content: { firstChild: any }) => {\n\t\t\tconst first = content.firstChild;\n\t\t\tpastedFirstMargin =\n\t\t\t\tfirst && first.type.name === 'paragraph'\n\t\t\t\t\t? first.attrs['margin'] ?? null\n\t\t\t\t\t: undefined;\n\t\t};\n\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tappendTransaction(transactions, oldState, newState) {\n\t\t\t\t\tif (!transactions.some((t) => t.docChanged)) {\n\t\t\t\t\t\tpastedFirstMargin = undefined;\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst tr = newState.tr;\n\t\t\t\t\tlet changed = false;\n\n\t\t\t\t\t// Job 1 — repair the first pasted paragraph. ProseMirror merges it\n\t\t\t\t\t// into the destination paragraph at paste time, dropping its margin\n\t\t\t\t\t// attr; reapply the recorded margin at the paste position.\n\t\t\t\t\tif (pastedFirstMargin !== undefined) {\n\t\t\t\t\t\tconst margin = pastedFirstMargin;\n\t\t\t\t\t\tlet pos = oldState.selection.from;\n\t\t\t\t\t\tfor (const t of transactions) pos = t.mapping.map(pos);\n\t\t\t\t\t\tconst $pos = newState.doc.resolve(\n\t\t\t\t\t\t\tMath.max(0, Math.min(pos, newState.doc.content.size)),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfor (let d = $pos.depth; d >= 1; d--) {\n\t\t\t\t\t\t\tconst node = $pos.node(d);\n\t\t\t\t\t\t\tif (node.type.name === 'paragraph') {\n\t\t\t\t\t\t\t\tif ((node.attrs['margin'] ?? null) !== margin) {\n\t\t\t\t\t\t\t\t\ttr.setNodeMarkup($pos.before(d), undefined, {\n\t\t\t\t\t\t\t\t\t\t...node.attrs,\n\t\t\t\t\t\t\t\t\t\tmargin,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\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\tpastedFirstMargin = undefined;\n\n\t\t\t\t\t// Job 2 — typed Enter inherits tightness. ProseMirror's splitBlock\n\t\t\t\t\t// gives a paragraph created at the end of a block DEFAULT attrs, so\n\t\t\t\t\t// pressing Enter in margin:0 content would otherwise produce a\n\t\t\t\t\t// default-margin (gap) paragraph. Make an EMPTY paragraph that\n\t\t\t\t\t// follows a margin:0 paragraph margin:0 too — so typing inside tight\n\t\t\t\t\t// (plain / Google-Docs) content stays tight, while default content\n\t\t\t\t\t// stays default. Non-empty paragraphs are never touched, so pasted\n\t\t\t\t\t// default-margin content is left alone.\n\t\t\t\t\tconst doc = tr.doc;\n\t\t\t\t\tlet prevMargin: string | null = null;\n\t\t\t\t\tdoc.forEach((node, pos) => {\n\t\t\t\t\t\tif (node.type.name !== 'paragraph') {\n\t\t\t\t\t\t\tprevMargin = null;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet margin = (node.attrs['margin'] as string | null) ?? null;\n\t\t\t\t\t\tif (node.childCount === 0 && margin !== '0' && prevMargin === '0') {\n\t\t\t\t\t\t\ttr.setNodeMarkup(pos, undefined, { ...node.attrs, margin: '0' });\n\t\t\t\t\t\t\tmargin = '0';\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprevMargin = margin;\n\t\t\t\t\t});\n\n\t\t\t\t\treturn changed ? tr.setMeta('addToHistory', false) : null;\n\t\t\t\t},\n\t\t\t\tprops: {\n\t\t\t\t\t// plainOnly channels: ignore clipboard HTML entirely — every\n\t\t\t\t\t// paste (Cmd/Ctrl+V and Cmd/Ctrl+Shift+V) becomes plain text.\n\t\t\t\t\t...(plainOnly\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain') ?? '';\n\t\t\t\t\t\t\t\t\tif (!text) return false; // images / non-text: let others handle\n\t\t\t\t\t\t\t\t\tconst slice = parseClipboardTextAsBreaks(\n\t\t\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\t\t\tview.state.schema,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\trecordFirstMargin(slice.content);\n\t\t\t\t\t\t\t\t\tview.dispatch(view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {}),\n\n\t\t\t\t\t// Plain-text paste (Cmd/Ctrl+Shift+V, which strips HTML): one\n\t\t\t\t\t// block with <br> per line and <br><br> per blank line — matches\n\t\t\t\t\t// Gmail's paste-without-formatting output exactly.\n\t\t\t\t\tclipboardTextParser(text, _$context, _plain, view) {\n\t\t\t\t\t\tconst slice = parseClipboardTextAsBreaks(text, view.state.schema);\n\t\t\t\t\t\trecordFirstMargin(slice.content);\n\t\t\t\t\t\treturn slice;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPastedHTML(html) {\n\t\t\t\t\t\tif (html.includes('data-pm-slice')) return html;\n\t\t\t\t\t\tconst container = document.createElement('div');\n\t\t\t\t\t\tcontainer.innerHTML = html;\n\t\t\t\t\t\twrapInlineContent(container);\n\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\tstripTrailingBrs(container);\n\t\t\t\t\t\treturn container.innerHTML;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPasted(slice) {\n\t\t\t\t\t\tlet content = normalizeHardBreaks(slice.content);\n\t\t\t\t\t\tif (!preserveMarks) {\n\t\t\t\t\t\t\tcontent = stripRichMarks(content);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontent = mirrorParagraphMargins(content);\n\t\t\t\t\t\trecordFirstMargin(content);\n\t\t\t\t\t\treturn new Slice(content, slice.openStart, slice.openEnd);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PasteNormalizationExtension","Extension","create","name","addOptions","preserveMarks","plainOnly","addProseMirrorPlugins","this","options","pastedFirstMargin","recordFirstMargin","content","first","firstChild","type","attrs","_a","undefined","Plugin","appendTransaction","transactions","oldState","newState","some","t","docChanged","tr","changed","margin","pos","selection","from","mapping","map","$pos","doc","resolve","Math","max","min","size","d","depth","node","setNodeMarkup","before","prevMargin","forEach","childCount","Object","assign","setMeta","props","handlePaste","view","event","text","_b","clipboardData","getData","slice","parseClipboardTextAsBreaks","state","schema","dispatch","replaceSelection","clipboardTextParser","_$context","_plain","transformPastedHTML","html","includes","container","document","createElement","innerHTML","wrapInlineContent","cleanBlockBrs","stripTrailingBrs","transformPasted","normalizeHardBreaks","stripRichMarks","mirrorParagraphMargins","Slice","openStart","openEnd"],"mappings":"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"}
1
+ {"version":3,"file":"PasteNormalizationExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PasteNormalizationExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport {\n\tcleanBlockBrs,\n\tmirrorParagraphMargins,\n\tnormalizeHardBreaks,\n\tparseClipboardTextAsBreaks,\n\tstripRichMarks,\n\tstripTrailingBrs,\n\twrapInlineContent,\n} from './pasteUtils';\n\n/**\n * Unified paste normalizer for all editor channels.\n *\n * Uses ProseMirror's recommended hooks instead of overriding handlePaste:\n * - clipboardTextParser: plain text → Slice (one block, <br> per line)\n * - transformPastedHTML: HTML → HTML (cleans Google Docs / Word artifacts)\n * - transformPasted: Slice → Slice (normalize hardBreaks, strip marks,\n * mirror the source paragraph-margin convention)\n *\n * Margins MIRROR the source (like Gmail): they are not added structurally, so\n * ChatGPT-pasted `<p>` keeps its default margin (gaps) while Google-Docs and\n * plain/paste-without-formatting content stays margin:0 (tight).\n *\n * `appendTransaction` does two bounded touch-ups:\n * 1. Repairs the FIRST pasted paragraph — ProseMirror merges it into the\n * cursor's paragraph at paste time, dropping its margin attr; we record that\n * margin (in transformPasted / the plain handlePaste) and reapply it at the\n * paste position.\n * 2. Typed-Enter inheritance — splitBlock gives a paragraph created at a block\n * end DEFAULT attrs, so an empty paragraph that follows a margin:0 paragraph\n * is set to margin:0 too. Typing inside tight content stays tight; default\n * content stays default; non-empty (pasted) paragraphs are never touched.\n *\n * `plainOnly` (channels with no rich formatting — WhatsApp, IG, FB, comments)\n * forces EVERY paste through the plain-text path: even Cmd/Ctrl+V ignores the\n * clipboard HTML and pastes text only, since those channels don't support\n * formatting anyway. Email and the signature editor (richPaste) keep the full\n * HTML pipeline.\n */\nexport const PasteNormalizationExtension = Extension.create({\n\tname: 'pasteNormalization',\n\taddOptions() {\n\t\treturn {\n\t\t\tpreserveMarks: false,\n\t\t\tplainOnly: false,\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\tconst preserveMarks = this.options.preserveMarks;\n\t\tconst plainOnly = this.options.plainOnly;\n\n\t\t// Margin of the first pasted paragraph, recorded at paste time so the\n\t\t// appendTransaction can restore it after ProseMirror merges that\n\t\t// paragraph into the destination (losing its attrs). `undefined` means\n\t\t// \"no paste pending\".\n\t\tlet pastedFirstMargin: string | null | undefined;\n\n\t\tconst recordFirstMargin = (content: { firstChild: any }) => {\n\t\t\tconst first = content.firstChild;\n\t\t\tpastedFirstMargin =\n\t\t\t\tfirst && first.type.name === 'paragraph'\n\t\t\t\t\t? first.attrs['margin'] ?? null\n\t\t\t\t\t: undefined;\n\t\t};\n\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tappendTransaction(transactions, oldState, newState) {\n\t\t\t\t\tif (!transactions.some((t) => t.docChanged)) {\n\t\t\t\t\t\tpastedFirstMargin = undefined;\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst tr = newState.tr;\n\t\t\t\t\tlet changed = false;\n\n\t\t\t\t\t// Job 1 — repair the first pasted paragraph. ProseMirror merges it\n\t\t\t\t\t// into the destination paragraph at paste time, dropping its margin\n\t\t\t\t\t// attr; reapply the recorded margin at the paste position.\n\t\t\t\t\tif (pastedFirstMargin !== undefined) {\n\t\t\t\t\t\tconst margin = pastedFirstMargin;\n\t\t\t\t\t\tlet pos = oldState.selection.from;\n\t\t\t\t\t\tfor (const t of transactions) pos = t.mapping.map(pos);\n\t\t\t\t\t\tconst $pos = newState.doc.resolve(\n\t\t\t\t\t\t\tMath.max(0, Math.min(pos, newState.doc.content.size)),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfor (let d = $pos.depth; d >= 1; d--) {\n\t\t\t\t\t\t\tconst node = $pos.node(d);\n\t\t\t\t\t\t\tif (node.type.name === 'paragraph') {\n\t\t\t\t\t\t\t\tif ((node.attrs['margin'] ?? null) !== margin) {\n\t\t\t\t\t\t\t\t\ttr.setNodeMarkup($pos.before(d), undefined, {\n\t\t\t\t\t\t\t\t\t\t...node.attrs,\n\t\t\t\t\t\t\t\t\t\tmargin,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\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\tpastedFirstMargin = undefined;\n\n\t\t\t\t\t// Job 2 — typed Enter inherits tightness. ProseMirror's splitBlock\n\t\t\t\t\t// gives a paragraph created at the end of a block DEFAULT attrs, so\n\t\t\t\t\t// pressing Enter in margin:0 content would otherwise produce a\n\t\t\t\t\t// default-margin (gap) paragraph. Make an EMPTY paragraph that\n\t\t\t\t\t// follows a margin:0 paragraph margin:0 too — so typing inside tight\n\t\t\t\t\t// (plain / Google-Docs) content stays tight, while default content\n\t\t\t\t\t// stays default. Non-empty paragraphs are never touched, so pasted\n\t\t\t\t\t// default-margin content is left alone.\n\t\t\t\t\tconst doc = tr.doc;\n\t\t\t\t\tlet prevMargin: string | null = null;\n\t\t\t\t\tdoc.forEach((node, pos) => {\n\t\t\t\t\t\tif (node.type.name !== 'paragraph') {\n\t\t\t\t\t\t\tprevMargin = null;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet margin = (node.attrs['margin'] as string | null) ?? null;\n\t\t\t\t\t\tif (node.childCount === 0 && margin !== '0' && prevMargin === '0') {\n\t\t\t\t\t\t\ttr.setNodeMarkup(pos, undefined, { ...node.attrs, margin: '0' });\n\t\t\t\t\t\t\tmargin = '0';\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprevMargin = margin;\n\t\t\t\t\t});\n\n\t\t\t\t\treturn changed ? tr.setMeta('addToHistory', false) : null;\n\t\t\t\t},\n\t\t\t\tprops: {\n\t\t\t\t\t// plainOnly channels: ignore clipboard HTML entirely — every\n\t\t\t\t\t// paste (Cmd/Ctrl+V and Cmd/Ctrl+Shift+V) becomes plain text.\n\t\t\t\t\t...(plainOnly\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain') ?? '';\n\t\t\t\t\t\t\t\t\tif (!text) return false; // images / non-text: let others handle\n\t\t\t\t\t\t\t\t\tconst slice = parseClipboardTextAsBreaks(\n\t\t\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\t\t\tview.state.schema,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\trecordFirstMargin(slice.content);\n\t\t\t\t\t\t\t\t\tview.dispatch(view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {}),\n\n\t\t\t\t\t// Plain-text paste (Cmd/Ctrl+Shift+V, which strips HTML): one\n\t\t\t\t\t// block with <br> per line and <br><br> per blank line — matches\n\t\t\t\t\t// Gmail's paste-without-formatting output exactly.\n\t\t\t\t\tclipboardTextParser(text, _$context, _plain, view) {\n\t\t\t\t\t\tconst slice = parseClipboardTextAsBreaks(text, view.state.schema);\n\t\t\t\t\t\trecordFirstMargin(slice.content);\n\t\t\t\t\t\treturn slice;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPastedHTML(html) {\n\t\t\t\t\t\tif (html.includes('data-pm-slice')) return html;\n\t\t\t\t\t\tconst container = document.createElement('div');\n\t\t\t\t\t\tcontainer.innerHTML = html;\n\t\t\t\t\t\t// Strip Apple interchange <br> (WebKit clipboard artifact)\n\t\t\t\t\t\t// before cleanBlockBrs converts it to a phantom <p></p>.\n\t\t\t\t\t\tcontainer\n\t\t\t\t\t\t\t.querySelectorAll('br.Apple-interchange-newline')\n\t\t\t\t\t\t\t.forEach((br) => br.remove());\n\t\t\t\t\t\twrapInlineContent(container);\n\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\tstripTrailingBrs(container);\n\t\t\t\t\t\treturn container.innerHTML;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPasted(slice) {\n\t\t\t\t\t\tlet content = normalizeHardBreaks(slice.content);\n\t\t\t\t\t\tif (!preserveMarks) {\n\t\t\t\t\t\t\tcontent = stripRichMarks(content);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontent = mirrorParagraphMargins(content);\n\t\t\t\t\t\trecordFirstMargin(content);\n\t\t\t\t\t\treturn new Slice(content, slice.openStart, slice.openEnd);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PasteNormalizationExtension","Extension","create","name","addOptions","preserveMarks","plainOnly","addProseMirrorPlugins","this","options","pastedFirstMargin","recordFirstMargin","content","first","firstChild","type","attrs","_a","undefined","Plugin","appendTransaction","transactions","oldState","newState","some","t","docChanged","tr","changed","margin","pos","selection","from","mapping","map","$pos","doc","resolve","Math","max","min","size","d","depth","node","setNodeMarkup","before","prevMargin","forEach","childCount","Object","assign","setMeta","props","handlePaste","view","event","text","_b","clipboardData","getData","slice","parseClipboardTextAsBreaks","state","schema","dispatch","replaceSelection","clipboardTextParser","_$context","_plain","transformPastedHTML","html","includes","container","document","createElement","innerHTML","querySelectorAll","br","remove","wrapInlineContent","cleanBlockBrs","stripTrailingBrs","transformPasted","normalizeHardBreaks","stripRichMarks","mirrorParagraphMargins","Slice","openStart","openEnd"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export declare const Menus: ({
2
3
  displayName: string;
3
4
  key: number;
@@ -1,2 +1,2 @@
1
- import{jsxs as t,jsx as n}from"react/jsx-runtime";import{getMarkRange as e}from"../node_modules/@tiptap/core/dist/index.js";import{useEditor as o,EditorContent as i}from"@tiptap/react";import{forwardRef as r,useRef as l,useEffect as s,useImperativeHandle as c}from"react";import{BikEditorShell as a}from"./BikEditor.styles.js";import{DEFAULT_FORMAT_STATE as u}from"./BikEditor.types.js";import{buildSectionedContent as d,normalizeHtml as m,extractContent as g,extractActiveFormats as v,extractSectionContent as h,extractBodyContent as f,insertInlineHtml as p,setSectionContentInEditor as C,findSectionEndPos as S,findSectionStartPos as k}from"./BikEditor.utils.js";import{buildExtensions as y}from"./extensions/buildExtensions.js";import{LinkBubbleMenu as x}from"./floating/LinkBubbleMenu.js";function B(t){return Object.entries(t).map((t=>{let[n,e]=t;return`${n.replace(/([A-Z])/g,(t=>`-${t.toLowerCase()}`))}:${e}`})).join(";")}const b=r(((r,b)=>{var A,I,j,L,E,O,T;const{initialContent:w,sections:F,features:H,disabled:M,maxCharacters:z,shortcuts:P,sendShortcut:R,mentions:D,slashCommands:N,link:U,onPaste:$,onReady:q,onChange:J,onSend:V,onFocus:W,onBlur:Z,onSelectionChange:_,minHeight:G,maxHeight:K,style:Q,className:X,editorClassName:Y,editorStyle:tt}=r,nt=(null==F?void 0:F.length)?d(m(null!=w?w:""),F.map((t=>Object.assign(Object.assign({},t),{content:m(t.content)})))):m(null!=w?w:""),et=l([]),ot=l(!1),it=l(q);it.current=q;const rt=l(J);rt.current=J;const lt=l(_);lt.current=_;const st=l(W);st.current=W;const ct=l(Z);ct.current=Z;const at=l(V);at.current=V;const ut=l(null!==(A=null==D?void 0:D.agents)&&void 0!==A?A:[]);ut.current=null!==(I=null==D?void 0:D.agents)&&void 0!==I?I:[];const dt=l(null!==(j=null==D?void 0:D.teams)&&void 0!==j?j:[]);dt.current=null!==(L=null==D?void 0:D.teams)&&void 0!==L?L:[];const mt=l(null!==(E=null==N?void 0:N.items)&&void 0!==E?E:[]);mt.current=null!==(O=null==N?void 0:N.items)&&void 0!==O?O:[];const gt=o({extensions:y({features:H,placeholder:r.placeholder,maxCharacters:z,hasSections:(null!==(T=null==F?void 0:F.length)&&void 0!==T?T:0)>0,mentions:{agents:D?ut:void 0,teams:D?dt:void 0},slashCommands:N?mt:void 0,onPaste:$,onSend:V?t=>{var n;return null===(n=at.current)||void 0===n?void 0:n.call(at,t)}:void 0,sendShortcut:R,shortcuts:P,onMentionSelected:null==D?void 0:D.onSelect,onSlashCommandSelected:null==N?void 0:N.onSelect,renderMentionItem:null==D?void 0:D.renderItem,renderMentionDropdown:null==D?void 0:D.renderDropdown,renderSlashCommandItem:null==N?void 0:N.renderItem,renderSlashCommandDropdown:null==N?void 0:N.renderDropdown}),content:nt,editable:!M,immediatelyRender:!1,editorProps:{attributes:Object.assign(Object.assign({},Y?{class:Y}:{}),tt?{style:B(tt)}:{})},onUpdate:t=>{let{editor:n}=t;var e;null===(e=rt.current)||void 0===e||e.call(rt,g(n))},onTransaction:t=>{let{editor:n}=t;var e;null===(e=lt.current)||void 0===e||e.call(lt,v(n))},onFocus:()=>{var t;return null===(t=st.current)||void 0===t?void 0:t.call(st)},onBlur:()=>{var t;return null===(t=ct.current)||void 0===t?void 0:t.call(ct)}});function vt(t){gt?t(gt):et.current.push(t)}return s((()=>{var t;if(gt){if(et.current.length>0){et.current.splice(0).forEach((t=>t(gt)))}ot.current||(ot.current=!0,null===(t=it.current)||void 0===t||t.call(it))}}),[gt]),c(b,(()=>({focus:t=>vt((n=>n.commands.focus(t))),blur:()=>vt((t=>t.commands.blur())),clearContent:()=>vt((t=>t.commands.clearContent(!0))),setContent:t=>{const n=m(t);vt((t=>t.commands.setContent(n,{emitUpdate:!0})))},insertContent:t=>{const n=m(t);vt((t=>t.commands.insertContent(n)))},insertInlineContent:t=>{vt((n=>p(n,t)))},insertAtStart:t=>{const n=m(t);vt((t=>t.commands.insertContentAt(1,n)))},insertBlock:t=>{const n=m(t);vt((t=>t.commands.insertContentAt(t.state.doc.content.size,n)))},appendInline:t=>{const n=m(t);vt((t=>t.commands.insertContentAt(t.state.doc.content.size-1,n)))},insertAtEnd(t){this.insertBlock(t)},appendContent(t){this.appendInline(t)},getContent:()=>gt?g(gt):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>{var t;return null!==(t=null==gt?void 0:gt.getJSON())&&void 0!==t?t:null},getMentions:()=>{const t=new Set,n=new Set;return gt?(gt.state.doc.descendants((e=>{"mentionAgent"===e.type.name&&null!=e.attrs.id?t.add(String(e.attrs.id)):"mentionTeam"===e.type.name&&null!=e.attrs.id&&n.add(String(e.attrs.id))})),{agentIds:Array.from(t),teamIds:Array.from(n)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!gt)return{from:0,to:0};const{from:t,to:n}=gt.state.selection;return{from:t,to:n}},insertAtPosition:(t,n)=>{const e=m(n);vt((n=>n.commands.insertContentAt(t,e)))},getSelectedText:()=>{if(!gt)return"";const{state:t}=gt,{from:n,to:o,empty:i}=t.selection;if(!i)return t.doc.textBetween(n,o," ");const r=t.schema.marks.link;if(r){const o=e(t.doc.resolve(n),r);if(o)return t.doc.textBetween(o.from,o.to," ")}return""},getCharacterCount:()=>{var t,n,e,o;return{count:null!==(o=null!==(e=null===(n=null===(t=null==gt?void 0:gt.storage.characterCount)||void 0===t?void 0:t.characters)||void 0===n?void 0:n.call(t))&&void 0!==e?e:null==gt?void 0:gt.getText().length)&&void 0!==o?o:0,limit:null!=z?z:null}},getSectionContent:t=>gt?h(gt,t):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(t,n)=>{const e=m(n);vt((n=>C(n,t,e)))},focusSection:t=>{vt((n=>{if("body"===t){let t=n.state.doc.content.size-1;return n.state.doc.descendants(((e,o)=>("sectionDivider"===e.type.name&&t===n.state.doc.content.size-1&&(t=o-1),t===n.state.doc.content.size-1))),t<1&&(t=1),void n.chain().focus().setTextSelection(t).run()}let e=-1;n.state.doc.descendants(((n,o)=>{if(-1!==e)return!1;"sectionDivider"===n.type.name&&n.attrs.sectionId===t&&(e=o+n.nodeSize+1)})),-1!==e&&n.chain().focus().setTextSelection(e).run()}))},clearSection:t=>{vt((n=>C(n,t,"<p></p>")))},getBodyContent:()=>gt?f(gt):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:t=>{const n=m(t);vt((t=>C(t,"body",n)))},setBodyAndSections:(t,n)=>{const e=d(m(t),n.map((t=>({id:t.id,content:m(t.content)}))));vt((t=>t.commands.setContent(e,{emitUpdate:!0})))},appendBodyContent:t=>{const n=m(t);vt((t=>{const e=S(t,"body");t.commands.insertContentAt(e-1,n)}))},insertAtSectionStart:(t,n)=>{const e=m(n);vt((n=>{const o=k(n,t);-1!==o&&n.commands.insertContentAt(o,e)}))},insertAtSectionEnd:(t,n)=>{const e=m(n);vt((n=>{const o=S(n,t);n.commands.insertContentAt(o,e)}))},getActiveFormats:()=>gt?v(gt):u,actions:{toggleBold:()=>null==gt?void 0:gt.chain().focus().toggleBold().run(),toggleItalic:()=>null==gt?void 0:gt.chain().focus().toggleItalic().run(),toggleUnderline:()=>null==gt?void 0:gt.chain().focus().toggleUnderline().run(),toggleStrike:()=>null==gt?void 0:gt.chain().focus().toggleStrike().run(),toggleBulletList:()=>null==gt?void 0:gt.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>null==gt?void 0:gt.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>null==gt?void 0:gt.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>null==gt?void 0:gt.chain().focus().toggleCodeBlock().run(),setTextAlign:t=>null==gt?void 0:gt.chain().focus().setTextAlign(t).run(),setFontFamily:t=>null==gt?void 0:gt.chain().focus().setFontFamily(t).run(),setFontSize:t=>null==gt?void 0:gt.chain().focus().setFontSize(t).run(),setColor:t=>null==gt?void 0:gt.chain().focus().setColor(t).run(),setHighlight:t=>null==gt?void 0:gt.chain().focus().toggleHighlight({color:t}).run(),unsetColor:()=>null==gt?void 0:gt.chain().focus().unsetColor().run(),unsetHighlight:()=>null==gt?void 0:gt.chain().focus().unsetHighlight().run(),setLink:(t,n)=>{gt&&(void 0!==n?gt.chain().focus().extendMarkRange("link").command((e=>{let{tr:o,state:i}=e;const{from:r,to:l}=o.selection,s=i.schema.marks.link;if(!s)return!1;const c=i.schema.text(n,[s.create({href:t})]),a=i.schema.text(" ");return o.replaceWith(r,l,[c,a]),!0})).run():gt.chain().focus().extendMarkRange("link").setLink({href:t}).insertContent(" ").run())},updateLink:t=>null==gt?void 0:gt.chain().focus().extendMarkRange("link").setLink({href:t}).run(),removeLink:()=>null==gt?void 0:gt.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:t=>null==gt?void 0:gt.chain().focus().insertContent(t).run(),insertVariable:t=>null==gt?void 0:gt.chain().focus().insertContent(`{{${t}}}`).run(),insertHtml:t=>null==gt?void 0:gt.commands.insertContent(m(t)),undo:()=>null==gt?void 0:gt.chain().focus().undo().run(),redo:()=>null==gt?void 0:gt.chain().focus().redo().run(),canUndo:()=>{var t;return null!==(t=null==gt?void 0:gt.can().undo())&&void 0!==t&&t},canRedo:()=>{var t;return null!==(t=null==gt?void 0:gt.can().redo())&&void 0!==t&&t},toggleSuperscript:()=>null==gt?void 0:gt.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>null==gt?void 0:gt.chain().focus().toggleSubscript().run(),insertImage:t=>null==gt?void 0:gt.chain().focus().setImage({src:t}).run()}})),[gt]),gt?t(a,Object.assign({minHeight:G,maxHeight:K,tightParagraphs:!(null==H?void 0:H.richPaste),style:Q,className:X},{children:[n(i,{editor:gt}),n(x,{editor:gt,renderLinkTooltip:null==U?void 0:U.renderTooltip})]})):null}));b.displayName="BikEditor";export{b as BikEditor};
1
+ import{jsxs as t,jsx as n}from"react/jsx-runtime";import{getMarkRange as e}from"../node_modules/@tiptap/core/dist/index.js";import{useEditor as o,EditorContent as i}from"@tiptap/react";import{forwardRef as r,useRef as l,useEffect as s,useImperativeHandle as c}from"react";import{BikEditorShell as u}from"./BikEditor.styles.js";import{DEFAULT_FORMAT_STATE as d}from"./BikEditor.types.js";import{buildSectionedContent as a,normalizeHtml as m,extractContent as g,extractActiveFormats as v,extractSectionContent as h,extractBodyContent as f,insertInlineHtml as p,setSectionContentInEditor as C,findSectionEndPos as S,findSectionStartPos as k}from"./BikEditor.utils.js";import{buildExtensions as y}from"./extensions/buildExtensions.js";import{LinkBubbleMenu as x}from"./floating/LinkBubbleMenu.js";function b(t){return Object.entries(t).map((t=>{let[n,e]=t;return`${n.replace(/([A-Z])/g,(t=>`-${t.toLowerCase()}`))}:${e}`})).join(";")}const B=r(((r,B)=>{var A,L,I,j,E,F,z;const{initialContent:O,sections:T,features:w,disabled:H,maxCharacters:M,shortcuts:P,sendShortcut:R,mentions:D,slashCommands:N,link:U,onPaste:q,onReady:$,onChange:J,onSend:V,onFocus:W,onBlur:Z,onSelectionChange:_,minHeight:G,maxHeight:K,style:Q,className:X,editorClassName:Y,editorStyle:tt}=r,nt=(null==T?void 0:T.length)?a(m(null!=O?O:""),T.map((t=>Object.assign(Object.assign({},t),{content:m(t.content)})))):m(null!=O?O:""),et=l([]),ot=l(!1),it=l($);it.current=$;const rt=l(J);rt.current=J;const lt=l(_);lt.current=_;const st=l(d),ct=l(W);ct.current=W;const ut=l(Z);ut.current=Z;const dt=l(V);dt.current=V;const at=l(null!==(A=null==D?void 0:D.agents)&&void 0!==A?A:[]);at.current=null!==(L=null==D?void 0:D.agents)&&void 0!==L?L:[];const mt=l(null!==(I=null==D?void 0:D.teams)&&void 0!==I?I:[]);mt.current=null!==(j=null==D?void 0:D.teams)&&void 0!==j?j:[];const gt=l(null!==(E=null==N?void 0:N.items)&&void 0!==E?E:[]);gt.current=null!==(F=null==N?void 0:N.items)&&void 0!==F?F:[];const vt=o({extensions:y({features:w,placeholder:r.placeholder,maxCharacters:M,hasSections:(null!==(z=null==T?void 0:T.length)&&void 0!==z?z:0)>0,mentions:{agents:D?at:void 0,teams:D?mt:void 0},slashCommands:N?gt:void 0,onPaste:q,onSend:V?t=>{var n;return null===(n=dt.current)||void 0===n?void 0:n.call(dt,t)}:void 0,sendShortcut:R,shortcuts:P,onMentionSelected:null==D?void 0:D.onSelect,onSlashCommandSelected:null==N?void 0:N.onSelect,renderMentionItem:null==D?void 0:D.renderItem,renderMentionDropdown:null==D?void 0:D.renderDropdown,renderSlashCommandItem:null==N?void 0:N.renderItem,renderSlashCommandDropdown:null==N?void 0:N.renderDropdown}),content:nt,editable:!H,immediatelyRender:!1,editorProps:{attributes:Object.assign(Object.assign({},Y?{class:Y}:{}),tt?{style:b(tt)}:{})},onUpdate:t=>{let{editor:n}=t;var e;null===(e=rt.current)||void 0===e||e.call(rt,g(n))},onTransaction:t=>{let{editor:n}=t;var e,o,i;const r=v(n),l=st.current;(l.bold!==r.bold||l.italic!==r.italic||l.underline!==r.underline||l.strike!==r.strike||l.bulletList!==r.bulletList||l.orderedList!==r.orderedList||l.blockquote!==r.blockquote||l.codeBlock!==r.codeBlock||l.superscript!==r.superscript||l.subscript!==r.subscript||l.textAlign!==r.textAlign||l.fontFamily!==r.fontFamily||l.fontSize!==r.fontSize||l.color!==r.color||l.highlight!==r.highlight||(null===(e=l.link)||void 0===e?void 0:e.href)!==(null===(o=r.link)||void 0===o?void 0:o.href))&&(st.current=r,null===(i=lt.current)||void 0===i||i.call(lt,r))},onFocus:()=>{var t;return null===(t=ct.current)||void 0===t?void 0:t.call(ct)},onBlur:()=>{var t;return null===(t=ut.current)||void 0===t?void 0:t.call(ut)}});function ht(t){vt?t(vt):et.current.push(t)}return s((()=>{var t;if(vt){if(et.current.length>0){et.current.splice(0).forEach((t=>t(vt)))}ot.current||(ot.current=!0,null===(t=it.current)||void 0===t||t.call(it))}}),[vt]),c(B,(()=>({focus:t=>ht((n=>n.commands.focus(t))),blur:()=>ht((t=>t.commands.blur())),clearContent:()=>ht((t=>t.commands.clearContent(!0))),setContent:t=>{const n=m(t);ht((t=>t.commands.setContent(n,{emitUpdate:!0})))},insertContent:t=>{const n=m(t);ht((t=>t.commands.insertContent(n)))},insertInlineContent:t=>{ht((n=>p(n,t)))},insertAtStart:t=>{const n=m(t);ht((t=>t.commands.insertContentAt(1,n)))},insertBlock:t=>{const n=m(t);ht((t=>t.commands.insertContentAt(t.state.doc.content.size,n)))},appendInline:t=>{const n=m(t);ht((t=>t.commands.insertContentAt(t.state.doc.content.size-1,n)))},insertAtEnd(t){this.insertBlock(t)},appendContent(t){this.appendInline(t)},getContent:()=>vt?g(vt):{html:"",text:"",isEmpty:!0,characterCount:0},getJSON:()=>{var t;return null!==(t=null==vt?void 0:vt.getJSON())&&void 0!==t?t:null},getMentions:()=>{const t=new Set,n=new Set;return vt?(vt.state.doc.descendants((e=>{"mentionAgent"===e.type.name&&null!=e.attrs.id?t.add(String(e.attrs.id)):"mentionTeam"===e.type.name&&null!=e.attrs.id&&n.add(String(e.attrs.id))})),{agentIds:Array.from(t),teamIds:Array.from(n)}):{agentIds:[],teamIds:[]}},getCursorPosition:()=>{if(!vt)return{from:0,to:0};const{from:t,to:n}=vt.state.selection;return{from:t,to:n}},insertAtPosition:(t,n)=>{const e=m(n);ht((n=>n.commands.insertContentAt(t,e)))},getSelectedText:()=>{if(!vt)return"";const{state:t}=vt,{from:n,to:o,empty:i}=t.selection;if(!i)return t.doc.textBetween(n,o," ");const r=t.schema.marks.link;if(r){const o=e(t.doc.resolve(n),r);if(o)return t.doc.textBetween(o.from,o.to," ")}return""},getCharacterCount:()=>{var t,n,e,o;return{count:null!==(o=null!==(e=null===(n=null===(t=null==vt?void 0:vt.storage.characterCount)||void 0===t?void 0:t.characters)||void 0===n?void 0:n.call(t))&&void 0!==e?e:null==vt?void 0:vt.getText().length)&&void 0!==o?o:0,limit:null!=M?M:null}},getSectionContent:t=>vt?h(vt,t):{html:"",text:"",isEmpty:!0,characterCount:0},setSectionContent:(t,n)=>{const e=m(n);ht((n=>C(n,t,e)))},focusSection:t=>{ht((n=>{if("body"===t){let t=n.state.doc.content.size-1;return n.state.doc.descendants(((e,o)=>("sectionDivider"===e.type.name&&t===n.state.doc.content.size-1&&(t=o-1),t===n.state.doc.content.size-1))),t<1&&(t=1),void n.chain().focus().setTextSelection(t).run()}let e=-1;n.state.doc.descendants(((n,o)=>{if(-1!==e)return!1;"sectionDivider"===n.type.name&&n.attrs.sectionId===t&&(e=o+n.nodeSize+1)})),-1!==e&&n.chain().focus().setTextSelection(e).run()}))},clearSection:t=>{ht((n=>C(n,t,"<p></p>")))},getBodyContent:()=>vt?f(vt):{html:"",text:"",isEmpty:!0,characterCount:0},setBodyContent:t=>{const n=m(t);ht((t=>C(t,"body",n)))},setBodyAndSections:(t,n)=>{const e=a(m(t),n.map((t=>({id:t.id,content:m(t.content)}))));ht((t=>t.commands.setContent(e,{emitUpdate:!0})))},appendBodyContent:t=>{const n=m(t);ht((t=>{const e=S(t,"body");t.commands.insertContentAt(e-1,n)}))},insertAtSectionStart:(t,n)=>{const e=m(n);ht((n=>{const o=k(n,t);-1!==o&&n.commands.insertContentAt(o,e)}))},insertAtSectionEnd:(t,n)=>{const e=m(n);ht((n=>{const o=S(n,t);n.commands.insertContentAt(o,e)}))},getActiveFormats:()=>vt?v(vt):d,actions:{toggleBold:()=>null==vt?void 0:vt.chain().focus().toggleBold().run(),toggleItalic:()=>null==vt?void 0:vt.chain().focus().toggleItalic().run(),toggleUnderline:()=>null==vt?void 0:vt.chain().focus().toggleUnderline().run(),toggleStrike:()=>null==vt?void 0:vt.chain().focus().toggleStrike().run(),toggleBulletList:()=>null==vt?void 0:vt.chain().focus().toggleBulletList().run(),toggleOrderedList:()=>null==vt?void 0:vt.chain().focus().toggleOrderedList().run(),toggleBlockquote:()=>null==vt?void 0:vt.chain().focus().toggleBlockquote().run(),toggleCodeBlock:()=>null==vt?void 0:vt.chain().focus().toggleCodeBlock().run(),setTextAlign:t=>null==vt?void 0:vt.chain().focus().setTextAlign(t).run(),setFontFamily:t=>null==vt?void 0:vt.chain().focus().setFontFamily(t).run(),setFontSize:t=>null==vt?void 0:vt.chain().focus().setFontSize(t).run(),setColor:t=>null==vt?void 0:vt.chain().focus().setColor(t).run(),setHighlight:t=>null==vt?void 0:vt.chain().focus().toggleHighlight({color:t}).run(),unsetColor:()=>null==vt?void 0:vt.chain().focus().unsetColor().run(),unsetHighlight:()=>null==vt?void 0:vt.chain().focus().unsetHighlight().run(),setLink:(t,n)=>{vt&&(void 0!==n?vt.chain().focus().extendMarkRange("link").command((e=>{let{tr:o,state:i}=e;const{from:r,to:l}=o.selection,s=i.schema.marks.link;if(!s)return!1;const c=i.schema.text(n,[s.create({href:t})]),u=i.schema.text(" ");return o.replaceWith(r,l,[c,u]),!0})).run():vt.chain().focus().extendMarkRange("link").setLink({href:t}).insertContent(" ").run())},updateLink:t=>null==vt?void 0:vt.chain().focus().extendMarkRange("link").setLink({href:t}).run(),removeLink:()=>null==vt?void 0:vt.chain().focus().extendMarkRange("link").unsetLink().run(),insertEmoji:t=>null==vt?void 0:vt.chain().focus().insertContent(t).run(),insertVariable:t=>null==vt?void 0:vt.chain().focus().insertContent(`{{${t}}}`).run(),insertHtml:t=>null==vt?void 0:vt.commands.insertContent(m(t)),undo:()=>null==vt?void 0:vt.chain().focus().undo().run(),redo:()=>null==vt?void 0:vt.chain().focus().redo().run(),canUndo:()=>{var t;return null!==(t=null==vt?void 0:vt.can().undo())&&void 0!==t&&t},canRedo:()=>{var t;return null!==(t=null==vt?void 0:vt.can().redo())&&void 0!==t&&t},toggleSuperscript:()=>null==vt?void 0:vt.chain().focus().toggleSuperscript().run(),toggleSubscript:()=>null==vt?void 0:vt.chain().focus().toggleSubscript().run(),insertImage:t=>null==vt?void 0:vt.chain().focus().setImage({src:t}).run()}})),[vt]),vt?t(u,Object.assign({minHeight:G,maxHeight:K,tightParagraphs:!(null==w?void 0:w.richPaste),style:Q,className:X},{children:[n(i,{editor:vt}),n(x,{editor:vt,renderLinkTooltip:null==U?void 0:U.renderTooltip})]})):null}));B.displayName="BikEditor";export{B as BikEditor};
2
2
  //# sourceMappingURL=BikEditor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from 'react';\nimport { BikEditorShell } from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n} from './BikEditor.types';\nimport {\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t} = props;\n\n\tconst initialEditorContent = sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tonSelectionChangeRef.current?.(extractActiveFormats(e));\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t}, [editor]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1) e.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","Object","entries","map","_ref","k","v","replace","c","toLowerCase","join","BikEditor","forwardRef","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","initialEditorContent","length","buildSectionedContent","normalizeHtml","s","assign","content","pendingQueue","useRef","hasCalledOnReady","onReadyRef","current","onChangeRef","onSelectionChangeRef","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","agents","_a","_b","teamMentionsRef","teams","_c","_d","slashCommandsRef","items","_e","_f","editor","useEditor","extensions","buildExtensions","placeholder","hasSections","_g","undefined","snapshot","call","onMentionSelected","onSelect","onSlashCommandSelected","renderMentionItem","renderItem","renderMentionDropdown","renderDropdown","renderSlashCommandItem","renderSlashCommandDropdown","editable","immediatelyRender","editorProps","attributes","class","onUpdate","_ref2","e","extractContent","onTransaction","_ref3","extractActiveFormats","enqueue","op","push","useEffect","splice","forEach","useImperativeHandle","focus","position","commands","blur","clearContent","setContent","html","normalised","emitUpdate","insertContent","insertInlineContent","insertInlineHtml","insertAtStart","insertContentAt","insertBlock","state","doc","size","appendInline","insertAtEnd","this","appendContent","getContent","text","isEmpty","characterCount","getJSON","getMentions","agentIds","Set","teamIds","descendants","node","type","name","attrs","add","String","Array","from","getCursorPosition","to","selection","insertAtPosition","pos","getSelectedText","empty","textBetween","linkMarkType","schema","marks","range","getMarkRange","resolve","getCharacterCount","count","storage","characters","getText","limit","getSectionContent","sectionId","extractSectionContent","setSectionContent","setSectionContentInEditor","focusSection","endOfBody","chain","setTextSelection","run","targetPos","nodeSize","clearSection","getBodyContent","extractBodyContent","setBodyContent","setBodyAndSections","body","id","appendBodyContent","boundaryPos","findSectionEndPos","insertAtSectionStart","findSectionStartPos","insertAtSectionEnd","getActiveFormats","DEFAULT_FORMAT_STATE","actions","toggleBold","toggleItalic","toggleUnderline","toggleStrike","toggleBulletList","toggleOrderedList","toggleBlockquote","toggleCodeBlock","setTextAlign","align","setFontFamily","font","setFontSize","setColor","color","setHighlight","toggleHighlight","unsetColor","unsetHighlight","setLink","href","extendMarkRange","command","_ref4","tr","linkNode","create","space","replaceWith","updateLink","removeLink","unsetLink","insertEmoji","emoji","insertVariable","variableName","insertHtml","undo","redo","canUndo","can","canRedo","toggleSuperscript","toggleSubscript","insertImage","src","setImage","_jsxs","BikEditorShell","tightParagraphs","richPaste","children","_jsx","EditorContent","LinkBubbleMenu","renderLinkTooltip","renderTooltip","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"BikEditor.js","sources":["../../../src/editor/BikEditor.tsx"],"sourcesContent":["'use client';\n\n/**\n * IMPLEMENTATION LAYER — TipTap-specific.\n * If the underlying editor is swapped, this file changes; BikEditor.types.ts and\n * src/editor/index.ts (the consumer contract) do NOT change.\n */\nimport { Editor, getMarkRange } from '@tiptap/core';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport React, {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n} from 'react';\nimport { BikEditorShell } from './BikEditor.styles';\nimport {\n\tBikEditorProps,\n\tBikEditorRef,\n\tDEFAULT_FORMAT_STATE,\n\tFormatState,\n} from './BikEditor.types';\nimport {\n\tbuildSectionedContent,\n\textractActiveFormats,\n\textractBodyContent,\n\textractContent,\n\textractSectionContent,\n\tfindSectionEndPos,\n\tfindSectionStartPos,\n\tinsertInlineHtml,\n\tnormalizeHtml,\n\tsetSectionContentInEditor,\n} from './BikEditor.utils';\nimport { buildExtensions } from './extensions/buildExtensions';\nimport { LinkBubbleMenu } from './floating/LinkBubbleMenu';\n\n/** Convert React.CSSProperties to an inline CSS string for editorProps.attributes. */\nfunction cssToString(style: React.CSSProperties): string {\n\treturn Object.entries(style)\n\t\t.map(\n\t\t\t([k, v]) => `${k.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`)}:${v}`,\n\t\t)\n\t\t.join(';');\n}\n\nconst BikEditorInner = (\n\tprops: BikEditorProps,\n\tref: React.Ref<BikEditorRef>,\n) => {\n\tconst {\n\t\tinitialContent,\n\t\tsections,\n\t\tfeatures,\n\t\tdisabled,\n\t\tmaxCharacters,\n\t\tshortcuts,\n\t\tsendShortcut,\n\t\tmentions,\n\t\tslashCommands,\n\t\tlink,\n\t\tonPaste,\n\t\tonReady,\n\t\tonChange,\n\t\tonSend,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonSelectionChange,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tstyle,\n\t\tclassName,\n\t\teditorClassName,\n\t\teditorStyle,\n\t} = props;\n\n\tconst initialEditorContent = sections?.length\n\t\t? buildSectionedContent(\n\t\t\t\tnormalizeHtml(initialContent ?? ''),\n\t\t\t\tsections.map((s) => ({ ...s, content: normalizeHtml(s.content) })),\n\t\t )\n\t\t: normalizeHtml(initialContent ?? '');\n\n\t// ── Command queue ─────────────────────────────────────────────────────────\n\t// TipTap's useEditor initializes asynchronously; the editor instance is null\n\t// until the first commit. Any imperative method called before the editor is\n\t// ready is enqueued here and flushed automatically once it becomes non-null.\n\t// Consumers never need setTimeout or readiness guards.\n\tconst pendingQueue = useRef<Array<(e: Editor) => void>>([]);\n\tconst hasCalledOnReady = useRef(false);\n\t// Keep stable refs to all callbacks so useEditor receives the same function\n\t// identity on every render — prevents TipTap from re-registering event\n\t// handlers every time the parent re-renders with new inline function props.\n\tconst onReadyRef = useRef(onReady);\n\tonReadyRef.current = onReady;\n\tconst onChangeRef = useRef(onChange);\n\tonChangeRef.current = onChange;\n\tconst onSelectionChangeRef = useRef(onSelectionChange);\n\tonSelectionChangeRef.current = onSelectionChange;\n\tconst prevFormatsRef = useRef<FormatState>(DEFAULT_FORMAT_STATE);\n\tconst onFocusRef = useRef(onFocus);\n\tonFocusRef.current = onFocus;\n\tconst onBlurRef = useRef(onBlur);\n\tonBlurRef.current = onBlur;\n\tconst onSendRef = useRef(onSend);\n\tonSendRef.current = onSend;\n\tconst agentMentionsRef = useRef(mentions?.agents ?? []);\n\tagentMentionsRef.current = mentions?.agents ?? [];\n\tconst teamMentionsRef = useRef(mentions?.teams ?? []);\n\tteamMentionsRef.current = mentions?.teams ?? [];\n\tconst slashCommandsRef = useRef(slashCommands?.items ?? []);\n\tslashCommandsRef.current = slashCommands?.items ?? [];\n\n\tconst editor = useEditor({\n\t\textensions: buildExtensions({\n\t\t\tfeatures,\n\t\t\tplaceholder: props.placeholder,\n\t\t\tmaxCharacters,\n\t\t\thasSections: (sections?.length ?? 0) > 0,\n\t\t\tmentions: {\n\t\t\t\tagents: mentions ? agentMentionsRef : undefined,\n\t\t\t\tteams: mentions ? teamMentionsRef : undefined,\n\t\t\t},\n\t\t\tslashCommands: slashCommands ? slashCommandsRef : undefined,\n\t\t\tonPaste,\n\t\t\tonSend: onSend ? (snapshot) => onSendRef.current?.(snapshot) : undefined,\n\t\t\tsendShortcut,\n\t\t\tshortcuts,\n\t\t\tonMentionSelected: mentions?.onSelect,\n\t\t\tonSlashCommandSelected: slashCommands?.onSelect,\n\t\t\trenderMentionItem: mentions?.renderItem,\n\t\t\trenderMentionDropdown: mentions?.renderDropdown,\n\t\t\trenderSlashCommandItem: slashCommands?.renderItem,\n\t\t\trenderSlashCommandDropdown: slashCommands?.renderDropdown,\n\t\t}),\n\t\tcontent: initialEditorContent,\n\t\teditable: !disabled,\n\t\timmediatelyRender: false, // SSR-safe — NEVER remove this\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\t...(editorClassName ? { class: editorClassName } : {}),\n\t\t\t\t...(editorStyle ? { style: cssToString(editorStyle) } : {}),\n\t\t\t},\n\t\t},\n\t\tonUpdate: ({ editor: e }) => {\n\t\t\tonChangeRef.current?.(extractContent(e));\n\t\t},\n\t\tonTransaction: ({ editor: e }) => {\n\t\t\tconst next = extractActiveFormats(e);\n\t\t\tconst prev = prevFormatsRef.current;\n\t\t\tconst changed =\n\t\t\t\tprev.bold !== next.bold ||\n\t\t\t\tprev.italic !== next.italic ||\n\t\t\t\tprev.underline !== next.underline ||\n\t\t\t\tprev.strike !== next.strike ||\n\t\t\t\tprev.bulletList !== next.bulletList ||\n\t\t\t\tprev.orderedList !== next.orderedList ||\n\t\t\t\tprev.blockquote !== next.blockquote ||\n\t\t\t\tprev.codeBlock !== next.codeBlock ||\n\t\t\t\tprev.superscript !== next.superscript ||\n\t\t\t\tprev.subscript !== next.subscript ||\n\t\t\t\tprev.textAlign !== next.textAlign ||\n\t\t\t\tprev.fontFamily !== next.fontFamily ||\n\t\t\t\tprev.fontSize !== next.fontSize ||\n\t\t\t\tprev.color !== next.color ||\n\t\t\t\tprev.highlight !== next.highlight ||\n\t\t\t\tprev.link?.href !== next.link?.href;\n\t\t\tif (changed) {\n\t\t\t\tprevFormatsRef.current = next;\n\t\t\t\tonSelectionChangeRef.current?.(next);\n\t\t\t}\n\t\t},\n\t\tonFocus: () => onFocusRef.current?.(),\n\t\tonBlur: () => onBlurRef.current?.(),\n\t});\n\n\t// ── enqueue ───────────────────────────────────────────────────────────────\n\t// Run immediately if the editor is ready; otherwise defer to the queue.\n\t// Closures passed to enqueue MUST capture all parameters explicitly —\n\t// they must NOT close over `editor` (which would be null at enqueue time).\n\tfunction enqueue(op: (e: Editor) => void): void {\n\t\tif (editor) {\n\t\t\top(editor);\n\t\t} else {\n\t\t\tpendingQueue.current.push(op);\n\t\t}\n\t}\n\n\t// Flush the pending queue and fire onReady when editor transitions null → ready.\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\t\tif (pendingQueue.current.length > 0) {\n\t\t\tconst queue = pendingQueue.current.splice(0);\n\t\t\tqueue.forEach((op) => op(editor));\n\t\t}\n\t\tif (!hasCalledOnReady.current) {\n\t\t\thasCalledOnReady.current = true;\n\t\t\tonReadyRef.current?.();\n\t\t}\n\t}, [editor]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\t// ── Focus ────────────────────────────────────────────────────────\n\t\t\tfocus: (position) => enqueue((e) => e.commands.focus(position)),\n\t\t\tblur: () => enqueue((e) => e.commands.blur()),\n\n\t\t\t// ── Content ──────────────────────────────────────────────────────\n\t\t\tclearContent: () => enqueue((e) => e.commands.clearContent(true)),\n\t\t\tsetContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.setContent(normalised, { emitUpdate: true }));\n\t\t\t},\n\t\t\tinsertContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContent(normalised));\n\t\t\t},\n\t\t\tinsertInlineContent: (html) => {\n\t\t\t\tenqueue((e) => insertInlineHtml(e, html));\n\t\t\t},\n\t\t\tinsertAtStart: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(1, normalised));\n\t\t\t},\n\t\t\tinsertBlock: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\tappendInline: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// doc.content.size is after the last </p> (block boundary).\n\t\t\t\t// Subtract 1 to land inside the last paragraph so text appends\n\t\t\t\t// inline rather than being wrapped in a new paragraph each call.\n\t\t\t\tenqueue((e) =>\n\t\t\t\t\te.commands.insertContentAt(e.state.doc.content.size - 1, normalised),\n\t\t\t\t);\n\t\t\t},\n\t\t\t// Backwards-compatible aliases\n\t\t\tinsertAtEnd(html) {\n\t\t\t\tthis.insertBlock(html);\n\t\t\t},\n\t\t\tappendContent(html) {\n\t\t\t\tthis.appendInline(html);\n\t\t\t},\n\t\t\tgetContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tgetJSON: () => editor?.getJSON() ?? null,\n\t\t\tgetMentions: () => {\n\t\t\t\tconst agentIds = new Set<string>();\n\t\t\t\tconst teamIds = new Set<string>();\n\t\t\t\tif (!editor) return { agentIds: [], teamIds: [] };\n\t\t\t\teditor.state.doc.descendants((node) => {\n\t\t\t\t\tif (node.type.name === 'mentionAgent' && node.attrs['id'] != null) {\n\t\t\t\t\t\tagentIds.add(String(node.attrs['id']));\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tnode.type.name === 'mentionTeam' &&\n\t\t\t\t\t\tnode.attrs['id'] != null\n\t\t\t\t\t) {\n\t\t\t\t\t\tteamIds.add(String(node.attrs['id']));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn { agentIds: Array.from(agentIds), teamIds: Array.from(teamIds) };\n\t\t\t},\n\n\t\t\t// ── Selection ────────────────────────────────────────────────────\n\t\t\tgetCursorPosition: () => {\n\t\t\t\tif (!editor) return { from: 0, to: 0 };\n\t\t\t\tconst { from, to } = editor.state.selection;\n\t\t\t\treturn { from, to };\n\t\t\t},\n\t\t\tinsertAtPosition: (pos, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => e.commands.insertContentAt(pos, normalised));\n\t\t\t},\n\t\t\tgetSelectedText: () => {\n\t\t\t\tif (!editor) return '';\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst { from, to, empty } = state.selection;\n\t\t\t\tif (!empty) {\n\t\t\t\t\treturn state.doc.textBetween(from, to, ' ');\n\t\t\t\t}\n\t\t\t\t// When the cursor is inside a link with nothing selected, return the\n\t\t\t\t// full link text — useful for pre-filling a link modal's text field.\n\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\tif (linkMarkType) {\n\t\t\t\t\tconst range = getMarkRange(state.doc.resolve(from), linkMarkType);\n\t\t\t\t\tif (range) {\n\t\t\t\t\t\treturn state.doc.textBetween(range.from, range.to, ' ');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t\t},\n\n\t\t\t// ── Character count ───────────────────────────────────────────────\n\t\t\tgetCharacterCount: () => ({\n\t\t\t\tcount:\n\t\t\t\t\teditor?.storage.characterCount?.characters?.() ??\n\t\t\t\t\teditor?.getText().length ??\n\t\t\t\t\t0,\n\t\t\t\tlimit: maxCharacters ?? null,\n\t\t\t}),\n\n\t\t\t// ── Sections ─────────────────────────────────────────────────────\n\t\t\tgetSectionContent: (sectionId) =>\n\t\t\t\teditor\n\t\t\t\t\t? extractSectionContent(editor, sectionId)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\n\t\t\tsetSectionContent: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, normalised));\n\t\t\t},\n\n\t\t\tfocusSection: (sectionId) => {\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tif (sectionId === 'body') {\n\t\t\t\t\t\tlet endOfBody = e.state.doc.content.size - 1;\n\t\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\t\tendOfBody === e.state.doc.content.size - 1\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tendOfBody = pos - 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn endOfBody === e.state.doc.content.size - 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (endOfBody < 1) endOfBody = 1;\n\t\t\t\t\t\te.chain().focus().setTextSelection(endOfBody).run();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet targetPos = -1;\n\t\t\t\t\te.state.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (targetPos !== -1) return false;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tnode.type.name === 'sectionDivider' &&\n\t\t\t\t\t\t\tnode.attrs['sectionId'] === sectionId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// pos + nodeSize lands right after the divider;\n\t\t\t\t\t\t\t// +1 more puts us inside the first paragraph of that section.\n\t\t\t\t\t\t\ttargetPos = pos + node.nodeSize + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (targetPos !== -1) {\n\t\t\t\t\t\te.chain().focus().setTextSelection(targetPos).run();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\n\t\t\tclearSection: (sectionId) => {\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, sectionId, '<p></p>'));\n\t\t\t},\n\n\t\t\t// ── Convenience body shorthands ───────────────────────────────────\n\t\t\tgetBodyContent: () =>\n\t\t\t\teditor\n\t\t\t\t\t? extractBodyContent(editor)\n\t\t\t\t\t: { html: '', text: '', isEmpty: true, characterCount: 0 },\n\t\t\tsetBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => setSectionContentInEditor(e, 'body', normalised));\n\t\t\t},\n\t\t\tsetBodyAndSections: (body, sections) => {\n\t\t\t\tconst html = buildSectionedContent(\n\t\t\t\t\tnormalizeHtml(body),\n\t\t\t\t\tsections.map((s) => ({\n\t\t\t\t\t\tid: s.id,\n\t\t\t\t\t\tcontent: normalizeHtml(s.content),\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tenqueue((e) => e.commands.setContent(html, { emitUpdate: true }));\n\t\t\t},\n\t\t\tappendBodyContent: (html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\t// findSectionEndPos returns the position of the first divider (or\n\t\t\t\t// doc.content.size), which is the block boundary after the last </p>.\n\t\t\t\t// Subtract 1 to stay inside the last paragraph so successive calls\n\t\t\t\t// append inline text rather than creating a new paragraph each time.\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst boundaryPos = findSectionEndPos(e, 'body');\n\t\t\t\t\te.commands.insertContentAt(boundaryPos - 1, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionStart: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionStartPos(e, sectionId);\n\t\t\t\t\tif (pos !== -1) e.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\tinsertAtSectionEnd: (sectionId, html) => {\n\t\t\t\tconst normalised = normalizeHtml(html);\n\t\t\t\tenqueue((e) => {\n\t\t\t\t\tconst pos = findSectionEndPos(e, sectionId);\n\t\t\t\t\te.commands.insertContentAt(pos, normalised);\n\t\t\t\t});\n\t\t\t},\n\t\t\t// ── Formats & actions ─────────────────────────────────────────────\n\t\t\tgetActiveFormats: () =>\n\t\t\t\teditor ? extractActiveFormats(editor) : DEFAULT_FORMAT_STATE,\n\t\t\tactions: {\n\t\t\t\ttoggleBold: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t\ttoggleItalic: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t\ttoggleUnderline: () => editor?.chain().focus().toggleUnderline().run(),\n\t\t\t\ttoggleStrike: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t\ttoggleBulletList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBulletList().run(),\n\t\t\t\ttoggleOrderedList: () =>\n\t\t\t\t\teditor?.chain().focus().toggleOrderedList().run(),\n\t\t\t\ttoggleBlockquote: () =>\n\t\t\t\t\teditor?.chain().focus().toggleBlockquote().run(),\n\t\t\t\ttoggleCodeBlock: () => editor?.chain().focus().toggleCodeBlock().run(),\n\t\t\t\tsetTextAlign: (align) =>\n\t\t\t\t\teditor?.chain().focus().setTextAlign(align).run(),\n\t\t\t\tsetFontFamily: (font) =>\n\t\t\t\t\teditor?.chain().focus().setFontFamily(font).run(),\n\t\t\t\tsetFontSize: (size) => editor?.chain().focus().setFontSize(size).run(),\n\t\t\t\tsetColor: (color) => editor?.chain().focus().setColor(color).run(),\n\t\t\t\tsetHighlight: (color) =>\n\t\t\t\t\teditor?.chain().focus().toggleHighlight({ color }).run(),\n\t\t\t\tunsetColor: () => editor?.chain().focus().unsetColor().run(),\n\t\t\t\tunsetHighlight: () => editor?.chain().focus().unsetHighlight().run(),\n\t\t\t\tsetLink: (href, text) => {\n\t\t\t\t\tif (!editor) return;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.command(({ tr, state }) => {\n\t\t\t\t\t\t\t\tconst { from, to } = tr.selection;\n\t\t\t\t\t\t\t\tconst linkMarkType = state.schema.marks['link'];\n\t\t\t\t\t\t\t\tif (!linkMarkType) return false;\n\t\t\t\t\t\t\t\tconst linkNode = state.schema.text(text, [\n\t\t\t\t\t\t\t\t\tlinkMarkType.create({ href }),\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\tconst space = state.schema.text(' ');\n\t\t\t\t\t\t\t\ttr.replaceWith(from, to, [linkNode, space]);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t} else {\n\t\t\t\t\t\teditor\n\t\t\t\t\t\t\t.chain()\n\t\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t\t.insertContent(' ')\n\t\t\t\t\t\t\t.run();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tupdateLink: (href) =>\n\t\t\t\t\teditor\n\t\t\t\t\t\t?.chain()\n\t\t\t\t\t\t.focus()\n\t\t\t\t\t\t.extendMarkRange('link')\n\t\t\t\t\t\t.setLink({ href })\n\t\t\t\t\t\t.run(),\n\t\t\t\tremoveLink: () =>\n\t\t\t\t\teditor?.chain().focus().extendMarkRange('link').unsetLink().run(),\n\t\t\t\tinsertEmoji: (emoji) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(emoji).run(),\n\t\t\t\tinsertVariable: (variableName) =>\n\t\t\t\t\teditor?.chain().focus().insertContent(`{{${variableName}}}`).run(),\n\t\t\t\tinsertHtml: (html) =>\n\t\t\t\t\teditor?.commands.insertContent(normalizeHtml(html)),\n\t\t\t\tundo: () => editor?.chain().focus().undo().run(),\n\t\t\t\tredo: () => editor?.chain().focus().redo().run(),\n\t\t\t\tcanUndo: () => editor?.can().undo() ?? false,\n\t\t\t\tcanRedo: () => editor?.can().redo() ?? false,\n\t\t\t\ttoggleSuperscript: () =>\n\t\t\t\t\teditor?.chain().focus().toggleSuperscript().run(),\n\t\t\t\ttoggleSubscript: () => editor?.chain().focus().toggleSubscript().run(),\n\t\t\t\tinsertImage: (src) => editor?.chain().focus().setImage({ src }).run(),\n\t\t\t},\n\t\t}),\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[editor],\n\t);\n\n\tif (!editor) return null;\n\n\treturn (\n\t\t<BikEditorShell\n\t\t\tminHeight={minHeight}\n\t\t\tmaxHeight={maxHeight}\n\t\t\ttightParagraphs={!features?.richPaste}\n\t\t\tstyle={style}\n\t\t\tclassName={className}\n\t\t>\n\t\t\t<EditorContent editor={editor} />\n\t\t\t<LinkBubbleMenu editor={editor} renderLinkTooltip={link?.renderTooltip} />\n\t\t</BikEditorShell>\n\t);\n};\n\nexport const BikEditor = forwardRef<BikEditorRef, BikEditorProps>(\n\tBikEditorInner,\n);\nBikEditor.displayName = 'BikEditor';\n"],"names":["cssToString","style","Object","entries","map","_ref","k","v","replace","c","toLowerCase","join","BikEditor","forwardRef","BikEditorInner","props","ref","initialContent","sections","features","disabled","maxCharacters","shortcuts","sendShortcut","mentions","slashCommands","link","onPaste","onReady","onChange","onSend","onFocus","onBlur","onSelectionChange","minHeight","maxHeight","className","editorClassName","editorStyle","initialEditorContent","length","buildSectionedContent","normalizeHtml","s","assign","content","pendingQueue","useRef","hasCalledOnReady","onReadyRef","current","onChangeRef","onSelectionChangeRef","prevFormatsRef","DEFAULT_FORMAT_STATE","onFocusRef","onBlurRef","onSendRef","agentMentionsRef","agents","_a","_b","teamMentionsRef","teams","_c","_d","slashCommandsRef","items","_e","_f","editor","useEditor","extensions","buildExtensions","placeholder","hasSections","_g","undefined","snapshot","call","onMentionSelected","onSelect","onSlashCommandSelected","renderMentionItem","renderItem","renderMentionDropdown","renderDropdown","renderSlashCommandItem","renderSlashCommandDropdown","editable","immediatelyRender","editorProps","attributes","class","onUpdate","_ref2","e","extractContent","onTransaction","_ref3","next","extractActiveFormats","prev","bold","italic","underline","strike","bulletList","orderedList","blockquote","codeBlock","superscript","subscript","textAlign","fontFamily","fontSize","color","highlight","href","enqueue","op","push","useEffect","splice","forEach","useImperativeHandle","focus","position","commands","blur","clearContent","setContent","html","normalised","emitUpdate","insertContent","insertInlineContent","insertInlineHtml","insertAtStart","insertContentAt","insertBlock","state","doc","size","appendInline","insertAtEnd","this","appendContent","getContent","text","isEmpty","characterCount","getJSON","getMentions","agentIds","Set","teamIds","descendants","node","type","name","attrs","add","String","Array","from","getCursorPosition","to","selection","insertAtPosition","pos","getSelectedText","empty","textBetween","linkMarkType","schema","marks","range","getMarkRange","resolve","getCharacterCount","count","storage","characters","getText","limit","getSectionContent","sectionId","extractSectionContent","setSectionContent","setSectionContentInEditor","focusSection","endOfBody","chain","setTextSelection","run","targetPos","nodeSize","clearSection","getBodyContent","extractBodyContent","setBodyContent","setBodyAndSections","body","id","appendBodyContent","boundaryPos","findSectionEndPos","insertAtSectionStart","findSectionStartPos","insertAtSectionEnd","getActiveFormats","actions","toggleBold","toggleItalic","toggleUnderline","toggleStrike","toggleBulletList","toggleOrderedList","toggleBlockquote","toggleCodeBlock","setTextAlign","align","setFontFamily","font","setFontSize","setColor","setHighlight","toggleHighlight","unsetColor","unsetHighlight","setLink","extendMarkRange","command","_ref4","tr","linkNode","create","space","replaceWith","updateLink","removeLink","unsetLink","insertEmoji","emoji","insertVariable","variableName","insertHtml","undo","redo","canUndo","can","canRedo","toggleSuperscript","toggleSubscript","insertImage","src","setImage","_jsxs","BikEditorShell","tightParagraphs","richPaste","children","_jsx","EditorContent","LinkBubbleMenu","renderLinkTooltip","renderTooltip","displayName"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import e from"styled-components";import{COLORS as t}from"../constants/Theme.js";const a=e.div`
1
+ import e from"styled-components";import{COLORS as t}from"../constants/Theme.js";const r=e.div`
2
2
  position: relative;
3
3
  width: 100%;
4
4
 
@@ -26,18 +26,6 @@ import e from"styled-components";import{COLORS as t}from"../constants/Theme.js";
26
26
  padding: 0;
27
27
  }
28
28
 
29
- /* ProseMirror appends an invisible trailing <br> after a paragraph that
30
- ends in a hard break, so the cursor can sit on that final line. A plain
31
- HTML viewer (Gmail, our email shadow DOM) doesn't add one, so the editor
32
- would show one phantom empty line MORE than the sent HTML per such
33
- paragraph. Hide it when the paragraph has other content (the break is
34
- NOT the first child — e.g. a paragraph ending in <br>, even when the
35
- <br> is nested inside a mark <span>); keep it for truly empty paragraphs
36
- where it is the only child and provides the blank line. Editor == output. */
37
- .ProseMirror-trailingBreak:not(:first-child) {
38
- display: none;
39
- }
40
-
41
29
  ul,
42
30
  ol {
43
31
  margin: 0;
@@ -79,5 +67,5 @@ import e from"styled-components";import{COLORS as t}from"../constants/Theme.js";
79
67
  text-decoration-color: #6366f1;
80
68
  }
81
69
  }
82
- `;export{a as BikEditorShell};
70
+ `;export{r as BikEditorShell};
83
71
  //# sourceMappingURL=BikEditor.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\ttightParagraphs?: boolean;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '80px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tpadding: 8px 12px;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\t/* Paragraph spacing.\n\t\t Email/signature (rich): paragraphs carry the browser-default 1em block\n\t\t margin — the SAME spacing the sent HTML gets (we emit plain <p>, which\n\t\t renders against the default <p> margin in Gmail and our email viewer),\n\t\t so editor view == emitted HTML == Gmail. A single Enter = a new\n\t\t paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.\n\t\t Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with\n\t\t no paragraph-gap concept — paragraphs are tight (margin:0) regardless of\n\t\t typed vs pasted. (A margin:0 attr still overrides to tight either way.) */\n\t\tp {\n\t\t\tmargin: ${({ tightParagraphs }) => (tightParagraphs ? '0' : '1em 0')};\n\t\t\tpadding: 0;\n\t\t}\n\n\t\t/* ProseMirror appends an invisible trailing <br> after a paragraph that\n\t\t ends in a hard break, so the cursor can sit on that final line. A plain\n\t\t HTML viewer (Gmail, our email shadow DOM) doesn't add one, so the editor\n\t\t would show one phantom empty line MORE than the sent HTML per such\n\t\t paragraph. Hide it when the paragraph has other content (the break is\n\t\t NOT the first child — e.g. a paragraph ending in <br>, even when the\n\t\t <br> is nested inside a mark <span>); keep it for truly empty paragraphs\n\t\t where it is the only child and provides the blank line. Editor == output. */\n\t\t.ProseMirror-trailingBreak:not(:first-child) {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t.bik-variable {\n\t}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n"],"names":["BikEditorShell","styled","div","_ref","minHeight","_ref2","maxHeight","_ref3","tightParagraphs","COLORS","content","brand"],"mappings":"gFAGaA,MAAAA,EAAiBC,EAAOC,GAInC;;;;;gBAKcC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;gBACtCC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;;;;;;;;;;;;;;;;;;aAkBzCC,IAAA,IAACC,gBAAEA,GAAiBD,EAAA,OAAMC,EAAkB,IAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAoC3DC,EAAOC,QAAQC;;;;WAIfF,EAAOC,QAAQC;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"BikEditor.styles.js","sources":["../../../src/editor/BikEditor.styles.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '../constants/Theme';\n\nexport const BikEditorShell = styled.div<{\n\tminHeight?: string;\n\tmaxHeight?: string;\n\ttightParagraphs?: boolean;\n}>`\n\tposition: relative;\n\twidth: 100%;\n\n\t.ProseMirror {\n\t\tmin-height: ${({ minHeight }) => minHeight ?? '80px'};\n\t\tmax-height: ${({ maxHeight }) => maxHeight ?? 'none'};\n\t\toverflow-y: auto;\n\t\toutline: none;\n\t\tpadding: 8px 12px;\n\t\tfont-size: 14px;\n\t\tline-height: 1.5;\n\t\tword-break: break-word;\n\n\t\t/* Paragraph spacing.\n\t\t Email/signature (rich): paragraphs carry the browser-default 1em block\n\t\t margin — the SAME spacing the sent HTML gets (we emit plain <p>, which\n\t\t renders against the default <p> margin in Gmail and our email viewer),\n\t\t so editor view == emitted HTML == Gmail. A single Enter = a new\n\t\t paragraph with a visible gap, like pasted Gmail/ChatGPT/Docs content.\n\t\t Other channels (WhatsApp/IG/FB/comments) are plain-text messaging, with\n\t\t no paragraph-gap concept — paragraphs are tight (margin:0) regardless of\n\t\t typed vs pasted. (A margin:0 attr still overrides to tight either way.) */\n\t\tp {\n\t\t\tmargin: ${({ tightParagraphs }) => (tightParagraphs ? '0' : '1em 0')};\n\t\t\tpadding: 0;\n\t\t}\n\n\t\tul,\n\t\tol {\n\t\t\tmargin: 0;\n\t\t\tpadding-left: 1.5em;\n\t\t}\n\n\t\tli + li {\n\t\t\tmargin-top: 2px;\n\t\t}\n\n\t\tp.is-editor-empty:first-child::before {\n\t\t\tcontent: attr(data-placeholder);\n\t\t\tfloat: left;\n\t\t\tcolor: #adb5bd;\n\t\t\tpointer-events: none;\n\t\t\theight: 0;\n\t\t}\n\t}\n\n\t.bik-mention {\n\t\tcolor: ${COLORS.content.brand};\n\t\tpadding: 1px 4px;\n\t}\n\t.bik-mention--team {\n\t\tcolor: ${COLORS.content.brand};\n\t}\n\t.bik-variable {\n\t}\n\n\ta,\n\t.bik-link {\n\t\tcolor: #4f46e5;\n\t\ttext-decoration: underline;\n\t\ttext-decoration-color: #a5b4fc;\n\t\ttext-underline-offset: 2px;\n\t\tcursor: pointer;\n\t\t&:hover {\n\t\t\tcolor: #3730a3;\n\t\t\ttext-decoration-color: #6366f1;\n\t\t}\n\t}\n`;\n"],"names":["BikEditorShell","styled","div","_ref","minHeight","_ref2","maxHeight","_ref3","tightParagraphs","COLORS","content","brand"],"mappings":"gFAGaA,MAAAA,EAAiBC,EAAOC,GAInC;;;;;gBAKcC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;gBACtCC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;;;;;;;;;;;;;;;;;;aAkBzCC,IAAA,IAACC,gBAAEA,GAAiBD,EAAA,OAAMC,EAAkB,IAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;WAwB3DC,EAAOC,QAAQC;;;;WAIfF,EAAOC,QAAQC;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,2 @@
1
- import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{Slice as e}from"@tiptap/pm/model";import{Plugin as n}from"@tiptap/pm/state";import{parseClipboardTextAsBreaks as r,wrapInlineContent as a,cleanBlockBrs as o,stripTrailingBrs as s,normalizeHardBreaks as i,stripRichMarks as l,mirrorParagraphMargins as p}from"./pasteUtils.js";const d=t.create({name:"pasteNormalization",addOptions:()=>({preserveMarks:!1,plainOnly:!1}),addProseMirrorPlugins(){const t=this.options.preserveMarks,d=this.options.plainOnly;let c;const m=t=>{var e;const n=t.firstChild;c=n&&"paragraph"===n.type.name?null!==(e=n.attrs.margin)&&void 0!==e?e:null:void 0};return[new n({appendTransaction(t,e,n){var r;if(!t.some((t=>t.docChanged)))return c=void 0,null;const a=n.tr;let o=!1;if(void 0!==c){const s=c;let i=e.selection.from;for(const e of t)i=e.mapping.map(i);const l=n.doc.resolve(Math.max(0,Math.min(i,n.doc.content.size)));for(let t=l.depth;t>=1;t--){const e=l.node(t);if("paragraph"===e.type.name){(null!==(r=e.attrs.margin)&&void 0!==r?r:null)!==s&&(a.setNodeMarkup(l.before(t),void 0,Object.assign(Object.assign({},e.attrs),{margin:s})),o=!0);break}}}c=void 0;const s=a.doc;let i=null;return s.forEach(((t,e)=>{var n;if("paragraph"!==t.type.name)return void(i=null);let r=null!==(n=t.attrs.margin)&&void 0!==n?n:null;0===t.childCount&&"0"!==r&&"0"===i&&(a.setNodeMarkup(e,void 0,Object.assign(Object.assign({},t.attrs),{margin:"0"})),r="0",o=!0),i=r})),o?a.setMeta("addToHistory",!1):null},props:Object.assign(Object.assign({},d?{handlePaste(t,e){var n,a;const o=null!==(a=null===(n=e.clipboardData)||void 0===n?void 0:n.getData("text/plain"))&&void 0!==a?a:"";if(!o)return!1;const s=r(o,t.state.schema);return m(s.content),t.dispatch(t.state.tr.replaceSelection(s)),!0}}:{}),{clipboardTextParser(t,e,n,a){const o=r(t,a.state.schema);return m(o.content),o},transformPastedHTML(t){if(t.includes("data-pm-slice"))return t;const e=document.createElement("div");return e.innerHTML=t,a(e),o(e),s(e),e.innerHTML},transformPasted(n){let r=i(n.content);return t||(r=l(r)),r=p(r),m(r),new e(r,n.openStart,n.openEnd)}})})]}});export{d as PasteNormalizationExtension};
1
+ import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{Slice as e}from"@tiptap/pm/model";import{Plugin as n}from"@tiptap/pm/state";import{parseClipboardTextAsBreaks as r,wrapInlineContent as a,cleanBlockBrs as o,stripTrailingBrs as s,normalizeHardBreaks as i,stripRichMarks as l,mirrorParagraphMargins as p}from"./pasteUtils.js";const c=t.create({name:"pasteNormalization",addOptions:()=>({preserveMarks:!1,plainOnly:!1}),addProseMirrorPlugins(){const t=this.options.preserveMarks,c=this.options.plainOnly;let d;const m=t=>{var e;const n=t.firstChild;d=n&&"paragraph"===n.type.name?null!==(e=n.attrs.margin)&&void 0!==e?e:null:void 0};return[new n({appendTransaction(t,e,n){var r;if(!t.some((t=>t.docChanged)))return d=void 0,null;const a=n.tr;let o=!1;if(void 0!==d){const s=d;let i=e.selection.from;for(const e of t)i=e.mapping.map(i);const l=n.doc.resolve(Math.max(0,Math.min(i,n.doc.content.size)));for(let t=l.depth;t>=1;t--){const e=l.node(t);if("paragraph"===e.type.name){(null!==(r=e.attrs.margin)&&void 0!==r?r:null)!==s&&(a.setNodeMarkup(l.before(t),void 0,Object.assign(Object.assign({},e.attrs),{margin:s})),o=!0);break}}}d=void 0;const s=a.doc;let i=null;return s.forEach(((t,e)=>{var n;if("paragraph"!==t.type.name)return void(i=null);let r=null!==(n=t.attrs.margin)&&void 0!==n?n:null;0===t.childCount&&"0"!==r&&"0"===i&&(a.setNodeMarkup(e,void 0,Object.assign(Object.assign({},t.attrs),{margin:"0"})),r="0",o=!0),i=r})),o?a.setMeta("addToHistory",!1):null},props:Object.assign(Object.assign({},c?{handlePaste(t,e){var n,a;const o=null!==(a=null===(n=e.clipboardData)||void 0===n?void 0:n.getData("text/plain"))&&void 0!==a?a:"";if(!o)return!1;const s=r(o,t.state.schema);return m(s.content),t.dispatch(t.state.tr.replaceSelection(s)),!0}}:{}),{clipboardTextParser(t,e,n,a){const o=r(t,a.state.schema);return m(o.content),o},transformPastedHTML(t){if(t.includes("data-pm-slice"))return t;const e=document.createElement("div");return e.innerHTML=t,e.querySelectorAll("br.Apple-interchange-newline").forEach((t=>t.remove())),a(e),o(e),s(e),e.innerHTML},transformPasted(n){let r=i(n.content);return t||(r=l(r)),r=p(r),m(r),new e(r,n.openStart,n.openEnd)}})})]}});export{c as PasteNormalizationExtension};
2
2
  //# sourceMappingURL=PasteNormalizationExtension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PasteNormalizationExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PasteNormalizationExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport {\n\tcleanBlockBrs,\n\tmirrorParagraphMargins,\n\tnormalizeHardBreaks,\n\tparseClipboardTextAsBreaks,\n\tstripRichMarks,\n\tstripTrailingBrs,\n\twrapInlineContent,\n} from './pasteUtils';\n\n/**\n * Unified paste normalizer for all editor channels.\n *\n * Uses ProseMirror's recommended hooks instead of overriding handlePaste:\n * - clipboardTextParser: plain text → Slice (one block, <br> per line)\n * - transformPastedHTML: HTML → HTML (cleans Google Docs / Word artifacts)\n * - transformPasted: Slice → Slice (normalize hardBreaks, strip marks,\n * mirror the source paragraph-margin convention)\n *\n * Margins MIRROR the source (like Gmail): they are not added structurally, so\n * ChatGPT-pasted `<p>` keeps its default margin (gaps) while Google-Docs and\n * plain/paste-without-formatting content stays margin:0 (tight).\n *\n * `appendTransaction` does two bounded touch-ups:\n * 1. Repairs the FIRST pasted paragraph — ProseMirror merges it into the\n * cursor's paragraph at paste time, dropping its margin attr; we record that\n * margin (in transformPasted / the plain handlePaste) and reapply it at the\n * paste position.\n * 2. Typed-Enter inheritance — splitBlock gives a paragraph created at a block\n * end DEFAULT attrs, so an empty paragraph that follows a margin:0 paragraph\n * is set to margin:0 too. Typing inside tight content stays tight; default\n * content stays default; non-empty (pasted) paragraphs are never touched.\n *\n * `plainOnly` (channels with no rich formatting — WhatsApp, IG, FB, comments)\n * forces EVERY paste through the plain-text path: even Cmd/Ctrl+V ignores the\n * clipboard HTML and pastes text only, since those channels don't support\n * formatting anyway. Email and the signature editor (richPaste) keep the full\n * HTML pipeline.\n */\nexport const PasteNormalizationExtension = Extension.create({\n\tname: 'pasteNormalization',\n\taddOptions() {\n\t\treturn {\n\t\t\tpreserveMarks: false,\n\t\t\tplainOnly: false,\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\tconst preserveMarks = this.options.preserveMarks;\n\t\tconst plainOnly = this.options.plainOnly;\n\n\t\t// Margin of the first pasted paragraph, recorded at paste time so the\n\t\t// appendTransaction can restore it after ProseMirror merges that\n\t\t// paragraph into the destination (losing its attrs). `undefined` means\n\t\t// \"no paste pending\".\n\t\tlet pastedFirstMargin: string | null | undefined;\n\n\t\tconst recordFirstMargin = (content: { firstChild: any }) => {\n\t\t\tconst first = content.firstChild;\n\t\t\tpastedFirstMargin =\n\t\t\t\tfirst && first.type.name === 'paragraph'\n\t\t\t\t\t? first.attrs['margin'] ?? null\n\t\t\t\t\t: undefined;\n\t\t};\n\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tappendTransaction(transactions, oldState, newState) {\n\t\t\t\t\tif (!transactions.some((t) => t.docChanged)) {\n\t\t\t\t\t\tpastedFirstMargin = undefined;\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst tr = newState.tr;\n\t\t\t\t\tlet changed = false;\n\n\t\t\t\t\t// Job 1 — repair the first pasted paragraph. ProseMirror merges it\n\t\t\t\t\t// into the destination paragraph at paste time, dropping its margin\n\t\t\t\t\t// attr; reapply the recorded margin at the paste position.\n\t\t\t\t\tif (pastedFirstMargin !== undefined) {\n\t\t\t\t\t\tconst margin = pastedFirstMargin;\n\t\t\t\t\t\tlet pos = oldState.selection.from;\n\t\t\t\t\t\tfor (const t of transactions) pos = t.mapping.map(pos);\n\t\t\t\t\t\tconst $pos = newState.doc.resolve(\n\t\t\t\t\t\t\tMath.max(0, Math.min(pos, newState.doc.content.size)),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfor (let d = $pos.depth; d >= 1; d--) {\n\t\t\t\t\t\t\tconst node = $pos.node(d);\n\t\t\t\t\t\t\tif (node.type.name === 'paragraph') {\n\t\t\t\t\t\t\t\tif ((node.attrs['margin'] ?? null) !== margin) {\n\t\t\t\t\t\t\t\t\ttr.setNodeMarkup($pos.before(d), undefined, {\n\t\t\t\t\t\t\t\t\t\t...node.attrs,\n\t\t\t\t\t\t\t\t\t\tmargin,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\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\tpastedFirstMargin = undefined;\n\n\t\t\t\t\t// Job 2 — typed Enter inherits tightness. ProseMirror's splitBlock\n\t\t\t\t\t// gives a paragraph created at the end of a block DEFAULT attrs, so\n\t\t\t\t\t// pressing Enter in margin:0 content would otherwise produce a\n\t\t\t\t\t// default-margin (gap) paragraph. Make an EMPTY paragraph that\n\t\t\t\t\t// follows a margin:0 paragraph margin:0 too — so typing inside tight\n\t\t\t\t\t// (plain / Google-Docs) content stays tight, while default content\n\t\t\t\t\t// stays default. Non-empty paragraphs are never touched, so pasted\n\t\t\t\t\t// default-margin content is left alone.\n\t\t\t\t\tconst doc = tr.doc;\n\t\t\t\t\tlet prevMargin: string | null = null;\n\t\t\t\t\tdoc.forEach((node, pos) => {\n\t\t\t\t\t\tif (node.type.name !== 'paragraph') {\n\t\t\t\t\t\t\tprevMargin = null;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet margin = (node.attrs['margin'] as string | null) ?? null;\n\t\t\t\t\t\tif (node.childCount === 0 && margin !== '0' && prevMargin === '0') {\n\t\t\t\t\t\t\ttr.setNodeMarkup(pos, undefined, { ...node.attrs, margin: '0' });\n\t\t\t\t\t\t\tmargin = '0';\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprevMargin = margin;\n\t\t\t\t\t});\n\n\t\t\t\t\treturn changed ? tr.setMeta('addToHistory', false) : null;\n\t\t\t\t},\n\t\t\t\tprops: {\n\t\t\t\t\t// plainOnly channels: ignore clipboard HTML entirely — every\n\t\t\t\t\t// paste (Cmd/Ctrl+V and Cmd/Ctrl+Shift+V) becomes plain text.\n\t\t\t\t\t...(plainOnly\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain') ?? '';\n\t\t\t\t\t\t\t\t\tif (!text) return false; // images / non-text: let others handle\n\t\t\t\t\t\t\t\t\tconst slice = parseClipboardTextAsBreaks(\n\t\t\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\t\t\tview.state.schema,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\trecordFirstMargin(slice.content);\n\t\t\t\t\t\t\t\t\tview.dispatch(view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {}),\n\n\t\t\t\t\t// Plain-text paste (Cmd/Ctrl+Shift+V, which strips HTML): one\n\t\t\t\t\t// block with <br> per line and <br><br> per blank line — matches\n\t\t\t\t\t// Gmail's paste-without-formatting output exactly.\n\t\t\t\t\tclipboardTextParser(text, _$context, _plain, view) {\n\t\t\t\t\t\tconst slice = parseClipboardTextAsBreaks(text, view.state.schema);\n\t\t\t\t\t\trecordFirstMargin(slice.content);\n\t\t\t\t\t\treturn slice;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPastedHTML(html) {\n\t\t\t\t\t\tif (html.includes('data-pm-slice')) return html;\n\t\t\t\t\t\tconst container = document.createElement('div');\n\t\t\t\t\t\tcontainer.innerHTML = html;\n\t\t\t\t\t\twrapInlineContent(container);\n\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\tstripTrailingBrs(container);\n\t\t\t\t\t\treturn container.innerHTML;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPasted(slice) {\n\t\t\t\t\t\tlet content = normalizeHardBreaks(slice.content);\n\t\t\t\t\t\tif (!preserveMarks) {\n\t\t\t\t\t\t\tcontent = stripRichMarks(content);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontent = mirrorParagraphMargins(content);\n\t\t\t\t\t\trecordFirstMargin(content);\n\t\t\t\t\t\treturn new Slice(content, slice.openStart, slice.openEnd);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PasteNormalizationExtension","Extension","create","name","addOptions","preserveMarks","plainOnly","addProseMirrorPlugins","this","options","pastedFirstMargin","recordFirstMargin","content","first","firstChild","type","attrs","_a","undefined","Plugin","appendTransaction","transactions","oldState","newState","some","t","docChanged","tr","changed","margin","pos","selection","from","mapping","map","$pos","doc","resolve","Math","max","min","size","d","depth","node","setNodeMarkup","before","prevMargin","forEach","childCount","Object","assign","setMeta","props","handlePaste","view","event","text","_b","clipboardData","getData","slice","parseClipboardTextAsBreaks","state","schema","dispatch","replaceSelection","clipboardTextParser","_$context","_plain","transformPastedHTML","html","includes","container","document","createElement","innerHTML","wrapInlineContent","cleanBlockBrs","stripTrailingBrs","transformPasted","normalizeHardBreaks","stripRichMarks","mirrorParagraphMargins","Slice","openStart","openEnd"],"mappings":"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"}
1
+ {"version":3,"file":"PasteNormalizationExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PasteNormalizationExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport {\n\tcleanBlockBrs,\n\tmirrorParagraphMargins,\n\tnormalizeHardBreaks,\n\tparseClipboardTextAsBreaks,\n\tstripRichMarks,\n\tstripTrailingBrs,\n\twrapInlineContent,\n} from './pasteUtils';\n\n/**\n * Unified paste normalizer for all editor channels.\n *\n * Uses ProseMirror's recommended hooks instead of overriding handlePaste:\n * - clipboardTextParser: plain text → Slice (one block, <br> per line)\n * - transformPastedHTML: HTML → HTML (cleans Google Docs / Word artifacts)\n * - transformPasted: Slice → Slice (normalize hardBreaks, strip marks,\n * mirror the source paragraph-margin convention)\n *\n * Margins MIRROR the source (like Gmail): they are not added structurally, so\n * ChatGPT-pasted `<p>` keeps its default margin (gaps) while Google-Docs and\n * plain/paste-without-formatting content stays margin:0 (tight).\n *\n * `appendTransaction` does two bounded touch-ups:\n * 1. Repairs the FIRST pasted paragraph — ProseMirror merges it into the\n * cursor's paragraph at paste time, dropping its margin attr; we record that\n * margin (in transformPasted / the plain handlePaste) and reapply it at the\n * paste position.\n * 2. Typed-Enter inheritance — splitBlock gives a paragraph created at a block\n * end DEFAULT attrs, so an empty paragraph that follows a margin:0 paragraph\n * is set to margin:0 too. Typing inside tight content stays tight; default\n * content stays default; non-empty (pasted) paragraphs are never touched.\n *\n * `plainOnly` (channels with no rich formatting — WhatsApp, IG, FB, comments)\n * forces EVERY paste through the plain-text path: even Cmd/Ctrl+V ignores the\n * clipboard HTML and pastes text only, since those channels don't support\n * formatting anyway. Email and the signature editor (richPaste) keep the full\n * HTML pipeline.\n */\nexport const PasteNormalizationExtension = Extension.create({\n\tname: 'pasteNormalization',\n\taddOptions() {\n\t\treturn {\n\t\t\tpreserveMarks: false,\n\t\t\tplainOnly: false,\n\t\t};\n\t},\n\taddProseMirrorPlugins() {\n\t\tconst preserveMarks = this.options.preserveMarks;\n\t\tconst plainOnly = this.options.plainOnly;\n\n\t\t// Margin of the first pasted paragraph, recorded at paste time so the\n\t\t// appendTransaction can restore it after ProseMirror merges that\n\t\t// paragraph into the destination (losing its attrs). `undefined` means\n\t\t// \"no paste pending\".\n\t\tlet pastedFirstMargin: string | null | undefined;\n\n\t\tconst recordFirstMargin = (content: { firstChild: any }) => {\n\t\t\tconst first = content.firstChild;\n\t\t\tpastedFirstMargin =\n\t\t\t\tfirst && first.type.name === 'paragraph'\n\t\t\t\t\t? first.attrs['margin'] ?? null\n\t\t\t\t\t: undefined;\n\t\t};\n\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tappendTransaction(transactions, oldState, newState) {\n\t\t\t\t\tif (!transactions.some((t) => t.docChanged)) {\n\t\t\t\t\t\tpastedFirstMargin = undefined;\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst tr = newState.tr;\n\t\t\t\t\tlet changed = false;\n\n\t\t\t\t\t// Job 1 — repair the first pasted paragraph. ProseMirror merges it\n\t\t\t\t\t// into the destination paragraph at paste time, dropping its margin\n\t\t\t\t\t// attr; reapply the recorded margin at the paste position.\n\t\t\t\t\tif (pastedFirstMargin !== undefined) {\n\t\t\t\t\t\tconst margin = pastedFirstMargin;\n\t\t\t\t\t\tlet pos = oldState.selection.from;\n\t\t\t\t\t\tfor (const t of transactions) pos = t.mapping.map(pos);\n\t\t\t\t\t\tconst $pos = newState.doc.resolve(\n\t\t\t\t\t\t\tMath.max(0, Math.min(pos, newState.doc.content.size)),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfor (let d = $pos.depth; d >= 1; d--) {\n\t\t\t\t\t\t\tconst node = $pos.node(d);\n\t\t\t\t\t\t\tif (node.type.name === 'paragraph') {\n\t\t\t\t\t\t\t\tif ((node.attrs['margin'] ?? null) !== margin) {\n\t\t\t\t\t\t\t\t\ttr.setNodeMarkup($pos.before(d), undefined, {\n\t\t\t\t\t\t\t\t\t\t...node.attrs,\n\t\t\t\t\t\t\t\t\t\tmargin,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\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\tpastedFirstMargin = undefined;\n\n\t\t\t\t\t// Job 2 — typed Enter inherits tightness. ProseMirror's splitBlock\n\t\t\t\t\t// gives a paragraph created at the end of a block DEFAULT attrs, so\n\t\t\t\t\t// pressing Enter in margin:0 content would otherwise produce a\n\t\t\t\t\t// default-margin (gap) paragraph. Make an EMPTY paragraph that\n\t\t\t\t\t// follows a margin:0 paragraph margin:0 too — so typing inside tight\n\t\t\t\t\t// (plain / Google-Docs) content stays tight, while default content\n\t\t\t\t\t// stays default. Non-empty paragraphs are never touched, so pasted\n\t\t\t\t\t// default-margin content is left alone.\n\t\t\t\t\tconst doc = tr.doc;\n\t\t\t\t\tlet prevMargin: string | null = null;\n\t\t\t\t\tdoc.forEach((node, pos) => {\n\t\t\t\t\t\tif (node.type.name !== 'paragraph') {\n\t\t\t\t\t\t\tprevMargin = null;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlet margin = (node.attrs['margin'] as string | null) ?? null;\n\t\t\t\t\t\tif (node.childCount === 0 && margin !== '0' && prevMargin === '0') {\n\t\t\t\t\t\t\ttr.setNodeMarkup(pos, undefined, { ...node.attrs, margin: '0' });\n\t\t\t\t\t\t\tmargin = '0';\n\t\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprevMargin = margin;\n\t\t\t\t\t});\n\n\t\t\t\t\treturn changed ? tr.setMeta('addToHistory', false) : null;\n\t\t\t\t},\n\t\t\t\tprops: {\n\t\t\t\t\t// plainOnly channels: ignore clipboard HTML entirely — every\n\t\t\t\t\t// paste (Cmd/Ctrl+V and Cmd/Ctrl+Shift+V) becomes plain text.\n\t\t\t\t\t...(plainOnly\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\thandlePaste(view, event) {\n\t\t\t\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain') ?? '';\n\t\t\t\t\t\t\t\t\tif (!text) return false; // images / non-text: let others handle\n\t\t\t\t\t\t\t\t\tconst slice = parseClipboardTextAsBreaks(\n\t\t\t\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\t\t\t\tview.state.schema,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\trecordFirstMargin(slice.content);\n\t\t\t\t\t\t\t\t\tview.dispatch(view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {}),\n\n\t\t\t\t\t// Plain-text paste (Cmd/Ctrl+Shift+V, which strips HTML): one\n\t\t\t\t\t// block with <br> per line and <br><br> per blank line — matches\n\t\t\t\t\t// Gmail's paste-without-formatting output exactly.\n\t\t\t\t\tclipboardTextParser(text, _$context, _plain, view) {\n\t\t\t\t\t\tconst slice = parseClipboardTextAsBreaks(text, view.state.schema);\n\t\t\t\t\t\trecordFirstMargin(slice.content);\n\t\t\t\t\t\treturn slice;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPastedHTML(html) {\n\t\t\t\t\t\tif (html.includes('data-pm-slice')) return html;\n\t\t\t\t\t\tconst container = document.createElement('div');\n\t\t\t\t\t\tcontainer.innerHTML = html;\n\t\t\t\t\t\t// Strip Apple interchange <br> (WebKit clipboard artifact)\n\t\t\t\t\t\t// before cleanBlockBrs converts it to a phantom <p></p>.\n\t\t\t\t\t\tcontainer\n\t\t\t\t\t\t\t.querySelectorAll('br.Apple-interchange-newline')\n\t\t\t\t\t\t\t.forEach((br) => br.remove());\n\t\t\t\t\t\twrapInlineContent(container);\n\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\tstripTrailingBrs(container);\n\t\t\t\t\t\treturn container.innerHTML;\n\t\t\t\t\t},\n\n\t\t\t\t\ttransformPasted(slice) {\n\t\t\t\t\t\tlet content = normalizeHardBreaks(slice.content);\n\t\t\t\t\t\tif (!preserveMarks) {\n\t\t\t\t\t\t\tcontent = stripRichMarks(content);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontent = mirrorParagraphMargins(content);\n\t\t\t\t\t\trecordFirstMargin(content);\n\t\t\t\t\t\treturn new Slice(content, slice.openStart, slice.openEnd);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PasteNormalizationExtension","Extension","create","name","addOptions","preserveMarks","plainOnly","addProseMirrorPlugins","this","options","pastedFirstMargin","recordFirstMargin","content","first","firstChild","type","attrs","_a","undefined","Plugin","appendTransaction","transactions","oldState","newState","some","t","docChanged","tr","changed","margin","pos","selection","from","mapping","map","$pos","doc","resolve","Math","max","min","size","d","depth","node","setNodeMarkup","before","prevMargin","forEach","childCount","Object","assign","setMeta","props","handlePaste","view","event","text","_b","clipboardData","getData","slice","parseClipboardTextAsBreaks","state","schema","dispatch","replaceSelection","clipboardTextParser","_$context","_plain","transformPastedHTML","html","includes","container","document","createElement","innerHTML","querySelectorAll","br","remove","wrapInlineContent","cleanBlockBrs","stripTrailingBrs","transformPasted","normalizeHardBreaks","stripRichMarks","mirrorParagraphMargins","Slice","openStart","openEnd"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export declare const Menus: ({
2
3
  displayName: string;
3
4
  key: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bikdotai/bik-component-library",
3
- "version": "0.0.811-beta.1",
3
+ "version": "0.0.811-beta.3",
4
4
  "description": "Bik Component Library",
5
5
  "repository": {
6
6
  "type": "git",