Javascript, HTMLStory
My First Blog
Mar 29, 20262 min read0 views00

HEllo frinds
Event handlers
Any prop that starts with on (e.g., onClick) is considered an event handler.
When merging event handlers, Slot will create a new function where the child handler takes precedence over the slot handler.
If one of the event handlers relies on event.defaultPrevented make sure that the order is correct.
import type { Editor } from '@tiptap/core'
import { useEditorState } from '@tiptap/react'
import React from 'react'
import { menuBarStateSelector } from './menuBarState.js'
export const MenuBar = ({ editor }: { editor: Editor | null }) => {
const editorState = useEditorState({
editor,
selector: menuBarStateSelector,
})
if (!editor) {
return null
}
return (
<div className="control-group">
<div className="button-group">
<button
onClick={() => editor.chain().focus().toggleBold().run()}
disabled={!editorState.canBold}
className={editorState.isBold ? 'is-active' : ''}
>
Bold
</button>
<button
onClick={() => editor.chain().focus().toggleItalic().run()}
disabled={!editorState.canItalic}
className={editorState.isItalic ? 'is-active' : ''}
>
Italic
</button>
<button
onClick={() => editor.chain().focus().toggleStrike().run()}
disabled={!editorState.canStrike}
className={editorState.isStrike ? 'is-active' : ''}
>
Strike
</button>
<button
onClick={() => editor.chain().focus().toggleCode().run()}
disabled={!editorState.canCode}
className={editorState.isCode ? 'is-active' : ''}
>
Code
</button>
<button onClick={() => editor.chain().focus().unsetAllMarks().run()}>Clear marks</button>
<button onClick={() => editor.chain().focus().clearNodes().run()}>Clear nodes</button>
<button
onClick={() => editor.chain().focus().setParagraph().run()}
className={editorState.isParagraph ? 'is-active' : ''}
>
Paragraph
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
className={editorState.isHeading1 ? 'is-active' : ''}
>
H1
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
className={editorState.isHeading2 ? 'is-active' : ''}
>
H2
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
className={editorState.isHeading3 ? 'is-active' : ''}
>
H3
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 4 }).run()}
className={editorState.isHeading4 ? 'is-active' : ''}
>
H4
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 5 }).run()}
className={editorState.isHeading5 ? 'is-active' : ''}
>
H5
</button>
<button
onClick={() => editor.chain().focus().toggleHeading({ level: 6 }).run()}
className={editorState.isHeading6 ? 'is-active' : ''}
>
H6
</button>
<button
onClick={() => editor.chain().focus().toggleBulletList().run()}
className={editorState.isBulletList ? 'is-active' : ''}
>
Bullet list
</button>
<button
onClick={() => editor.chain().focus().toggleOrderedList().run()}
className={editorState.isOrderedList ? 'is-active' : ''}
>
Ordered list
</button>
<button
onClick={() => editor.chain().focus().toggleCodeBlock().run()}
className={editorState.isCodeBlock ? 'is-active' : ''}
>
Code block
</button>
<button
onClick={() => editor.chain().focus().toggleBlockquote().run()}
className={editorState.isBlockquote ? 'is-active' : ''}
>
Blockquote
</button>
<button onClick={() => editor.chain().focus().setHorizontalRule().run()}>Horizontal rule</button>
<button onClick={() => editor.chain().focus().setHardBreak().run()}>Hard break</button>
<button onClick={() => editor.chain().focus().undo().run()} disabled={!editorState.canUndo}>
Undo
</button>
<button onClick={() => editor.chain().focus().redo().run()} disabled={!editorState.canRedo}>
Redo
</button>
</div>
</div>
)
}
Features
Slash menu & bubble menu
AI autocomplete (type
++to activate, or select from slash menu)Image uploads (drag & drop / copy & paste, or select from slash menu)
Add tweets from the command slash menu: