Do not display editor block placeholder when disabled
Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -3,49 +3,91 @@
|
|||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
import { Extension } from "@tiptap/core";
|
import { Extension } from "@tiptap/core";
|
||||||
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
import { type EditorState, Plugin, PluginKey } from "@tiptap/pm/state";
|
||||||
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
import { Decoration, DecorationSet, type EditorView } from "@tiptap/pm/view";
|
||||||
|
|
||||||
const placeholderKey = new PluginKey("placeholder");
|
const placeholderKey = new PluginKey("placeholder");
|
||||||
|
|
||||||
|
function computeDecorations(
|
||||||
|
state: EditorState,
|
||||||
|
editable: boolean,
|
||||||
|
): DecorationSet {
|
||||||
|
if (!editable) return DecorationSet.empty;
|
||||||
|
|
||||||
|
const { selection } = state;
|
||||||
|
if (!selection.empty) return DecorationSet.empty;
|
||||||
|
|
||||||
|
const $pos = selection.$from;
|
||||||
|
const node = $pos.parent;
|
||||||
|
|
||||||
|
if (node.type.name !== "paragraph") return DecorationSet.empty;
|
||||||
|
if (node.content.size !== 0) return DecorationSet.empty;
|
||||||
|
|
||||||
|
if ($pos.depth >= 2) {
|
||||||
|
const parentName = $pos.node($pos.depth - 1).type.name;
|
||||||
|
if (
|
||||||
|
parentName === "listItem"
|
||||||
|
|| parentName === "tableCell"
|
||||||
|
|| parentName === "tableHeader"
|
||||||
|
) {
|
||||||
|
return DecorationSet.empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pos = $pos.before($pos.depth);
|
||||||
|
|
||||||
|
return DecorationSet.create(state.doc, [
|
||||||
|
Decoration.node(pos, pos + node.nodeSize, {
|
||||||
|
"class": "is-empty-focused",
|
||||||
|
"data-placeholder": "Write or type / for commands\u2026",
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
export const PlaceholderExtension = Extension.create({
|
export const PlaceholderExtension = Extension.create({
|
||||||
name: "placeholder",
|
name: "placeholder",
|
||||||
|
|
||||||
addProseMirrorPlugins() {
|
addProseMirrorPlugins() {
|
||||||
|
const { editor } = this;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new Plugin({
|
new Plugin({
|
||||||
key: placeholderKey,
|
key: placeholderKey,
|
||||||
|
|
||||||
|
view() {
|
||||||
|
let lastEditable = editor.isEditable;
|
||||||
|
return {
|
||||||
|
update(view: EditorView) {
|
||||||
|
const editable = editor.isEditable;
|
||||||
|
if (editable !== lastEditable) {
|
||||||
|
lastEditable = editable;
|
||||||
|
view.dispatch(
|
||||||
|
view.state.tr.setMeta(placeholderKey, true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
state: {
|
||||||
|
init(_config, state) {
|
||||||
|
return computeDecorations(state, editor.isEditable);
|
||||||
|
},
|
||||||
|
apply(tr, value, _oldState, newState) {
|
||||||
|
if (
|
||||||
|
!tr.docChanged
|
||||||
|
&& !tr.selectionSet
|
||||||
|
&& !tr.getMeta(placeholderKey)
|
||||||
|
) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return computeDecorations(newState, editor.isEditable);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
decorations(state) {
|
decorations(state) {
|
||||||
const { selection } = state;
|
return placeholderKey.getState(state) as DecorationSet;
|
||||||
if (!selection.empty) return DecorationSet.empty;
|
|
||||||
|
|
||||||
const $pos = selection.$from;
|
|
||||||
const node = $pos.parent;
|
|
||||||
|
|
||||||
if (node.type.name !== "paragraph") return DecorationSet.empty;
|
|
||||||
if (node.content.size !== 0) return DecorationSet.empty;
|
|
||||||
|
|
||||||
if ($pos.depth >= 2) {
|
|
||||||
const parentName = $pos.node($pos.depth - 1).type.name;
|
|
||||||
if (
|
|
||||||
parentName === "listItem"
|
|
||||||
|| parentName === "tableCell"
|
|
||||||
|| parentName === "tableHeader"
|
|
||||||
) {
|
|
||||||
return DecorationSet.empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const pos = $pos.before($pos.depth);
|
|
||||||
|
|
||||||
return DecorationSet.create(state.doc, [
|
|
||||||
Decoration.node(pos, pos + node.nodeSize, {
|
|
||||||
"class": "is-empty-focused",
|
|
||||||
"data-placeholder": "Write or type / for commands\u2026",
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user