UNPKG

reactjs-tiptap-editor

Version:

A modern WYSIWYG rich text editor based on tiptap and shadcn ui for React

427 lines (426 loc) 12.7 kB
import { h as v, j as x, N as k, k as y, n as S, m as I } from "./clsx-DaPvp9ji.js"; import { jsxs as f, jsx as d, Fragment as P } from "react/jsx-runtime"; import { useState as M, useCallback as R } from "react"; import { Resizable as N } from "re-resizable"; import { g as l } from "./dom-dataset-CIEeltF6.js"; import { G as j, j as U, B as q, u as A, d as L, A as D } from "./index-RcSPeQHn.js"; import "./theme.js"; const m = { youtube: { example: "https://www.youtube.com/watch?v=I4sMhHbHYXM", src: "https://www.youtube.com/embed/I4sMhHbHYXM", srcPrefix: "https://www.youtube.com/embed", linkRule: [ /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\s/]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[&?]v=)|youtu\.be\/)([\w-]{11})/ ] }, youku: { example: "https://v.youku.com/v_show/id_XNDM0NDM4MTcy.html?spm=a2h0c.8166622.PhoneSokuUgc_4.dtitle", src: "https://player.youku.com/embed/XNDM0NDM4MTcy", srcPrefix: "https://player.youku.com/embed", linkRule: [String.raw`v.youku.com\/v_show\/id_\w+\=*`], idRule: String.raw`id_\w+\=*` }, bilibili: { example: "https://www.bilibili.com/video/BV1EJ411u7DN", src: "https://player.bilibili.com/player.html?bvid=BV1EJ411u7DN", srcPrefix: "https://player.bilibili.com/player.html?bvid", linkRule: [String.raw`www.bilibili.com\/video\/\w+`] }, qqvideo: { example: "https://v.qq.com/x/cover/mzc0020006aw1mn/u0033nvzb5v.html", src: "https://v.qq.com/txp/iframe/player.html?vid=u0033nvzb5v", srcPrefix: "https://v.qq.com/txp/iframe/player.html?vid", linkRule: [String.raw`v.qq.com\/x\/cover\/\w+\/\w+`] }, amap: { example: "https://ditu.amap.com/", src: "https://www.amap.com/place/B000A45467", srcPrefix: "", linkRule: [String.raw`\.amap\.com`] }, baidu_map: { example: "https://j.map.baidu.com/15/fo", src: "https://j.map.baidu.com/15/fo", srcPrefix: "", linkRule: [String.raw`map\.baidu\.com`] }, modao: { example: "https://free.modao.cc/app/2cd26580a6717a147454df7470e7ec464093cba3/embed/v2#screen=sk71k6d1dfxulzx", src: "https://free.modao.cc/app/6UkpAxcGE3nPz52GLqhnOZgC7MATBSy/embed/v2", srcPrefix: "", linkRule: [String.raw`https:\/\/\w+.modao.cc\/app\/\w+\/embed\/v2`], tips: "Modao > More > Share > Embed > COPY" }, lanhu: { example: "https://lanhuapp.com/link/#/invite?sid=evP7L", src: "https://lanhuapp.com/url/evP7L", srcPrefix: "", linkRule: [String.raw`https:\/\/lanhuapp.com\/url\/\w+`], tips: "Lanhu > Project > Share > Copy Link" }, figma: { example: "https://www.figma.com/file/aS9uSgPXoNpaPkzbjNcK8v/Demo?node-id=0%3A1", src: "https://www.figma.com/file/aS9uSgPXoNpaPkzbjNcK8v/Demo?node-id=0%3A1", srcPrefix: "https://www.figma.com/embed?embed_host=share&url", linkRule: [String.raw`https:\/\/www.figma.com\/file\/\w+`] }, canva: { example: "https://www.canva.cn/design/DAD61-t29UI/view", src: "https://www.canva.cn/design/DAD61-t29UI/view", srcPrefix: "", linkRule: [String.raw`https:\/\/www.canva.cn\/design\/.+\/view`] }, processon: { example: "https://www.processon.com/embed/5ea99d8607912948b0e6fe78", src: "https://www.processon.com/embed/5ea99d8607912948b0e6fe78", srcPrefix: "", linkRule: [String.raw`https:\/\/www.processon.com\/embed\/\w+`] }, codepen: { example: "https://codepen.io/mekery/embed/YzyrKOJ", src: "https://codepen.io/mekery/embed/YzyrKOJ", srcPrefix: "", linkRule: [String.raw`https:\/\/codepen.io\/.+\/embed\/\w+`] }, jinshuju: { example: "https://jinshuju.net/f/q9YvVf", src: "https://jinshuju.net/f/q9YvVf", srcPrefix: "", linkRule: [String.raw`https:\/\/jinshuju.net\/f\/\w+`] }, iframe: { example: "https://v.youku.com/v_show/id_XNDM0NDM4MTcy.html", src: "https://player.youku.com/embed/XNDM0NDM4MTcy", srcPrefix: "", linkRule: [".+"] }, googlemaps: { example: "https://goo.gl/maps/8Ys8b4K1ZJY2", src: "https://www.google.com/maps/embed?pb=https://goo.gl/maps/8Ys8b4K1ZJY2", srcPrefix: "", linkRule: [String.raw`https:\/\/goo.gl\/maps\/\w+`] } }; function _(e) { const t = m.youtube, i = e.matchedUrl; e.validLink = !0; const r = i.split("="), n = r.length; if (n > 0) { const c = r[n - 1]; e.src = `${t.srcPrefix}/${c}`, e.validId = !0; } return e; } function $(e) { const t = m.youku, i = e.matchedUrl, r = t.idRule, n = new RegExp(r), c = i.match(n); if (c && c.length > 0) { const o = c[0].slice(3); e.validId = !0, e.src = `${t.srcPrefix}/${o}`; } else e.validId = !1; return e; } function T(e) { const t = m.bilibili, r = e.matchedUrl.split("/"), n = r.length; if (n > 0) { const c = r[n - 1]; e.src = `${t.srcPrefix}=${c}`, e.validId = !0; } return e; } function Y(e) { const t = m.qqvideo, r = e.matchedUrl.split("/"), n = r.length; if (n > 0) { const c = r[n - 1]; e.src = `${t.srcPrefix}=${c}`, e.validId = !0; } return e; } function z(e, t) { return t.src = e, t.validId = !0, t; } function C(e, t) { return t.src = e, t.validId = !0, t; } function E(e, t) { return t.src = e, t.validId = !0, t.originalLink = e, t; } function H(e) { return e.src = e.matchedUrl, e.validId = !0, e.originalLink = e.src, e; } function B(e) { return e.src = e.matchedUrl, e.validId = !0, e.originalLink = e.src, e; } function V(e) { const t = m.figma; return e.src = `${t.srcPrefix}=${encodeURIComponent(e.matchedUrl)}`, e.validId = !0, e.originalLink = e.matchedUrl, e; } function K(e, t) { return t.src = `${t.matchedUrl}?embed`, t.validId = !0, t.originalLink = e, t; } function O(e, t) { return t.src = `${t.matchedUrl}`, t.validId = !0, t.originalLink = e, t; } function X(e) { return e.src = `${e.matchedUrl}`, e.validId = !0, e.originalLink = e.src, e; } function J(e, t) { return t.src = `${t.matchedUrl}?background=white&banner=show&embedded=true`, t.validId = !0, t.originalLink = e, t; } function W(e, t) { return t.src = `${t.matchedUrl}`, t.validId = !0, t.originalLink = e, t; } function F(e, t, i) { if (e === "googlemaps") return i.validLink = !0, i.matchedUrl = t, i; const n = m[e].linkRule; for (const c of n) { const o = new RegExp(c), a = t.match(o); if (a && a.length > 0) return i.validLink = !0, i.matchedUrl = e === "youtube" ? a[1] : a[0], i; } return i; } function G(e) { var i, r; let t = "iframe"; return ((i = e.includes) != null && i.call(e, "youtube") || (r = e.includes) != null && r.call(e, "youtu.be")) && (t = "youtube"), e.includes("youku") && (t = "youku"), e.includes("bilibili") && (t = "bilibili"), e.includes("qq") && (t = "qqvideo"), e.includes("amap") && (t = "amap"), e.includes("map.baidu") && (t = "baidu_map"), (e.includes("google.com/maps") || e.includes("maps.app.goo.gl")) && (t = "googlemaps"), e.includes("modao") && (t = "modao"), e.includes("lanhuapp") && (t = "lanhu"), e.includes("figma") && (t = "figma"), e.includes("canva") && (t = "canva"), e.includes("processon") && (t = "processon"), e.includes("codepen") && (t = "codepen"), e.includes("jinshuju") && (t = "jinshuju"), e.includes("iframe") && (t = "iframe"), t; } function Z(e) { let t = { validLink: !1, validId: !1, matchedUrl: "", originalLink: e, src: "" }; const i = G(e); if (t = F(i, e, t), !t.validLink) return t; switch (i) { case "youtube": return _(t); case "youku": return $(t); case "bilibili": return T(t); case "qqvideo": return Y(t); case "amap": return z(e, t); case "baidu_map": return C(e, t); case "googlemaps": return E(e, t); case "modao": return H(t); case "lanhu": return B(t); case "figma": return V(t); case "canva": return K(e, t); case "processon": return O(e, t); case "codepen": return X(t); case "jinshuju": return J(e, t); case "iframe": return W(e, t); default: return e; } } const Q = "_wrap_5y04w_1", ee = "_innerWrap_5y04w_15", w = { wrap: Q, innerWrap: ee }; function te({ editor: e, node: t, updateAttributes: i }) { const r = j(), { src: n, width: c, height: o } = t.attrs, [a, p] = M(""); function u() { if (!a) return; const s = Z(a); e.chain().updateAttributes(b.name, { src: (s == null ? void 0 : s.src) || a }).setNodeSelection(e.state.selection.from).focus().run(); } const g = R( (s) => { i({ width: s.width, height: s.height }); }, [i] ); return /* @__PURE__ */ f(v, { children: [ !n && /* @__PURE__ */ f("div", { className: "richtext-mx-auto richtext-my-[12px] richtext-flex richtext-max-w-[600px] richtext-items-center richtext-justify-center richtext-gap-[10px] richtext-rounded-[12px] richtext-border richtext-border-solid richtext-border-border richtext-p-[10px]", children: [ /* @__PURE__ */ d( U, { autoFocus: !0, className: "richtext-flex-1", onInput: (s) => p(s.target.value), placeholder: "Enter link", type: "url", value: a } ), /* @__PURE__ */ d( q, { className: "richtext-w-[60px]", onClick: u, children: "OK" } ) ] }), n && /* @__PURE__ */ d( N, { size: { width: Number.parseInt(c), height: Number.parseInt(o) }, onResizeStop: (s, ie, re, h) => { g({ width: Number.parseInt(c) + h.width, height: Number.parseInt(o) + h.height }); }, children: /* @__PURE__ */ d("div", { className: x(w.wrap, "render-wrapper"), children: /* @__PURE__ */ d( "div", { className: w.innerWrap, style: { pointerEvents: r ? "none" : "auto" }, children: /* @__PURE__ */ d( "iframe", { className: "richtext-my-[12px] ", src: n } ) } ) }) } ) ] }); } function pe() { const e = A(b.name), { icon: t = void 0, tooltip: i = void 0, shortcutKeys: r = void 0, tooltipOptions: n = {}, action: c = void 0, isActive: o = void 0 } = (e == null ? void 0 : e.componentProps) ?? {}, { editorDisabled: a, update: p } = L(o), u = () => { a || c && (c(), p()); }; return e ? /* @__PURE__ */ d( D, { action: u, disabled: a, icon: t, shortcutKeys: r, tooltip: i, tooltipOptions: n } ) : /* @__PURE__ */ d(P, {}); } const b = /* @__PURE__ */ k.create({ name: "iframe", content: "", marks: "", group: "block", selectable: !0, atom: !0, draggable: !0, addOptions() { var e; return { ...(e = this.parent) == null ? void 0 : e.call(this), HTMLAttributes: { class: "iframe" }, button: ({ editor: t, extension: i, t: r }) => ({ componentProps: { action: (n) => t.commands.setIframe(n), upload: i.options.upload, // isActive: () => editor.can().setIframe({}), icon: "Iframe", tooltip: r("editor.iframe.tooltip") } }) }; }, addAttributes() { return { width: { default: 600, parseHTML: l("width") }, height: { default: 300, parseHTML: l("height") }, src: { default: null, parseHTML: l("src") }, defaultShowPicker: { default: !1 }, frameborder: { default: 0 }, allowfullscreen: { default: this.options.allowFullscreen, parseHTML: () => this.options.allowFullscreen } }; }, parseHTML() { return [ { tag: "iframe" } ]; }, renderHTML({ HTMLAttributes: e }) { return ["iframe", I(this.options.HTMLAttributes, e)]; }, addCommands() { return { setIframe: (e) => ({ tr: t, commands: i, chain: r }) => { var c, o, a; if (((a = (o = (c = t.selection) == null ? void 0 : c.node) == null ? void 0 : o.type) == null ? void 0 : a.name) == this.name) return i.updateAttributes(this.name, e); const n = e || { url: "" }; return r().insertContent({ type: this.name, attrs: n }).run(); } }; }, addInputRules() { return [ S({ find: /^\$iframe\$$/, type: this.type, getAttributes: () => ({ width: "100%" }) }) ]; }, addNodeView() { return y(te); } }); export { b as I, pe as R, Z as g };