reactjs-tiptap-editor
Version:
A modern WYSIWYG rich text editor based on tiptap and shadcn ui for React
3 lines (2 loc) • 14.2 kB
JavaScript
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const p=require("react"),C=require("./RichTextEditor-DaQRHXru.cjs"),x=require("./dom-dataset-DmsCLv1q.cjs"),a=require("./index-CSvnpArE.cjs"),b=require("./ListItem.cjs"),S=require("./index-CrxasX7b.cjs"),v=require("./Document.cjs"),k=require("./Selection.cjs"),P=require("./TextBubble.cjs"),M=require("./TrailingNode.cjs"),m=require("./index-Dz3YxLE7.cjs");function T(){var l;const t=p.useRef({editor:null}),[e,i]=p.useState(!1),[o,r]=p.useState(null);return p.useEffect(()=>{var s;(s=t.current)!=null&&s.editor&&(i(!0),r(t.current.editor))},[t,(l=t.current)==null?void 0:l.editor]),{isReady:e,editor:o,editorRef:t}}const E=a.Extension.create({name:"characterCount",addOptions(){return{limit:null,mode:"textSize",textCounter:t=>t.length,wordCounter:t=>t.split(" ").filter(e=>e!=="").length}},addStorage(){return{characters:()=>0,words:()=>0}},onBeforeCreate(){this.storage.characters=t=>{const e=(t==null?void 0:t.node)||this.editor.state.doc;if(((t==null?void 0:t.mode)||this.options.mode)==="textSize"){const o=e.textBetween(0,e.content.size,void 0," ");return this.options.textCounter(o)}return e.nodeSize},this.storage.words=t=>{const e=(t==null?void 0:t.node)||this.editor.state.doc,i=e.textBetween(0,e.content.size," "," ");return this.options.wordCounter(i)}},addProseMirrorPlugins(){let t=!1;return[new a.Plugin({key:new a.PluginKey("characterCount"),appendTransaction:(e,i,o)=>{if(t)return;const r=this.options.limit;if(r==null||r===0){t=!0;return}const l=this.storage.characters({node:o.doc});if(l>r){const s=l-r,n=0,c=s;console.warn(`[CharacterCount] Initial content exceeded limit of ${r} characters. Content was automatically trimmed.`);const u=o.tr.deleteRange(n,c);return t=!0,u}t=!0},filterTransaction:(e,i)=>{const o=this.options.limit;if(!e.docChanged||o===0||o===null||o===void 0)return!0;const r=this.storage.characters({node:i.doc}),l=this.storage.characters({node:e.doc});if(l<=o||r>o&&l>o&&l<=r)return!0;if(r>o&&l>o&&l>r||!e.getMeta("paste"))return!1;const n=e.selection.$head.pos,c=l-o,u=n-c,h=n;return e.deleteRange(u,h),!(this.storage.characters({node:e.doc})>o)}})]}});function A(t={}){return new a.Plugin({view(e){return new O(e,t)}})}class O{constructor(e,i){var o;this.editorView=e,this.cursorPos=null,this.element=null,this.timeout=-1,this.width=(o=i.width)!==null&&o!==void 0?o:1,this.color=i.color===!1?void 0:i.color||"black",this.class=i.class,this.handlers=["dragover","dragend","drop","dragleave"].map(r=>{let l=s=>{this[r](s)};return e.dom.addEventListener(r,l),{name:r,handler:l}})}destroy(){this.handlers.forEach(({name:e,handler:i})=>this.editorView.dom.removeEventListener(e,i))}update(e,i){this.cursorPos!=null&&i.doc!=e.state.doc&&(this.cursorPos>e.state.doc.content.size?this.setCursor(null):this.updateOverlay())}setCursor(e){e!=this.cursorPos&&(this.cursorPos=e,e==null?(this.element.parentNode.removeChild(this.element),this.element=null):this.updateOverlay())}updateOverlay(){let e=this.editorView.state.doc.resolve(this.cursorPos),i=!e.parent.inlineContent,o;if(i){let n=e.nodeBefore,c=e.nodeAfter;if(n||c){let u=this.editorView.nodeDOM(this.cursorPos-(n?n.nodeSize:0));if(u){let h=u.getBoundingClientRect(),f=n?h.bottom:h.top;n&&c&&(f=(f+this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top)/2),o={left:h.left,right:h.right,top:f-this.width/2,bottom:f+this.width/2}}}}if(!o){let n=this.editorView.coordsAtPos(this.cursorPos);o={left:n.left-this.width/2,right:n.left+this.width/2,top:n.top,bottom:n.bottom}}let r=this.editorView.dom.offsetParent;this.element||(this.element=r.appendChild(document.createElement("div")),this.class&&(this.element.className=this.class),this.element.style.cssText="position: absolute; z-index: 50; pointer-events: none;",this.color&&(this.element.style.backgroundColor=this.color)),this.element.classList.toggle("prosemirror-dropcursor-block",i),this.element.classList.toggle("prosemirror-dropcursor-inline",!i);let l,s;if(!r||r==document.body&&getComputedStyle(r).position=="static")l=-pageXOffset,s=-pageYOffset;else{let n=r.getBoundingClientRect();l=n.left-r.scrollLeft,s=n.top-r.scrollTop}this.element.style.left=o.left-l+"px",this.element.style.top=o.top-s+"px",this.element.style.width=o.right-o.left+"px",this.element.style.height=o.bottom-o.top+"px"}scheduleRemoval(e){clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.setCursor(null),e)}dragover(e){if(!this.editorView.editable)return;let i=this.editorView.posAtCoords({left:e.clientX,top:e.clientY}),o=i&&i.inside>=0&&this.editorView.state.doc.nodeAt(i.inside),r=o&&o.type.spec.disableDropCursor,l=typeof r=="function"?r(this.editorView,i,e):r;if(i&&!l){let s=i.pos;if(this.editorView.dragging&&this.editorView.dragging.slice){let n=a.dropPoint(this.editorView.state.doc,s,this.editorView.dragging.slice);n!=null&&(s=n)}this.setCursor(s),this.scheduleRemoval(5e3)}}dragend(){this.scheduleRemoval(20)}drop(){this.scheduleRemoval(20)}dragleave(e){(e.target==this.editorView.dom||!this.editorView.dom.contains(e.relatedTarget))&&this.setCursor(null)}}const B=a.Extension.create({name:"dropCursor",addOptions(){return{color:"currentColor",width:1,class:void 0}},addProseMirrorPlugins(){return[A(this.options)]}}),N=a.Extension.create({name:"focus",addOptions(){return{className:"has-focus",mode:"all"}},addProseMirrorPlugins(){return[new a.Plugin({key:new a.PluginKey("focus"),props:{decorations:({doc:t,selection:e})=>{const{isEditable:i,isFocused:o}=this.editor,{anchor:r}=e,l=[];if(!i||!o)return a.DecorationSet.create(t,[]);let s=0;this.options.mode==="deepest"&&t.descendants((c,u)=>{if(c.isText)return;if(!(r>=u&&r<=u+c.nodeSize-1))return!1;s+=1});let n=0;return t.descendants((c,u)=>{if(c.isText||!(r>=u&&r<=u+c.nodeSize-1))return!1;if(n+=1,this.options.mode==="deepest"&&s-n>0||this.options.mode==="shallowest"&&n>1)return this.options.mode==="deepest";l.push(a.Decoration.node(u,u+c.nodeSize,{class:this.options.className}))}),a.DecorationSet.create(t,l)}}})]}});class d extends a.Selection{constructor(e){super(e,e)}map(e,i){let o=e.resolve(i.map(this.head));return d.valid(o)?new d(o):a.Selection.near(o)}content(){return a.Slice.empty}eq(e){return e instanceof d&&e.head==this.head}toJSON(){return{type:"gapcursor",pos:this.head}}static fromJSON(e,i){if(typeof i.pos!="number")throw new RangeError("Invalid input for GapCursor.fromJSON");return new d(e.resolve(i.pos))}getBookmark(){return new y(this.anchor)}static valid(e){let i=e.parent;if(i.isTextblock||!z(e)||!D(e))return!1;let o=i.type.spec.allowGapCursor;if(o!=null)return o;let r=i.contentMatchAt(e.index()).defaultType;return r&&r.isTextblock}static findGapCursorFrom(e,i,o=!1){e:for(;;){if(!o&&d.valid(e))return e;let r=e.pos,l=null;for(let s=e.depth;;s--){let n=e.node(s);if(i>0?e.indexAfter(s)<n.childCount:e.index(s)>0){l=n.child(i>0?e.indexAfter(s):e.index(s)-1);break}else if(s==0)return null;r+=i;let c=e.doc.resolve(r);if(d.valid(c))return c}for(;;){let s=i>0?l.firstChild:l.lastChild;if(!s){if(l.isAtom&&!l.isText&&!a.NodeSelection.isSelectable(l)){e=e.doc.resolve(r+l.nodeSize*i),o=!1;continue e}break}l=s,r+=i;let n=e.doc.resolve(r);if(d.valid(n))return n}return null}}}d.prototype.visible=!1;d.findFrom=d.findGapCursorFrom;a.Selection.jsonID("gapcursor",d);class y{constructor(e){this.pos=e}map(e){return new y(e.map(this.pos))}resolve(e){let i=e.resolve(this.pos);return d.valid(i)?new d(i):a.Selection.near(i)}}function z(t){for(let e=t.depth;e>=0;e--){let i=t.index(e),o=t.node(e);if(i==0){if(o.type.spec.isolating)return!0;continue}for(let r=o.child(i-1);;r=r.lastChild){if(r.childCount==0&&!r.inlineContent||r.isAtom||r.type.spec.isolating)return!0;if(r.inlineContent)return!1}}return!0}function D(t){for(let e=t.depth;e>=0;e--){let i=t.indexAfter(e),o=t.node(e);if(i==o.childCount){if(o.type.spec.isolating)return!0;continue}for(let r=o.child(i);;r=r.firstChild){if(r.childCount==0&&!r.inlineContent||r.isAtom||r.type.spec.isolating)return!0;if(r.inlineContent)return!1}}return!0}function L(){return new a.Plugin({props:{decorations:q,createSelectionBetween(t,e,i){return e.pos==i.pos&&d.valid(i)?new d(i):null},handleClick:V,handleKeyDown:R,handleDOMEvents:{beforeinput:H}}})}const R=a.keydownHandler({ArrowLeft:g("horiz",-1),ArrowRight:g("horiz",1),ArrowUp:g("vert",-1),ArrowDown:g("vert",1)});function g(t,e){const i=t=="vert"?e>0?"down":"up":e>0?"right":"left";return function(o,r,l){let s=o.selection,n=e>0?s.$to:s.$from,c=s.empty;if(s instanceof a.TextSelection){if(!l.endOfTextblock(i)||n.depth==0)return!1;c=!1,n=o.doc.resolve(e>0?n.after():n.before())}let u=d.findGapCursorFrom(n,e,c);return u?(r&&r(o.tr.setSelection(new d(u))),!0):!1}}function V(t,e,i){if(!t||!t.editable)return!1;let o=t.state.doc.resolve(e);if(!d.valid(o))return!1;let r=t.posAtCoords({left:i.clientX,top:i.clientY});return r&&r.inside>-1&&a.NodeSelection.isSelectable(t.state.doc.nodeAt(r.inside))?!1:(t.dispatch(t.state.tr.setSelection(new d(o))),!0)}function H(t,e){if(e.inputType!="insertCompositionText"||!(t.state.selection instanceof d))return!1;let{$from:i}=t.state.selection,o=i.parent.contentMatchAt(i.index()).findWrapping(t.state.schema.nodes.text);if(!o)return!1;let r=a.Fragment.empty;for(let s=o.length-1;s>=0;s--)r=a.Fragment.from(o[s].createAndFill(null,r));let l=t.state.tr.replace(i.pos,i.pos,new a.Slice(r,0,0));return l.setSelection(a.TextSelection.near(l.doc.resolve(i.pos+1))),t.dispatch(l),!1}function q(t){if(!(t.selection instanceof d))return null;let e=document.createElement("div");return e.className="ProseMirror-gapcursor",a.DecorationSet.create(t.doc,[a.Decoration.widget(t.selection.head,e,{key:"gapcursor"})])}const F=a.Extension.create({name:"gapCursor",addProseMirrorPlugins(){return[L()]},extendNodeSchema(t){var e;const i={name:t.name,options:t.options,storage:t.storage};return{allowGapCursor:(e=a.callOrReturn(a.getExtensionField(t,"allowGapCursor",i)))!==null&&e!==void 0?e:null}}}),I=a.Node.create({name:"hardBreak",addOptions(){return{keepMarks:!0,HTMLAttributes:{}}},inline:!0,group:"inline",selectable:!1,linebreakReplacement:!0,parseHTML(){return[{tag:"br"}]},renderHTML({HTMLAttributes:t}){return["br",a.mergeAttributes(this.options.HTMLAttributes,t)]},renderText(){return`
`},addCommands(){return{setHardBreak:()=>({commands:t,chain:e,state:i,editor:o})=>t.first([()=>t.exitCode(),()=>t.command(()=>{const{selection:r,storedMarks:l}=i;if(r.$from.parent.type.spec.isolating)return!1;const{keepMarks:s}=this.options,{splittableMarks:n}=o.extensionManager,c=l||r.$to.parentOffset&&r.$from.marks();return e().insertContent({type:this.name}).command(({tr:u,dispatch:h})=>{if(h&&c&&s){const f=c.filter(w=>n.includes(w.type.name));u.ensureMarks(f)}return!0}).run()})])}},addKeyboardShortcuts(){return{"Mod-Enter":()=>this.editor.commands.setHardBreak(),"Shift-Enter":()=>this.editor.commands.setHardBreak()}}}),K=a.Node.create({name:"paragraph",priority:1e3,addOptions(){return{HTMLAttributes:{}}},group:"block",content:"inline*",parseHTML(){return[{tag:"p"}]},renderHTML({HTMLAttributes:t}){return["p",a.mergeAttributes(this.options.HTMLAttributes,t),0]},addCommands(){return{setParagraph:()=>({commands:t})=>t.setNode(this.name)}},addKeyboardShortcuts(){return{"Mod-Alt-0":()=>this.editor.commands.setParagraph()}}}),W=a.Extension.create({name:"placeholder",addOptions(){return{emptyEditorClass:"is-editor-empty",emptyNodeClass:"is-empty",placeholder:"Write something …",showOnlyWhenEditable:!0,showOnlyCurrent:!0,includeChildren:!1}},addProseMirrorPlugins(){return[new a.Plugin({key:new a.PluginKey("placeholder"),props:{decorations:({doc:t,selection:e})=>{const i=this.editor.isEditable||!this.options.showOnlyWhenEditable,{anchor:o}=e,r=[];if(!i)return null;const l=this.editor.isEmpty;return t.descendants((s,n)=>{const c=o>=n&&o<=n+s.nodeSize,u=!s.isLeaf&&a.isNodeEmpty(s);if((c||!this.options.showOnlyCurrent)&&u){const h=[this.options.emptyNodeClass];l&&h.push(this.options.emptyEditorClass);const f=a.Decoration.node(n,n+s.nodeSize,{class:h.join(" "),"data-placeholder":typeof this.options.placeholder=="function"?this.options.placeholder({editor:this.editor,node:s,pos:n,hasAnchor:c}):this.options.placeholder});r.push(f)}return this.options.includeChildren}),a.DecorationSet.create(t,r)}}})]}}),G=a.Node.create({name:"text",group:"inline"}),J=a.Extension.create({name:"base-kit",addExtensions(){const t=[];return this.options.document!==!1&&t.push(v.Document.configure()),this.options.placeholder!==!1&&t.push(W.configure({placeholder:({node:e,pos:i,editor:o})=>{var r,l,s,n,c;return((r=e==null?void 0:e.type)==null?void 0:r.name)==="columns"||((l=e==null?void 0:e.content)==null?void 0:l.size)!==0?"":((s=e==null?void 0:e.type)==null?void 0:s.name)==="heading"?`${m.localeActions.t(`editor.heading.h${e.attrs.level}.tooltip`)}`:((n=e==null?void 0:e.type)==null?void 0:n.name)==="codeBlock"||((c=e==null?void 0:e.type)==null?void 0:c.name)==="table"?"":o.extensionManager.extensions.some(u=>u.name==="slashCommand")?m.localeActions.t("editor.slash"):m.localeActions.t("editor.content")},...this.options.placeholder})),this.options.focus!==!1&&t.push(N.configure({className:"focus",...this.options.focus})),this.options.text!==!1&&t.push(G.configure()),this.options.textBubble!==!1&&t.push(P.TextBubble.configure()),this.options.gapcursor!==!1&&t.push(F.configure()),this.options.dropcursor!==!1&&t.push(B.configure({...this.options.dropcursor,width:2,class:"ProseMirror-dropcursor border-black"})),this.options.characterCount!==!1&&t.push(E.configure(this.options.characterCount)),this.options.paragraph!==!1&&t.push(K.configure(this.options.paragraph)),this.options.hardBreak!==!1&&t.push(I.configure(this.options.hardBreak)),this.options.listItem!==!1&&t.push(b.ListItem.configure(this.options.listItem)),this.options.textStyle!==!1&&t.push(S.TextStyle.configure(this.options.textStyle)),this.options.trailingNode!==!1&&t.push(M.TrailingNode.configure(this.options.trailingNode)),this.options.selection!==!1&&t.push(k.Selection),this.options.multiColumn!==!1&&t.push(C.Column,C.MultiColumn),t}});exports.default=C.RichTextEditor;exports.BubbleMenu=x.BubbleMenu;exports.BaseKit=J;exports.useEditorState=T;