diff --git a/dist/index.css.map b/dist/index.css.map index 07db5f7..934cc91 100644 --- a/dist/index.css.map +++ b/dist/index.css.map @@ -1 +1 @@ -{"version":3,"sources":["../src/MixInput.css"],"sourcesContent":[".mix-input{\r\n padding: .375rem;\r\n border: 1px solid #ccc;\r\n border-radius: .25rem;\r\n min-height: 27px;\r\n display: block;\r\n font-size: 1rem;\r\n}\r\n\r\n.mix-input:focus{\r\n border: 1px solid #000;\r\n}\r\n\r\n.mix-input:hover {\r\n border: .0625rem solid #aaa;\r\n}\r\n\r\n.mix-input p.is-editor-empty:not(:has([data-type=\"tag\"]:first-child))::before {\r\n color: #adb5bd;\r\n content: attr(data-placeholder);\r\n float: left;\r\n height: 0;\r\n pointer-events: none;\r\n}\r\n\r\n.mi-paragraph{\r\n margin: 0;\r\n min-height: 27px;\r\n line-height: 1.6;\r\n}\r\n\r\n.mi-mention{\r\n background-color: aliceblue;\r\n border: 1px solid #ccc;\r\n border-radius: .25rem;\r\n padding: 2px 3px;\r\n display: inline-block;\r\n margin-inline: 2px;\r\n}\r\n\r\n.mi-tag{\r\n background-color: #f3f3f3;\r\n border: 1px solid #ccc;\r\n border-radius: 5px;\r\n padding: 2px 3px;\r\n margin-inline: 3px;\r\n}"],"mappings":"AAAA,CAAC,UAAD,QACW,QACT,OAAQ,IAAI,MAAM,KAFpB,cAGiB,OACf,WAAY,KACZ,QAAS,MACT,UAAW,IACb,CAEA,CATC,SASS,OACR,OAAQ,IAAI,MAAM,IACpB,CAEA,CAbC,SAaS,OACR,OAAQ,SAAS,MAAM,IACzB,CAEA,CAjBC,UAiBU,CAAC,CAAC,eAAe,KAAK,KAAK,CAAC,cAAgB,cAAc,QACnE,MAAO,QACP,QAAS,KAAK,kBACd,MAAO,KACP,OAAQ,EACR,eAAgB,IAClB,CAEA,CAAC,aAzBD,OA0BU,EACR,WAAY,KACZ,YAAa,GACf,CAEA,CAAC,WACC,iBAAkB,QAClB,OAAQ,IAAI,MAAM,KAjCpB,cAkCiB,OAlCjB,QAmCW,IAAI,IACb,QAAS,aACT,cAAe,GACjB,CAEA,CAAC,OACC,iBAAkB,QAClB,OAAQ,IAAI,MAAM,KA1CpB,cA2CiB,IA3CjB,QA4CW,IAAI,IACb,cAAe,GACjB","names":[]} \ No newline at end of file +{"version":3,"sources":["../src/MixInput.css"],"sourcesContent":[".mix-input{\n padding: .375rem;\n border: 1px solid #ccc;\n border-radius: .25rem;\n min-height: 27px;\n display: block;\n font-size: 1rem;\n}\n\n.mix-input:focus{\n border: 1px solid #000;\n}\n\n.mix-input:hover {\n border: .0625rem solid #aaa;\n}\n\n.mix-input p.is-editor-empty:not(:has([data-type=\"tag\"]:first-child))::before {\n color: #adb5bd;\n content: attr(data-placeholder);\n float: left;\n height: 0;\n pointer-events: none;\n}\n\n.mi-paragraph{\n margin: 0;\n min-height: 27px;\n line-height: 1.6;\n}\n\n.mi-mention{\n background-color: aliceblue;\n border: 1px solid #ccc;\n border-radius: .25rem;\n padding: 2px 3px;\n display: inline-block;\n margin-inline: 2px;\n}\n\n.mi-tag{\n background-color: #f3f3f3;\n border: 1px solid #ccc;\n border-radius: 5px;\n padding: 2px 3px;\n margin-inline: 3px;\n}"],"mappings":"AAAA,CAAC,UAAD,QACW,QACT,OAAQ,IAAI,MAAM,KAFpB,cAGiB,OACf,WAAY,KACZ,QAAS,MACT,UAAW,IACb,CAEA,CATC,SASS,OACR,OAAQ,IAAI,MAAM,IACpB,CAEA,CAbC,SAaS,OACR,OAAQ,SAAS,MAAM,IACzB,CAEA,CAjBC,UAiBU,CAAC,CAAC,eAAe,KAAK,KAAK,CAAC,cAAgB,cAAc,QACnE,MAAO,QACP,QAAS,KAAK,kBACd,MAAO,KACP,OAAQ,EACR,eAAgB,IAClB,CAEA,CAAC,aAzBD,OA0BU,EACR,WAAY,KACZ,YAAa,GACf,CAEA,CAAC,WACC,iBAAkB,QAClB,OAAQ,IAAI,MAAM,KAjCpB,cAkCiB,OAlCjB,QAmCW,IAAI,IACb,QAAS,aACT,cAAe,GACjB,CAEA,CAAC,OACC,iBAAkB,QAClB,OAAQ,IAAI,MAAM,KA1CpB,cA2CiB,IA3CjB,QA4CW,IAAI,IACb,cAAe,GACjB","names":[]} \ No newline at end of file diff --git a/dist/index.d.mts b/dist/index.d.mts index 675e867..9129195 100644 --- a/dist/index.d.mts +++ b/dist/index.d.mts @@ -19,16 +19,17 @@ type MixInputValue = Tag | string type MixInputValues = MixInputValue[][] interface MixInputProps extends HTMLAttributes, Omit { - value: MixInputValues + value?: MixInputValues placeholder?: string - onChange: (value: MixInputValues) => void + onChange?: (value: MixInputValues) => void readonly?: boolean tagClassName?: string editorOptions?: UseEditorOptions tagAttrs?: Record tagView?: (props: NodeViewProps) => React.ReactNode + immediatelyRender?: boolean + ref?: React.Ref // multiline?: boolean - // showTagDeleteBtn?: boolean } interface MixInputRef { diff --git a/dist/index.d.ts b/dist/index.d.ts index 675e867..9129195 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -19,16 +19,17 @@ type MixInputValue = Tag | string type MixInputValues = MixInputValue[][] interface MixInputProps extends HTMLAttributes, Omit { - value: MixInputValues + value?: MixInputValues placeholder?: string - onChange: (value: MixInputValues) => void + onChange?: (value: MixInputValues) => void readonly?: boolean tagClassName?: string editorOptions?: UseEditorOptions tagAttrs?: Record tagView?: (props: NodeViewProps) => React.ReactNode + immediatelyRender?: boolean + ref?: React.Ref // multiline?: boolean - // showTagDeleteBtn?: boolean } interface MixInputRef { diff --git a/dist/index.js b/dist/index.js index 7d6403b..848d868 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,3 +1,3 @@ "use client"; -"use strict";var v=Object.create;var c=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var D=(t,r)=>{for(var n in r)c(t,n,{get:r[n],enumerable:!0})},M=(t,r,n,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let e of L(r))!F.call(t,e)&&e!==n&&c(t,e,{get:()=>r[e],enumerable:!(o=H(r,e))||o.enumerable});return t};var s=(t,r,n)=>(n=t!=null?v(j(t)):{},M(r||!t||!t.__esModule?c(n,"default",{value:t,enumerable:!0}):n,t)),$=t=>M(c({},"__esModule",{value:!0}),t);var G={};D(G,{default:()=>B,editorValueToMixInputValue:()=>l,mixInputValueToEditorValue:()=>x});module.exports=$(G);var p=s(require("react"));function U(t){return typeof t=="object"&&t.type==="tag"}function W(t){return{type:"tag",attrs:{...t.attrs}}}function l(t){let r=[];return t.forEach(n=>{var o;n.type==="paragraph"&&(r.push([]),(o=n==null?void 0:n.content)==null||o.forEach(e=>{var u,d;e.type==="text"&&e.text&&((u=r.at(-1))==null||u.push(e.text)),e.type==="tag"&&((d=r.at(-1))==null||d.push(W(e)))}))}),r}function x(t){let r=[];return t.forEach((n,o)=>{Array.isArray(r[o])||r.push({type:"paragraph",content:[]});let e=r.at(-1);typeof n=="string"&&(e!=null&&e.content)&&e.content.push({type:"text",text:n}),!Array.isArray(n)&&U(n)&&(e!=null&&e.content)&&e.content.push({type:"tag",attrs:{...n.attrs}}),Array.isArray(n)&&n.forEach(u=>{typeof u=="string"&&(e!=null&&e.content)&&e.content.push({type:"text",text:u}),typeof u=="object"&&u.type==="tag"&&(e!=null&&e.content)&&e.content.push({type:"tag",attrs:{...u.attrs}})})}),r}var g=require("@tiptap/react"),N=s(require("@tiptap/extension-document")),A=s(require("@tiptap/extension-paragraph")),E=s(require("@tiptap/extension-text")),P=s(require("@tiptap/extension-placeholder"));var m=require("@tiptap/core"),b=require("@tiptap/react");var T=require("@tiptap/react"),f=s(require("react"));function y(t){let{tagView:r,tagClassName:n}=t.extension.options,{label:o,...e}=t.node.attrs;return f.default.createElement(f.default.Fragment,null,f.default.createElement(T.NodeViewWrapper,{className:`mi-tag ${n||""}`,"data-type":"tag",as:"span"},r?r(t):f.default.createElement("span",{...e},o)),"\u200B")}var I=m.Node.create({name:"tag",group:"inline",inline:!0,atom:!0,selectable:!1,parseHTML(){return[{tag:`span[data-type="${this.name}"]`}]},renderHTML({HTMLAttributes:t}){return["span",(0,m.mergeAttributes)(t)]},addNodeView(){return(0,b.ReactNodeViewRenderer)(y)},addAttributes(){let t={};for(let r in this.options.attrs)t[r]={default:this.options.attrs[r]};return t}});var _={id:void 0,label:"undefined",className:void 0,style:void 0},z=(0,p.forwardRef)((t,r)=>{let{onChange:n,value:o,placeholder:e,readonly:u=!1,tagClassName:d,editorOptions:O,className:R,tagAttrs:C,tagView:S,...J}=t,h=(0,p.useRef)(null),a=(0,g.useEditor)({editorProps:{attributes:{class:`mix-input ${R||""}`}},extensions:[N.default,A.default.configure({HTMLAttributes:{class:"mi-paragraph"}}),E.default,P.default.configure({placeholder:e}),I.configure({tagClassName:d,attrs:{..._,...C},tagView:S})],onUpdate:({editor:i})=>{var V;n==null||n(l(((V=i==null?void 0:i.getJSON())==null?void 0:V.content)||[]))},...O}),k=i=>{a==null||a.chain().focus().insertContent(i).run()};return(0,p.useEffect)(()=>{let i=x(o);i.length===0&&(i=[{type:"paragraph"}]),JSON.stringify(i)!==JSON.stringify(a==null?void 0:a.getJSON().content)&&(a==null||a.commands.setContent(i))},[o]),(0,p.useImperativeHandle)(r,()=>({element:h.current,editor:a,insertContent:k})),p.default.createElement(g.EditorContent,{editor:a,innerRef:h,...J})}),w=z;var B=w;0&&(module.exports={editorValueToMixInputValue,mixInputValueToEditorValue}); +"use strict";var j=Object.create;var l=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,U=Object.prototype.hasOwnProperty;var W=(t,r)=>{for(var n in r)l(t,n,{get:r[n],enumerable:!0})},T=(t,r,n,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let e of F(r))!U.call(t,e)&&e!==n&&l(t,e,{get:()=>r[e],enumerable:!(o=D(r,e))||o.enumerable});return t};var d=(t,r,n)=>(n=t!=null?j($(t)):{},T(r||!t||!t.__esModule?l(n,"default",{value:t,enumerable:!0}):n,t)),_=t=>T(l({},"__esModule",{value:!0}),t);var Q={};W(Q,{default:()=>K,editorValueToMixInputValue:()=>x,mixInputValueToEditorValue:()=>m});module.exports=_(Q);var p=d(require("react"));function z(t){return typeof t=="object"&&t.type==="tag"}function B(t){return{type:"tag",attrs:{...t.attrs}}}function x(t){let r=[];return t.forEach(n=>{var o;n.type==="paragraph"&&(r.push([]),(o=n==null?void 0:n.content)==null||o.forEach(e=>{var i,c;e.type==="text"&&e.text&&((i=r.at(-1))==null||i.push(e.text)),e.type==="tag"&&((c=r.at(-1))==null||c.push(B(e)))}))}),r}function m(t){let r=[];return t.forEach((n,o)=>{Array.isArray(r[o])||r.push({type:"paragraph",content:[]});let e=r.at(-1);typeof n=="string"&&(e!=null&&e.content)&&e.content.push({type:"text",text:n}),!Array.isArray(n)&&z(n)&&(e!=null&&e.content)&&e.content.push({type:"tag",attrs:{...n.attrs}}),Array.isArray(n)&&n.forEach(i=>{typeof i=="string"&&(e!=null&&e.content)&&e.content.push({type:"text",text:i}),typeof i=="object"&&i.type==="tag"&&(e!=null&&e.content)&&e.content.push({type:"tag",attrs:{...i.attrs}})})}),r}var y=require("@tiptap/react"),A=d(require("@tiptap/extension-document")),E=d(require("@tiptap/extension-paragraph")),R=d(require("@tiptap/extension-text")),P=d(require("@tiptap/extension-placeholder"));var g=require("@tiptap/core"),I=require("@tiptap/react");var b=require("@tiptap/react"),f=d(require("react"));function V(t){let{tagView:r,tagClassName:n}=t.extension.options,{label:o,className:e,...i}=t.node.attrs;return f.default.createElement(f.default.Fragment,null,f.default.createElement(b.NodeViewWrapper,{"data-type":"tag",as:"span"},r?r(t):f.default.createElement("span",{className:`${n||""} ${e||""}`,...i},o)),"\u200B")}var N=g.Node.create({name:"tag",group:"inline",inline:!0,atom:!0,selectable:!1,parseHTML(){return[{tag:`span[data-type="${this.name}"]`}]},renderHTML({HTMLAttributes:t}){return["span",(0,g.mergeAttributes)(t)]},addNodeView(){return(0,I.ReactNodeViewRenderer)(V)},addAttributes(){let t={};for(let r in this.options.attrs)t[r]={default:this.options.attrs[r]};return t}});var G={id:void 0,label:"undefined",className:void 0,style:void 0},q=(0,p.forwardRef)((t,r)=>{let{onChange:n,value:o=[],placeholder:e,readonly:i=!1,tagClassName:c="mi-tag",editorOptions:C,className:O,tagAttrs:S,tagView:J,immediatelyRender:v=!0,...k}=t,h=(0,p.useRef)(null),M=(0,p.useRef)(""),a=(0,y.useEditor)({immediatelyRender:v,editorProps:{attributes:{class:`mix-input ${O||""}`}},extensions:[A.default,E.default.configure({HTMLAttributes:{class:"mi-paragraph"}}),R.default,P.default.configure({placeholder:e}),N.configure({tagClassName:c,attrs:{...G,...S},tagView:J})],onUpdate:({editor:u})=>{var s;n==null||n(x(((s=u==null?void 0:u.getJSON())==null?void 0:s.content)||[]))},...C}),H=u=>{a==null||a.chain().focus().insertContent(u).run()};return(0,p.useEffect)(()=>{if(!a)return;let u=m(o);u.length===0&&(u=[{type:"paragraph"}]);let s=JSON.stringify(u),L=JSON.stringify(a.getJSON().content);s!==L&&s!==M.current&&(M.current=s,setTimeout(()=>{a&&!a.isDestroyed&&a.commands.setContent(u)},0))},[o,a]),(0,p.useImperativeHandle)(r,()=>({element:h.current,editor:a,insertContent:H})),p.default.createElement(y.EditorContent,{editor:a,innerRef:h,...k})}),w=q;var K=w;0&&(module.exports={editorValueToMixInputValue,mixInputValueToEditorValue}); //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map index e4f9ce9..b33472e 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/index.ts","../src/MixInput.tsx","../src/utils.ts","../src/TagExtension.ts","../src/Tag.tsx"],"sourcesContent":["import MixInput from './MixInput'\r\nimport { editorValueToMixInputValue, mixInputValueToEditorValue } from './utils'\r\nimport type { MixInputProps, MixInputRef, MixInputValue, MixInputValues, Tag } from './MixInputType.d'\r\nimport { type Editor } from '@tiptap/core'\r\nexport default MixInput\r\nexport { editorValueToMixInputValue, mixInputValueToEditorValue }\r\n\r\nexport type {\r\n MixInputProps,\r\n MixInputRef,\r\n MixInputValue,\r\n MixInputValues,\r\n Tag,\r\n Editor\r\n}\r\n","import './MixInput.css'\r\n\r\nimport React, { type ForwardedRef, forwardRef, useEffect, useImperativeHandle, useRef } from 'react'\r\n\r\nimport { editorValueToMixInputValue, mixInputValueToEditorValue } from './utils'\r\nimport { EditorContent, useEditor } from '@tiptap/react'\r\nimport Document from '@tiptap/extension-document'\r\nimport Paragraph from '@tiptap/extension-paragraph'\r\nimport Text from '@tiptap/extension-text'\r\nimport Placeholder from '@tiptap/extension-placeholder'\r\nimport TagExtension from './TagExtension'\r\nimport { type MixInputProps, type MixInputRef, type MixInputValue } from './MixInputType'\r\n\r\nconst DEFAULT_TAG_ATTRS = {\r\n id: undefined,\r\n label: 'undefined',\r\n className: undefined,\r\n style: undefined,\r\n}\r\n\r\nconst MixInput = forwardRef((props: MixInputProps, ref: ForwardedRef) => {\r\n const {\r\n onChange,\r\n value,\r\n // multiline,\r\n // showTagDeleteBtn = false,\r\n placeholder,\r\n readonly = false,\r\n tagClassName,\r\n editorOptions,\r\n className,\r\n tagAttrs,\r\n tagView,\r\n ...restProps\r\n } = props\r\n\r\n const editorRef = useRef(null)\r\n\r\n const editor = useEditor({\r\n editorProps: {\r\n attributes: { class: `mix-input ${className || ''}` },\r\n },\r\n extensions: [\r\n Document,\r\n Paragraph.configure({\r\n HTMLAttributes: { class: 'mi-paragraph' },\r\n }),\r\n Text,\r\n Placeholder.configure({ placeholder }),\r\n TagExtension.configure({\r\n tagClassName,\r\n attrs: { ...DEFAULT_TAG_ATTRS, ...tagAttrs },\r\n tagView,\r\n }),\r\n ],\r\n onUpdate: ({ editor }) => {\r\n onChange?.(editorValueToMixInputValue(editor?.getJSON()?.content || []))\r\n },\r\n ...editorOptions,\r\n })\r\n\r\n const insertContent = (content: MixInputValue | MixInputValue[] | MixInputValue[][]) => {\r\n editor?.chain().focus().insertContent(content).run()\r\n }\r\n\r\n useEffect(() => {\r\n let updatedValueFromParent = mixInputValueToEditorValue(value)\r\n if (updatedValueFromParent.length === 0) {\r\n updatedValueFromParent = [{ type: 'paragraph' }]\r\n }\r\n if (JSON.stringify(updatedValueFromParent) === JSON.stringify(editor?.getJSON().content)) return\r\n\r\n editor?.commands.setContent(updatedValueFromParent)\r\n }, [value])\r\n\r\n useImperativeHandle(ref, () => ({\r\n element: editorRef.current,\r\n editor,\r\n insertContent,\r\n }))\r\n\r\n return (\r\n )}\r\n />\r\n )\r\n})\r\n\r\nexport default MixInput\r\n","\r\nimport type { MixInputValue, MixInputValues, Tag } from './MixInputType'\r\nimport { JSONContent } from '@tiptap/core'\r\n\r\nfunction isTag(item: MixInputValue): item is Tag {\r\n return typeof item === 'object' && item.type === 'tag'\r\n}\r\n\r\nfunction createTagObj(item: JSONContent): Tag {\r\n return { type: 'tag', attrs: { ...item.attrs } }\r\n}\r\n\r\nexport function editorValueToMixInputValue(value: JSONContent[]) {\r\n const mixInputValues: MixInputValues = []\r\n value.forEach((line) => {\r\n if (line.type === 'paragraph') {\r\n mixInputValues.push([])\r\n line?.content?.forEach((item) => {\r\n if (item.type === 'text' && item.text) {\r\n mixInputValues.at(-1)?.push(item.text)\r\n }\r\n if (item.type === 'tag') {\r\n mixInputValues.at(-1)?.push(createTagObj(item))\r\n }\r\n })\r\n }\r\n })\r\n return mixInputValues\r\n}\r\n\r\nexport function mixInputValueToEditorValue(mixInputValues: MixInputValue[] | MixInputValue[][]) {\r\n const jsonContent: JSONContent[] = []\r\n mixInputValues.forEach((item, i) => {\r\n if (!Array.isArray(jsonContent[i])) {\r\n jsonContent.push({ type: 'paragraph', content: [] })\r\n }\r\n const lastItem = jsonContent.at(-1)\r\n if (typeof item === 'string' && lastItem?.content) {\r\n lastItem.content.push({\r\n type: 'text',\r\n text: item,\r\n })\r\n }\r\n if (!Array.isArray(item) && isTag(item) && lastItem?.content) {\r\n lastItem.content.push({\r\n type: 'tag',\r\n attrs: { ...item.attrs },\r\n })\r\n }\r\n if (Array.isArray(item)) {\r\n item.forEach((subItem) => {\r\n if (typeof subItem === 'string' && lastItem?.content) {\r\n lastItem.content.push({\r\n type: 'text',\r\n text: subItem,\r\n })\r\n }\r\n if (typeof subItem === 'object' && subItem.type === 'tag' && lastItem?.content) {\r\n lastItem.content.push({\r\n type: 'tag',\r\n attrs: { ...subItem.attrs },\r\n })\r\n }\r\n })\r\n }\r\n })\r\n return jsonContent\r\n}","import { Attribute, mergeAttributes, Node } from \"@tiptap/core\";\r\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\r\nimport Tag from \"./Tag\";\r\n\r\nexport default Node.create({\r\n name: \"tag\",\r\n group: \"inline\",\r\n inline: true,\r\n atom: true,\r\n selectable: false,\r\n\r\n parseHTML() {\r\n return [\r\n {\r\n tag: `span[data-type=\"${this.name}\"]`,\r\n },\r\n ]\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\"span\", mergeAttributes(HTMLAttributes)];\r\n },\r\n\r\n addNodeView() {\r\n return ReactNodeViewRenderer(Tag)\r\n },\r\n\r\n addAttributes() {\r\n const extraAttrs: Record = {}\r\n for (const key in this.options.attrs) {\r\n extraAttrs[key] = { default: this.options.attrs[key] }\r\n }\r\n return extraAttrs\r\n },\r\n})\r\n","import { type NodeViewProps, NodeViewWrapper } from '@tiptap/react'\r\nimport React from 'react'\r\n\r\nexport default function Tag(props: NodeViewProps) {\r\n const { tagView, tagClassName } = props.extension.options\r\n const { label, ...restAttrs } = props.node.attrs\r\n return (\r\n <>\r\n \r\n {tagView ? tagView(props) : {label}}\r\n \r\n {'\\u200B'}\r\n \r\n )\r\n}\r\n"],"mappings":"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","names":["src_exports","__export","src_default","editorValueToMixInputValue","mixInputValueToEditorValue","__toCommonJS","import_react","isTag","item","createTagObj","editorValueToMixInputValue","value","mixInputValues","line","_a","_b","mixInputValueToEditorValue","jsonContent","i","lastItem","subItem","import_react","import_extension_document","import_extension_paragraph","import_extension_text","import_extension_placeholder","import_core","import_react","import_react","Tag","props","tagView","tagClassName","label","restAttrs","React","TagExtension_default","HTMLAttributes","Tag","extraAttrs","key","DEFAULT_TAG_ATTRS","MixInput","props","ref","onChange","value","placeholder","readonly","tagClassName","editorOptions","className","tagAttrs","tagView","restProps","editorRef","editor","Document","Paragraph","Text","Placeholder","TagExtension_default","_a","editorValueToMixInputValue","insertContent","content","updatedValueFromParent","mixInputValueToEditorValue","React","MixInput_default","src_default","MixInput_default"]} \ No newline at end of file +{"version":3,"sources":["../src/index.ts","../src/MixInput.tsx","../src/utils.ts","../src/TagExtension.ts","../src/Tag.tsx"],"sourcesContent":["import MixInput from './MixInput'\nimport { editorValueToMixInputValue, mixInputValueToEditorValue } from './utils'\nimport type { MixInputProps, MixInputRef, MixInputValue, MixInputValues, Tag } from './MixInputType.d'\nimport { type Editor } from '@tiptap/core'\nexport default MixInput\nexport { editorValueToMixInputValue, mixInputValueToEditorValue }\n\nexport type {\n MixInputProps,\n MixInputRef,\n MixInputValue,\n MixInputValues,\n Tag,\n Editor\n}\n","import './MixInput.css'\n\nimport React, { type ForwardedRef, forwardRef, useEffect, useImperativeHandle, useRef } from 'react'\n\nimport { editorValueToMixInputValue, mixInputValueToEditorValue } from './utils'\nimport { EditorContent, useEditor } from '@tiptap/react'\nimport Document from '@tiptap/extension-document'\nimport Paragraph from '@tiptap/extension-paragraph'\nimport Text from '@tiptap/extension-text'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport TagExtension from './TagExtension'\nimport { type MixInputProps, type MixInputRef, type MixInputValue } from './MixInputType'\n\nconst DEFAULT_TAG_ATTRS = {\n id: undefined,\n label: 'undefined',\n className: undefined,\n style: undefined,\n}\n\nconst MixInput = forwardRef((props: MixInputProps, ref?: ForwardedRef) => {\n const {\n onChange,\n value = [],\n // multiline,\n placeholder,\n readonly = false,\n tagClassName = 'mi-tag',\n editorOptions,\n className,\n tagAttrs,\n tagView,\n immediatelyRender = true,\n ...restProps\n } = props\n\n const editorRef = useRef(null)\n const previousValueRef = useRef('')\n\n const editor = useEditor({\n immediatelyRender,\n editorProps: {\n attributes: { class: `mix-input ${className || ''}` },\n },\n extensions: [\n Document,\n Paragraph.configure({\n HTMLAttributes: { class: 'mi-paragraph' },\n }),\n Text,\n Placeholder.configure({ placeholder }),\n TagExtension.configure({\n tagClassName,\n attrs: { ...DEFAULT_TAG_ATTRS, ...tagAttrs },\n tagView,\n }),\n ],\n onUpdate: ({ editor }) => {\n onChange?.(editorValueToMixInputValue(editor?.getJSON()?.content || []))\n },\n ...editorOptions,\n })\n\n const insertContent = (content: MixInputValue | MixInputValue[] | MixInputValue[][]) => {\n editor?.chain().focus().insertContent(content).run()\n }\n\n useEffect(() => {\n if (!editor) return\n\n let updatedValueFromParent = mixInputValueToEditorValue(value)\n if (updatedValueFromParent.length === 0) {\n updatedValueFromParent = [{ type: 'paragraph' }]\n }\n\n const currentValueStr = JSON.stringify(updatedValueFromParent)\n const editorContentStr = JSON.stringify(editor.getJSON().content)\n\n // Only update if content has actually changed\n if (currentValueStr !== editorContentStr && currentValueStr !== previousValueRef.current) {\n previousValueRef.current = currentValueStr\n\n // Use setTimeout to move the update out of React's rendering phase\n setTimeout(() => {\n if (editor && !editor.isDestroyed) {\n editor.commands.setContent(updatedValueFromParent)\n }\n }, 0)\n }\n }, [value, editor])\n\n useImperativeHandle(ref, () => ({\n element: editorRef.current,\n editor,\n insertContent,\n }))\n\n return (\n )}\n />\n )\n})\n\nexport default MixInput\n","\nimport type { MixInputValue, MixInputValues, Tag } from './MixInputType'\nimport { JSONContent } from '@tiptap/core'\n\nfunction isTag(item: MixInputValue): item is Tag {\n return typeof item === 'object' && item.type === 'tag'\n}\n\nfunction createTagObj(item: JSONContent): Tag {\n return { type: 'tag', attrs: { ...item.attrs } }\n}\n\nexport function editorValueToMixInputValue(value: JSONContent[]) {\n const mixInputValues: MixInputValues = []\n value.forEach((line) => {\n if (line.type === 'paragraph') {\n mixInputValues.push([])\n line?.content?.forEach((item) => {\n if (item.type === 'text' && item.text) {\n mixInputValues.at(-1)?.push(item.text)\n }\n if (item.type === 'tag') {\n mixInputValues.at(-1)?.push(createTagObj(item))\n }\n })\n }\n })\n return mixInputValues\n}\n\nexport function mixInputValueToEditorValue(mixInputValues: MixInputValue[] | MixInputValue[][]) {\n const jsonContent: JSONContent[] = []\n mixInputValues.forEach((item, i) => {\n if (!Array.isArray(jsonContent[i])) {\n jsonContent.push({ type: 'paragraph', content: [] })\n }\n const lastItem = jsonContent.at(-1)\n if (typeof item === 'string' && lastItem?.content) {\n lastItem.content.push({\n type: 'text',\n text: item,\n })\n }\n if (!Array.isArray(item) && isTag(item) && lastItem?.content) {\n lastItem.content.push({\n type: 'tag',\n attrs: { ...item.attrs },\n })\n }\n if (Array.isArray(item)) {\n item.forEach((subItem) => {\n if (typeof subItem === 'string' && lastItem?.content) {\n lastItem.content.push({\n type: 'text',\n text: subItem,\n })\n }\n if (typeof subItem === 'object' && subItem.type === 'tag' && lastItem?.content) {\n lastItem.content.push({\n type: 'tag',\n attrs: { ...subItem.attrs },\n })\n }\n })\n }\n })\n return jsonContent\n}","import { type Attribute, mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport Tag from \"./Tag\";\n\nexport default Node.create({\n name: \"tag\",\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: false,\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\"span\", mergeAttributes(HTMLAttributes)];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(Tag)\n },\n\n addAttributes() {\n const extraAttrs: Record = {}\n for (const key in this.options.attrs) {\n extraAttrs[key] = { default: this.options.attrs[key] }\n }\n return extraAttrs\n },\n})\n","import { type NodeViewProps, NodeViewWrapper } from '@tiptap/react'\nimport React from 'react'\n\nexport default function Tag(props: NodeViewProps) {\n const { tagView, tagClassName } = props.extension.options\n const { label, className, ...restAttrs } = props.node.attrs\n return (\n <>\n \n {tagView ? (\n tagView(props)\n ) : (\n \n {label}\n \n )}\n \n {'\\u200B'}\n \n )\n}\n"],"mappings":"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","names":["src_exports","__export","src_default","editorValueToMixInputValue","mixInputValueToEditorValue","__toCommonJS","import_react","isTag","item","createTagObj","editorValueToMixInputValue","value","mixInputValues","line","_a","_b","mixInputValueToEditorValue","jsonContent","i","lastItem","subItem","import_react","import_extension_document","import_extension_paragraph","import_extension_text","import_extension_placeholder","import_core","import_react","import_react","Tag","props","tagView","tagClassName","label","className","restAttrs","React","TagExtension_default","HTMLAttributes","Tag","extraAttrs","key","DEFAULT_TAG_ATTRS","MixInput","props","ref","onChange","value","placeholder","readonly","tagClassName","editorOptions","className","tagAttrs","tagView","immediatelyRender","restProps","editorRef","previousValueRef","editor","Document","Paragraph","Text","Placeholder","TagExtension_default","_a","editorValueToMixInputValue","insertContent","content","updatedValueFromParent","mixInputValueToEditorValue","currentValueStr","editorContentStr","React","MixInput_default","src_default","MixInput_default"]} \ No newline at end of file diff --git a/dist/index.mjs b/dist/index.mjs index 17d6091..adae8c7 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -1,3 +1,3 @@ "use client"; -import O,{forwardRef as R,useEffect as C,useImperativeHandle as S,useRef as J}from"react";function I(e){return typeof e=="object"&&e.type==="tag"}function N(e){return{type:"tag",attrs:{...e.attrs}}}function f(e){let n=[];return e.forEach(r=>{var i;r.type==="paragraph"&&(n.push([]),(i=r==null?void 0:r.content)==null||i.forEach(t=>{var p,u;t.type==="text"&&t.text&&((p=n.at(-1))==null||p.push(t.text)),t.type==="tag"&&((u=n.at(-1))==null||u.push(N(t)))}))}),n}function d(e){let n=[];return e.forEach((r,i)=>{Array.isArray(n[i])||n.push({type:"paragraph",content:[]});let t=n.at(-1);typeof r=="string"&&(t!=null&&t.content)&&t.content.push({type:"text",text:r}),!Array.isArray(r)&&I(r)&&(t!=null&&t.content)&&t.content.push({type:"tag",attrs:{...r.attrs}}),Array.isArray(r)&&r.forEach(p=>{typeof p=="string"&&(t!=null&&t.content)&&t.content.push({type:"text",text:p}),typeof p=="object"&&p.type==="tag"&&(t!=null&&t.content)&&t.content.push({type:"tag",attrs:{...p.attrs}})})}),n}import{EditorContent as k,useEditor as v}from"@tiptap/react";import H from"@tiptap/extension-document";import L from"@tiptap/extension-paragraph";import j from"@tiptap/extension-text";import F from"@tiptap/extension-placeholder";import{mergeAttributes as E,Node as P}from"@tiptap/core";import{ReactNodeViewRenderer as w}from"@tiptap/react";import{NodeViewWrapper as A}from"@tiptap/react";import s from"react";function c(e){let{tagView:n,tagClassName:r}=e.extension.options,{label:i,...t}=e.node.attrs;return s.createElement(s.Fragment,null,s.createElement(A,{className:`mi-tag ${r||""}`,"data-type":"tag",as:"span"},n?n(e):s.createElement("span",{...t},i)),"\u200B")}var m=P.create({name:"tag",group:"inline",inline:!0,atom:!0,selectable:!1,parseHTML(){return[{tag:`span[data-type="${this.name}"]`}]},renderHTML({HTMLAttributes:e}){return["span",E(e)]},addNodeView(){return w(c)},addAttributes(){let e={};for(let n in this.options.attrs)e[n]={default:this.options.attrs[n]};return e}});var D={id:void 0,label:"undefined",className:void 0,style:void 0},$=R((e,n)=>{let{onChange:r,value:i,placeholder:t,readonly:p=!1,tagClassName:u,editorOptions:y,className:h,tagAttrs:V,tagView:M,...T}=e,l=J(null),o=v({editorProps:{attributes:{class:`mix-input ${h||""}`}},extensions:[H,L.configure({HTMLAttributes:{class:"mi-paragraph"}}),j,F.configure({placeholder:t}),m.configure({tagClassName:u,attrs:{...D,...V},tagView:M})],onUpdate:({editor:a})=>{var x;r==null||r(f(((x=a==null?void 0:a.getJSON())==null?void 0:x.content)||[]))},...y}),b=a=>{o==null||o.chain().focus().insertContent(a).run()};return C(()=>{let a=d(i);a.length===0&&(a=[{type:"paragraph"}]),JSON.stringify(a)!==JSON.stringify(o==null?void 0:o.getJSON().content)&&(o==null||o.commands.setContent(a))},[i]),S(n,()=>({element:l.current,editor:o,insertContent:b})),O.createElement(k,{editor:o,innerRef:l,...T})}),g=$;var dt=g;export{dt as default,f as editorValueToMixInputValue,d as mixInputValueToEditorValue}; +import J,{forwardRef as v,useEffect as k,useImperativeHandle as H,useRef as y}from"react";function R(e){return typeof e=="object"&&e.type==="tag"}function P(e){return{type:"tag",attrs:{...e.attrs}}}function f(e){let n=[];return e.forEach(r=>{var p;r.type==="paragraph"&&(n.push([]),(p=r==null?void 0:r.content)==null||p.forEach(t=>{var o,s;t.type==="text"&&t.text&&((o=n.at(-1))==null||o.push(t.text)),t.type==="tag"&&((s=n.at(-1))==null||s.push(P(t)))}))}),n}function c(e){let n=[];return e.forEach((r,p)=>{Array.isArray(n[p])||n.push({type:"paragraph",content:[]});let t=n.at(-1);typeof r=="string"&&(t!=null&&t.content)&&t.content.push({type:"text",text:r}),!Array.isArray(r)&&R(r)&&(t!=null&&t.content)&&t.content.push({type:"tag",attrs:{...r.attrs}}),Array.isArray(r)&&r.forEach(o=>{typeof o=="string"&&(t!=null&&t.content)&&t.content.push({type:"text",text:o}),typeof o=="object"&&o.type==="tag"&&(t!=null&&t.content)&&t.content.push({type:"tag",attrs:{...o.attrs}})})}),n}import{EditorContent as L,useEditor as j}from"@tiptap/react";import D from"@tiptap/extension-document";import F from"@tiptap/extension-paragraph";import $ from"@tiptap/extension-text";import U from"@tiptap/extension-placeholder";import{mergeAttributes as C,Node as O}from"@tiptap/core";import{ReactNodeViewRenderer as S}from"@tiptap/react";import{NodeViewWrapper as w}from"@tiptap/react";import d from"react";function l(e){let{tagView:n,tagClassName:r}=e.extension.options,{label:p,className:t,...o}=e.node.attrs;return d.createElement(d.Fragment,null,d.createElement(w,{"data-type":"tag",as:"span"},n?n(e):d.createElement("span",{className:`${r||""} ${t||""}`,...o},p)),"\u200B")}var g=O.create({name:"tag",group:"inline",inline:!0,atom:!0,selectable:!1,parseHTML(){return[{tag:`span[data-type="${this.name}"]`}]},renderHTML({HTMLAttributes:e}){return["span",C(e)]},addNodeView(){return S(l)},addAttributes(){let e={};for(let n in this.options.attrs)e[n]={default:this.options.attrs[n]};return e}});var W={id:void 0,label:"undefined",className:void 0,style:void 0},_=v((e,n)=>{let{onChange:r,value:p=[],placeholder:t,readonly:o=!1,tagClassName:s="mi-tag",editorOptions:h,className:M,tagAttrs:T,tagView:b,immediatelyRender:I=!0,...N}=e,x=y(null),m=y(""),i=j({immediatelyRender:I,editorProps:{attributes:{class:`mix-input ${M||""}`}},extensions:[D,F.configure({HTMLAttributes:{class:"mi-paragraph"}}),$,U.configure({placeholder:t}),g.configure({tagClassName:s,attrs:{...W,...T},tagView:b})],onUpdate:({editor:a})=>{var u;r==null||r(f(((u=a==null?void 0:a.getJSON())==null?void 0:u.content)||[]))},...h}),A=a=>{i==null||i.chain().focus().insertContent(a).run()};return k(()=>{if(!i)return;let a=c(p);a.length===0&&(a=[{type:"paragraph"}]);let u=JSON.stringify(a),E=JSON.stringify(i.getJSON().content);u!==E&&u!==m.current&&(m.current=u,setTimeout(()=>{i&&!i.isDestroyed&&i.commands.setContent(a)},0))},[p,i]),H(n,()=>({element:x.current,editor:i,insertContent:A})),J.createElement(L,{editor:i,innerRef:x,...N})}),V=_;var lt=V;export{lt as default,f as editorValueToMixInputValue,c as mixInputValueToEditorValue}; //# sourceMappingURL=index.mjs.map \ No newline at end of file diff --git a/dist/index.mjs.map b/dist/index.mjs.map index f1e7c70..75a09d4 100644 --- a/dist/index.mjs.map +++ b/dist/index.mjs.map @@ -1 +1 @@ -{"version":3,"sources":["../src/MixInput.tsx","../src/utils.ts","../src/TagExtension.ts","../src/Tag.tsx","../src/index.ts"],"sourcesContent":["import './MixInput.css'\r\n\r\nimport React, { type ForwardedRef, forwardRef, useEffect, useImperativeHandle, useRef } from 'react'\r\n\r\nimport { editorValueToMixInputValue, mixInputValueToEditorValue } from './utils'\r\nimport { EditorContent, useEditor } from '@tiptap/react'\r\nimport Document from '@tiptap/extension-document'\r\nimport Paragraph from '@tiptap/extension-paragraph'\r\nimport Text from '@tiptap/extension-text'\r\nimport Placeholder from '@tiptap/extension-placeholder'\r\nimport TagExtension from './TagExtension'\r\nimport { type MixInputProps, type MixInputRef, type MixInputValue } from './MixInputType'\r\n\r\nconst DEFAULT_TAG_ATTRS = {\r\n id: undefined,\r\n label: 'undefined',\r\n className: undefined,\r\n style: undefined,\r\n}\r\n\r\nconst MixInput = forwardRef((props: MixInputProps, ref: ForwardedRef) => {\r\n const {\r\n onChange,\r\n value,\r\n // multiline,\r\n // showTagDeleteBtn = false,\r\n placeholder,\r\n readonly = false,\r\n tagClassName,\r\n editorOptions,\r\n className,\r\n tagAttrs,\r\n tagView,\r\n ...restProps\r\n } = props\r\n\r\n const editorRef = useRef(null)\r\n\r\n const editor = useEditor({\r\n editorProps: {\r\n attributes: { class: `mix-input ${className || ''}` },\r\n },\r\n extensions: [\r\n Document,\r\n Paragraph.configure({\r\n HTMLAttributes: { class: 'mi-paragraph' },\r\n }),\r\n Text,\r\n Placeholder.configure({ placeholder }),\r\n TagExtension.configure({\r\n tagClassName,\r\n attrs: { ...DEFAULT_TAG_ATTRS, ...tagAttrs },\r\n tagView,\r\n }),\r\n ],\r\n onUpdate: ({ editor }) => {\r\n onChange?.(editorValueToMixInputValue(editor?.getJSON()?.content || []))\r\n },\r\n ...editorOptions,\r\n })\r\n\r\n const insertContent = (content: MixInputValue | MixInputValue[] | MixInputValue[][]) => {\r\n editor?.chain().focus().insertContent(content).run()\r\n }\r\n\r\n useEffect(() => {\r\n let updatedValueFromParent = mixInputValueToEditorValue(value)\r\n if (updatedValueFromParent.length === 0) {\r\n updatedValueFromParent = [{ type: 'paragraph' }]\r\n }\r\n if (JSON.stringify(updatedValueFromParent) === JSON.stringify(editor?.getJSON().content)) return\r\n\r\n editor?.commands.setContent(updatedValueFromParent)\r\n }, [value])\r\n\r\n useImperativeHandle(ref, () => ({\r\n element: editorRef.current,\r\n editor,\r\n insertContent,\r\n }))\r\n\r\n return (\r\n )}\r\n />\r\n )\r\n})\r\n\r\nexport default MixInput\r\n","\r\nimport type { MixInputValue, MixInputValues, Tag } from './MixInputType'\r\nimport { JSONContent } from '@tiptap/core'\r\n\r\nfunction isTag(item: MixInputValue): item is Tag {\r\n return typeof item === 'object' && item.type === 'tag'\r\n}\r\n\r\nfunction createTagObj(item: JSONContent): Tag {\r\n return { type: 'tag', attrs: { ...item.attrs } }\r\n}\r\n\r\nexport function editorValueToMixInputValue(value: JSONContent[]) {\r\n const mixInputValues: MixInputValues = []\r\n value.forEach((line) => {\r\n if (line.type === 'paragraph') {\r\n mixInputValues.push([])\r\n line?.content?.forEach((item) => {\r\n if (item.type === 'text' && item.text) {\r\n mixInputValues.at(-1)?.push(item.text)\r\n }\r\n if (item.type === 'tag') {\r\n mixInputValues.at(-1)?.push(createTagObj(item))\r\n }\r\n })\r\n }\r\n })\r\n return mixInputValues\r\n}\r\n\r\nexport function mixInputValueToEditorValue(mixInputValues: MixInputValue[] | MixInputValue[][]) {\r\n const jsonContent: JSONContent[] = []\r\n mixInputValues.forEach((item, i) => {\r\n if (!Array.isArray(jsonContent[i])) {\r\n jsonContent.push({ type: 'paragraph', content: [] })\r\n }\r\n const lastItem = jsonContent.at(-1)\r\n if (typeof item === 'string' && lastItem?.content) {\r\n lastItem.content.push({\r\n type: 'text',\r\n text: item,\r\n })\r\n }\r\n if (!Array.isArray(item) && isTag(item) && lastItem?.content) {\r\n lastItem.content.push({\r\n type: 'tag',\r\n attrs: { ...item.attrs },\r\n })\r\n }\r\n if (Array.isArray(item)) {\r\n item.forEach((subItem) => {\r\n if (typeof subItem === 'string' && lastItem?.content) {\r\n lastItem.content.push({\r\n type: 'text',\r\n text: subItem,\r\n })\r\n }\r\n if (typeof subItem === 'object' && subItem.type === 'tag' && lastItem?.content) {\r\n lastItem.content.push({\r\n type: 'tag',\r\n attrs: { ...subItem.attrs },\r\n })\r\n }\r\n })\r\n }\r\n })\r\n return jsonContent\r\n}","import { Attribute, mergeAttributes, Node } from \"@tiptap/core\";\r\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\r\nimport Tag from \"./Tag\";\r\n\r\nexport default Node.create({\r\n name: \"tag\",\r\n group: \"inline\",\r\n inline: true,\r\n atom: true,\r\n selectable: false,\r\n\r\n parseHTML() {\r\n return [\r\n {\r\n tag: `span[data-type=\"${this.name}\"]`,\r\n },\r\n ]\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\"span\", mergeAttributes(HTMLAttributes)];\r\n },\r\n\r\n addNodeView() {\r\n return ReactNodeViewRenderer(Tag)\r\n },\r\n\r\n addAttributes() {\r\n const extraAttrs: Record = {}\r\n for (const key in this.options.attrs) {\r\n extraAttrs[key] = { default: this.options.attrs[key] }\r\n }\r\n return extraAttrs\r\n },\r\n})\r\n","import { type NodeViewProps, NodeViewWrapper } from '@tiptap/react'\r\nimport React from 'react'\r\n\r\nexport default function Tag(props: NodeViewProps) {\r\n const { tagView, tagClassName } = props.extension.options\r\n const { label, ...restAttrs } = props.node.attrs\r\n return (\r\n <>\r\n \r\n {tagView ? tagView(props) : {label}}\r\n \r\n {'\\u200B'}\r\n \r\n )\r\n}\r\n","import MixInput from './MixInput'\r\nimport { editorValueToMixInputValue, mixInputValueToEditorValue } from './utils'\r\nimport type { MixInputProps, MixInputRef, MixInputValue, MixInputValues, Tag } from './MixInputType.d'\r\nimport { type Editor } from '@tiptap/core'\r\nexport default MixInput\r\nexport { editorValueToMixInputValue, mixInputValueToEditorValue }\r\n\r\nexport type {\r\n MixInputProps,\r\n MixInputRef,\r\n MixInputValue,\r\n MixInputValues,\r\n Tag,\r\n Editor\r\n}\r\n"],"mappings":"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","names":["React","forwardRef","useEffect","useImperativeHandle","useRef","isTag","item","createTagObj","editorValueToMixInputValue","value","mixInputValues","line","_a","_b","mixInputValueToEditorValue","jsonContent","lastItem","subItem","EditorContent","useEditor","Document","Paragraph","Text","Placeholder","mergeAttributes","Node","ReactNodeViewRenderer","NodeViewWrapper","React","Tag","props","tagView","tagClassName","label","restAttrs","TagExtension_default","Node","HTMLAttributes","mergeAttributes","ReactNodeViewRenderer","Tag","extraAttrs","key","DEFAULT_TAG_ATTRS","MixInput","forwardRef","props","ref","onChange","value","placeholder","readonly","tagClassName","editorOptions","className","tagAttrs","tagView","restProps","editorRef","useRef","editor","useEditor","Document","Paragraph","Text","Placeholder","TagExtension_default","_a","editorValueToMixInputValue","insertContent","content","useEffect","updatedValueFromParent","mixInputValueToEditorValue","useImperativeHandle","React","EditorContent","MixInput_default","src_default","MixInput_default"]} \ No newline at end of file +{"version":3,"sources":["../src/MixInput.tsx","../src/utils.ts","../src/TagExtension.ts","../src/Tag.tsx","../src/index.ts"],"sourcesContent":["import './MixInput.css'\n\nimport React, { type ForwardedRef, forwardRef, useEffect, useImperativeHandle, useRef } from 'react'\n\nimport { editorValueToMixInputValue, mixInputValueToEditorValue } from './utils'\nimport { EditorContent, useEditor } from '@tiptap/react'\nimport Document from '@tiptap/extension-document'\nimport Paragraph from '@tiptap/extension-paragraph'\nimport Text from '@tiptap/extension-text'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport TagExtension from './TagExtension'\nimport { type MixInputProps, type MixInputRef, type MixInputValue } from './MixInputType'\n\nconst DEFAULT_TAG_ATTRS = {\n id: undefined,\n label: 'undefined',\n className: undefined,\n style: undefined,\n}\n\nconst MixInput = forwardRef((props: MixInputProps, ref?: ForwardedRef) => {\n const {\n onChange,\n value = [],\n // multiline,\n placeholder,\n readonly = false,\n tagClassName = 'mi-tag',\n editorOptions,\n className,\n tagAttrs,\n tagView,\n immediatelyRender = true,\n ...restProps\n } = props\n\n const editorRef = useRef(null)\n const previousValueRef = useRef('')\n\n const editor = useEditor({\n immediatelyRender,\n editorProps: {\n attributes: { class: `mix-input ${className || ''}` },\n },\n extensions: [\n Document,\n Paragraph.configure({\n HTMLAttributes: { class: 'mi-paragraph' },\n }),\n Text,\n Placeholder.configure({ placeholder }),\n TagExtension.configure({\n tagClassName,\n attrs: { ...DEFAULT_TAG_ATTRS, ...tagAttrs },\n tagView,\n }),\n ],\n onUpdate: ({ editor }) => {\n onChange?.(editorValueToMixInputValue(editor?.getJSON()?.content || []))\n },\n ...editorOptions,\n })\n\n const insertContent = (content: MixInputValue | MixInputValue[] | MixInputValue[][]) => {\n editor?.chain().focus().insertContent(content).run()\n }\n\n useEffect(() => {\n if (!editor) return\n\n let updatedValueFromParent = mixInputValueToEditorValue(value)\n if (updatedValueFromParent.length === 0) {\n updatedValueFromParent = [{ type: 'paragraph' }]\n }\n\n const currentValueStr = JSON.stringify(updatedValueFromParent)\n const editorContentStr = JSON.stringify(editor.getJSON().content)\n\n // Only update if content has actually changed\n if (currentValueStr !== editorContentStr && currentValueStr !== previousValueRef.current) {\n previousValueRef.current = currentValueStr\n\n // Use setTimeout to move the update out of React's rendering phase\n setTimeout(() => {\n if (editor && !editor.isDestroyed) {\n editor.commands.setContent(updatedValueFromParent)\n }\n }, 0)\n }\n }, [value, editor])\n\n useImperativeHandle(ref, () => ({\n element: editorRef.current,\n editor,\n insertContent,\n }))\n\n return (\n )}\n />\n )\n})\n\nexport default MixInput\n","\nimport type { MixInputValue, MixInputValues, Tag } from './MixInputType'\nimport { JSONContent } from '@tiptap/core'\n\nfunction isTag(item: MixInputValue): item is Tag {\n return typeof item === 'object' && item.type === 'tag'\n}\n\nfunction createTagObj(item: JSONContent): Tag {\n return { type: 'tag', attrs: { ...item.attrs } }\n}\n\nexport function editorValueToMixInputValue(value: JSONContent[]) {\n const mixInputValues: MixInputValues = []\n value.forEach((line) => {\n if (line.type === 'paragraph') {\n mixInputValues.push([])\n line?.content?.forEach((item) => {\n if (item.type === 'text' && item.text) {\n mixInputValues.at(-1)?.push(item.text)\n }\n if (item.type === 'tag') {\n mixInputValues.at(-1)?.push(createTagObj(item))\n }\n })\n }\n })\n return mixInputValues\n}\n\nexport function mixInputValueToEditorValue(mixInputValues: MixInputValue[] | MixInputValue[][]) {\n const jsonContent: JSONContent[] = []\n mixInputValues.forEach((item, i) => {\n if (!Array.isArray(jsonContent[i])) {\n jsonContent.push({ type: 'paragraph', content: [] })\n }\n const lastItem = jsonContent.at(-1)\n if (typeof item === 'string' && lastItem?.content) {\n lastItem.content.push({\n type: 'text',\n text: item,\n })\n }\n if (!Array.isArray(item) && isTag(item) && lastItem?.content) {\n lastItem.content.push({\n type: 'tag',\n attrs: { ...item.attrs },\n })\n }\n if (Array.isArray(item)) {\n item.forEach((subItem) => {\n if (typeof subItem === 'string' && lastItem?.content) {\n lastItem.content.push({\n type: 'text',\n text: subItem,\n })\n }\n if (typeof subItem === 'object' && subItem.type === 'tag' && lastItem?.content) {\n lastItem.content.push({\n type: 'tag',\n attrs: { ...subItem.attrs },\n })\n }\n })\n }\n })\n return jsonContent\n}","import { type Attribute, mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport Tag from \"./Tag\";\n\nexport default Node.create({\n name: \"tag\",\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: false,\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\"span\", mergeAttributes(HTMLAttributes)];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(Tag)\n },\n\n addAttributes() {\n const extraAttrs: Record = {}\n for (const key in this.options.attrs) {\n extraAttrs[key] = { default: this.options.attrs[key] }\n }\n return extraAttrs\n },\n})\n","import { type NodeViewProps, NodeViewWrapper } from '@tiptap/react'\nimport React from 'react'\n\nexport default function Tag(props: NodeViewProps) {\n const { tagView, tagClassName } = props.extension.options\n const { label, className, ...restAttrs } = props.node.attrs\n return (\n <>\n \n {tagView ? (\n tagView(props)\n ) : (\n \n {label}\n \n )}\n \n {'\\u200B'}\n \n )\n}\n","import MixInput from './MixInput'\nimport { editorValueToMixInputValue, mixInputValueToEditorValue } from './utils'\nimport type { MixInputProps, MixInputRef, MixInputValue, MixInputValues, Tag } from './MixInputType.d'\nimport { type Editor } from '@tiptap/core'\nexport default MixInput\nexport { editorValueToMixInputValue, mixInputValueToEditorValue }\n\nexport type {\n MixInputProps,\n MixInputRef,\n MixInputValue,\n MixInputValues,\n Tag,\n Editor\n}\n"],"mappings":"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","names":["React","forwardRef","useEffect","useImperativeHandle","useRef","isTag","item","createTagObj","editorValueToMixInputValue","value","mixInputValues","line","_a","_b","mixInputValueToEditorValue","jsonContent","i","lastItem","subItem","EditorContent","useEditor","Document","Paragraph","Text","Placeholder","mergeAttributes","Node","ReactNodeViewRenderer","NodeViewWrapper","React","Tag","props","tagView","tagClassName","label","className","restAttrs","TagExtension_default","Node","HTMLAttributes","mergeAttributes","ReactNodeViewRenderer","Tag","extraAttrs","key","DEFAULT_TAG_ATTRS","MixInput","forwardRef","props","ref","onChange","value","placeholder","readonly","tagClassName","editorOptions","className","tagAttrs","tagView","immediatelyRender","restProps","editorRef","useRef","previousValueRef","editor","useEditor","Document","Paragraph","Text","Placeholder","TagExtension_default","_a","editorValueToMixInputValue","insertContent","content","useEffect","updatedValueFromParent","mixInputValueToEditorValue","currentValueStr","editorContentStr","useImperativeHandle","React","EditorContent","MixInput_default","src_default","MixInput_default"]} \ No newline at end of file