@blocknote/react
Version:
A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.
363 lines (362 loc) • 11 kB
JavaScript
import { createContext as e, useCallback as t, useContext as n, useDebugValue as r, useEffect as i, useInsertionEffect as a, useLayoutEffect as o, useMemo as s, useRef as c, useState as l } from "react";
import { FloatingFocusManager as ee, FloatingPortal as u, autoUpdate as te, hide as d, useDismiss as f, useFloating as p, useHover as m, useInteractions as h, useMergeRefs as g, useTransitionStatus as ne, useTransitionStyles as _ } from "@floating-ui/react";
import { useSyncExternalStoreWithSelector as v } from "use-sync-external-store/shim/with-selector";
import y from "fast-deep-equal/es6/react.js";
import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
import { BlockNoteEditor as C, BlockNoteSchema as w, createParagraphBlockSpec as T, defaultStyleSpecs as E } from "@blocknote/core";
import { posToDOMRect as D } from "@tiptap/core";
//#region src/editor/BlockNoteContext.ts
var O = e(void 0);
function k(e) {
return n(O);
}
//#endregion
//#region src/hooks/useBlockNoteEditor.ts
function A(e) {
let t = k(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 j(e, t = (e) => e) {
return v(e.subscribe, () => e.state, () => e.state, t, M);
}
function M(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 = N(e);
return n.length === N(t).length && n.every((n) => Object.prototype.hasOwnProperty.call(t, n) && Object.is(e[n], t[n]));
}
function N(e) {
return Object.keys(e).concat(Object.getOwnPropertySymbols(e));
}
//#endregion
//#region src/hooks/useExtension.ts
function P(e, t) {
let n = (t?.editor ?? A()).getExtension(e);
if (!n) throw Error("Extension not found", { cause: { plugin: e } });
return n;
}
function F(e, t) {
let { store: n } = P(e, t);
if (!n) throw Error("Store not found on plugin", { cause: { plugin: e } });
return j(n, t?.selector);
}
//#endregion
//#region src/util/useIsomorphicLayoutEffect.ts
var I = typeof window < "u" ? o : i, re = 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 L(e) {
let t = k(), n = e.editor || t?.editor || null, i = e.on || "all", [a] = l(() => new re(n)), o = v(a.subscribe, a.getSnapshot, a.getServerSnapshot, e.selector, e.equalityFn ?? y);
return I(() => a.watch(n, i), [
n,
a,
i
]), r(o), o;
}
//#endregion
//#region src/hooks/useEditorDomElement.ts
function R(e) {
let t = k();
if (e ||= t?.editor, !e) throw Error("'editor' is required in `useEditorDOMElement`, either from BlockNoteContext or as a function argument");
return L({
editor: e,
selector: (e) => e.editor.domElement,
equalityFn: (e, t) => e === t,
on: "mount"
});
}
//#endregion
//#region src/editor/BlockNoteViewContext.ts
var z = e(void 0);
function B() {
return n(z);
}
//#endregion
//#region src/editor/PortalElementOverride.tsx
var V = typeof window < "u" ? a : i, H = e(null);
function U() {
let e = n(H), t = R();
return e || (t?.parentElement ?? null);
}
function W(e) {
return /* @__PURE__ */ x(H.Provider, {
value: null,
children: e.children
});
}
function G(e) {
let { target: t, children: n } = e, r = A(), i = B()?.applyThemedRoot, [a] = l(() => typeof document > "u" ? null : document.createElement("div"));
return V(() => {
if (!(!a || !t)) return t.appendChild(a), () => a.remove();
}, [a, t]), V(() => {
!a || !t || i?.(a);
}, [
a,
t,
i
]), V(() => {
if (!(!a || !t)) return r.registerPortalElement(a), () => r.unregisterPortalElement(a);
}, [
r,
a,
t
]), t === void 0 ? n : /* @__PURE__ */ x(H.Provider, {
value: a,
children: n
});
}
function K() {
let [e] = l(() => {
if (typeof document > "u") return null;
let e = document.createElement("span");
return e.className = "bn-portal-anchor", e;
}), n = t((t) => {
t && e && e.parentElement !== t && t.appendChild(e);
}, [e]);
return {
anchor: e,
holder: /* @__PURE__ */ x("span", {
ref: n,
className: q,
style: {
position: "absolute",
width: 0,
height: 0,
overflow: "visible"
}
})
};
}
var q = "bn-portal-anchor-holder";
function J(e) {
return Array.from(e.childNodes).some((e) => !(e instanceof Element && e.classList.contains(q)));
}
function Y(e) {
let { anchor: t, holder: n } = K(), r = U(), i = t ?? r, a = typeof e.children == "function" ? e.children(i) : e.children;
return /* @__PURE__ */ S(b, { children: [n, /* @__PURE__ */ x(H.Provider, {
value: i,
children: a
})] });
}
//#endregion
//#region src/components/Popovers/GenericPopover.tsx
function X(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 ie(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 = A(), n = U(), { whileElementsMounted: r, middleware: a, ...o } = e.useFloatingOptions ?? {}, { refs: s, floatingStyles: l, context: v, middlewareData: y } = p({
whileElementsMounted: ie(te, e.useFloatingOptions?.whileElementsMounted),
middleware: [...a ?? [], d()],
...o
}), { isMounted: b, styles: S } = _(v, e.useTransitionStylesProps), { status: C } = ne(v, e.useTransitionStatusProps), w = f(v, e.useDismissProps), T = m(v, {
enabled: !1,
...e.useHoverProps
}), { getFloatingProps: E } = h([w, T]), D = c(""), O = c(null), k = g([O, s.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)) && s.setReference(n);
let r = "getClientRects" in e.reference ? e.reference.getClientRects : void 0;
s.setPositionReference({
getBoundingClientRect: X(e.reference),
...r ? { getClientRects: r } : {},
contextElement: n
});
}
}, [
e.reference,
s,
e.focusManagerProps?.disabled,
t
]), i(() => {
(C === "initial" || C === "open") && O.current && J(O.current) && (D.current = O.current.innerHTML);
}, [
C,
e.reference,
e.children
]), !b || !n) return !1;
let j = {
...e.elementProps,
style: {
display: "flex",
...e.elementProps?.style,
zIndex: `calc(var(--bn-ui-base-z-index, 0) + ${e.elementProps?.style?.zIndex || 0})`,
...l,
...S,
...y.hide?.referenceHidden ? { visibility: "hidden" } : {}
},
...E()
};
return C === "close" ? /* @__PURE__ */ x(u, {
root: n,
children: /* @__PURE__ */ x("div", {
ref: k,
...j,
dangerouslySetInnerHTML: { __html: D.current }
})
}) : e.focusManagerProps?.disabled ? /* @__PURE__ */ x(u, {
root: n,
children: /* @__PURE__ */ x("div", {
ref: k,
...j,
children: /* @__PURE__ */ x(Y, { children: e.children })
})
}) : /* @__PURE__ */ x(u, {
root: n,
children: /* @__PURE__ */ x(ee, {
...e.focusManagerProps,
context: v,
children: /* @__PURE__ */ x("div", {
ref: k,
...j,
children: /* @__PURE__ */ x(Y, { children: e.children })
})
})
});
}, Q = e(void 0);
function $() {
return n(Q);
}
//#endregion
//#region src/i18n/dictionary.ts
function ae() {
return k().editor.dictionary;
}
//#endregion
//#region src/components/Popovers/PositionPopover.tsx
var oe = (e) => {
let { position: t, children: n, ...r } = e, { from: i, to: a } = t || {}, o = A(), c = R(), l = s(() => {
if (i !== void 0 && a !== void 0) return {
element: c?.firstElementChild || void 0,
getBoundingClientRect: () => D(o.prosemirrorView, i, a ?? i)
};
}, [
o,
c,
i,
a
]);
return /* @__PURE__ */ x(Z, {
reference: l,
...r,
children: t !== void 0 && n
});
}, se = (e = {}, t = []) => s(() => {
let t = C.create(e);
return window && (window.ProseMirror = t._tiptapEditor), t;
}, t), ce = (e) => {
let [n, r] = l(!1), a = L({
editor: e.editor,
selector: ({ editor: e }) => e.isEmpty
}), o = $(), s = t(() => {
r(!0);
}, []), c = t(() => {
r(!1);
}, []);
return i(() => {
e.editable && e.autoFocus && e.editor.focus();
}, [
e.autoFocus,
e.editable,
e.editor
]), /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(o.Comments.Editor, {
autoFocus: e.autoFocus,
className: "bn-comment-editor",
editor: e.editor,
onFocus: s,
onBlur: c,
editable: e.editable
}), e.actions && /* @__PURE__ */ x("div", {
className: "bn-comment-actions-wrapper",
children: e.actions({
isFocused: n,
isEmpty: a
})
})] });
}, { textColor: le, backgroundColor: ue, ...de } = E, fe = w.create({
blockSpecs: { paragraph: T() },
styleSpecs: de
});
//#endregion
//#region src/components/Comments/confirmDiscardUnsavedComment.ts
function pe(e) {
return !e.hasUnsavedContent || !e.confirmBeforeDiscard || (e.confirm ?? ((e) => window.confirm(e)))(e.message);
}
//#endregion
export { j as C, k as E, M as S, O as T, R as _, oe as a, P as b, $ as c, Y as d, G as f, B as g, z as h, se as i, Z as l, U as m, fe as n, ae as o, W as p, ce as r, Q as s, pe as t, X as u, L as v, A as w, F as x, I as y };
//# sourceMappingURL=confirmDiscardUnsavedComment-BLTco3jJ.js.map