Skip to content

Commit

Permalink
Menu demo (#81)
Browse files Browse the repository at this point in the history
Co-authored-by: jrapala <[email protected]>
  • Loading branch information
coolov and jrapala authored Jan 30, 2024
1 parent 0d351ae commit 5456570
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 2 deletions.
73 changes: 73 additions & 0 deletions demo/Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { toggleMark } from "prosemirror-commands";
import type { MarkType } from "prosemirror-model";
import type { EditorState } from "prosemirror-state";
import React, { ReactNode } from "react";

import { useEditorEventCallback, useEditorState } from "../src/index.js";

// lifted from:
// https://github.com/ProseMirror/prosemirror-example-setup/blob/master/src/menu.ts#L58
function isMarkActive(mark: MarkType, state: EditorState): boolean {
const { from, $from, to, empty } = state.selection;
return empty
? !!mark.isInSet(state.storedMarks || $from.marks())
: state.doc.rangeHasMark(from, to, mark);
}

export function Button(props: {
className?: string;
children?: ReactNode;
isActive: boolean;
title: string;
onClick: () => void;
}) {
return (
<button
type="button"
title={props.title}
aria-pressed={props.isActive}
className={`button ${props.className}`}
onClick={props.onClick}
>
<span className="visually-hidden">{props.title}</span>
<span aria-hidden>{props.children}</span>
</button>
);
}

export default function Menu() {
const state = useEditorState();

const toggleBold = useEditorEventCallback((view) => {
if (!view) return;
const toggleBoldMark = toggleMark(view.state.schema.marks["strong"]);
toggleBoldMark(view.state, view.dispatch, view);
});

const toggleItalic = useEditorEventCallback((view) => {
if (!view) return;
const toggleItalicMark = toggleMark(view.state.schema.marks["em"]);
toggleItalicMark(view.state, view.dispatch, view);
});

return (
<div className="menu">
<Button
className="bold"
title="Bold (⌘b)"
isActive={!!state && isMarkActive(state.schema.marks["strong"], state)}
onClick={toggleBold}
>
B
</Button>
<Button
className="italic"
title="Italic (⌘i)"
isActive={!!state && isMarkActive(state.schema.marks["em"], state)}
onClick={toggleItalic}
>
I
</Button>
</div>
);
}
45 changes: 44 additions & 1 deletion demo/main.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.ProseMirror {
border: thin solid black;
border: thin solid #ccc;
border-radius: 0.25rem;
padding: 1rem;
outline: none;
Expand All @@ -11,3 +11,46 @@ main {
width: 80%;
max-width: 700px;
}

.menu {
display: flex;
margin-bottom: 5px;
}

.button {
cursor: pointer;
width: 36px;
height: 36px;
margin-right: 5px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: none;
border: thin solid #ccc;
border-radius: 0.25rem;
color: black;
background-color: white;

&[aria-pressed="true"] {
background-color: #ddd;
color: blue;
}
}

.button.bold {
font-weight: 700;
}

.button.italic {
font-style: italic;
}

.visually-hidden {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
20 changes: 19 additions & 1 deletion demo/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
liftEmptyBlock,
newlineInCode,
splitBlock,
toggleMark,
} from "prosemirror-commands";
import { keymap } from "prosemirror-keymap";
import { Schema } from "prosemirror-model";
Expand All @@ -22,6 +23,7 @@ import {
import { ReactNodeViewConstructor } from "../src/nodeViews/createReactNodeViewConstructor.js";
import { react } from "../src/plugins/react.js";

import Menu from "./Menu.js";
import "./main.css";

const schema = new Schema({
Expand All @@ -32,6 +34,20 @@ const schema = new Schema({
list_item: { content: "paragraph+", toDOM: () => ["li", 0] },
text: { group: "inline" },
},
marks: {
em: {
parseDOM: [{ tag: "em" }],
toDOM() {
return ["em", 0];
},
},
strong: {
parseDOM: [{ tag: "strong" }],
toDOM() {
return ["strong", 0];
},
},
},
});

const editorState = EditorState.create({
Expand All @@ -54,6 +70,8 @@ const editorState = EditorState.create({
),
"Shift-Enter": baseKeymap.Enter,
"Shift-Tab": liftListItem(schema.nodes.list_item),
"Mod-b": toggleMark(schema.marks["strong"]),
"Mod-i": toggleMark(schema.marks["em"]),
}),
react(),
],
Expand Down Expand Up @@ -101,13 +119,13 @@ function DemoEditor() {

return (
<main>
<h1>React ProseMirror Demo</h1>
<ProseMirror
mount={mount}
state={state}
nodeViews={nodeViews}
dispatchTransaction={dispatchTransaction}
>
<Menu />
<div ref={setMount} />
{renderNodeViews()}
</ProseMirror>
Expand Down

0 comments on commit 5456570

Please sign in to comment.