The toolbar provides a customizable UI for document editing with support for custom buttons, responsive layouts, and role-based controls.
Quick Start
const superdoc = new SuperDoc({
selector: '#editor',
document: 'contract.docx',
toolbar: '#toolbar' // Simple toolbar with defaults
});
Module Configuration
Container element for toolbar
modules.toolbar.toolbarGroups
string[]
default:"['left', 'center', 'right']"
Layout regions for button placement
Custom button arrangement by groupShow Example configuration
groups: {
left: ['undo', 'redo'],
center: ['bold', 'italic', 'underline'],
right: ['documentMode', 'export']
}
modules.toolbar.excludeItems
Button names to exclude from toolbar
Custom SVG icons for buttons
Custom tooltips and labels
Available font options in font dropdown
modules.toolbar.hideButtons
Auto-hide buttons on small screens
modules.toolbar.responsiveToContainer
Size relative to container instead of window
modules.toolbar.customButtons
Custom button definitions
Text Formatting
Bold, italic, underline, strikethrough
Font Controls
Font family, size, color, highlight
Paragraph
Alignment, lists, indentation
Document Tools
Undo, redo, search, links, tables
Text Formatting
Toggle bold formatting (Ctrl+B
)
Toggle italic formatting (Ctrl+I
)
Toggle underline formatting (Ctrl+U
)
Toggle strikethrough formatting
Font Controls
Background highlight color
These buttons appear when their respective modules are enabled
Add comment (requires Comments module)
Accept tracked change (requires Track Changes)
Reject tracked change (requires Track Changes)
Switch between editing/viewing/suggesting modes
Button type: 'button'
or 'dropdown'
Layout group: ‘left’, ‘center’, or ‘right’
command
string | function
required
Command name or handler function
modules: {
toolbar: {
customButtons: [{
type: 'button',
name: 'myButton',
tooltip: 'My Custom Button',
icon: '<svg>...</svg>',
group: 'center',
command: ({ item, argument, option }) => {
superdoc.activeEditor.commands.myCommand();
}
}]
}
}
customButtons: [{
type: 'dropdown',
name: 'templates',
tooltip: 'Insert Template',
icon: templateIcon,
hasCaret: true,
options: [
{ label: 'Contract', key: 'contract' },
{ label: 'Invoice', key: 'invoice' }
],
command: ({ option }) => {
if (option) loadTemplate(option.key);
}
}]
Icon when active (optional)
customButtons: [{
type: 'button',
name: 'darkMode',
tooltip: 'Toggle Dark Mode',
icon: moonIcon,
activeIcon: sunIcon,
active: false,
command: ({ item }) => {
const isActive = !item.active.value;
item.active.value = isActive;
setDarkMode(isActive);
}
}]
Command System
Command Handler
Commands receive these parameters:
The toolbar button object
Value passed (e.g., color hex, font name)
Selected dropdown option (dropdowns only)
command: ({ item, argument, option }) => {
const editor = superdoc.activeEditor;
// Color button passes hex
if (item.name === 'color') {
editor.commands.setColor(argument); // #FF0000
}
// Dropdown passes selected option
if (option) {
handleOption(option.key);
}
}
Built-in Command Names
Use string command names for standard operations
// Text formatting
command: 'toggleBold'
command: 'toggleItalic'
command: 'toggleUnderline'
// Paragraph
command: 'setTextAlign'
command: 'toggleBulletList'
// Special handlers
command: 'setZoom' // Handled by SuperDoc
command: 'setDocumentMode' // Changes editing state
Icon Customization
Replace Built-in Icons
Map of button names to SVG strings
modules: {
toolbar: {
icons: {
bold: '<svg viewBox="0 0 24 24">...</svg>',
italic: '<svg viewBox="0 0 24 24">...</svg>',
// Function for dynamic icons
darkMode: () => isDark ? sunIcon : moonIcon
}
}
}
Icons should be 24x24 viewBox SVGs with fill="currentColor"
for proper theming
Font Configuration
Available font optionsShow Font object properties
fonts: [
// System fonts
{ label: 'Arial', key: 'Arial' },
{ label: 'Times', key: 'Times New Roman' },
// Custom web font
{
label: 'Brand Font',
key: 'BrandFont, sans-serif',
fontWeight: 400,
props: {
style: { fontFamily: 'BrandFont' }
}
}
]
Responsive Behavior
Breakpoints
The toolbar adapts at these widths:
Hide: styles, format painter
Container-Based Sizing
modules: {
toolbar: {
responsiveToContainer: true, // Size based on container
hideButtons: true // Auto-hide on small screens
}
}
Role-Based Controls
role: 'viewer'
// Shows: zoom, search, print, export
// All editing disabled
Common Configurations
Contract Review
modules: {
toolbar: {
groups: {
left: ['undo', 'redo', 'search'],
center: ['addComment', 'acceptChange', 'rejectChange'],
right: ['documentMode', 'export']
},
customButtons: [{
name: 'approve',
icon: checkIcon,
tooltip: 'Approve Document',
group: 'right',
command: () => approveDocument()
}]
}
}
Minimal Editor
modules: {
toolbar: {
groups: {
center: [
'bold', 'italic',
'link', 'image',
'list', 'numberedlist'
]
},
excludeItems: ['zoom', 'ruler', 'pageBreak']
}
}
AI-Enhanced
modules: {
toolbar: {
customButtons: [{
type: 'dropdown',
name: 'aiTools',
icon: aiIcon,
tooltip: 'AI Tools',
options: [
{ label: 'Improve Writing', key: 'improve' },
{ label: 'Fix Grammar', key: 'grammar' },
{ label: 'Make Concise', key: 'concise' }
],
command: ({ option }) => {
const selection = editor.getSelectedText();
aiProcess(option.key, selection);
}
}]
}
}
Toolbar instance when configured
// Get toolbar instance
const toolbar = superdoc.toolbar;
// Get specific button
const boldButton = toolbar.getToolbarItemByName('bold');
// Update button state
boldButton.active.value = true;
boldButton.disabled.value = false;
// Update entire toolbar
toolbar.updateToolbarState();
Events
toolbar.on('superdoc-command', ({ item, argument }) => {
console.log(`Command: ${item.command}`);
console.log(`Argument: ${argument}`);
});
State Changes
toolbar.on('state-update', () => {
const boldActive = toolbar
.getToolbarItemByName('bold')
.active.value;
updateUIIndicator(boldActive);
});
Styling
CSS Variables
:root {
--toolbar-height: 48px;
--toolbar-bg: white;
--toolbar-border: #e0e0e0;
--toolbar-button-size: 32px;
--toolbar-button-hover: #f5f5f5;
--toolbar-button-active: #e3f2fd;
}
[data-theme="dark"] {
--toolbar-bg: #1e1e1e;
--toolbar-border: #444;
--toolbar-button-hover: #2a2a2a;
}
Best practices:
- Use functions for dynamic icons (lazy loading)
- Use
responsiveToContainer
for embedded editors
- Keep command functions lightweight
- Remove unused buttons via
excludeItems
Troubleshooting
// Check selector exists
if (!document.querySelector('#toolbar')) {
console.error('Toolbar container not found');
}
// Wait for ready event
superdoc.once('ready', () => {
console.log(superdoc.toolbar); // Now available
});
// Check role permissions
if (superdoc.config.role === 'viewer') {
// Editing buttons disabled
}
// Check editor connection
if (!superdoc.activeEditor) {
// No editor to execute commands on
}