Customization

Toolbar Customization

Customize the two-level composable toolbar with render props or compound components.

Overview

The editor uses a two-level composable toolbar with a title bar and a formatting bar.

Layout Structure

  • Title Bar: 3-column layout — Logo and Right Actions span full height, Document Name + Menus stack vertically in the center
  • Formatting Bar: Rendered inside a rounded pill with a subtle gray background
  • Every slot is customizable — pass your own logo, action buttons, or extra toolbar items

There are two ways to customize the toolbar:

  1. DocxEditor props — Quick setup with render props
  2. Compound components — Full control using EditorToolbar and its sub-components

Quick Setup (DocxEditor Props)

The simplest way to customize the toolbar:

import { DocxEditor } from '@eigenpal/docx-js-editor';
 
function App() {
  const [fileName, setFileName] = useState('Untitled.docx');
 
  return (
    <DocxEditor
      documentBuffer={buffer}
      renderLogo={() => <img src="/logo.svg" alt="Logo" />}
      documentName={fileName}
      onDocumentNameChange={setFileName}
      renderTitleBarRight={() => (
        <div>
          <button onClick={handleSave}>Save</button>
        </div>
      )}
    />
  );
}

DocxEditor Toolbar Props

PropTypeDefaultDescription
renderLogo() => ReactNodeCustom logo/icon in the title bar
documentNamestringEditable document name displayed in the title bar
onDocumentNameChange(name: string) => voidCalled when the user edits the document name
renderTitleBarRight() => ReactNodeCustom actions on the right side of the title bar

All existing toolbar props (showToolbar, showZoomControl, showRuler, toolbarExtra, etc.) continue to work.


Customizing the Font Dropdown

The toolbar's font-family dropdown can be customized via the fontFamilies prop on DocxEditor. Pass either bare strings, full FontOption objects, or a mix. Omit the prop to keep the built-in 12-font default.

Bare strings

Strings render in the "Other" group:

import { DocxEditor } from '@eigenpal/docx-js-editor';
 
<DocxEditor
  documentBuffer={buffer}
  fontFamilies={['Arial', 'Helvetica', 'Comic Sans MS']}
/>

FontOption objects (CSS fallbacks + grouping)

Use FontOption[] to enable CSS fallback chains and category grouping (sans-serif / serif / monospace / other):

import { DocxEditor, type FontOption } from '@eigenpal/docx-js-editor';
 
const FONTS: FontOption[] = [
  { name: 'Inter', fontFamily: 'Inter, system-ui, sans-serif', category: 'sans-serif' },
  { name: 'Roboto', fontFamily: 'Roboto, sans-serif', category: 'sans-serif' },
  { name: 'Source Serif', fontFamily: '"Source Serif Pro", Georgia, serif', category: 'serif' },
  { name: 'JetBrains Mono', fontFamily: '"JetBrains Mono", monospace', category: 'monospace' },
];
 
<DocxEditor documentBuffer={buffer} fontFamilies={FONTS} />

Mixed input

Strings and FontOption objects can be combined; strings still land in "Other":

<DocxEditor
  documentBuffer={buffer}
  fontFamilies={[
    { name: 'Inter', fontFamily: 'Inter, sans-serif', category: 'sans-serif' },
    'Comic Sans MS',
  ]}
/>

Stable reference required. Pass a memoized array or hoist it to module scope. An inline fontFamilies={[...]} creates a fresh identity on every render and invalidates the picker's internal memo.

An empty array (fontFamilies={[]}) renders an empty but still-enabled dropdown.


Compound Component API

For full control over the toolbar structure, use EditorToolbar directly:

import { EditorToolbar, type EditorToolbarProps } from '@eigenpal/docx-js-editor';
 
function MyEditor({ toolbarProps }: { toolbarProps: EditorToolbarProps }) {
  return (
    <EditorToolbar {...toolbarProps}>
      <EditorToolbar.TitleBar>
        <EditorToolbar.Logo>
          <img src="/logo.svg" alt="My App" />
        </EditorToolbar.Logo>
        <EditorToolbar.DocumentName
          value={fileName}
          onChange={setFileName}
          placeholder="Untitled"
        />
        <EditorToolbar.MenuBar />
        <EditorToolbar.TitleBarRight>
          <button onClick={handleSave}>Save</button>
          <button onClick={handleShare}>Share</button>
        </EditorToolbar.TitleBarRight>
      </EditorToolbar.TitleBar>
      <EditorToolbar.FormattingBar />
    </EditorToolbar>
  );
}

Sub-Components

EditorToolbar

The root wrapper. Provides toolbar context to all sub-components.

PropTypeDescription
childrenReactNodeSub-components (TitleBar, FormattingBar)
classNamestringAdditional CSS class for the container
...ToolbarPropsAll standard toolbar props (formatting state, handlers, etc.)

EditorToolbar.TitleBar

Three-column layout. Automatically arranges children:

  • Left column: Logo (spans full height)
  • Center column: DocumentName on top, MenuBar below
  • Right column: TitleBarRight (spans full height)
PropTypeDescription
childrenReactNodeLogo, DocumentName, MenuBar, TitleBarRight

EditorToolbar.Logo

Renders custom content (icon, image, badge) left-aligned in the title bar.

PropTypeDescription
childrenReactNodeLogo content

EditorToolbar.DocumentName

Editable text input styled as a borderless field.

PropTypeDefaultDescription
valuestringCurrent document name
onChange(value: string) => voidCalled on name change
placeholderstring'Untitled'Placeholder text

EditorToolbar.MenuBar

Renders File, Format, and Insert dropdown menus. Automatically wired to the toolbar context — no props needed.

Menu contents are derived from the toolbar context (print, page setup, text direction, image/table insert, page break, table of contents).

EditorToolbar.TitleBarRight

Right-aligned container for custom actions (buttons, toggles, status indicators).

PropTypeDescription
childrenReactNodeAction buttons, toggles, etc.

EditorToolbar.FormattingBar

The icon formatting toolbar (undo/redo, zoom, fonts, bold/italic/underline, colors, alignment, lists, etc.) rendered inside a rounded pill with a subtle gray background. Can also be used standalone outside of EditorToolbar.

PropTypeDescription
childrenReactNodeAdditional toolbar items appended at the end
inlinebooleanWhen true, renders with display: contents for embedding in a flex row

Customization Patterns

Custom logo with branding

<DocxEditor
  renderLogo={() => (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
      <img src="/logo.svg" width={24} height={24} />
      <span style={{ fontWeight: 600 }}>My App</span>
    </div>
  )}
/>

Right-side actions with status

<DocxEditor
  renderTitleBarRight={() => (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
      <span style={{ fontSize: 12, color: '#666' }}>Saved</span>
      <button onClick={handleExport}>Export</button>
      <button onClick={handleShare}>Share</button>
    </div>
  )}
/>

Extra formatting toolbar items

Use toolbarExtra to append custom buttons to the formatting bar:

<DocxEditor
  toolbarExtra={
    <>
      <button onClick={handleSpellCheck}>Spell Check</button>
      <button onClick={handleWordCount}>Word Count</button>
    </>
  }
/>

Compound components with custom elements

Mix standard sub-components with your own elements inside the TitleBar:

<EditorToolbar {...toolbarProps}>
  <EditorToolbar.TitleBar>
    <EditorToolbar.Logo>
      <MyBrandLogo />
    </EditorToolbar.Logo>
    <EditorToolbar.DocumentName value={name} onChange={setName} />
    <EditorToolbar.MenuBar />
    <EditorToolbar.TitleBarRight>
      <UserAvatar />
      <ShareButton />
      <SaveButton />
    </EditorToolbar.TitleBarRight>
  </EditorToolbar.TitleBar>
  <EditorToolbar.FormattingBar>
    <CustomToolbarButton icon="spell_check" onClick={handleSpellCheck} />
  </EditorToolbar.FormattingBar>
</EditorToolbar>