tiptap/docs/guide/menus.md
Lode Claassen d31e49b03a
docs: Improve introducing examples in the documentation (#4334)
* skip 'like that' when we don't need it anyway

* change to 'like this' because it is before the example instead of after
2023-08-18 10:53:07 -07:00

5.4 KiB
Raw Blame History

tableOfContents
true

Create menus

Introduction

Tiptap comes very raw, but thats a good thing. You have full control about the appearance of it.

When we say full control, we mean it. You can (and have to) build a menu on your own. We help you to wire everything up.

Menus

The editor provides a fluent API to trigger commands and add active states. You can use any markup you like. To make the positioning of menus easier, we provide a few utilities and components. Lets go through the most typical use cases one by one.

Fixed menu

A fixed menu, for example on top of the editor, can be anything. We dont provide such menu. Just add a <div> with a few <button>s. How those buttons can trigger commands is explained below.

Bubble menu

The bubble menu appears when selecting text. Markup and styling is totally up to you.

https://embed.tiptap.dev/preview/Extensions/BubbleMenu?hideSource

Floating menu

The floating menu appears in empty lines. Markup and styling is totally up to you.

https://embed.tiptap.dev/preview/Extensions/FloatingMenu?hideSource

Slash commands (work in progress)

Its not an official extension yet, but theres an experiment you can use to add what we call slash commands. It allows you to start a new line with / and will bring up a popup to select which node should be added.

Buttons

Okay, youve got your menu. But how do you wire things up?

Commands

Youve got the editor running already and want to add your first button. You need a <button> HTML tag with a click handler. Depending on your setup, that can look like the following example:

<button onclick="editor.chain().focus().toggleBold().run()">
  Bold
</button>

Oh, thats a long command, right? Actually, its a chain of commands. Lets go through this one by one:

editor.chain().focus().toggleBold().run()
  1. editor should be a Tiptap instance,
  2. chain() is used to tell the editor you want to execute multiple commands,
  3. focus() sets the focus back to the editor,
  4. toggleBold() marks the selected text bold, or removes the bold mark from the text selection if its already applied and
  5. run() will execute the chain.

In other words: This will be a typical Bold button for your text editor.

Which commands are available depends on what extensions you have registered with the editor. Most extensions come with a set…(), unset…() and toggle…() command. Read the extension documentation to see whats actually available or just surf through your code editors autocomplete.

Keep the focus

You have already seen the focus() command in the above example. When you click on the button, the browser focuses that DOM element and the editor loses focus. Its likely you want to add focus() to all your menu buttons, so the writing flow of your users isnt interrupted.

The active state

The editor provides an isActive() method to check if something is applied to the selected text already. In Vue.js you can toggle a CSS class with help of that function:

<button :class="{ 'is-active': editor.isActive('bold') }" @click="editor.chain().focus().toggleBold().run()">
  Bold
</button>

This toggles the .is-active class accordingly and works for nodes and marks. You can even check for specific attributes. Here is an example with the Highlight mark, that ignores different attributes:

editor.isActive('highlight')

And an example that compares the given attribute(s):

editor.isActive('highlight', { color: '#ffa8a8' })

There is even support for regular expressions:

editor.isActive('textStyle', { color: /.*/ })

You can even check nodes and marks, but check for the attributes only. Here is an example with the TextAlign extension:

editor.isActive({ textAlign: 'right' })

If your selection spans multiple nodes or marks, or only part of the selection has a mark, isActive() will return false and indicate nothing is active. This is how it is supposed to be, because it allows people to apply a new node or mark to that selection right-away.

User experience

When designing a great user experience you should consider a few things.

Accessibility

:::warning Incomplete This section needs some work. Do you know what else needs to be taken into account when building an editor menu? Let us know on GitHub or send us an email to humans@tiptap.dev! :::

Icons

Most editor menus use icons for their buttons. In some of our demos, we use the open source icon set Remix Icon, which is free to use. But its totally up to you what you use. Here are a few icon sets you can consider: