Skip to content

Commit 7b5b5c1

Browse files
authored
fix: toggle heading only when same level (#125)
fixes: #105
1 parent 16cfde3 commit 7b5b5c1

File tree

2 files changed

+99
-2
lines changed

2 files changed

+99
-2
lines changed

src/rich-text/commands/index.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,16 @@ function toggleWrapIn(nodeType: NodeType) {
7373
/** Command to set a block type to a paragraph (plain text) */
7474
const setToTextCommand = setBlockType(schema.nodes.paragraph);
7575

76-
function toggleBlockType(
76+
/**
77+
* Creates a command that toggles the NodeType of the current node to the passed type
78+
* @param nodeType The type to toggle to
79+
* @param attrs? A key-value map of attributes that must be present on this node for it to be toggled off
80+
*/
81+
export function toggleBlockType(
7782
nodeType: NodeType,
7883
attrs?: { [key: string]: unknown }
7984
) {
80-
const nodeCheck = nodeTypeActive(nodeType);
85+
const nodeCheck = nodeTypeActive(nodeType, attrs);
8186
const setBlockTypeCommand = setBlockType(nodeType, attrs);
8287

8388
return (state: EditorState, dispatch: (tr: Transaction) => void) => {

test/rich-text/commands/index.test.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { EditorState, Transaction } from "prosemirror-state";
22
import {
33
exitInclusiveMarkCommand,
44
insertHorizontalRuleCommand,
5+
toggleBlockType,
56
} from "../../../src/rich-text/commands";
67
import { richTextSchema } from "../../../src/rich-text/schema";
78
import { applySelection, createState } from "../test-helpers";
@@ -41,6 +42,97 @@ describe("commands", () => {
4142
describe("toggleBlockType", () => {
4243
it.todo("should insert a paragraph at the end of the doc");
4344
it.todo("should not insert a paragraph at the end of the doc");
45+
46+
it("should toggle a type off when attributes match", () => {
47+
const state = applySelection(
48+
createState("<h1>heading</h1>", []),
49+
3
50+
);
51+
const resolvedNode = state.selection.$from;
52+
expect(resolvedNode.node().type.name).toBe("heading");
53+
54+
const { newState, isValid } = executeTransaction(
55+
state,
56+
toggleBlockType(richTextSchema.nodes.heading, { level: 1 })
57+
);
58+
59+
expect(isValid).toBeTruthy();
60+
expect(newState.doc).toMatchNodeTree({
61+
"type.name": "doc",
62+
"content": [
63+
{
64+
"type.name": "paragraph",
65+
"childCount": 1,
66+
},
67+
],
68+
});
69+
});
70+
71+
it("should should toggle a type on and set attributes when the NodeType doesn't match", () => {
72+
const state = applySelection(
73+
createState("<p>paragraph</p>", []),
74+
3
75+
);
76+
const resolvedNode = state.selection.$from;
77+
expect(resolvedNode.node().type.name).toBe("paragraph");
78+
79+
const { newState, isValid } = executeTransaction(
80+
state,
81+
toggleBlockType(richTextSchema.nodes.heading, { level: 1 })
82+
);
83+
84+
expect(isValid).toBeTruthy();
85+
expect(newState.doc).toMatchNodeTree({
86+
"type.name": "doc",
87+
"content": [
88+
{
89+
"type.name": "heading",
90+
"attrs": {
91+
level: 1,
92+
markup: "",
93+
},
94+
"childCount": 1,
95+
},
96+
{
97+
"type.name": "paragraph",
98+
"childCount": 0,
99+
},
100+
],
101+
});
102+
});
103+
104+
it("should should toggle a type on and set attributes when the NodeType matches", () => {
105+
const state = applySelection(
106+
createState("<h1>heading</h1>", []),
107+
3
108+
);
109+
const resolvedNode = state.selection.$from;
110+
expect(resolvedNode.node().type.name).toBe("heading");
111+
112+
const { newState, isValid } = executeTransaction(
113+
state,
114+
toggleBlockType(richTextSchema.nodes.heading, { level: 2 })
115+
);
116+
117+
expect(isValid).toBeTruthy();
118+
expect(newState.doc).toMatchNodeTree({
119+
"type.name": "doc",
120+
"content": [
121+
{
122+
"type.name": "heading",
123+
"attrs": {
124+
level: 2,
125+
markup: "",
126+
},
127+
"childCount": 1,
128+
},
129+
{
130+
"type.name": "paragraph",
131+
"childCount": 0,
132+
},
133+
],
134+
});
135+
});
44136
});
45137

46138
describe("insertHorizontalRuleCommand", () => {

0 commit comments

Comments
 (0)