UNPKG

@blocknote/react

Version:

A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.

290 lines (289 loc) 8.93 kB
import { createContext as e, useCallback as t, useContext as n, useDebugValue as r, useEffect as i, useLayoutEffect as a, useMemo as o, useRef as s, useState as c } from "react"; import { FloatingFocusManager as l, FloatingPortal as u, autoUpdate as d, useDismiss as f, useFloating as p, useHover as m, useInteractions as h, useMergeRefs as g, useTransitionStatus as _, useTransitionStyles as v } from "@floating-ui/react"; import { useSyncExternalStoreWithSelector as y } from "use-sync-external-store/shim/with-selector"; import { BlockNoteEditor as b, BlockNoteSchema as x, createParagraphBlockSpec as S, defaultStyleSpecs as C } from "@blocknote/core"; import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime"; import D from "fast-deep-equal/es6/react.js"; import { posToDOMRect as O } from "@tiptap/core"; //#region src/editor/BlockNoteContext.ts var k = e(void 0); function A(e) { return n(k); } //#endregion //#region src/hooks/useBlockNoteEditor.ts function j(e) { let t = A(e); if (!t?.editor) throw Error("useBlockNoteEditor was called outside of a BlockNoteContext provider or BlockNoteView component"); return t.editor; } //#endregion //#region src/hooks/useStore.ts function M(e, t = (e) => e) { return y(e.subscribe, () => e.state, () => e.state, t, N); } function N(e, t) { if (Object.is(e, t)) return !0; if (typeof e != "object" || !e || typeof t != "object" || !t) return !1; if (e instanceof Map && t instanceof Map) { if (e.size !== t.size) return !1; for (let [n, r] of e) if (!t.has(n) || !Object.is(r, t.get(n))) return !1; return !0; } if (e instanceof Set && t instanceof Set) { if (e.size !== t.size) return !1; for (let n of e) if (!t.has(n)) return !1; return !0; } if (e instanceof Date && t instanceof Date) return e.getTime() === t.getTime(); let n = P(e); return n.length === P(t).length && n.every((n) => Object.prototype.hasOwnProperty.call(t, n) && Object.is(e[n], t[n])); } function P(e) { return Object.keys(e).concat(Object.getOwnPropertySymbols(e)); } //#endregion //#region src/hooks/useExtension.ts function F(e, t) { let n = (t?.editor ?? j()).getExtension(e); if (!n) throw Error("Extension not found", { cause: { plugin: e } }); return n; } function I(e, t) { let { store: n } = F(e, t); if (!n) throw Error("Store not found on plugin", { cause: { plugin: e } }); return M(n, t?.selector); } //#endregion //#region src/components/Popovers/GenericPopover.tsx function L(e) { let t = new DOMRect(), n = "getBoundingClientRect" in e ? () => e.getBoundingClientRect() : () => e.element.getBoundingClientRect(); return () => e.element && (e.cacheMountedBoundingClientRect ?? !0) ? (e.element.isConnected && (t = n()), t) : n(); } function R(e, t) { return e ? t ? (n, r, i) => { let a = e(n, r, i), o = t(n, r, i); return () => { a?.(), o?.(); }; } : e : t; } var z = (e) => { let t = j(), n = e.portalElement === null ? typeof document < "u" ? document.body : void 0 : e.portalElement ?? t?.portalElement; if (!n) throw Error("Portal element not found"); let { whileElementsMounted: r, ...a } = e.useFloatingOptions ?? {}, { refs: o, floatingStyles: c, context: y } = p({ whileElementsMounted: R(d, e.useFloatingOptions?.whileElementsMounted), ...a }), { isMounted: b, styles: x } = v(y, e.useTransitionStylesProps), { status: S } = _(y, e.useTransitionStatusProps), C = f(y, e.useDismissProps), w = m(y, { enabled: !1, ...e.useHoverProps }), { getFloatingProps: E } = h([C, w]), D = s(""), O = s(null), k = g([O, o.setFloating]); if (i(() => { if (e.reference) { let n = "element" in e.reference ? e.reference.element : void 0; n !== void 0 && (e.focusManagerProps?.disabled || !t.isWithinEditor(n)) && o.setReference(n); let r = "getClientRects" in e.reference ? e.reference.getClientRects : void 0; o.setPositionReference({ getBoundingClientRect: L(e.reference), ...r ? { getClientRects: r } : {}, contextElement: n }); } }, [ e.reference, o, e.focusManagerProps?.disabled, t ]), i(() => { (S === "initial" || S === "open") && O.current?.innerHTML && (D.current = O.current.innerHTML); }, [ S, e.reference, e.children ]), !b) return !1; let A = { ...e.elementProps, style: { display: "flex", ...e.elementProps?.style, zIndex: `calc(var(--bn-ui-base-z-index, 0) + ${e.elementProps?.style?.zIndex || 0})`, ...c, ...x }, ...E() }; return S === "close" ? /* @__PURE__ */ T(u, { root: n, children: /* @__PURE__ */ T("div", { ref: k, ...A, dangerouslySetInnerHTML: { __html: D.current } }) }) : e.focusManagerProps?.disabled ? /* @__PURE__ */ T(u, { root: n, children: /* @__PURE__ */ T("div", { ref: k, ...A, children: e.children }) }) : /* @__PURE__ */ T(u, { root: n, children: /* @__PURE__ */ T(l, { ...e.focusManagerProps, context: y, children: /* @__PURE__ */ T("div", { ref: k, ...A, children: e.children }) }) }); }, B = e(void 0); function V() { return n(B); } //#endregion //#region src/i18n/dictionary.ts function H() { return A().editor.dictionary; } //#endregion //#region src/hooks/useEditorState.ts var U = typeof window < "u" ? a : i, W = class { transactionNumber = 0; lastTransactionNumber = 0; lastSnapshot; editor; subscribers = /* @__PURE__ */ new Set(); constructor(e) { this.editor = e, this.lastSnapshot = { editor: e, transactionNumber: 0 }, this.getSnapshot = this.getSnapshot.bind(this), this.getServerSnapshot = this.getServerSnapshot.bind(this), this.watch = this.watch.bind(this), this.subscribe = this.subscribe.bind(this); } getSnapshot() { return this.transactionNumber === this.lastTransactionNumber ? this.lastSnapshot : (this.lastTransactionNumber = this.transactionNumber, this.lastSnapshot = { editor: this.editor, transactionNumber: this.transactionNumber }, this.lastSnapshot); } getServerSnapshot() { return { editor: null, transactionNumber: 0 }; } subscribe(e) { return this.subscribers.add(e), () => { this.subscribers.delete(e); }; } watch(e, t) { if (this.editor = e, this.editor) { let e = () => { this.transactionNumber += 1, this.subscribers.forEach((e) => e()); }, n = this.editor._tiptapEditor, r = { all: [ "transaction", "create", "mount", "unmount" ], mount: [ "create", "mount", "unmount" ], selection: ["selectionUpdate"], change: ["update"] }; for (let i of r[t]) n.on(i, e); return () => { for (let i of r[t]) n.off(i, e); }; } } }; function G(e) { let t = A(), n = e.editor || t?.editor || null, i = e.on || "all", [a] = c(() => new W(n)), o = y(a.subscribe, a.getSnapshot, a.getServerSnapshot, e.selector, e.equalityFn ?? D); return U(() => a.watch(n, i), [ n, a, i ]), r(o), o; } //#endregion //#region src/hooks/useEditorDomElement.ts function K(e) { let t = A(); return e ||= t?.editor, G({ editor: e, selector: (e) => e.editor?.domElement, equalityFn: (e, t) => e === t, on: "mount" }); } //#endregion //#region src/components/Popovers/PositionPopover.tsx var q = (e) => { let { position: t, children: n, portalElement: r, ...i } = e, { from: a, to: s } = t || {}, c = j(), l = K(), u = o(() => { if (a !== void 0 && s !== void 0) return { element: l?.firstElementChild || void 0, getBoundingClientRect: () => O(c.prosemirrorView, a, s ?? a) }; }, [ c, l, a, s ]); return /* @__PURE__ */ T(z, { reference: u, portalElement: r, ...i, children: t !== void 0 && n }); }, J = (e = {}, t = []) => o(() => { let t = b.create(e); return window && (window.ProseMirror = t._tiptapEditor), t; }, t), Y = (e) => { let [n, r] = c(!1), a = G({ editor: e.editor, selector: ({ editor: e }) => e.isEmpty }), o = V(), s = t(() => { r(!0); }, []), l = t(() => { r(!1); }, []); return i(() => { e.editable && e.autoFocus && e.editor.focus(); }, [ e.autoFocus, e.editable, e.editor ]), /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ T(o.Comments.Editor, { autoFocus: e.autoFocus, className: "bn-comment-editor", editor: e.editor, onFocus: s, onBlur: l, editable: e.editable }), e.actions && /* @__PURE__ */ T("div", { className: "bn-comment-actions-wrapper", children: e.actions({ isFocused: n, isEmpty: a }) })] }); }, { textColor: X, backgroundColor: ee, ...Z } = C, Q = x.create({ blockSpecs: { paragraph: S() }, styleSpecs: Z }); //#endregion //#region src/components/Comments/confirmDiscardUnsavedComment.ts function $(e) { return !e.hasUnsavedContent || !e.confirmBeforeDiscard || (e.confirm ?? ((e) => window.confirm(e)))(e.message); } //#endregion export { j as _, q as a, H as c, z as d, L as f, M as g, N as h, J as i, B as l, I as m, Q as n, K as o, F as p, Y as r, G as s, $ as t, V as u, k as v, A as y }; //# sourceMappingURL=confirmDiscardUnsavedComment-D1Q3ha7c.js.map