@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
JavaScript
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