ToolbarItem has three variants:
interface ToolbarItem { command : string; svg : string; dropdowncontent? : string; tips? : string; onRender? : Function; }
Rendering a svg button, trigger onCommand action when clicking the button.
{ command : "bold", svg : SubEditor.svgList["b"], tips : "bold" }
The following example produce same result as above, action clicking on item button is defined specifically in onRender().
{ command : "bold", svg : SubEditor.svgList["b"], tips : "bold", onRender : (_editor : SubEditor, el : HTMLElement) => { el.addEventListener('click', (e) => { const cmd = el.getAttribute("data-command") as string; _editor.command(cmd,[]); }); } }
Result html markups:
<span class="se-button se-ToolbarItem" data-command="bold" data-tips="bold"> <span class="se-icon"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M7 5v14h7A3.6 3.6 0 0017 16A3.6 3.6 0 0015 12A3.6 3.6 0 0017 8.5A3.6 3.6 0 0014 5h-7ZM9 7h4.5A2.1 2.1 0 0114.5 9A2.1 2.1 0 0113.5 11h-4.5v-4ZM9 13h4.5A2.1 2.1 0 0114.5 15.5A2.1 2.1 0 0113.5 17h-4.5v-4Z"></path> </svg> </span> </span>
Dropdown menu can be created by providing the necessary html markup in dropdowncontent. By adding "horizontal" to se-dropdown-content class will render the sub-menu horizontally. By default clicking on the subeditor.refToolbar.querySelector(".se-dropdown-trigger button") will automatically show sub-menu. The buttons in sub-menu will need to define in onRender().
{ command : "align", svg : SubEditor.svgList["align_left"], tips : "align", dropdowncontent : '<div class="se-dropdown se-ToolbarItem" data-tips="align"><div class="se-dropdown-trigger"><button class="se-button" aria-haspopup="true" aria-controls="dropdown-menu-align"><span></span><span class="se-icon">'+SubEditor.svgList["align_left"]+'</span></button></div><div class="se-dropdown-menu" id="dropdown-menu-align" role="menu"><div class="se-dropdown-content horizontal"><span class="se-button se-ToolbarItem" data-command="align" data-value="left" data-tips="align left"><span class="se-icon">'+SubEditor.svgList["align_left"]+'</span></span><span class="se-button se-ToolbarItem" data-command="align" data-value="center" data-tips="align center"><span class="se-icon">'+SubEditor.svgList["align_center"]+'</span></span><span class="se-button se-ToolbarItem" data-command="align" data-value="right" data-tips="align right"><span class="se-icon">'+SubEditor.svgList["align_right"]+'</span></span><span class="se-button ToolbarItem" data-command="align" data-value="justify" data-tips="align justify"><span class="se-icon">'+SubEditor.svgList["align_justify"]+'</span></span></div></div></div>', onRender : (_editor : SubEditor, el : HTMLElement) => { //look for each button in sub-menu and el.querySelectorAll('.se-button[data-command]').forEach(btn => { btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); _editor.command("align",[btn.getAttribute("data-value") as string]); return false; }); }); //subscribe to onFeatureChange event to highlight the button if the current content at cursor has matching style _editor.event.register([{ event : "onFeatureChange", target : [], callback : () => { el.querySelectorAll('.se-button').forEach(btn => { btn.classList.remove('is-featured'); if(btn.getAttribute("data-value") === _editor.feature?.align) { btn.classList.add('is-featured'); } }); }}]); //end of feature change } }
By capturing the onclick event in onRender(), custom content can be created base on different condition. For more detail example, please check out the source code at /src/toolbar/(image, link, table, color).
{ command : "table", svg : SubEditor.svgList["table"], tips : "table", onRender : (_editor : SubEditor, el : HTMLElement) => { el.addEventListener('click', (e) => { //subscribe to onClick event: el.querySelector('.se-dropdown-trigger > button')?.addEventListener('click', () => { //determine if dropdown is open by checking is-active class if(el.querySelector('.se-dropdown-menu')!.classList.contains("is-active")) { //your own code //example: for table, if we are already in table, render submenu for table opertions such as merge/unmerge // if we are not currently in table, render an UI allowing user to create a new table by choosing number of columns and rows } }); }); } }
This method takes a function that accepts an editor instance and returns a ToolbarItem. Item set by presetToolbarItem will have the highest priority, it shall replace the item set by plugin (registerToolbarItem) and default item with same name.
//take advantage of _editor.ln() to provide localized language string when rendering content var newbold = function(_editor) { return { command : "bold", svg : SubEditor.svgList["b"], tips : "bold" } }; //create a new ToolbarItem name newbold SubEditor.presetToolbarItem("newbold", newbold); //can be used now: var subeditor = new SubEditor(elem, { toolbarList : ["newbold"], pluginList : ["bold"] // bold plugin is required for onCommand("bold", []) to work });
It is possible to pass the above function directly into toolbarList.
var new SubEditor(elem, { toolbarList : [newbold], pluginList : ["bold"] // bold plugin is required for onCommand("bold", []) to work });