Skip to content

Commit

Permalink
fix: toggle heading only when same level (#125)
Browse files Browse the repository at this point in the history
fixes: #105
  • Loading branch information
dancormier committed May 12, 2022
1 parent 16cfde3 commit 7b5b5c1
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/rich-text/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,16 @@ function toggleWrapIn(nodeType: NodeType) {
/** Command to set a block type to a paragraph (plain text) */
const setToTextCommand = setBlockType(schema.nodes.paragraph);

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

return (state: EditorState, dispatch: (tr: Transaction) => void) => {
Expand Down
92 changes: 92 additions & 0 deletions test/rich-text/commands/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { EditorState, Transaction } from "prosemirror-state";
import {
exitInclusiveMarkCommand,
insertHorizontalRuleCommand,
toggleBlockType,
} from "../../../src/rich-text/commands";
import { richTextSchema } from "../../../src/rich-text/schema";
import { applySelection, createState } from "../test-helpers";
Expand Down Expand Up @@ -41,6 +42,97 @@ describe("commands", () => {
describe("toggleBlockType", () => {
it.todo("should insert a paragraph at the end of the doc");
it.todo("should not insert a paragraph at the end of the doc");

it("should toggle a type off when attributes match", () => {
const state = applySelection(
createState("<h1>heading</h1>", []),
3
);
const resolvedNode = state.selection.$from;
expect(resolvedNode.node().type.name).toBe("heading");

const { newState, isValid } = executeTransaction(
state,
toggleBlockType(richTextSchema.nodes.heading, { level: 1 })
);

expect(isValid).toBeTruthy();
expect(newState.doc).toMatchNodeTree({
"type.name": "doc",
"content": [
{
"type.name": "paragraph",
"childCount": 1,
},
],
});
});

it("should should toggle a type on and set attributes when the NodeType doesn't match", () => {
const state = applySelection(
createState("<p>paragraph</p>", []),
3
);
const resolvedNode = state.selection.$from;
expect(resolvedNode.node().type.name).toBe("paragraph");

const { newState, isValid } = executeTransaction(
state,
toggleBlockType(richTextSchema.nodes.heading, { level: 1 })
);

expect(isValid).toBeTruthy();
expect(newState.doc).toMatchNodeTree({
"type.name": "doc",
"content": [
{
"type.name": "heading",
"attrs": {
level: 1,
markup: "",
},
"childCount": 1,
},
{
"type.name": "paragraph",
"childCount": 0,
},
],
});
});

it("should should toggle a type on and set attributes when the NodeType matches", () => {
const state = applySelection(
createState("<h1>heading</h1>", []),
3
);
const resolvedNode = state.selection.$from;
expect(resolvedNode.node().type.name).toBe("heading");

const { newState, isValid } = executeTransaction(
state,
toggleBlockType(richTextSchema.nodes.heading, { level: 2 })
);

expect(isValid).toBeTruthy();
expect(newState.doc).toMatchNodeTree({
"type.name": "doc",
"content": [
{
"type.name": "heading",
"attrs": {
level: 2,
markup: "",
},
"childCount": 1,
},
{
"type.name": "paragraph",
"childCount": 0,
},
],
});
});
});

describe("insertHorizontalRuleCommand", () => {
Expand Down

0 comments on commit 7b5b5c1

Please sign in to comment.