Strange behavior of demo editor toolbar

On loading the basic demo page I see a strange behavior of the toolbar.

It starts with a full set of icons. If I then select all (ctrl+a), the icons for type, bullets and select button disappear which I don’t understand - if I can press a letter I should be able to create a bullet.

If I then press delete (clear the document) the bullet icons are missing, it seems they are often missing on the first line but I have been able to bring them there by creating a bullet on the second line and then deleting before it. That created a strange state, a line with a bullet but the bullet icons missing.

If I clear the document and then insert->horizontal rule I get a strange state … most of the toolbar is gone, there is no cursor, pressing a letter will replace the rule with the letter (as if it’s selected ?) and the other buttons also have unexpected behavior (ie choosing insert->rule again does nothing).

any help ?

Two side notes … removing buttons from the toolbar in response to state changes creates a strange and distracting experience, it is much better IMO to have the full toolbar always on and just disable buttons which are not relevant to the state instead of hiding them, or at least have an option for that.

also the way the editor itself grows and shrinks with content is strange and unusual. One expect the editor frame to stay constant with editing.

This is due to the top element being a heading. If you change the top line type -> plain then you’ll be able to add bullets at the top (same thing for the select all case). What’s happening here is that the schema definition tells ProseMirror that bullets are not allowed within a heading and then the toolbar hides the buttons that are not available.

Agreed, for my implementation I went with always showing buttons and also made every button always available (where it will replace the node type of the active line if need be).

CSS on one of the top divs will fix this. This is not intrinsic to ProseMirror, it is just how it is setup on the demo pages.

I think everything you asked about is customizable! ProseMirror aims to be a powerful editor but not necessarily something you can just toss into a website and start using.

Thanks wes-r for your help ! I understand it better now

Agreed, for my implementation I went with always showing buttons and also made every button always available (where it will replace the node type of the active line if need be).

Can you tell how to achieve this ?

Also is there a way to create a toolbar item showing the ‘type’ of the current cursor position ?

Thanks !

You want the onDeselect option to menu items.

Note that the prosemirror-menu module is mostly an example of how you could do a menu, not a core prosemirror module that I’m seriously supporting.

I’m using my own menu and not the prosemirror-menu module. Because of that, keeping menu items visible was straightforward (just don’t hide them). To allow them to always be clickable was rough. There may be an easier way but I had to write a command that will transform all nodes within the selection to a paragraph, lift any bullets or block quotes and then wrapIn the clicked node type (e.g. heading 2). This was very specific to our use case as we treat many of these node types as mutually exclusive (i.e. no headings within quotes, no quotes within bullets, etc).

Thx marijn

the documentation you linked to does not mention onSelect

Sorry, the option I meant is called onDeselect

There is a typo in the doc here

The option name is onDeselected not onDeselect (see

In case it’s useful to others, here is a dirty way to make all menu buttons disabled instead of hidden when not relevant, without making changes to example-setup etc:

	function disableOnDeselect(a) {
		if (a.content) a.content.forEach(disableOnDeselect);
		else if (Array.isArray(a)) a.forEach(disableOnDeselect);
	    else if (a.spec) a.spec.onDeselected="disable";
	let menuContent=buildMenuItems(schema).fullMenu;

	let view = new MenuBarEditorView(document.querySelector("#editor"), {
		state: state,
		menuContent: menuContent

Thanks for catching that. Fixed.