API Reference

@univerjs/ui

Shared application UI framework, workbench services, menus, dialogs, and Facade UI APIs for Univer.

TypeScript
import { UniverUIPlugin } from '@univerjs/ui'univer.registerPlugin(UniverUIPlugin, config)

Entry Points

  • Facade: @univerjs/ui/facade
  • Locale: @univerjs/ui/locale/*

Unit presence and undo/redo groups

The root entry exports IUnitPresenceUIAdapterRegistry, UnitPresenceUIAdapterRegistry, IUnitPresenceUIAdapter, local and remote presence-state types, IUnitPresencePoint, and UndoRedoGroupService.

Use HoverTrack with HOVER_TRACK_HOST_CLASS_NAME for themed hover tracking. preventBrowserZoomInContainers() blocks browser zoom only inside the supplied containers.

Mobile hosts can use MOBILE_UI_MODE, MobileDialogService, MobileDrawer, MobileDrawerSnap, and MobileMenu. The Facade also exposes setRibbonType() for changing between collapsed, simple, classic, and grid layouts at runtime.

Notifications

Resolve INotificationService from your plugin's injector and call show(options). It returns an IDisposable; disposing it dismisses that notification. INotificationOptions.classNames applies CSS classes to individual parts of this notification, including toast, title, description, and actionButton.

TypeScript
import { INotificationService } from '@univerjs/ui'const notificationService = injector.get(INotificationService)const notice = notificationService.show({  title: 'Review required',  content: 'Check the latest changes before continuing.',  type: 'warning',  duration: Number.POSITIVE_INFINITY,  closable: false,  dismissible: false,  action: { label: 'Dismiss', onClick: () => notice.dispose() },  classNames: {    toast: 'review-notice',    actionButton: 'review-notice-action',  },})

Define these classes in your application stylesheet. duration: Number.POSITIVE_INFINITY keeps the notice visible; closable controls the close button and dismissible controls user dismissal. Dispose any remaining notice when its owner is removed.

IUniverUIConfig

TypeScript
import type { DependencyOverride } from '@univerjs/core'import type { IWorkbenchOptions, MenuConfig } from '@univerjs/ui'export interface IUniverUIConfig extends IWorkbenchOptions {  /** Disable auto focus when Univer bootstraps. */  disableAutoFocus?: true  override?: DependencyOverride  menu?: MenuConfig  popupRootId?: string  /**   * The fallback avatar for user.   */  avatarFallback?: string}
TypeScript
import type { MenuConfig, MenuItemConfig } from '@univerjs/ui'

MenuConfig is a flat Record<string, MenuItemConfig> for the shared menu system used by Sheets, Docs, Slides, Boards, and PDFs. In plugin mode, pass it as menu to UniverUIPlugin. Sheets and Docs also accept it through UniverSheetsCorePreset and UniverDocsCorePreset. Use FUniver.updateMenuConfig(config) to merge changes at runtime and refresh the UI immediately. Unspecified properties retain their existing overrides or schema defaults; overrides also apply to menus registered later.

KeyExampleScope
Ribbon tab keyribbon.insertorder among tabs.
Ribbon group keyribbon.start.formatorder among groups in that tab.
Menu item IDsheet.command.set-range-boldItem properties, order among siblings, and gridLayout within its Ribbon group.
Context-menu item IDboard.menu.duplicate-selectionItem properties and order within its context-menu group; gridLayout does not affect popup menus.

Use RibbonPosition and the group enums, such as RibbonStartGroup, from @univerjs/ui for tab and group keys. Ribbon item IDs are available through the rendered element's data-u-command attribute. For context menus, use the item IDs defined by the product menu schema. An item ID can differ from its command ID. An item override applies wherever that item ID is used; order does not move an item into another group or tab.

OptionTypeBehavior
ordernumberLower values come first among siblings. Applies to tabs, groups, and menu items.
gridLayoutIRibbonGridLayoutOverrides the item's placement in the grid Ribbon. Omitted optional fields retain their existing values.
hidden, disabled, activatedbooleanOverrides the menu item's display or interaction state.
title, tooltipstringOverrides the menu item's text or locale key.
iconIMenuItem['icon']Overrides the menu item's icon.
typeMenuItemTypeOverrides the menu item's presentation type.
TypeScript
import type { MenuConfig } from '@univerjs/ui'import { UniverUIPlugin } from '@univerjs/ui'const menu: MenuConfig = {  'ribbon.insert': { order: -1 },  'ribbon.start.format': { order: -1 },  'sheet.command.set-range-font-family': {    order: 0,    gridLayout: { row: 1, column: 1, width: 160 },  },}univer.registerPlugin(UniverUIPlugin, { container: 'app', ribbonType: 'grid', menu })

Use IDs from the target product. The shared Facade methods require @univerjs/ui/facade in plugin mode, in addition to the product's own Facade entry.

Product guideInitial configurationExample menu item IDLayout scope
SheetsUniverUIPlugin or UniverSheetsCorePresetsheet.command.set-range-boldShared Ribbon and context menus.
DocsUniverUIPlugin or UniverDocsCorePresetdoc.command.set-inline-format-boldShared Ribbon and context menus.
SlidesUniverUIPluginslide.menu.insert.textShared Ribbon; product Ribbon registration requires editing to be enabled.
BoardsUniverUIPluginboard.menu.duplicate-selectionShared context menus. The independent canvas toolbar uses UniverBoardsUIPlugin.toolbar.tools, not gridLayout.
PDFsUniverUIPluginpdf.menu.tool.highlightShared Ribbon; product Ribbon registration requires editing to be enabled.

Slides, Boards, and PDFs use plugin mode and do not provide core presets. Pass menu and ribbonType to the shared UI plugin, not the product UI plugin. Menu overrides do not create unregistered buttons or enable a product's disabled editor UI.

IRibbonGridLayout

TypeScript
import type { IRibbonGridLayout } from '@univerjs/ui'

These fields only affect ribbonType: 'grid'. Coordinates start at 1 within each group, which has two rows. Explicit grid positions determine visual placement; changing order alone does not move a button with an explicit position. Avoid overlapping cells: conflicts and invalid geometry use automatic placement.

FieldTypeRequiredBehavior
rownumberYesRow 1 or 2.
columnnumberYesPositive integer column index.
rowSpannumberNoDefaults to 1. Use 2 for a large button starting in row 1.
columnSpannumberNoPositive integer, defaults to 1.
showLabelbooleanNoShow the menu label; defaults to false.
widthnumberNoPositive, finite width in pixels.
iconSizenumberNoPositive, finite icon size in pixels.

When overriding an existing item, unspecified optional fields are inherited from its schema or earlier configuration. For example, changing the font selector's width retains its existing columnSpan.

IFacadeMenuItem

TypeScript
import type { IFacadeMenuItem, IFacadeSubmenuItem } from '@univerjs/ui/facade'

Options for FUniver.createMenu(). Call appendTo() on the returned FMenu to register it.

OptionTypeRequiredBehavior
idstringYesUnique menu ID; also the key used by MenuConfig.
titlestringYesMenu text or locale key.
actionstring or (() => void)YesCommand ID or callback to execute.
icon, tooltipstringNoIcon name and tooltip text or locale key.
ordernumberNoDisplay order among siblings.
gridLayoutIRibbonGridLayoutNoInitial grid placement within the target Ribbon group.
TypeScript
import '@univerjs/ui/facade'univerAPI  .createMenu({    id: 'custom-action',    title: 'Custom action',    action: () => console.log('Custom action clicked'),    order: 4,    gridLayout: { row: 1, column: 3, showLabel: true, width: 96 },  })  .appendTo('ribbon.start.history')

IFacadeSubmenuItem

Options for FUniver.createSubmenu(). It accepts the same id, title, icon, tooltip, order, and gridLayout options as IFacadeMenuItem, without action. gridLayout controls the submenu trigger in the Ribbon, not the popup's children. Use FSubmenu.addSubmenu() and addSeparator() to build its contents.

How is this guide?

© 2026 DreamNum Co., Ltd.