@bikdotai/bik-component-library 0.0.806-beta.9 → 0.0.807-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/cjs/components/feature-announcements/FeatureAnnouncementProvider.js +1 -1
  2. package/dist/cjs/components/feature-announcements/FeatureAnnouncementProvider.js.map +1 -1
  3. package/dist/cjs/components/feature-announcements/MajorUpdatePopup.js +1 -1
  4. package/dist/cjs/components/feature-announcements/MajorUpdatePopup.js.map +1 -1
  5. package/dist/cjs/components/feature-announcements/MinorUpdatePopup.js +1 -1
  6. package/dist/cjs/components/feature-announcements/MinorUpdatePopup.js.map +1 -1
  7. package/dist/cjs/components/feature-announcements/utils/animationHelpers.js.map +1 -1
  8. package/dist/cjs/editor/BikEditor.styles.js +8 -2
  9. package/dist/cjs/editor/BikEditor.styles.js.map +1 -1
  10. package/dist/cjs/editor/extensions/buildExtensions.js +1 -1
  11. package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
  12. package/dist/cjs/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js +2 -0
  13. package/dist/cjs/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js.map +1 -0
  14. package/dist/cjs/editor/extensions/plainClipboard/PlainClipboardExtension.js +1 -1
  15. package/dist/cjs/editor/extensions/plainClipboard/PlainClipboardExtension.js.map +1 -1
  16. package/dist/cjs/editor/extensions/plainClipboard/pasteUtils.js +2 -0
  17. package/dist/cjs/editor/extensions/plainClipboard/pasteUtils.js.map +1 -0
  18. package/dist/cjs/src/components/bik-layout/MockMenus.d.ts +0 -1
  19. package/dist/cjs/src/components/feature-announcements/types/props.types.d.ts +3 -3
  20. package/dist/cjs/src/components/feature-announcements/utils/animationHelpers.d.ts +1 -1
  21. package/dist/cjs/src/editor/extensions/plainClipboard/ClipboardNormalizationExtension.d.ts +7 -0
  22. package/dist/cjs/src/editor/extensions/plainClipboard/pasteUtils.d.ts +21 -0
  23. package/dist/esm/components/feature-announcements/FeatureAnnouncementProvider.js +1 -1
  24. package/dist/esm/components/feature-announcements/FeatureAnnouncementProvider.js.map +1 -1
  25. package/dist/esm/components/feature-announcements/MajorUpdatePopup.js +1 -1
  26. package/dist/esm/components/feature-announcements/MajorUpdatePopup.js.map +1 -1
  27. package/dist/esm/components/feature-announcements/MinorUpdatePopup.js +1 -1
  28. package/dist/esm/components/feature-announcements/MinorUpdatePopup.js.map +1 -1
  29. package/dist/esm/components/feature-announcements/utils/animationHelpers.js.map +1 -1
  30. package/dist/esm/editor/BikEditor.styles.js +6 -0
  31. package/dist/esm/editor/BikEditor.styles.js.map +1 -1
  32. package/dist/esm/editor/extensions/buildExtensions.js +1 -1
  33. package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
  34. package/dist/esm/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js +2 -0
  35. package/dist/esm/editor/extensions/plainClipboard/ClipboardNormalizationExtension.js.map +1 -0
  36. package/dist/esm/editor/extensions/plainClipboard/PlainClipboardExtension.js +1 -1
  37. package/dist/esm/editor/extensions/plainClipboard/PlainClipboardExtension.js.map +1 -1
  38. package/dist/esm/editor/extensions/plainClipboard/pasteUtils.js +2 -0
  39. package/dist/esm/editor/extensions/plainClipboard/pasteUtils.js.map +1 -0
  40. package/dist/esm/src/components/bik-layout/MockMenus.d.ts +0 -1
  41. package/dist/esm/src/components/feature-announcements/types/props.types.d.ts +3 -3
  42. package/dist/esm/src/components/feature-announcements/utils/animationHelpers.d.ts +1 -1
  43. package/dist/esm/src/editor/extensions/plainClipboard/ClipboardNormalizationExtension.d.ts +7 -0
  44. package/dist/esm/src/editor/extensions/plainClipboard/pasteUtils.d.ts +21 -0
  45. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"animationHelpers.js","sources":["../../../../../src/components/feature-announcements/utils/animationHelpers.ts"],"sourcesContent":["import { ANIMATION_TIMING } from '../constants';\n\n/**\n * Calculate transform for closing animation\n * @param popupElement - Popup element reference\n * @param targetElement - Target element to animate towards\n * @returns Transform CSS string\n */\nexport const calculateCloseTransform = (\n\tpopupElement: HTMLElement,\n\ttargetElement: Element,\n): string => {\n\tconst popupRect = popupElement.getBoundingClientRect();\n\tconst targetRect = targetElement.getBoundingClientRect();\n\n\tconst translateX =\n\t\ttargetRect.left +\n\t\ttargetRect.width / 2 -\n\t\t(popupRect.left + popupRect.width / 2);\n\tconst translateY =\n\t\ttargetRect.top +\n\t\ttargetRect.height / 2 -\n\t\t(popupRect.top + popupRect.height / 2);\n\n\treturn `translate(${translateX}px, ${translateY}px) scale(0)`;\n};\n\n/**\n * Hide Joyride arrow element\n * @param popupRef - Reference to popup element\n */\nexport const hideJoyrideArrow = (popupRef: HTMLElement | null): void => {\n\tif (!popupRef) return;\n\n\tconst tooltip = popupRef.closest('[class*=\"react-joyride__tooltip\"]');\n\tif (!tooltip) return;\n\n\tconst arrow = tooltip.querySelector(\n\t\t'[class*=\"react-joyride__arrow\"]',\n\t) as HTMLElement;\n\tif (arrow) {\n\t\tarrow.style.display = 'none';\n\t\tarrow.style.visibility = 'hidden';\n\t\tarrow.style.opacity = '0';\n\t}\n};\n\n/**\n * Execute callback after animation completes\n * @param callback - Function to execute\n * @param delay - Optional delay override\n */\nexport const executeAfterAnimation = (\n\tcallback: () => void,\n\tdelay: number = ANIMATION_TIMING.CLOSE_DURATION,\n): void => {\n\tsetTimeout(callback, delay);\n};\n"],"names":["calculateCloseTransform","popupElement","targetElement","popupRect","getBoundingClientRect","targetRect","left","width","top","height","hideJoyrideArrow","popupRef","tooltip","closest","arrow","querySelector","style","display","visibility","opacity","executeAfterAnimation","callback","delay","arguments","length","undefined","ANIMATION_TIMING","CLOSE_DURATION","setTimeout"],"mappings":"oEAQaA,EAA0BA,CACtCC,EACAC,KAEA,MAAMC,EAAYF,EAAaG,wBACzBC,EAAaH,EAAcE,wBAWjC,MAAoB,aARnBC,EAAWC,KACXD,EAAWE,MAAQ,GAClBJ,EAAUG,KAAOH,EAAUI,MAAQ,SAEpCF,EAAWG,IACXH,EAAWI,OAAS,GACnBN,EAAUK,IAAML,EAAUM,OAAS,gBAEwB,EAOjDC,EAAoBC,IAChC,IAAKA,EAAU,OAEf,MAAMC,EAAUD,EAASE,QAAQ,qCACjC,IAAKD,EAAS,OAEd,MAAME,EAAQF,EAAQG,cACrB,mCAEGD,IACHA,EAAME,MAAMC,QAAU,OACtBH,EAAME,MAAME,WAAa,SACzBJ,EAAME,MAAMG,QAAU,IACtB,EAQWC,EAAwB,SACpCC,GAES,IADTC,EAAAC,UAAAC,OAAAD,QAAAE,IAAAF,UAAAE,GAAAF,UAAgBG,GAAAA,EAAiBC,eAEjCC,WAAWP,EAAUC,EACtB"}
1
+ {"version":3,"file":"animationHelpers.js","sources":["../../../../../src/components/feature-announcements/utils/animationHelpers.ts"],"sourcesContent":["import { ANIMATION_TIMING } from '../constants';\n\n/**\n * Calculate transform for closing animation\n * @param popupElement - Popup element reference\n * @param targetElement - Target element to animate towards\n * @returns Transform CSS string\n */\nexport const calculateCloseTransform = (\n\tpopupElement: HTMLElement,\n\ttargetElement: Element,\n): string => {\n\tconst popupRect = popupElement.getBoundingClientRect();\n\tconst targetRect = targetElement.getBoundingClientRect();\n\n\tconst translateX =\n\t\ttargetRect.left +\n\t\ttargetRect.width / 2 -\n\t\t(popupRect.left + popupRect.width / 2);\n\tconst translateY =\n\t\ttargetRect.top +\n\t\ttargetRect.height / 2 -\n\t\t(popupRect.top + popupRect.height / 2);\n\n\treturn `translate(${translateX}px, ${translateY}px) scale(0)`;\n};\n\n/**\n * Hide Joyride arrow element\n * @param popupRef - Reference to popup element\n */\nexport const hideJoyrideArrow = (popupRef: HTMLElement | null): void => {\n\tif (!popupRef) return;\n\n\tconst tooltip = popupRef.closest('[class*=\"react-joyride__tooltip\"]');\n\tif (!tooltip) return;\n\n\tconst arrow = tooltip.querySelector(\n\t\t'[class*=\"react-joyride__arrow\"]',\n\t) as HTMLElement;\n\tif (arrow) {\n\t\tarrow.style.display = 'none';\n\t\tarrow.style.visibility = 'hidden';\n\t\tarrow.style.opacity = '0';\n\t}\n};\n\n/**\n * Execute callback after animation completes\n * @param callback - Function to execute\n * @param delay - Optional delay override\n */\nexport const executeAfterAnimation = (\n\tcallback: () => void | Promise<void>,\n\tdelay: number = ANIMATION_TIMING.CLOSE_DURATION,\n): void => {\n\tsetTimeout(callback, delay);\n};\n"],"names":["calculateCloseTransform","popupElement","targetElement","popupRect","getBoundingClientRect","targetRect","left","width","top","height","hideJoyrideArrow","popupRef","tooltip","closest","arrow","querySelector","style","display","visibility","opacity","executeAfterAnimation","callback","delay","arguments","length","undefined","ANIMATION_TIMING","CLOSE_DURATION","setTimeout"],"mappings":"oEAQaA,EAA0BA,CACtCC,EACAC,KAEA,MAAMC,EAAYF,EAAaG,wBACzBC,EAAaH,EAAcE,wBAWjC,MAAoB,aARnBC,EAAWC,KACXD,EAAWE,MAAQ,GAClBJ,EAAUG,KAAOH,EAAUI,MAAQ,SAEpCF,EAAWG,IACXH,EAAWI,OAAS,GACnBN,EAAUK,IAAML,EAAUM,OAAS,gBAEwB,EAOjDC,EAAoBC,IAChC,IAAKA,EAAU,OAEf,MAAMC,EAAUD,EAASE,QAAQ,qCACjC,IAAKD,EAAS,OAEd,MAAME,EAAQF,EAAQG,cACrB,mCAEGD,IACHA,EAAME,MAAMC,QAAU,OACtBH,EAAME,MAAME,WAAa,SACzBJ,EAAME,MAAMG,QAAU,IACtB,EAQWC,EAAwB,SACpCC,GAES,IADTC,EAAAC,UAAAC,OAAAD,QAAAE,IAAAF,UAAAE,GAAAF,UAAgBG,GAAAA,EAAiBC,eAEjCC,WAAWP,EAAUC,EACtB"}
@@ -17,6 +17,12 @@ import e from"styled-components";import{COLORS as o}from"../constants/Theme.js";
17
17
  padding: 0;
18
18
  }
19
19
 
20
+ /* Enter = new paragraph → visible gap. Shift+Enter = <br> inside
21
+ the same paragraph → no gap. Matches Google Docs / Word behavior. */
22
+ p + p {
23
+ margin-top: 4px;
24
+ }
25
+
20
26
  ul,
21
27
  ol {
22
28
  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}>`\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\tp {\n\t\t\tmargin: 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","COLORS","content","brand"],"mappings":"gFAGaA,MAAAA,EAAiBC,EAAOC,GAGnC;;;;;gBAKcC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;gBACtCC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiC3CC,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}>`\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\tp {\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\t\t}\n\n\t\t/* Enter = new paragraph → visible gap. Shift+Enter = <br> inside\n\t\t the same paragraph → no gap. Matches Google Docs / Word behavior. */\n\t\tp + p {\n\t\t\tmargin-top: 4px;\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","COLORS","content","brand"],"mappings":"gFAGaA,MAAAA,EAAiBC,EAAOC,GAGnC;;;;;gBAKcC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;gBACtCC,IAAA,IAACC,UAAEA,GAAWD,EAAA,OAAKC,QAAAA,EAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAuC3CC,EAAOC,QAAQC;;;;WAIfF,EAAOC,QAAQC;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,2 @@
1
- import e from"@tiptap/extension-character-count";import o from"@tiptap/extension-color";import t from"@tiptap/extension-font-family";import n from"@tiptap/extension-highlight";import i from"@tiptap/extension-image";import r from"@tiptap/extension-link";import s from"@tiptap/extension-placeholder";import a from"@tiptap/extension-subscript";import m from"@tiptap/extension-superscript";import p from"@tiptap/extension-text-align";import{TextStyle as l}from"@tiptap/extension-text-style";import d from"@tiptap/extension-underline";import c from"@tiptap/starter-kit";import{FontSizeExtension as u}from"./FontSizeExtension.js";import{buildAgentMentionExtension as f,buildTeamMentionExtension as h}from"./mention/MentionExtension.js";import{PasteExtension as x}from"./paste/PasteExtension.js";import{PlainClipboardExtension as g}from"./plainClipboard/PlainClipboardExtension.js";import{SectionDividerNode as v}from"./sectionDivider/SectionDividerNode.js";import{SendShortcutExtension as S}from"./sendShortcut/SendShortcutExtension.js";import{buildSlashCommandExtension as C}from"./slashCommand/SlashCommandExtension.js";import{VariableDecorationExtension as k}from"./variable/VariableDecorationExtension.js";function b(b){var M,j,P,E,y,D,w,I,T;const O=null!==(j=null===(M=b.features)||void 0===M?void 0:M.richPaste)&&void 0!==j&&j,R=null!==(E=null===(P=b.features)||void 0===P?void 0:P.richTypography)&&void 0!==E&&E,z=null===(y=b.features)||void 0===y?void 0:y.allowedMarks,A=e=>!z||z.includes(e);return[...[c.configure({link:!1,underline:!1,bold:!!A("bold")&&{},italic:!!A("italic")&&{},strike:!!A("strike")&&{},code:!!A("code")&&{}}),...A("underline")?[d]:[],r.extend({addPasteRules:()=>[],addInputRules:()=>[]}).configure({openOnClick:!1,autolink:!1,linkOnPaste:!1,HTMLAttributes:{rel:"noopener noreferrer",class:"bik-link"}}),l,s.configure({placeholder:null!==(D=b.placeholder)&&void 0!==D?D:"Type a message..."}),...b.onPaste?[x.configure({onPaste:b.onPaste})]:[],...O?[]:[g],S.configure({onSend:b.onSend,sendShortcut:b.sendShortcut,extraShortcuts:null!==(w=b.shortcuts)&&void 0!==w?w:[]}),k,...b.maxCharacters?[e.configure({limit:b.maxCharacters})]:[],v],...[...(null===(I=b.mentions)||void 0===I?void 0:I.agents)?[f(b.mentions.agents,b.onMentionSelected,b.renderMentionItem,b.renderMentionDropdown)]:[],...(null===(T=b.mentions)||void 0===T?void 0:T.teams)?[h(b.mentions.teams,b.onMentionSelected,b.renderMentionItem,b.renderMentionDropdown)]:[],...b.slashCommands?[C(b.slashCommands,b.onSlashCommandSelected,b.renderSlashCommandItem,b.renderSlashCommandDropdown)]:[]],...R?[o,n.configure({multicolor:!0}),t,u,p.configure({types:["heading","paragraph"]}),a,m,i]:[o]]}export{b as buildExtensions};
1
+ import o from"@tiptap/extension-character-count";import e from"@tiptap/extension-color";import t from"@tiptap/extension-font-family";import n from"@tiptap/extension-highlight";import i from"@tiptap/extension-image";import r from"@tiptap/extension-link";import a from"@tiptap/extension-placeholder";import s from"@tiptap/extension-subscript";import m from"@tiptap/extension-superscript";import p from"@tiptap/extension-text-align";import{TextStyle as l}from"@tiptap/extension-text-style";import d from"@tiptap/extension-underline";import c from"@tiptap/starter-kit";import{FontSizeExtension as u}from"./FontSizeExtension.js";import{buildAgentMentionExtension as f,buildTeamMentionExtension as h}from"./mention/MentionExtension.js";import{PasteExtension as x}from"./paste/PasteExtension.js";import{ClipboardNormalizationExtension as g}from"./plainClipboard/ClipboardNormalizationExtension.js";import{PlainClipboardExtension as v}from"./plainClipboard/PlainClipboardExtension.js";import{SectionDividerNode as S}from"./sectionDivider/SectionDividerNode.js";import{SendShortcutExtension as C}from"./sendShortcut/SendShortcutExtension.js";import{buildSlashCommandExtension as b}from"./slashCommand/SlashCommandExtension.js";import{VariableDecorationExtension as k}from"./variable/VariableDecorationExtension.js";function j(j){var M,E,P,y,D,w,I,T,z;const N=null!==(E=null===(M=j.features)||void 0===M?void 0:M.richPaste)&&void 0!==E&&E,O=null!==(y=null===(P=j.features)||void 0===P?void 0:P.richTypography)&&void 0!==y&&y,R=null===(D=j.features)||void 0===D?void 0:D.allowedMarks,A=o=>!R||R.includes(o);return[...[c.configure({link:!1,underline:!1,bold:!!A("bold")&&{},italic:!!A("italic")&&{},strike:!!A("strike")&&{},code:!!A("code")&&{}}),...A("underline")?[d]:[],r.extend({addPasteRules:()=>[],addInputRules:()=>[]}).configure({openOnClick:!1,autolink:!1,linkOnPaste:!1,HTMLAttributes:{rel:"noopener noreferrer",class:"bik-link"}}),l,a.configure({placeholder:null!==(w=j.placeholder)&&void 0!==w?w:"Type a message..."}),...j.onPaste?[x.configure({onPaste:j.onPaste})]:[],...N?[g]:[v],C.configure({onSend:j.onSend,sendShortcut:j.sendShortcut,extraShortcuts:null!==(I=j.shortcuts)&&void 0!==I?I:[]}),k,...j.maxCharacters?[o.configure({limit:j.maxCharacters})]:[],S],...[...(null===(T=j.mentions)||void 0===T?void 0:T.agents)?[f(j.mentions.agents,j.onMentionSelected,j.renderMentionItem,j.renderMentionDropdown)]:[],...(null===(z=j.mentions)||void 0===z?void 0:z.teams)?[h(j.mentions.teams,j.onMentionSelected,j.renderMentionItem,j.renderMentionDropdown)]:[],...j.slashCommands?[b(j.slashCommands,j.onSlashCommandSelected,j.renderSlashCommandItem,j.renderSlashCommandDropdown)]:[]],...O?[e,n.configure({multicolor:!0}),t,u,p.configure({types:["heading","paragraph"]}),s,m,i]:[e]]}export{j as buildExtensions};
2
2
  //# sourceMappingURL=buildExtensions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildExtensions.js","sources":["../../../../src/editor/extensions/buildExtensions.ts"],"sourcesContent":["import CharacterCount from '@tiptap/extension-character-count';\nimport Color from '@tiptap/extension-color';\nimport FontFamily from '@tiptap/extension-font-family';\nimport Highlight from '@tiptap/extension-highlight';\nimport Image from '@tiptap/extension-image';\nimport Link from '@tiptap/extension-link';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport TextAlign from '@tiptap/extension-text-align';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Underline from '@tiptap/extension-underline';\nimport StarterKit from '@tiptap/starter-kit';\nimport type { ReactNode } from 'react';\nimport type {\n\tEditorFeatures,\n\tEditorSnapshot,\n\tKeyboardShortcut,\n\tMentionDropdownRenderProps,\n\tMentionItem,\n\tPasteData,\n\tSlashCommandDropdownRenderProps,\n\tSlashCommandItem,\n} from '../BikEditor.types';\nimport { FontSizeExtension } from './FontSizeExtension';\nimport {\n\tbuildAgentMentionExtension,\n\tbuildTeamMentionExtension,\n} from './mention/MentionExtension';\nimport { PasteExtension } from './paste/PasteExtension';\nimport { PlainClipboardExtension } from './plainClipboard/PlainClipboardExtension';\nimport { SectionDividerNode } from './sectionDivider/SectionDividerNode';\nimport { SendShortcutExtension } from './sendShortcut/SendShortcutExtension';\nimport { buildSlashCommandExtension } from './slashCommand/SlashCommandExtension';\nimport { VariableDecorationExtension } from './variable/VariableDecorationExtension';\n\ninterface ExtensionConfig {\n\tfeatures?: EditorFeatures;\n\tplaceholder?: string;\n\tmaxCharacters?: number;\n\thasSections?: boolean;\n\tmentions?: {\n\t\tagents?: { current: MentionItem[] };\n\t\tteams?: { current: MentionItem[] };\n\t};\n\tslashCommands?: { current: SlashCommandItem[] };\n\tonPaste?: (data: PasteData) => boolean | void;\n\tonSend?: (content: EditorSnapshot) => void;\n\tsendShortcut?:\n\t\t| { key: string; modifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'> }\n\t\t| Array<{\n\t\t\t\tkey: string;\n\t\t\t\tmodifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'>;\n\t\t }>;\n\tshortcuts?: KeyboardShortcut[];\n\tonMentionSelected?: (item: MentionItem, char: '@' | '#') => void;\n\tonSlashCommandSelected?: (command: SlashCommandItem) => void;\n\trenderMentionItem?: (item: MentionItem, isActive: boolean) => ReactNode;\n\trenderMentionDropdown?: (props: MentionDropdownRenderProps) => ReactNode;\n\trenderSlashCommandItem?: (\n\t\titem: SlashCommandItem,\n\t\tisActive: boolean,\n\t) => ReactNode;\n\trenderSlashCommandDropdown?: (\n\t\tprops: SlashCommandDropdownRenderProps,\n\t) => ReactNode;\n}\n\nexport function buildExtensions(config: ExtensionConfig) {\n\tconst hasRichPaste = config.features?.richPaste ?? false;\n\tconst hasRichTypography = config.features?.richTypography ?? false;\n\n\t// When allowedMarks is specified only those marks are registered in the schema.\n\t// This disables rendering, keyboard shortcuts AND paste-preservation for the\n\t// excluded marks — all three come for free when the extension is absent.\n\tconst allowedMarks = config.features?.allowedMarks;\n\tconst isMark = (m: 'bold' | 'italic' | 'strike' | 'underline' | 'code') =>\n\t\t!allowedMarks || allowedMarks.includes(m);\n\n\tconst base = [\n\t\t// Exclude Link and Underline from StarterKit — TipTap v3 bundles both.\n\t\t// Without this, two copies of each are registered and the StarterKit copy's\n\t\t// click handler calls window.open even when openOnClick: false is set.\n\t\tStarterKit.configure({\n\t\t\tlink: false,\n\t\t\tunderline: false,\n\t\t\tbold: isMark('bold') ? {} : false,\n\t\t\titalic: isMark('italic') ? {} : false,\n\t\t\tstrike: isMark('strike') ? {} : false,\n\t\t\tcode: isMark('code') ? {} : false,\n\t\t}),\n\t\t...(isMark('underline') ? [Underline] : []),\n\t\t// Extend Link to strip addPasteRules() and addInputRules() so pasting a\n\t\t// URL never creates a hyperlink regardless of autolink/linkOnPaste values.\n\t\tLink.extend({\n\t\t\taddPasteRules: () => [],\n\t\t\taddInputRules: () => [],\n\t\t}).configure({\n\t\t\topenOnClick: false,\n\t\t\tautolink: false,\n\t\t\tlinkOnPaste: false,\n\t\t\tHTMLAttributes: {\n\t\t\t\trel: 'noopener noreferrer',\n\t\t\t\tclass: 'bik-link',\n\t\t\t},\n\t\t}),\n\t\tTextStyle,\n\t\tPlaceholder.configure({\n\t\t\tplaceholder: config.placeholder ?? 'Type a message...',\n\t\t}),\n\t\t// Consumer paste callback runs first. If it returns true the event is\n\t\t// consumed and neither PlainClipboardExtension nor the editor's default\n\t\t// paste handling will run for that event.\n\t\t...(config.onPaste\n\t\t\t? [PasteExtension.configure({ onPaste: config.onPaste })]\n\t\t\t: []),\n\t\t// Strip HTML on paste for non-rich modes so plain text is inserted.\n\t\t...(!hasRichPaste ? [PlainClipboardExtension] : []),\n\t\tSendShortcutExtension.configure({\n\t\t\tonSend: config.onSend,\n\t\t\tsendShortcut: config.sendShortcut,\n\t\t\textraShortcuts: config.shortcuts ?? [],\n\t\t}),\n\t\tVariableDecorationExtension,\n\t\t...(config.maxCharacters\n\t\t\t? [CharacterCount.configure({ limit: config.maxCharacters })]\n\t\t\t: []),\n\t\t// Always register SectionDividerNode so the custom <div data-section-divider>\n\t\t// node is part of the schema in every editor instance. This means imperative\n\t\t// callers (setBodyAndSections / setSectionContent) work even when no\n\t\t// `sections` prop was provided at mount time.\n\t\tSectionDividerNode,\n\t];\n\n\tconst mentionExtensions = [\n\t\t...(config.mentions?.agents\n\t\t\t? [\n\t\t\t\t\tbuildAgentMentionExtension(\n\t\t\t\t\t\tconfig.mentions.agents,\n\t\t\t\t\t\tconfig.onMentionSelected,\n\t\t\t\t\t\tconfig.renderMentionItem,\n\t\t\t\t\t\tconfig.renderMentionDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t\t...(config.mentions?.teams\n\t\t\t? [\n\t\t\t\t\tbuildTeamMentionExtension(\n\t\t\t\t\t\tconfig.mentions.teams,\n\t\t\t\t\t\tconfig.onMentionSelected,\n\t\t\t\t\t\tconfig.renderMentionItem,\n\t\t\t\t\t\tconfig.renderMentionDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t\t...(config.slashCommands\n\t\t\t? [\n\t\t\t\t\tbuildSlashCommandExtension(\n\t\t\t\t\t\tconfig.slashCommands,\n\t\t\t\t\t\tconfig.onSlashCommandSelected,\n\t\t\t\t\t\tconfig.renderSlashCommandItem,\n\t\t\t\t\t\tconfig.renderSlashCommandDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t];\n\n\tconst richExtensions = hasRichTypography\n\t\t? [\n\t\t\t\tColor,\n\t\t\t\tHighlight.configure({ multicolor: true }),\n\t\t\t\tFontFamily,\n\t\t\t\tFontSizeExtension,\n\t\t\t\tTextAlign.configure({ types: ['heading', 'paragraph'] }),\n\t\t\t\tSubscript,\n\t\t\t\tSuperscript,\n\t\t\t\tImage,\n\t\t ]\n\t\t: [Color];\n\n\treturn [...base, ...mentionExtensions, ...richExtensions];\n}\n"],"names":["buildExtensions","config","hasRichPaste","_b","_a","features","richPaste","hasRichTypography","_d","_c","richTypography","allowedMarks","_e","isMark","m","includes","StarterKit","configure","link","underline","bold","italic","strike","code","Underline","Link","extend","addPasteRules","addInputRules","openOnClick","autolink","linkOnPaste","HTMLAttributes","rel","class","TextStyle","Placeholder","placeholder","_f","onPaste","PasteExtension","PlainClipboardExtension","SendShortcutExtension","onSend","sendShortcut","extraShortcuts","_g","shortcuts","VariableDecorationExtension","maxCharacters","CharacterCount","limit","SectionDividerNode","_h","mentions","agents","buildAgentMentionExtension","onMentionSelected","renderMentionItem","renderMentionDropdown","_j","teams","buildTeamMentionExtension","slashCommands","buildSlashCommandExtension","onSlashCommandSelected","renderSlashCommandItem","renderSlashCommandDropdown","Color","Highlight","multicolor","FontFamily","FontSizeExtension","TextAlign","types","Subscript","Superscript","Image"],"mappings":"orCAoEM,SAAUA,EAAgBC,yBAC/B,MAAMC,EAA6C,QAA9BC,EAAiB,QAAjBC,EAAAH,EAAOI,gBAAU,IAAAD,OAAA,EAAAA,EAAAE,iBAAa,IAAAH,GAAAA,EAC7CI,EAAuD,QAAnCC,EAAiB,QAAjBC,EAAAR,EAAOI,gBAAU,IAAAI,OAAA,EAAAA,EAAAC,sBAAkB,IAAAF,GAAAA,EAKvDG,EAA8B,QAAfC,EAAAX,EAAOI,gBAAQ,IAAAO,OAAA,EAAAA,EAAED,aAChCE,EAAUC,IACdH,GAAgBA,EAAaI,SAASD,GAuGxC,MAAO,IArGM,CAIZE,EAAWC,UAAU,CACpBC,MAAM,EACNC,WAAW,EACXC,OAAMP,EAAO,SAAU,CAAE,EACzBQ,SAAQR,EAAO,WAAY,CAAE,EAC7BS,SAAQT,EAAO,WAAY,CAAE,EAC7BU,OAAMV,EAAO,SAAU,CAAE,OAEtBA,EAAO,aAAe,CAACW,GAAa,GAGxCC,EAAKC,OAAO,CACXC,cAAeA,IAAM,GACrBC,cAAeA,IAAM,KACnBX,UAAU,CACZY,aAAa,EACbC,UAAU,EACVC,aAAa,EACbC,eAAgB,CACfC,IAAK,sBACLC,MAAO,cAGTC,EACAC,EAAYnB,UAAU,CACrBoB,oBAAaC,EAAArC,EAAOoC,2BAAe,yBAKhCpC,EAAOsC,QACR,CAACC,EAAevB,UAAU,CAAEsB,QAAStC,EAAOsC,WAC5C,MAEErC,EAA2C,GAA5B,CAACuC,GACrBC,EAAsBzB,UAAU,CAC/B0B,OAAQ1C,EAAO0C,OACfC,aAAc3C,EAAO2C,aACrBC,uBAAgBC,EAAA7C,EAAO8C,yBAAa,KAErCC,KACI/C,EAAOgD,cACR,CAACC,EAAejC,UAAU,CAAEkC,MAAOlD,EAAOgD,iBAC1C,GAKHG,MAGyB,aACrBC,EAAApD,EAAOqD,+BAAUC,QAClB,CACAC,EACCvD,EAAOqD,SAASC,OAChBtD,EAAOwD,kBACPxD,EAAOyD,kBACPzD,EAAO0D,wBAGR,eACCC,EAAA3D,EAAOqD,+BAAUO,OAClB,CACAC,EACC7D,EAAOqD,SAASO,MAChB5D,EAAOwD,kBACPxD,EAAOyD,kBACPzD,EAAO0D,wBAGR,MACC1D,EAAO8D,cACR,CACAC,EACC/D,EAAO8D,cACP9D,EAAOgE,uBACPhE,EAAOiE,uBACPjE,EAAOkE,6BAGR,OAGmB5D,EACpB,CACA6D,EACAC,EAAUpD,UAAU,CAAEqD,YAAY,IAClCC,EACAC,EACAC,EAAUxD,UAAU,CAAEyD,MAAO,CAAC,UAAW,eACzCC,EACAC,EACAC,GAEA,CAACT,GAGL"}
1
+ {"version":3,"file":"buildExtensions.js","sources":["../../../../src/editor/extensions/buildExtensions.ts"],"sourcesContent":["import CharacterCount from '@tiptap/extension-character-count';\nimport Color from '@tiptap/extension-color';\nimport FontFamily from '@tiptap/extension-font-family';\nimport Highlight from '@tiptap/extension-highlight';\nimport Image from '@tiptap/extension-image';\nimport Link from '@tiptap/extension-link';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport TextAlign from '@tiptap/extension-text-align';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Underline from '@tiptap/extension-underline';\nimport StarterKit from '@tiptap/starter-kit';\nimport type { ReactNode } from 'react';\nimport type {\n\tEditorFeatures,\n\tEditorSnapshot,\n\tKeyboardShortcut,\n\tMentionDropdownRenderProps,\n\tMentionItem,\n\tPasteData,\n\tSlashCommandDropdownRenderProps,\n\tSlashCommandItem,\n} from '../BikEditor.types';\nimport { FontSizeExtension } from './FontSizeExtension';\nimport {\n\tbuildAgentMentionExtension,\n\tbuildTeamMentionExtension,\n} from './mention/MentionExtension';\nimport { PasteExtension } from './paste/PasteExtension';\nimport { ClipboardNormalizationExtension } from './plainClipboard/ClipboardNormalizationExtension';\nimport { PlainClipboardExtension } from './plainClipboard/PlainClipboardExtension';\nimport { SectionDividerNode } from './sectionDivider/SectionDividerNode';\nimport { SendShortcutExtension } from './sendShortcut/SendShortcutExtension';\nimport { buildSlashCommandExtension } from './slashCommand/SlashCommandExtension';\nimport { VariableDecorationExtension } from './variable/VariableDecorationExtension';\n\ninterface ExtensionConfig {\n\tfeatures?: EditorFeatures;\n\tplaceholder?: string;\n\tmaxCharacters?: number;\n\thasSections?: boolean;\n\tmentions?: {\n\t\tagents?: { current: MentionItem[] };\n\t\tteams?: { current: MentionItem[] };\n\t};\n\tslashCommands?: { current: SlashCommandItem[] };\n\tonPaste?: (data: PasteData) => boolean | void;\n\tonSend?: (content: EditorSnapshot) => void;\n\tsendShortcut?:\n\t\t| { key: string; modifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'> }\n\t\t| Array<{\n\t\t\t\tkey: string;\n\t\t\t\tmodifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'>;\n\t\t }>;\n\tshortcuts?: KeyboardShortcut[];\n\tonMentionSelected?: (item: MentionItem, char: '@' | '#') => void;\n\tonSlashCommandSelected?: (command: SlashCommandItem) => void;\n\trenderMentionItem?: (item: MentionItem, isActive: boolean) => ReactNode;\n\trenderMentionDropdown?: (props: MentionDropdownRenderProps) => ReactNode;\n\trenderSlashCommandItem?: (\n\t\titem: SlashCommandItem,\n\t\tisActive: boolean,\n\t) => ReactNode;\n\trenderSlashCommandDropdown?: (\n\t\tprops: SlashCommandDropdownRenderProps,\n\t) => ReactNode;\n}\n\nexport function buildExtensions(config: ExtensionConfig) {\n\tconst hasRichPaste = config.features?.richPaste ?? false;\n\tconst hasRichTypography = config.features?.richTypography ?? false;\n\n\t// When allowedMarks is specified only those marks are registered in the schema.\n\t// This disables rendering, keyboard shortcuts AND paste-preservation for the\n\t// excluded marks — all three come for free when the extension is absent.\n\tconst allowedMarks = config.features?.allowedMarks;\n\tconst isMark = (m: 'bold' | 'italic' | 'strike' | 'underline' | 'code') =>\n\t\t!allowedMarks || allowedMarks.includes(m);\n\n\tconst base = [\n\t\t// Exclude Link and Underline from StarterKit — TipTap v3 bundles both.\n\t\t// Without this, two copies of each are registered and the StarterKit copy's\n\t\t// click handler calls window.open even when openOnClick: false is set.\n\t\tStarterKit.configure({\n\t\t\tlink: false,\n\t\t\tunderline: false,\n\t\t\tbold: isMark('bold') ? {} : false,\n\t\t\titalic: isMark('italic') ? {} : false,\n\t\t\tstrike: isMark('strike') ? {} : false,\n\t\t\tcode: isMark('code') ? {} : false,\n\t\t}),\n\t\t...(isMark('underline') ? [Underline] : []),\n\t\t// Extend Link to strip addPasteRules() and addInputRules() so pasting a\n\t\t// URL never creates a hyperlink regardless of autolink/linkOnPaste values.\n\t\tLink.extend({\n\t\t\taddPasteRules: () => [],\n\t\t\taddInputRules: () => [],\n\t\t}).configure({\n\t\t\topenOnClick: false,\n\t\t\tautolink: false,\n\t\t\tlinkOnPaste: false,\n\t\t\tHTMLAttributes: {\n\t\t\t\trel: 'noopener noreferrer',\n\t\t\t\tclass: 'bik-link',\n\t\t\t},\n\t\t}),\n\t\tTextStyle,\n\t\tPlaceholder.configure({\n\t\t\tplaceholder: config.placeholder ?? 'Type a message...',\n\t\t}),\n\t\t// Consumer paste callback runs first. If it returns true the event is\n\t\t// consumed and neither PlainClipboardExtension nor the editor's default\n\t\t// paste handling will run for that event.\n\t\t...(config.onPaste\n\t\t\t? [PasteExtension.configure({ onPaste: config.onPaste })]\n\t\t\t: []),\n\t\t// Non-rich editors: strip rich marks + normalize blanks on paste.\n\t\t// Rich editors (email): only normalize blanks (fix Google Docs spacing).\n\t\t...(!hasRichPaste\n\t\t\t? [PlainClipboardExtension]\n\t\t\t: [ClipboardNormalizationExtension]),\n\t\tSendShortcutExtension.configure({\n\t\t\tonSend: config.onSend,\n\t\t\tsendShortcut: config.sendShortcut,\n\t\t\textraShortcuts: config.shortcuts ?? [],\n\t\t}),\n\t\tVariableDecorationExtension,\n\t\t...(config.maxCharacters\n\t\t\t? [CharacterCount.configure({ limit: config.maxCharacters })]\n\t\t\t: []),\n\t\t// Always register SectionDividerNode so the custom <div data-section-divider>\n\t\t// node is part of the schema in every editor instance. This means imperative\n\t\t// callers (setBodyAndSections / setSectionContent) work even when no\n\t\t// `sections` prop was provided at mount time.\n\t\tSectionDividerNode,\n\t];\n\n\tconst mentionExtensions = [\n\t\t...(config.mentions?.agents\n\t\t\t? [\n\t\t\t\t\tbuildAgentMentionExtension(\n\t\t\t\t\t\tconfig.mentions.agents,\n\t\t\t\t\t\tconfig.onMentionSelected,\n\t\t\t\t\t\tconfig.renderMentionItem,\n\t\t\t\t\t\tconfig.renderMentionDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t\t...(config.mentions?.teams\n\t\t\t? [\n\t\t\t\t\tbuildTeamMentionExtension(\n\t\t\t\t\t\tconfig.mentions.teams,\n\t\t\t\t\t\tconfig.onMentionSelected,\n\t\t\t\t\t\tconfig.renderMentionItem,\n\t\t\t\t\t\tconfig.renderMentionDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t\t...(config.slashCommands\n\t\t\t? [\n\t\t\t\t\tbuildSlashCommandExtension(\n\t\t\t\t\t\tconfig.slashCommands,\n\t\t\t\t\t\tconfig.onSlashCommandSelected,\n\t\t\t\t\t\tconfig.renderSlashCommandItem,\n\t\t\t\t\t\tconfig.renderSlashCommandDropdown,\n\t\t\t\t\t),\n\t\t\t ]\n\t\t\t: []),\n\t];\n\n\tconst richExtensions = hasRichTypography\n\t\t? [\n\t\t\t\tColor,\n\t\t\t\tHighlight.configure({ multicolor: true }),\n\t\t\t\tFontFamily,\n\t\t\t\tFontSizeExtension,\n\t\t\t\tTextAlign.configure({ types: ['heading', 'paragraph'] }),\n\t\t\t\tSubscript,\n\t\t\t\tSuperscript,\n\t\t\t\tImage,\n\t\t ]\n\t\t: [Color];\n\n\treturn [...base, ...mentionExtensions, ...richExtensions];\n}\n"],"names":["buildExtensions","config","hasRichPaste","_b","_a","features","richPaste","hasRichTypography","_d","_c","richTypography","allowedMarks","_e","isMark","m","includes","StarterKit","configure","link","underline","bold","italic","strike","code","Underline","Link","extend","addPasteRules","addInputRules","openOnClick","autolink","linkOnPaste","HTMLAttributes","rel","class","TextStyle","Placeholder","placeholder","_f","onPaste","PasteExtension","ClipboardNormalizationExtension","PlainClipboardExtension","SendShortcutExtension","onSend","sendShortcut","extraShortcuts","_g","shortcuts","VariableDecorationExtension","maxCharacters","CharacterCount","limit","SectionDividerNode","_h","mentions","agents","buildAgentMentionExtension","onMentionSelected","renderMentionItem","renderMentionDropdown","_j","teams","buildTeamMentionExtension","slashCommands","buildSlashCommandExtension","onSlashCommandSelected","renderSlashCommandItem","renderSlashCommandDropdown","Color","Highlight","multicolor","FontFamily","FontSizeExtension","TextAlign","types","Subscript","Superscript","Image"],"mappings":"0xCAqEM,SAAUA,EAAgBC,yBAC/B,MAAMC,EAA6C,QAA9BC,EAAiB,QAAjBC,EAAAH,EAAOI,gBAAU,IAAAD,OAAA,EAAAA,EAAAE,iBAAa,IAAAH,GAAAA,EAC7CI,EAAuD,QAAnCC,EAAiB,QAAjBC,EAAAR,EAAOI,gBAAU,IAAAI,OAAA,EAAAA,EAAAC,sBAAkB,IAAAF,GAAAA,EAKvDG,EAA8B,QAAfC,EAAAX,EAAOI,gBAAQ,IAAAO,OAAA,EAAAA,EAAED,aAChCE,EAAUC,IACdH,GAAgBA,EAAaI,SAASD,GA0GxC,MAAO,IAxGM,CAIZE,EAAWC,UAAU,CACpBC,MAAM,EACNC,WAAW,EACXC,OAAMP,EAAO,SAAU,CAAE,EACzBQ,SAAQR,EAAO,WAAY,CAAE,EAC7BS,SAAQT,EAAO,WAAY,CAAE,EAC7BU,OAAMV,EAAO,SAAU,CAAE,OAEtBA,EAAO,aAAe,CAACW,GAAa,GAGxCC,EAAKC,OAAO,CACXC,cAAeA,IAAM,GACrBC,cAAeA,IAAM,KACnBX,UAAU,CACZY,aAAa,EACbC,UAAU,EACVC,aAAa,EACbC,eAAgB,CACfC,IAAK,sBACLC,MAAO,cAGTC,EACAC,EAAYnB,UAAU,CACrBoB,oBAAaC,EAAArC,EAAOoC,2BAAe,yBAKhCpC,EAAOsC,QACR,CAACC,EAAevB,UAAU,CAAEsB,QAAStC,EAAOsC,WAC5C,MAGErC,EAEF,CAACuC,GADD,CAACC,GAEJC,EAAsB1B,UAAU,CAC/B2B,OAAQ3C,EAAO2C,OACfC,aAAc5C,EAAO4C,aACrBC,uBAAgBC,EAAA9C,EAAO+C,yBAAa,KAErCC,KACIhD,EAAOiD,cACR,CAACC,EAAelC,UAAU,CAAEmC,MAAOnD,EAAOiD,iBAC1C,GAKHG,MAGyB,aACrBC,EAAArD,EAAOsD,+BAAUC,QAClB,CACAC,EACCxD,EAAOsD,SAASC,OAChBvD,EAAOyD,kBACPzD,EAAO0D,kBACP1D,EAAO2D,wBAGR,eACCC,EAAA5D,EAAOsD,+BAAUO,OAClB,CACAC,EACC9D,EAAOsD,SAASO,MAChB7D,EAAOyD,kBACPzD,EAAO0D,kBACP1D,EAAO2D,wBAGR,MACC3D,EAAO+D,cACR,CACAC,EACChE,EAAO+D,cACP/D,EAAOiE,uBACPjE,EAAOkE,uBACPlE,EAAOmE,6BAGR,OAGmB7D,EACpB,CACA8D,EACAC,EAAUrD,UAAU,CAAEsD,YAAY,IAClCC,EACAC,EACAC,EAAUzD,UAAU,CAAE0D,MAAO,CAAC,UAAW,eACzCC,EACAC,EACAC,GAEA,CAACT,GAGL"}
@@ -0,0 +1,2 @@
1
+ import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{DOMParser as e,Slice as r}from"@tiptap/pm/model";import{Plugin as o}from"@tiptap/pm/state";import{BLOCK_SELECTOR as i,cleanBlockBrs as a,normalizeBlanks as n}from"./pasteUtils.js";const l=t.create({name:"clipboardNormalization",addProseMirrorPlugins:()=>[new o({props:{handlePaste(t,o){var l,p,d;if(null===(p=null===(l=o.clipboardData)||void 0===l?void 0:l.files)||void 0===p?void 0:p.length)return!1;const s=null===(d=o.clipboardData)||void 0===d?void 0:d.getData("text/html");if(!s)return!1;if(s.includes("data-pm-slice"))return!1;const c=document.createElement("div");if(c.innerHTML=s,!c.querySelector(i))return!1;a(c);const m=t.state.schema,u=e.fromSchema(m).parseSlice(c),f=n(u.content),v=new r(f,u.openStart,u.openEnd);return t.dispatch(t.state.tr.replaceSelection(v)),!0}}})]});export{l as ClipboardNormalizationExtension};
2
+ //# sourceMappingURL=ClipboardNormalizationExtension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClipboardNormalizationExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/ClipboardNormalizationExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { DOMParser as ProseMirrorDOMParser, Slice } from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport { BLOCK_SELECTOR, cleanBlockBrs, normalizeBlanks } from './pasteUtils';\n\n/**\n * Lightweight paste normalizer for rich-paste editors (email).\n * Fixes Google Docs' standalone `<br>` between paragraphs and collapses\n * consecutive empty paragraphs — but keeps ALL formatting marks intact.\n */\nexport const ClipboardNormalizationExtension = Extension.create({\n\tname: 'clipboardNormalization',\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tprops: {\n\t\t\t\t\thandlePaste(_view, event) {\n\t\t\t\t\t\tif (event.clipboardData?.files?.length) return false;\n\t\t\t\t\t\tconst html = event.clipboardData?.getData('text/html');\n\t\t\t\t\t\tif (!html) return false;\n\t\t\t\t\t\tif (html.includes('data-pm-slice')) return false;\n\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\tif (!container.querySelector(BLOCK_SELECTOR)) return false;\n\n\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\tconst schema = _view.state.schema;\n\t\t\t\t\t\tconst parsed =\n\t\t\t\t\t\t\tProseMirrorDOMParser.fromSchema(schema).parseSlice(container);\n\t\t\t\t\t\tconst cleaned = normalizeBlanks(parsed.content);\n\t\t\t\t\t\tconst slice = new Slice(cleaned, parsed.openStart, parsed.openEnd);\n\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["ClipboardNormalizationExtension","Extension","create","name","addProseMirrorPlugins","Plugin","props","handlePaste","_view","event","_b","clipboardData","_a","files","length","html","_c","getData","includes","container","document","createElement","innerHTML","querySelector","BLOCK_SELECTOR","cleanBlockBrs","schema","state","parsed","ProseMirrorDOMParser","fromSchema","parseSlice","cleaned","normalizeBlanks","content","slice","Slice","openStart","openEnd","dispatch","tr","replaceSelection"],"mappings":"8QAUaA,EAAkCC,EAAUC,OAAO,CAC/DC,KAAM,yBACNC,sBAAqBA,IACb,CACN,IAAIC,EAAO,CACVC,MAAO,CACNC,YAAYC,EAAOC,aAClB,WAAIC,EAAqB,UAArBD,EAAME,qBAAe,IAAAC,OAAA,EAAAA,EAAAC,4BAAOC,OAAQ,OAAO,EAC/C,MAAMC,EAA0B,QAAnBC,EAAAP,EAAME,qBAAa,IAAAK,OAAA,EAAAA,EAAEC,QAAQ,aAC1C,IAAKF,EAAM,OAAO,EAClB,GAAIA,EAAKG,SAAS,iBAAkB,OAAO,EAE3C,MAAMC,EAAYC,SAASC,cAAc,OAEzC,GADAF,EAAUG,UAAYP,GACjBI,EAAUI,cAAcC,GAAiB,OAAO,EAErDC,EAAcN,GACd,MAAMO,EAASlB,EAAMmB,MAAMD,OACrBE,EACLC,EAAqBC,WAAWJ,GAAQK,WAAWZ,GAC9Ca,EAAUC,EAAgBL,EAAOM,SACjCC,EAAQ,IAAIC,EAAMJ,EAASJ,EAAOS,UAAWT,EAAOU,SAE1D,OADA9B,EAAM+B,SAAS/B,EAAMmB,MAAMa,GAAGC,iBAAiBN,KACxC,CACR"}
@@ -1,2 +1,2 @@
1
- import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{DOMParser as e,Slice as o,Fragment as n}from"@tiptap/pm/model";import{Plugin as a}from"@tiptap/pm/state";const r=new Set(["bold","italic","strike","underline","code"]);function l(t){const e=[];return t.forEach((t=>{if(t.isText){const o=t.marks.filter((t=>r.has(t.type.name)));e.push(o.length===t.marks.length?t:t.mark(o))}else e.push(t.copy(l(t.content)))})),n.from(e)}function i(t){const e=[];let o=!1;return t.forEach((t=>{var n;if("paragraph"===t.type.name&&1===t.childCount&&"hardBreak"===(null===(n=t.firstChild)||void 0===n?void 0:n.type.name))return o||e.push(t.type.create(t.attrs)),void(o=!0);const a="paragraph"===t.type.name&&0===t.childCount;a&&o||(o=a,t.isBlock&&!t.isLeaf?e.push(t.copy(i(t.content))):e.push(t))})),n.from(e)}const c=t.create({name:"plainClipboard",addProseMirrorPlugins:()=>[new a({props:{handlePaste(t,a){var r,c,s,p;if(null===(c=null===(r=a.clipboardData)||void 0===r?void 0:r.files)||void 0===c?void 0:c.length)return!1;const d=null===(s=a.clipboardData)||void 0===s?void 0:s.getData("text/html"),m=null===(p=a.clipboardData)||void 0===p?void 0:p.getData("text/plain");if(!m)return!1;if(null==d?void 0:d.includes("data-pm-slice"))return!1;const h=t.state.schema;if(d){console.log("[PASTE-DEBUG] clipboard html:",d);const n=document.createElement("div");n.innerHTML=d;const a=e.fromSchema(h).parseSlice(n);console.log("[PASTE-DEBUG] parsed nodes:"),a.content.forEach(((t,e,o)=>{var n;const a=[];null===(n=t.forEach)||void 0===n||n.call(t,(t=>a.push(t.type.name+(t.isText?`="${t.text}"`:"")))),console.log(` [${o}] ${t.type.name} children=[${a.join(", ")}]`)}));const r=i(l(a.content));console.log("[PASTE-DEBUG] after normalizeBlanks:"),r.forEach(((t,e,o)=>{var n;const a=[];null===(n=t.forEach)||void 0===n||n.call(t,(t=>a.push(t.type.name+(t.isText?`="${t.text}"`:"")))),console.log(` [${o}] ${t.type.name} children=[${a.join(", ")}]`)}));const c=new o(r,a.openStart,a.openEnd);return t.dispatch(t.state.tr.replaceSelection(c)),!0}const u=m.split("\n").map((t=>h.node("paragraph",null,t?[h.text(t)]:[]))),f=new o(n.fromArray(u),1,1);return t.dispatch(t.state.tr.replaceSelection(f)),!0}}})]});export{c as PlainClipboardExtension};
1
+ import{Extension as t}from"../../../node_modules/@tiptap/core/dist/index.js";import{DOMParser as e,Slice as r,Fragment as a}from"@tiptap/pm/model";import{Plugin as o}from"@tiptap/pm/state";import{BLOCK_SELECTOR as i,cleanBlockBrs as n,normalizeBlanks as l,stripRichMarks as p}from"./pasteUtils.js";const d=t.create({name:"plainClipboard",addProseMirrorPlugins:()=>[new o({props:{handlePaste(t,o){var d,s,c,m;if(null===(s=null===(d=o.clipboardData)||void 0===d?void 0:d.files)||void 0===s?void 0:s.length)return!1;const u=null===(c=o.clipboardData)||void 0===c?void 0:c.getData("text/html"),f=null===(m=o.clipboardData)||void 0===m?void 0:m.getData("text/plain");if(!f)return!1;if(null==u?void 0:u.includes("data-pm-slice"))return!1;const v=t.state.schema;if(u){const a=document.createElement("div");a.innerHTML=u;if(a.querySelector(i)){n(a);const o=e.fromSchema(v).parseSlice(a),i=l(p(o.content)),d=new r(i,o.openStart,o.openEnd);return t.dispatch(t.state.tr.replaceSelection(d)),!0}}const h=f.split("\n").map((t=>v.node("paragraph",null,t?[v.text(t)]:[]))),S=new r(a.fromArray(h),1,1);return t.dispatch(t.state.tr.replaceSelection(S)),!0}}})]});export{d as PlainClipboardExtension};
2
2
  //# sourceMappingURL=PlainClipboardExtension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PlainClipboardExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PlainClipboardExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport {\n\tFragment,\n\tNode as PMNode,\n\tDOMParser as ProseMirrorDOMParser,\n\tSlice,\n} from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\n\nconst BASIC_MARKS = new Set(['bold', 'italic', 'strike', 'underline', 'code']);\n\n/**\n * Strip only \"rich\" marks (link, textStyle, highlight, etc.) while keeping\n * basic formatting marks (bold, italic, strike, underline, code) that\n * messaging channels can represent.\n */\nfunction stripRichMarks(fragment: Fragment): Fragment {\n\tconst nodes: PMNode[] = [];\n\tfragment.forEach((node) => {\n\t\tif (node.isText) {\n\t\t\tconst kept = node.marks.filter((m) => BASIC_MARKS.has(m.type.name));\n\t\t\tnodes.push(kept.length === node.marks.length ? node : node.mark(kept));\n\t\t} else {\n\t\t\tnodes.push(node.copy(stripRichMarks(node.content)));\n\t\t}\n\t});\n\treturn Fragment.from(nodes);\n}\n\n/**\n * 1. Convert paragraphs containing only a hard_break into empty paragraphs.\n * (Google Docs: `<p><span style=\"...\"><br></span></p>`)\n * 2. Collapse consecutive empty paragraphs into one.\n * (Google Docs emits both a standalone `<br>` AND a `<p><br></p>` per\n * blank line — ProseMirror wraps the standalone into its own paragraph,\n * doubling each blank line.)\n */\nfunction normalizeBlanks(fragment: Fragment): Fragment {\n\tconst nodes: PMNode[] = [];\n\tlet prevEmpty = false;\n\tfragment.forEach((node) => {\n\t\tconst isHardBreakOnly =\n\t\t\tnode.type.name === 'paragraph' &&\n\t\t\tnode.childCount === 1 &&\n\t\t\tnode.firstChild?.type.name === 'hardBreak';\n\t\tif (isHardBreakOnly) {\n\t\t\tif (!prevEmpty) nodes.push(node.type.create(node.attrs));\n\t\t\tprevEmpty = true;\n\t\t\treturn;\n\t\t}\n\t\tconst isEmpty = node.type.name === 'paragraph' && node.childCount === 0;\n\t\tif (isEmpty && prevEmpty) return;\n\t\tprevEmpty = isEmpty;\n\t\tif (node.isBlock && !node.isLeaf) {\n\t\t\tnodes.push(node.copy(normalizeBlanks(node.content)));\n\t\t} else {\n\t\t\tnodes.push(node);\n\t\t}\n\t});\n\treturn Fragment.from(nodes);\n}\n\nexport const PlainClipboardExtension = Extension.create({\n\tname: 'plainClipboard',\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tprops: {\n\t\t\t\t\thandlePaste(_view, event) {\n\t\t\t\t\t\tif (event.clipboardData?.files?.length) return false; // let ImagePaste handle\n\t\t\t\t\t\tconst html = event.clipboardData?.getData('text/html');\n\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!text) return false;\n\n\t\t\t\t\t\t// ProseMirror stamps its own clipboard with data-pm-slice.\n\t\t\t\t\t\t// Let ProseMirror handle its own format natively — it round-trips perfectly.\n\t\t\t\t\t\tif (html?.includes('data-pm-slice')) return false;\n\n\t\t\t\t\t\tconst schema = _view.state.schema;\n\n\t\t\t\t\t\tif (html) {\n\t\t\t\t\t\t\tconsole.log('[PASTE-DEBUG] clipboard html:', html);\n\t\t\t\t\t\t\t// Parse the HTML to get the correct block structure,\n\t\t\t\t\t\t\t// then strip rich marks (links, colors, fonts) while\n\t\t\t\t\t\t\t// keeping basic formatting (bold, italic, strike, etc.)\n\t\t\t\t\t\t\tconst container = document.createElement('div');\n\t\t\t\t\t\t\tcontainer.innerHTML = html;\n\t\t\t\t\t\t\tconst parsed =\n\t\t\t\t\t\t\t\tProseMirrorDOMParser.fromSchema(schema).parseSlice(container);\n\t\t\t\t\t\t\tconsole.log('[PASTE-DEBUG] parsed nodes:');\n\t\t\t\t\t\t\tparsed.content.forEach((n: any, _: any, i: number) => {\n\t\t\t\t\t\t\t\tconst kids: string[] = [];\n\t\t\t\t\t\t\t\tn.forEach?.((c: any) =>\n\t\t\t\t\t\t\t\t\tkids.push(c.type.name + (c.isText ? `=\"${c.text}\"` : '')),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t` [${i}] ${n.type.name} children=[${kids.join(', ')}]`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst cleaned = normalizeBlanks(stripRichMarks(parsed.content));\n\t\t\t\t\t\t\tconsole.log('[PASTE-DEBUG] after normalizeBlanks:');\n\t\t\t\t\t\t\tcleaned.forEach((n: any, _: any, i: number) => {\n\t\t\t\t\t\t\t\tconst kids: string[] = [];\n\t\t\t\t\t\t\t\tn.forEach?.((c: any) =>\n\t\t\t\t\t\t\t\t\tkids.push(c.type.name + (c.isText ? `=\"${c.text}\"` : '')),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t` [${i}] ${n.type.name} children=[${kids.join(', ')}]`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst slice = new Slice(\n\t\t\t\t\t\t\t\tcleaned,\n\t\t\t\t\t\t\t\tparsed.openStart,\n\t\t\t\t\t\t\t\tparsed.openEnd,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Plain text only (no HTML): split on newlines\n\t\t\t\t\t\tconst paragraphs = text\n\t\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t\t.map((line) =>\n\t\t\t\t\t\t\t\tschema.node('paragraph', null, line ? [schema.text(line)] : []),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tconst slice = new Slice(Fragment.fromArray(paragraphs), 1, 1);\n\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["BASIC_MARKS","Set","stripRichMarks","fragment","nodes","forEach","node","isText","kept","marks","filter","m","has","type","name","push","length","mark","copy","content","Fragment","from","normalizeBlanks","prevEmpty","childCount","_a","firstChild","create","attrs","isEmpty","isBlock","isLeaf","PlainClipboardExtension","Extension","addProseMirrorPlugins","Plugin","props","handlePaste","_view","event","_b","clipboardData","files","html","_c","getData","text","_d","includes","schema","state","console","log","container","document","createElement","innerHTML","parsed","ProseMirrorDOMParser","fromSchema","parseSlice","n","_","i","kids","call","c","join","cleaned","slice","Slice","openStart","openEnd","dispatch","tr","replaceSelection","paragraphs","split","map","line","fromArray"],"mappings":"6LASA,MAAMA,EAAc,IAAIC,IAAI,CAAC,OAAQ,SAAU,SAAU,YAAa,SAOtE,SAASC,EAAeC,GACvB,MAAMC,EAAkB,GASxB,OARAD,EAASE,SAASC,IACjB,GAAIA,EAAKC,OAAQ,CAChB,MAAMC,EAAOF,EAAKG,MAAMC,QAAQC,GAAMX,EAAYY,IAAID,EAAEE,KAAKC,QAC7DV,EAAMW,KAAKP,EAAKQ,SAAWV,EAAKG,MAAMO,OAASV,EAAOA,EAAKW,KAAKT,GAChE,MACAJ,EAAMW,KAAKT,EAAKY,KAAKhB,EAAeI,EAAKa,UACzC,IAEKC,EAASC,KAAKjB,EACtB,CAUA,SAASkB,EAAgBnB,GACxB,MAAMC,EAAkB,GACxB,IAAImB,GAAY,EAoBhB,OAnBApB,EAASE,SAASC,UAKjB,GAHoB,cAAnBA,EAAKO,KAAKC,MACU,IAApBR,EAAKkB,YAC0B,eAAhB,QAAfC,EAAAnB,EAAKoB,kBAAU,IAAAD,OAAA,EAAAA,EAAEZ,KAAKC,MAItB,OAFKS,GAAWnB,EAAMW,KAAKT,EAAKO,KAAKc,OAAOrB,EAAKsB,aACjDL,GAAY,GAGb,MAAMM,EAA6B,cAAnBvB,EAAKO,KAAKC,MAA4C,IAApBR,EAAKkB,WACnDK,GAAWN,IACfA,EAAYM,EACRvB,EAAKwB,UAAYxB,EAAKyB,OACzB3B,EAAMW,KAAKT,EAAKY,KAAKI,EAAgBhB,EAAKa,WAE1Cf,EAAMW,KAAKT,GACX,IAEKc,EAASC,KAAKjB,EACtB,OAEa4B,EAA0BC,EAAUN,OAAO,CACvDb,KAAM,iBACNoB,sBAAqBA,IACb,CACN,IAAIC,EAAO,CACVC,MAAO,CACNC,YAAYC,EAAOC,eAClB,WAAIC,EAAqB,UAArBD,EAAME,qBAAe,IAAAhB,OAAA,EAAAA,EAAAiB,4BAAO1B,OAAQ,OAAO,EAC/C,MAAM2B,EAA0B,QAAnBC,EAAAL,EAAME,qBAAa,IAAAG,OAAA,EAAAA,EAAEC,QAAQ,aACpCC,EAA0B,QAAnBC,EAAAR,EAAME,qBAAa,IAAAM,OAAA,EAAAA,EAAEF,QAAQ,cAC1C,IAAKC,EAAM,OAAO,EAIlB,GAAIH,aAAI,EAAJA,EAAMK,SAAS,iBAAkB,OAAO,EAE5C,MAAMC,EAASX,EAAMY,MAAMD,OAE3B,GAAIN,EAAM,CACTQ,QAAQC,IAAI,gCAAiCT,GAI7C,MAAMU,EAAYC,SAASC,cAAc,OACzCF,EAAUG,UAAYb,EACtB,MAAMc,EACLC,EAAqBC,WAAWV,GAAQW,WAAWP,GACpDF,QAAQC,IAAI,+BACZK,EAAOtC,QAAQd,SAAQ,CAACwD,EAAQC,EAAQC,WACvC,MAAMC,EAAiB,GACX,QAAZvC,EAAAoC,EAAExD,eAAU,IAAAoB,GAAAA,EAAAwC,KAAAJ,GAACK,GACZF,EAAKjD,KAAKmD,EAAErD,KAAKC,MAAQoD,EAAE3D,YAAc2D,EAAEpB,QAAU,OAEtDK,QAAQC,IACP,MAAMW,MAAMF,EAAEhD,KAAKC,kBAAkBkD,EAAKG,KAAK,SAC/C,IAEF,MAAMC,EAAU9C,EAAgBpB,EAAeuD,EAAOtC,UACtDgC,QAAQC,IAAI,wCACZgB,EAAQ/D,SAAQ,CAACwD,EAAQC,EAAQC,WAChC,MAAMC,EAAiB,GACX,QAAZvC,EAAAoC,EAAExD,eAAU,IAAAoB,GAAAA,EAAAwC,KAAAJ,GAACK,GACZF,EAAKjD,KAAKmD,EAAErD,KAAKC,MAAQoD,EAAE3D,YAAc2D,EAAEpB,QAAU,OAEtDK,QAAQC,IACP,MAAMW,MAAMF,EAAEhD,KAAKC,kBAAkBkD,EAAKG,KAAK,SAC/C,IAEF,MAAME,EAAQ,IAAIC,EACjBF,EACAX,EAAOc,UACPd,EAAOe,SAGR,OADAlC,EAAMmC,SAASnC,EAAMY,MAAMwB,GAAGC,iBAAiBN,KACxC,CACP,CAGD,MAAMO,EAAa9B,EACjB+B,MAAM,MACNC,KAAKC,GACL9B,EAAO3C,KAAK,YAAa,KAAMyE,EAAO,CAAC9B,EAAOH,KAAKiC,IAAS,MAExDV,EAAQ,IAAIC,EAAMlD,EAAS4D,UAAUJ,GAAa,EAAG,GAE3D,OADAtC,EAAMmC,SAASnC,EAAMY,MAAMwB,GAAGC,iBAAiBN,KACxC,CACR"}
1
+ {"version":3,"file":"PlainClipboardExtension.js","sources":["../../../../../src/editor/extensions/plainClipboard/PlainClipboardExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport {\n\tFragment,\n\tDOMParser as ProseMirrorDOMParser,\n\tSlice,\n} from '@tiptap/pm/model';\nimport { Plugin } from '@tiptap/pm/state';\nimport {\n\tBLOCK_SELECTOR,\n\tcleanBlockBrs,\n\tnormalizeBlanks,\n\tstripRichMarks,\n} from './pasteUtils';\n\nexport const PlainClipboardExtension = Extension.create({\n\tname: 'plainClipboard',\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tprops: {\n\t\t\t\t\thandlePaste(_view, event) {\n\t\t\t\t\t\tif (event.clipboardData?.files?.length) return false;\n\t\t\t\t\t\tconst html = event.clipboardData?.getData('text/html');\n\t\t\t\t\t\tconst text = event.clipboardData?.getData('text/plain');\n\t\t\t\t\t\tif (!text) return false;\n\n\t\t\t\t\t\tif (html?.includes('data-pm-slice')) return false;\n\n\t\t\t\t\t\tconst schema = _view.state.schema;\n\n\t\t\t\t\t\tif (html) {\n\t\t\t\t\t\t\tconst container = document.createElement('div');\n\t\t\t\t\t\t\tcontainer.innerHTML = html;\n\t\t\t\t\t\t\tconst hasBlocks = container.querySelector(BLOCK_SELECTOR);\n\t\t\t\t\t\t\tif (hasBlocks) {\n\t\t\t\t\t\t\t\tcleanBlockBrs(container);\n\t\t\t\t\t\t\t\tconst parsed =\n\t\t\t\t\t\t\t\t\tProseMirrorDOMParser.fromSchema(schema).parseSlice(container);\n\t\t\t\t\t\t\t\tconst cleaned = normalizeBlanks(stripRichMarks(parsed.content));\n\t\t\t\t\t\t\t\tconst slice = new Slice(\n\t\t\t\t\t\t\t\t\tcleaned,\n\t\t\t\t\t\t\t\t\tparsed.openStart,\n\t\t\t\t\t\t\t\t\tparsed.openEnd,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\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}\n\n\t\t\t\t\t\tconst paragraphs = text\n\t\t\t\t\t\t\t.split('\\n')\n\t\t\t\t\t\t\t.map((line) =>\n\t\t\t\t\t\t\t\tschema.node('paragraph', null, line ? [schema.text(line)] : []),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tconst slice = new Slice(Fragment.fromArray(paragraphs), 1, 1);\n\t\t\t\t\t\t_view.dispatch(_view.state.tr.replaceSelection(slice));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["PlainClipboardExtension","Extension","create","name","addProseMirrorPlugins","Plugin","props","handlePaste","_view","event","_b","clipboardData","_a","files","length","html","_c","getData","text","_d","includes","schema","state","container","document","createElement","innerHTML","querySelector","BLOCK_SELECTOR","cleanBlockBrs","parsed","ProseMirrorDOMParser","fromSchema","parseSlice","cleaned","normalizeBlanks","stripRichMarks","content","slice","Slice","openStart","openEnd","dispatch","tr","replaceSelection","paragraphs","split","map","line","node","Fragment","fromArray"],"mappings":"gTAcaA,EAA0BC,EAAUC,OAAO,CACvDC,KAAM,iBACNC,sBAAqBA,IACb,CACN,IAAIC,EAAO,CACVC,MAAO,CACNC,YAAYC,EAAOC,eAClB,WAAIC,EAAqB,UAArBD,EAAME,qBAAe,IAAAC,OAAA,EAAAA,EAAAC,4BAAOC,OAAQ,OAAO,EAC/C,MAAMC,EAA0B,QAAnBC,EAAAP,EAAME,qBAAa,IAAAK,OAAA,EAAAA,EAAEC,QAAQ,aACpCC,EAA0B,QAAnBC,EAAAV,EAAME,qBAAa,IAAAQ,OAAA,EAAAA,EAAEF,QAAQ,cAC1C,IAAKC,EAAM,OAAO,EAElB,GAAIH,aAAI,EAAJA,EAAMK,SAAS,iBAAkB,OAAO,EAE5C,MAAMC,EAASb,EAAMc,MAAMD,OAE3B,GAAIN,EAAM,CACT,MAAMQ,EAAYC,SAASC,cAAc,OACzCF,EAAUG,UAAYX,EAEtB,GADkBQ,EAAUI,cAAcC,GAC3B,CACdC,EAAcN,GACd,MAAMO,EACLC,EAAqBC,WAAWX,GAAQY,WAAWV,GAC9CW,EAAUC,EAAgBC,EAAeN,EAAOO,UAChDC,EAAQ,IAAIC,EACjBL,EACAJ,EAAOU,UACPV,EAAOW,SAGR,OADAjC,EAAMkC,SAASlC,EAAMc,MAAMqB,GAAGC,iBAAiBN,KACxC,CACP,CACD,CAED,MAAMO,EAAa3B,EACjB4B,MAAM,MACNC,KAAKC,GACL3B,EAAO4B,KAAK,YAAa,KAAMD,EAAO,CAAC3B,EAAOH,KAAK8B,IAAS,MAExDV,EAAQ,IAAIC,EAAMW,EAASC,UAAUN,GAAa,EAAG,GAE3D,OADArC,EAAMkC,SAASlC,EAAMc,MAAMqB,GAAGC,iBAAiBN,KACxC,CACR"}
@@ -0,0 +1,2 @@
1
+ import{Fragment as e}from"@tiptap/pm/model";const t=new Set(["P","LI","H1","H2","H3","H4","H5","H6","TD","TH","PRE"]),r="p,div,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,table,pre",n=new Set(["bold","italic","strike","underline","code"]);function o(e){const r=Array.from(e.querySelectorAll("br"));for(const n of r){let r=!1,o=n.parentElement;for(;o&&o!==e;){if(t.has(o.tagName)){r=!0;break}o=o.parentElement}r||n.parentElement.replaceChild(document.createElement("p"),n)}}function a(t){const r=[];let n=!1;return t.forEach((e=>{var t;if("paragraph"===e.type.name&&1===e.childCount&&"hardBreak"===(null===(t=e.firstChild)||void 0===t?void 0:t.type.name))return n||r.push(e.type.create(e.attrs)),void(n=!0);const o="paragraph"===e.type.name&&0===e.childCount;o&&n||(n=o,e.isBlock&&!e.isLeaf?r.push(e.copy(a(e.content))):r.push(e))})),e.from(r)}function l(t){const r=[];return t.forEach((e=>{if(e.isText){const t=e.marks.filter((e=>n.has(e.type.name)));r.push(t.length===e.marks.length?e:e.mark(t))}else r.push(e.copy(l(e.content)))})),e.from(r)}export{r as BLOCK_SELECTOR,t as TEXTBLOCK_TAGS,o as cleanBlockBrs,a as normalizeBlanks,l as stripRichMarks};
2
+ //# sourceMappingURL=pasteUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pasteUtils.js","sources":["../../../../../src/editor/extensions/plainClipboard/pasteUtils.ts"],"sourcesContent":["import { Fragment, Node as PMNode } from '@tiptap/pm/model';\n\nexport const TEXTBLOCK_TAGS = new Set([\n\t'P',\n\t'LI',\n\t'H1',\n\t'H2',\n\t'H3',\n\t'H4',\n\t'H5',\n\t'H6',\n\t'TD',\n\t'TH',\n\t'PRE',\n]);\n\nexport const BLOCK_SELECTOR =\n\t'p,div,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,table,pre';\n\nconst BASIC_MARKS = new Set(['bold', 'italic', 'strike', 'underline', 'code']);\n\n/**\n * Replace `<br>` elements that sit at block level (not inside a textblock\n * like `<p>`, `<li>`, etc.) with empty `<p></p>` elements. Google Docs\n * puts standalone `<br>` tags between paragraphs to represent blank lines.\n * Without this, ProseMirror parses them as top-level hardBreak nodes.\n */\nexport function cleanBlockBrs(container: HTMLElement): void {\n\tconst brs = Array.from(container.querySelectorAll('br'));\n\tfor (const br of brs) {\n\t\tlet insideTextblock = false;\n\t\tlet el = br.parentElement;\n\t\twhile (el && el !== container) {\n\t\t\tif (TEXTBLOCK_TAGS.has(el.tagName)) {\n\t\t\t\tinsideTextblock = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tel = el.parentElement;\n\t\t}\n\t\tif (!insideTextblock) {\n\t\t\tbr.parentElement!.replaceChild(document.createElement('p'), br);\n\t\t}\n\t}\n}\n\n/**\n * 1. Convert paragraphs containing only a hard_break into empty paragraphs.\n * 2. Collapse consecutive empty paragraphs into one.\n */\nexport function normalizeBlanks(fragment: Fragment): Fragment {\n\tconst nodes: PMNode[] = [];\n\tlet prevEmpty = false;\n\tfragment.forEach((node) => {\n\t\tconst isHardBreakOnly =\n\t\t\tnode.type.name === 'paragraph' &&\n\t\t\tnode.childCount === 1 &&\n\t\t\tnode.firstChild?.type.name === 'hardBreak';\n\t\tif (isHardBreakOnly) {\n\t\t\tif (!prevEmpty) nodes.push(node.type.create(node.attrs));\n\t\t\tprevEmpty = true;\n\t\t\treturn;\n\t\t}\n\t\tconst isEmpty = node.type.name === 'paragraph' && node.childCount === 0;\n\t\tif (isEmpty && prevEmpty) return;\n\t\tprevEmpty = isEmpty;\n\t\tif (node.isBlock && !node.isLeaf) {\n\t\t\tnodes.push(node.copy(normalizeBlanks(node.content)));\n\t\t} else {\n\t\t\tnodes.push(node);\n\t\t}\n\t});\n\treturn Fragment.from(nodes);\n}\n\n/**\n * Strip only \"rich\" marks (link, textStyle, highlight, etc.) while keeping\n * basic formatting marks (bold, italic, strike, underline, code) that\n * messaging channels can represent.\n */\nexport function stripRichMarks(fragment: Fragment): Fragment {\n\tconst nodes: PMNode[] = [];\n\tfragment.forEach((node) => {\n\t\tif (node.isText) {\n\t\t\tconst kept = node.marks.filter((m) => BASIC_MARKS.has(m.type.name));\n\t\t\tnodes.push(kept.length === node.marks.length ? node : node.mark(kept));\n\t\t} else {\n\t\t\tnodes.push(node.copy(stripRichMarks(node.content)));\n\t\t}\n\t});\n\treturn Fragment.from(nodes);\n}\n"],"names":["TEXTBLOCK_TAGS","Set","BLOCK_SELECTOR","BASIC_MARKS","cleanBlockBrs","container","brs","Array","from","querySelectorAll","br","insideTextblock","el","parentElement","has","tagName","replaceChild","document","createElement","normalizeBlanks","fragment","nodes","prevEmpty","forEach","node","type","name","childCount","_a","firstChild","push","create","attrs","isEmpty","isBlock","isLeaf","copy","content","Fragment","stripRichMarks","isText","kept","marks","filter","m","length","mark"],"mappings":"4CAEaA,MAAAA,EAAiB,IAAIC,IAAI,CACrC,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,QAGYC,EACZ,wDAEKC,EAAc,IAAIF,IAAI,CAAC,OAAQ,SAAU,SAAU,YAAa,SAQhE,SAAUG,EAAcC,GAC7B,MAAMC,EAAMC,MAAMC,KAAKH,EAAUI,iBAAiB,OAClD,IAAK,MAAMC,KAAMJ,EAAK,CACrB,IAAIK,GAAkB,EAClBC,EAAKF,EAAGG,cACZ,KAAOD,GAAMA,IAAOP,GAAW,CAC9B,GAAIL,EAAec,IAAIF,EAAGG,SAAU,CACnCJ,GAAkB,EAClB,KACA,CACDC,EAAKA,EAAGC,aACR,CACIF,GACJD,EAAGG,cAAeG,aAAaC,SAASC,cAAc,KAAMR,EAE7D,CACF,CAMM,SAAUS,EAAgBC,GAC/B,MAAMC,EAAkB,GACxB,IAAIC,GAAY,EAoBhB,OAnBAF,EAASG,SAASC,UAKjB,GAHoB,cAAnBA,EAAKC,KAAKC,MACU,IAApBF,EAAKG,YAC0B,eAAhB,QAAfC,EAAAJ,EAAKK,kBAAU,IAAAD,OAAA,EAAAA,EAAEH,KAAKC,MAItB,OAFKJ,GAAWD,EAAMS,KAAKN,EAAKC,KAAKM,OAAOP,EAAKQ,aACjDV,GAAY,GAGb,MAAMW,EAA6B,cAAnBT,EAAKC,KAAKC,MAA4C,IAApBF,EAAKG,WACnDM,GAAWX,IACfA,EAAYW,EACRT,EAAKU,UAAYV,EAAKW,OACzBd,EAAMS,KAAKN,EAAKY,KAAKjB,EAAgBK,EAAKa,WAE1ChB,EAAMS,KAAKN,GACX,IAEKc,EAAS9B,KAAKa,EACtB,CAOM,SAAUkB,EAAenB,GAC9B,MAAMC,EAAkB,GASxB,OARAD,EAASG,SAASC,IACjB,GAAIA,EAAKgB,OAAQ,CAChB,MAAMC,EAAOjB,EAAKkB,MAAMC,QAAQC,GAAMzC,EAAYW,IAAI8B,EAAEnB,KAAKC,QAC7DL,EAAMS,KAAKW,EAAKI,SAAWrB,EAAKkB,MAAMG,OAASrB,EAAOA,EAAKsB,KAAKL,GAChE,MACApB,EAAMS,KAAKN,EAAKY,KAAKG,EAAef,EAAKa,UACzC,IAEKC,EAAS9B,KAAKa,EACtB"}
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  export declare const Menus: ({
3
2
  displayName: string;
4
3
  key: number;
@@ -9,12 +9,12 @@ export interface PopupBaseProps {
9
9
  feature: FeatureAnnouncement;
10
10
  currentIndex: number;
11
11
  totalFeatures: number;
12
- onSkip: () => void;
13
- onExplore: () => void;
12
+ onSkip: () => Promise<void> | void;
13
+ onExplore: (triggeredAction?: string) => void;
14
14
  onPrevious: () => void;
15
15
  onNext: () => void;
16
16
  setIsClosing?: (isClosing: boolean) => void;
17
- onSecondaryAction?: () => void;
17
+ onSecondaryAction?: () => Promise<void> | void;
18
18
  }
19
19
  /**
20
20
  * Major update popup props
@@ -15,4 +15,4 @@ export declare const hideJoyrideArrow: (popupRef: HTMLElement | null) => void;
15
15
  * @param callback - Function to execute
16
16
  * @param delay - Optional delay override
17
17
  */
18
- export declare const executeAfterAnimation: (callback: () => void, delay?: number) => void;
18
+ export declare const executeAfterAnimation: (callback: () => void | Promise<void>, delay?: number) => void;
@@ -0,0 +1,7 @@
1
+ import { Extension } from '@tiptap/core';
2
+ /**
3
+ * Lightweight paste normalizer for rich-paste editors (email).
4
+ * Fixes Google Docs' standalone `<br>` between paragraphs and collapses
5
+ * consecutive empty paragraphs — but keeps ALL formatting marks intact.
6
+ */
7
+ export declare const ClipboardNormalizationExtension: Extension<any, any>;
@@ -0,0 +1,21 @@
1
+ import { Fragment } from '@tiptap/pm/model';
2
+ export declare const TEXTBLOCK_TAGS: Set<string>;
3
+ export declare const BLOCK_SELECTOR = "p,div,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,table,pre";
4
+ /**
5
+ * Replace `<br>` elements that sit at block level (not inside a textblock
6
+ * like `<p>`, `<li>`, etc.) with empty `<p></p>` elements. Google Docs
7
+ * puts standalone `<br>` tags between paragraphs to represent blank lines.
8
+ * Without this, ProseMirror parses them as top-level hardBreak nodes.
9
+ */
10
+ export declare function cleanBlockBrs(container: HTMLElement): void;
11
+ /**
12
+ * 1. Convert paragraphs containing only a hard_break into empty paragraphs.
13
+ * 2. Collapse consecutive empty paragraphs into one.
14
+ */
15
+ export declare function normalizeBlanks(fragment: Fragment): Fragment;
16
+ /**
17
+ * Strip only "rich" marks (link, textStyle, highlight, etc.) while keeping
18
+ * basic formatting marks (bold, italic, strike, underline, code) that
19
+ * messaging channels can represent.
20
+ */
21
+ export declare function stripRichMarks(fragment: Fragment): Fragment;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bikdotai/bik-component-library",
3
- "version": "0.0.806-beta.9",
3
+ "version": "0.0.807-beta.0",
4
4
  "description": "Bik Component Library",
5
5
  "repository": {
6
6
  "type": "git",