Skip to content

About

React UI component library behind ONLYOFFICE Apps

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

3,691 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@onlyoffice/apps-ui-kit

React UI component library behind ONLYOFFICE Apps.

React

About This Library

@onlyoffice/apps-ui-kit provides the React components and color system used across the ONLYOFFICE Apps frontend products. It began life inside the DocSpace-client monorepo and is now developed as a standalone package.

ONLYOFFICE Apps

Note: version 4.0.0 renamed the package, made it ESM-only and put an exports map in front of every subpath. See CHANGELOG.md.

New here? docs/getting-started.md is the one page to read first: what to install, the two providers to mount, why the stylesheet needs no import, and which import form to use. docs/components.md is the catalogue, with a table for choosing between the components that are easy to confuse.

Scope: not every directory in this package is public API. Modules coupled to an ONLYOFFICE Apps portal — api/, billing/, selectors/, uploader/, ai-agent/, document-editor/ and providers/api — ship in the package but are intended for ONLYOFFICE's own products. See docs/public-api.md.

Features ✨

  • TypeScript-first - Full type definitions included out of the box
  • Color system - Built-in globalColors palette with named color tokens for light and dark UI states
  • Interactive docs - Every component is documented with Storybook stories and controls
  • Tree-shakeable - ESM only, one module per source file; import only what you use
  • Well-tested - Components are tested with Vitest and React Testing Library
  • Modern tooling - Built with Rollup, linted and formatted with Biome

Requirements

  • React ^19.0.0
  • React DOM ^19.0.0

Installation

# pnpm
pnpm add @onlyoffice/apps-ui-kit

# npm
npm install @onlyoffice/apps-ui-kit

# yarn
yarn add @onlyoffice/apps-ui-kit

To try a build of this repository instead, pack it and install the file:

pnpm build && pnpm pack
pnpm add file:../path/to/onlyoffice-apps-ui-kit-4.0.1.tgz

Peer dependencies: four are required — react and react-dom ^19.0.0, plus i18next and react-i18next, which the translated components need and which break silently if a second copy ends up in the tree. Fifteen more are optional and only matter to the modules that use them: mobx / mobx-react and react-router for the portal-coupled modules, axios for providers/api, socket.io-client for utils/socket, @onlyoffice/document-editor-react for document-editor/, and @onlyoffice/ai-chat with the markdown and KaTeX stack for ai-agent/. An install downloads none of the optional set. See peerDependencies in package.json.

axios is the exception worth knowing about: the main entry reaches it through uploader and billing, so a consumer that bundles the barrel has to install it even though it is declared optional. Tracked in docs/public-api.md.

Styles come with the components: every module imports its own CSS file, so a bundler ships exactly the styles of the components you import, split along the same chunks as the code. Nothing has to be imported by hand. The whole-library stylesheet is still published for setups that cannot process CSS imports from node_modules; importing it loads every component's styles at once:

import "@onlyoffice/apps-ui-kit/styles.css";

Quick Start

Using a Component

import { Text } from "@onlyoffice/apps-ui-kit";

function App() {
  return (
    <Text fontSize="14px" isBold>
      Hello World
    </Text>
  );
}

Using the Color Palette

import { globalColors } from "@onlyoffice/apps-ui-kit/providers/theme";

const primaryBlue = globalColors.lightBlueMain;
const errorRed = globalColors.mainRed;

Usage

Import from main entry

import {
  Aside,
  AsideHeader,
  Avatar,
  Backdrop,
  Badge,
  Button,
  Calendar,
  Checkbox,
  CircleSkeleton,
  ComboBox,
  ContextMenu,
  ContextMenuButton,
  DatePicker,
  DateTimePicker,
  DropDown,
  DropDownItem,
  EmailInput,
  EmptyScreenContainer,
  EmptyView,
  FieldContainer,
  FileInput,
  Heading,
  HelpButton,
  IconButton,
  InputBlock,
  Label,
  Link,
  Loader,
  LoadingButton,
  MCPIcon,
  ModalDialog,
  Portal,
  ProgressBar,
  RadioButton,
  RadioButtonGroup,
  RectangleSkeleton,
  RoomIcon,
  Row,
  RowContainer,
  RowContent,
  Scrollbar,
  SearchInput,
  SelectedItem,
  SelectionArea,
  Slider,
  SnackBar,
  TabItem,
  Tabs,
  Tag,
  Tags,
  Text,
  TextInput,
  Textarea,
  ThemeProvider,
  TimePicker,
  Toast,
  toastr,
  ToggleButton,
  Tooltip,
  TopLoaderService,
  BaseTile,
  FileTile,
  FolderTile,
  RoomTile,
  TemplateTile,
  TileContainer,
  TileContent,
} from "@onlyoffice/apps-ui-kit";

Six components that look like they belong in this list are not reachable from the main entry today: FilterInput, LoaderWrapper, PublicRoomBar, RoomLogo, Selector and StatusMessage. Three are default exports, which export * does not re-export; the other folders are not registered in components/index.ts. Import them by subpath — import { Selector } from "@onlyoffice/apps-ui-kit/components/selector", import FilterInput from "@onlyoffice/apps-ui-kit/components/filter" — and note that an ONLYOFFICE Apps plugin cannot reach them at all, since the portal gives plugins the main entry and refuses every subpath.

Import specific components

import { AccessRightSelect } from "@onlyoffice/apps-ui-kit/components/access-right-select";
import { Aside, AsideHeader } from "@onlyoffice/apps-ui-kit/components/aside";
import { Avatar } from "@onlyoffice/apps-ui-kit/components/avatar";
import { Backdrop } from "@onlyoffice/apps-ui-kit/components/backdrop";
import { Badge } from "@onlyoffice/apps-ui-kit/components/badge";
import { Button, ButtonSize } from "@onlyoffice/apps-ui-kit/components/button";
import { Calendar } from "@onlyoffice/apps-ui-kit/components/calendar";
import { CategoryItem } from "@onlyoffice/apps-ui-kit/components/category-item";
import { Checkbox } from "@onlyoffice/apps-ui-kit/components/checkbox";
import { CircleSkeleton } from "@onlyoffice/apps-ui-kit/components/circle";
import { ColorInput } from "@onlyoffice/apps-ui-kit/components/color-input";
import { ColorPicker } from "@onlyoffice/apps-ui-kit/components/color-picker";
import { ComboBox } from "@onlyoffice/apps-ui-kit/components/combobox";
import { ContextMenu } from "@onlyoffice/apps-ui-kit/components/context-menu";
import {
  ContextMenuButton,
  ContextMenuButtonDisplayType,
} from "@onlyoffice/apps-ui-kit/components/context-menu-button";
import { DatePicker } from "@onlyoffice/apps-ui-kit/components/date-picker";
import { DateTimePicker } from "@onlyoffice/apps-ui-kit/components/date-time-picker";
import { DragAndDrop } from "@onlyoffice/apps-ui-kit/components/drag-and-drop";
import { DropDown } from "@onlyoffice/apps-ui-kit/components/drop-down";
import { DropDownItem } from "@onlyoffice/apps-ui-kit/components/drop-down-item";
import { Dropzone } from "@onlyoffice/apps-ui-kit/components/dropzone";
import { EmailInput } from "@onlyoffice/apps-ui-kit/components/email-input";
import { EmptyScreenContainer } from "@onlyoffice/apps-ui-kit/components/empty-screen-container";
import { EmptyView } from "@onlyoffice/apps-ui-kit/components/empty-view";
import { ErrorContainer } from "@onlyoffice/apps-ui-kit/components/error-container";
import { FieldContainer } from "@onlyoffice/apps-ui-kit/components/field-container";
import { FileInput } from "@onlyoffice/apps-ui-kit/components/file-input";
import { FilterInput } from "@onlyoffice/apps-ui-kit/components/filter";
import {
  FloatingButton,
  FloatingButtonIcons,
} from "@onlyoffice/apps-ui-kit/components/floating-button";
import { FormWrapper } from "@onlyoffice/apps-ui-kit/components/form-wrapper";
import {
  Heading,
  HeadingLevel,
  HeadingSize,
} from "@onlyoffice/apps-ui-kit/components/heading";
import { HelpButton } from "@onlyoffice/apps-ui-kit/components/help-button";
import { IconButton } from "@onlyoffice/apps-ui-kit/components/icon-button";
import { ImageEditor } from "@onlyoffice/apps-ui-kit/components/image-editor";
import { InfiniteLoaderComponent } from "@onlyoffice/apps-ui-kit/components/infinite-loader";
import { InputBlock } from "@onlyoffice/apps-ui-kit/components/input-block";
import { Label } from "@onlyoffice/apps-ui-kit/components/label";
import {
  Link,
  LinkType,
  LinkTarget,
} from "@onlyoffice/apps-ui-kit/components/link";
import { LinkWithDropdown } from "@onlyoffice/apps-ui-kit/components/link-with-dropdown";
import { Loader, LoaderTypes } from "@onlyoffice/apps-ui-kit/components/loader";
import { LoaderWrapper } from "@onlyoffice/apps-ui-kit/components/loader-wrapper";
import { LoadingButton } from "@onlyoffice/apps-ui-kit/components/loading-button";
import { MainButton } from "@onlyoffice/apps-ui-kit/components/main-button";
import { MainButtonMobile } from "@onlyoffice/apps-ui-kit/components/main-button-mobile";
import {
  MCPIcon,
  MCPIconSize,
} from "@onlyoffice/apps-ui-kit/components/mcp-icon";
import {
  ModalDialog,
  ModalDialogType,
} from "@onlyoffice/apps-ui-kit/components/modal-dialog";
import { Navigation } from "@onlyoffice/apps-ui-kit/components/navigation";
import { OperationsProgressButton } from "@onlyoffice/apps-ui-kit/components/operations-progress-button";
import { Paging } from "@onlyoffice/apps-ui-kit/components/paging";
import { PasswordInput } from "@onlyoffice/apps-ui-kit/components/password-input";
import { Portal } from "@onlyoffice/apps-ui-kit/components/portal";
import { PortalLogo } from "@onlyoffice/apps-ui-kit/components/portal-logo";
import {
  ProgressBar,
  PreparationPortalProgress,
} from "@onlyoffice/apps-ui-kit/components/progress-bar";
import { PublicRoomBar } from "@onlyoffice/apps-ui-kit/components/public-room-bar";
import { RadioButton } from "@onlyoffice/apps-ui-kit/components/radio-button";
import { RadioButtonGroup } from "@onlyoffice/apps-ui-kit/components/radio-button-group";
import { RectangleSkeleton } from "@onlyoffice/apps-ui-kit/components/rectangle";
import { RoomIcon } from "@onlyoffice/apps-ui-kit/components/room-icon";
import { RoomLogo } from "@onlyoffice/apps-ui-kit/components/room-logo";
import {
  Row,
  RowContainer,
  RowContent,
} from "@onlyoffice/apps-ui-kit/components/rows";
import { Scrollbar } from "@onlyoffice/apps-ui-kit/components/scrollbar";
import { SearchInput } from "@onlyoffice/apps-ui-kit/components/search-input";
import { Section } from "@onlyoffice/apps-ui-kit/components/section";
import { SelectedItem } from "@onlyoffice/apps-ui-kit/components/selected-item";
import { SelectionArea } from "@onlyoffice/apps-ui-kit/components/selection-area";
import {
  Selector,
  SelectorAccessRightsMode,
} from "@onlyoffice/apps-ui-kit/components/selector";
import { Slider } from "@onlyoffice/apps-ui-kit/components/slider";
import { SnackBar } from "@onlyoffice/apps-ui-kit/components/snackbar";
import { StatusMessage } from "@onlyoffice/apps-ui-kit/components/status-message";
import { TabItem } from "@onlyoffice/apps-ui-kit/components/tab-item";
import {
  TableContainer,
  TableBody,
  TableRow,
  TableHeader,
  TableGroupMenu,
  TableCell,
} from "@onlyoffice/apps-ui-kit/components/table";
import { Tabs, TabsTypes } from "@onlyoffice/apps-ui-kit/components/tabs";
import { Tag } from "@onlyoffice/apps-ui-kit/components/tag";
import { Tags } from "@onlyoffice/apps-ui-kit/components/tags";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
import {
  TextInput,
  InputSize,
  InputType,
} from "@onlyoffice/apps-ui-kit/components/text-input";
import { Textarea } from "@onlyoffice/apps-ui-kit/components/textarea";
import { ThemeProvider } from "@onlyoffice/apps-ui-kit/components/theme-provider";
import { TimePicker } from "@onlyoffice/apps-ui-kit/components/time-picker";
import { Toast, toastr } from "@onlyoffice/apps-ui-kit/components/toast";
import { ToggleButton } from "@onlyoffice/apps-ui-kit/components/toggle-button";
import {
  Tooltip,
  TooltipContainer,
  withTooltip,
} from "@onlyoffice/apps-ui-kit/components/tooltip";
import { TopLoaderService } from "@onlyoffice/apps-ui-kit/components/top-loading-indicator";
import {
  BaseTile,
  FileTile,
  FolderTile,
  RoomTile,
  TemplateTile,
  TileContainer,
  TileContent,
} from "@onlyoffice/apps-ui-kit/components/tiles";

Import contexts and hooks

import {
  ThemeProvider,
  useTheme,
} from "@onlyoffice/apps-ui-kit/context/ThemeContext";
import {
  InterfaceDirectionProvider,
  useInterfaceDirection,
} from "@onlyoffice/apps-ui-kit/context/InterfaceDirectionContext";

import { useAnimation } from "@onlyoffice/apps-ui-kit/hooks/useAnimation";
import { useDebounce } from "@onlyoffice/apps-ui-kit/hooks/useDebounce";
import { useEventListener } from "@onlyoffice/apps-ui-kit/hooks/useEventListener";
import { useIsomorphicLayoutEffect } from "@onlyoffice/apps-ui-kit/hooks/useIsomorphicLayoutEffect";

Import providers

import { Providers } from "@onlyoffice/apps-ui-kit/providers";
import { ApiProvider, useApi } from "@onlyoffice/apps-ui-kit/providers/api";
import { ErrorBoundary } from "@onlyoffice/apps-ui-kit/providers/error-boundary";
import { TranslationProvider, useI18N } from "@onlyoffice/apps-ui-kit/providers/translation";
import { ThemeProvider } from "@onlyoffice/apps-ui-kit/providers/theme";
import type { TTranslations } from "@onlyoffice/apps-ui-kit/providers/translation";

Import errors

import {
  Error401,
  Error403,
  Error404,
  ErrorOfflineContainer,
  ErrorInvalidLink,
  ErrorUnavailable,
  AccessRestricted,
} from "@onlyoffice/apps-ui-kit/errors";

Import utilities

import {
  isMobile,
  isTablet,
  isDesktop,
  checkIsSSR,
} from "@onlyoffice/apps-ui-kit/utils";
import {
  IconSizeType,
  isIconSizeType,
} from "@onlyoffice/apps-ui-kit/utils/common-icons-style";
import DomHelpers from "@onlyoffice/apps-ui-kit/utils/dom-helpers";
import { useClickOutside } from "@onlyoffice/apps-ui-kit/utils/use-click-outside";
import { getCommonTranslation } from "@onlyoffice/apps-ui-kit/utils/i18n";
import { combineUrl } from "@onlyoffice/apps-ui-kit/utils/combineUrl";
import {
  getCookie,
  setCookie,
  deleteCookie,
} from "@onlyoffice/apps-ui-kit/utils/cookie";
import {
  parseAddress,
  parseAddresses,
  EmailSettings,
} from "@onlyoffice/apps-ui-kit/utils/email";

Import enums, constants, and types

import { ShareAccessRights, EmployeeType, RoomsType, ThemeKeys, FileType, FolderType } from "@onlyoffice/apps-ui-kit/enums";
import { LOADER_STYLE, OPERATIONS_NAME, EMPTY_ARRAY, EMPTY_OBJECT } from "@onlyoffice/apps-ui-kit/constants";
import type { TFile, TFolder, TUser, TFileSecurity, TFolderSecurity, TRoomSecurity } from "@onlyoffice/apps-ui-kit/types";

Components

Component Description
AccessRightSelect Dropdown selector for managing access rights and permissions on resources
AddButton Button component for adding items with optional label, loading state, and accent styling
AppLoader Full-page loading spinner displayed during application initialization
Article Responsive sidebar panel with header, main button, and body sections for navigation
Aside Sliding panel component for displaying side content like settings, details, or forms
AsideHeader Header component for aside panels with optional back/close buttons, custom icons, and loading states
Avatar Component for displaying user or group avatars with images, initials, icons, and role indicators
Backdrop Customizable overlay for modals, dialogs, and aside components with touch support
Badge Versatile badge for notifications, status markers, or interactive elements with various display modes
Button Versatile button component with primary/secondary variants, multiple sizes, loading states, and tooltip support
Calendar Custom calendar component for date selection
CategoryItem Navigation link item with optional badge and arrow indicator for menu hierarchies
Checkbox Customizable checkbox with indeterminate and error states
CircleSkeleton Circular skeleton loader for avatar and icon placeholders
ColorInput Text input for entering and validating color values
ColorPicker Interactive color selection component for choosing colors visually
ComboBox Combo box combining text input with dropdown list, supporting search and custom styling
ContextMenu Context menu for displaying contextual actions with submenus, headers, toggles, and hotkeys
ContextMenuButton Button for displaying context menu actions on list items with dropdown support
DatePicker Date picker input component for selecting dates
DateTimePicker Combined date and time input component
DragAndDrop File drag-and-drop handler for upload operations
DropDown Dropdown component for menus, options, and contextual content with auto-positioning
DropDownItem Dropdown item for menus and lists with separator, header, submenu, and toggle support
Dropzone Interactive file drop area with visual feedback and file type restrictions
EmailInput Email address input with built-in validation and error reporting
EmptyScreenContainer Component for displaying empty states with image, text, and action buttons
EmptyView Empty state component with icon, title, description, and interactive options
ErrorContainer Full-page error display with decorative background, message, and action button
FieldContainer Container wrapper for form fields with consistent spacing and styling
FileInput File entry field
FilterInput Filter component with search, sorting, and view options for data filtering
FloatingButton Circular floating action button with progress indicator and alert icon
FormWrapper Wrapper for form elements providing consistent form styling and layout
Heading Heading text structured in levels with customizable sizes and types
HelpButton Info icon button that triggers a tooltip with help content
IconButton Button component displaying an icon with hover, click, and disabled states
ImageEditor Image cropping and editing component with file upload and preview support
InfiniteLoader Virtualized infinite scroll container for loading items progressively
InputBlock Input component combining text input with optional icon and children elements
Label Form label with required indicator and tooltip support
Link Hyperlink component with page and action types
LinkWithDropdown Link that opens a dropdown menu with additional options
Loader Loading indicator with multiple animation types
LoaderWrapper Wrapper that dims children and blocks interactions during loading
LoadingButton Circular button with animated progress bar and completion indicator
MainButton Primary action button with optional dropdown menu for desktop
MainButtonMobile Floating action button with expandable menu for mobile interface
MCPIcon Icon component for MCP (Model Context Protocol) with image or text fallback
ModalDialog Versatile modal dialog component supporting both modal and aside (side panel) display types with keyboard shortcuts
Navigation Breadcrumb navigation with expandable hierarchical sections
NewChat AI chat interface backed by the @onlyoffice/ai-chat package with threads, streaming responses, file attachments, and tool calls
OperationsProgressButton Operation progress tracker for multiple concurrent operations with error checking
Paging Pagination controls for navigating through pages of data
PasswordInput Password input with strength validation, generator, and reveal/hide toggle
Portal Renders children into a different DOM node
PortalLogo Responsive logo component with fallback handling
ProgressBar Visual progress indicator bar and portal preparation progress display
PublicRoomBar Information bar for public room notifications with header, body text, and close button
RadioButton Radio button component with customizable labels and styles
RadioButtonGroup Group of radio buttons with horizontal/vertical layouts and text labels
RectangleSkeleton Rectangular skeleton loader for text, buttons, and content placeholders
RoomIcon Room icon component with support for images, colors, badges, editing, and various states
RoomLogo Room logo component displaying room type icons with archive, template, and checkbox support
Row Versatile list row with checkbox, context menu, badges, and modern/default layouts for file or member listings
RowContainer Wrapper for rendering multiple rows with optional react-window virtualization and infinite loading
RowContent Layout helper that arranges row title, icons, and side sections while generating tablet-friendly summaries
Scrollbar Custom scrollbar component with auto-hide, RTL support, and flexible styling options
SearchInput Search input component with auto-refresh, clear button, and debounce support
Section Page layout with header, filter, body, footer, info panel, and operations progress sections
SelectedItem Component for displaying selected items with remove functionality
SelectionArea Mouse-driven rectangular selection area for selecting multiple items
Selector Dropdown selector with access rights modes for item selection with permissions
Slider Range input slider with optional fill visualization and RTL support
SnackBar Toast notification component for temporary messages and alerts
StatusMessage Animated status message component for displaying error and warning messages
TabItem Tab navigation component with active states, multi-select, and disabled state support
TableContainer Modular table with body, row, header, group menu, and cell sub-components
Tabs Tab container component with primary/secondary themes, sticky positioning, and content management
Tag Tag component for displaying virtual room tags
Tags Container component for displaying multiple tags
Text Typography component with various styling options
TextInput Input field for single-line strings with masking support
Textarea Multi-line text input with JSON formatting, line numbers, and copy functionality
ThemeProviderComponent The older theme provider; new code uses ThemeProvider from providers/theme
TimePicker Time input component for selecting time values
Toast Notification component with success, error, warning, and info variants (see i18n Setup)
ToggleButton Customizable toggle button with loading and disabled states
Tooltip Customizable tooltip with multiple trigger options
TopLoaderService Top page progress bar service with start(), end(), cancel() static methods
BaseTile Base tile component providing foundational structure for all tile components
FileTile File tile component for displaying file information with thumbnail preview
FolderTile Folder tile component with support for compact and big folder views
RoomTile Room tile component for displaying room information with tags and metadata
TemplateTile Template tile component with owner and storage metadata
TileContainer Container for organizing tiles in a grid layout with automatic categorization
TileContent Content wrapper component for tile children with consistent styling

Contexts

Context Description
ThemeContext Theme management context with support for Base/Dark themes and custom color schemes
InterfaceDirectionContext Interface direction context for managing LTR/RTL layout support

Hooks

Hook Description
useAnimation Manages animation state with phases (none/start/progress/finish), dispatches custom window events, and returns refs and triggerAnimation()
useDebounce Debounces callback execution with configurable delay and automatic cleanup on unmount
useEventListener Typed event listener hook for Window, HTML/SVG elements, Document, and MediaQueryList with automatic cleanup
useIsomorphicLayoutEffect SSR-safe effect hook — uses useLayoutEffect in browser, useEffect on server

Providers

Composed providers that wrap your application with error handling, API access, translations, and theming.

Provider Description
Providers All-in-one composition of ErrorBoundary, ApiProvider, TranslationProvider, and ThemeProvider
ApiProvider Creates React Context with profilesApi and commonSettingsApi from @onlyoffice/docspace-api-sdk
ErrorBoundary Class component that catches render errors with custom fallback UI and onError callback
TranslationProvider Wraps I18nextProvider and initializes i18next with translation resources
ThemeProvider Resolves theme (Base/Dark/System), fetches color themes, monitors system preferences

Quick Start

import { Providers } from "@onlyoffice/apps-ui-kit/providers";
import enCommon from "@onlyoffice/apps-ui-kit/locales/en/Common.json";
import type { TTranslations } from "@onlyoffice/apps-ui-kit/providers/translation";

const translations: TTranslations = new Map([
  ["en", new Map([["Common", enCommon]])],
]);

<Providers
  url="https://your-docspace.com"
  apiKey="your-api-key"
  translations={translations}
  locale="en"
>
  <App />
</Providers>;

See Providers with i18n for full internationalization guide.

Errors

Pre-built error page components that wrap ErrorContainer with localized messages via getCommonTranslation.

Component Translation Key Description
Error401 Error401Text Unauthorized access error
Error403 Error403Text Forbidden access error
Error404 Error404Text Page not found error
ErrorOfflineContainer ErrorOfflineText Offline / no connection error
ErrorInvalidLink InvalidLink, LinkDoesNotExist Invalid or expired link error
ErrorUnavailable ErrorDeactivatedText Portal deactivated error
AccessRestricted AccessDenied, PortalRestriction Access restricted error
import { Error401, Error403, Error404 } from "@onlyoffice/apps-ui-kit/errors";

Utilities

Utility Description
common-icons-style Styled-components CSS helper for consistent icon sizing with IconSizeType enum
combineUrl Merges base URL with path segments, handling trailing/leading slashes
common getUserTypeTranslation for employee role types, RoomsTypeValues, RoomsTypes helpers
context React context with optional sectionWidth and sectionHeight
cookie getCookie, setCookie, deleteCookie — cookie management with asc_language special handling
date Date utilities: formatting, arithmetic, comparison, duration, timezone, and parsing
device Device detection utilities: isMobile, isTablet, isDesktop, checkIsSSR
dom-helpers DOM utilities for viewport, element positioning, scrollbar width, and z-index management
edge-scrolling Auto-scrolls when mouse is near viewport edges — used for drag-and-drop operations
email Email parsing and validation: parseAddress, parseAddresses, EmailSettings, isValidDomainName
get-system-theme Returns system theme preference (Dark or Base) from AscDesktopEditor or prefers-color-scheme
get-text-color Determines optimal text color (black/white) for a background based on perceived brightness
getFilesFromEvent Converts drag/drop/paste/input events to File arrays with recursive directory handling
getLogoUrl Generates logo URL using WhiteLabelLogoType enum with culture and theme parameters
hasOwnProperty Safe Object.hasOwn check with try-catch that handles null/undefined
i18n getCommonTranslation(key) — retrieves localized strings from window.i18n
openingNewTab Detects middle-click / Ctrl+Click / Cmd+Click to open URLs in new tabs
trim-separator Cleans up context menu arrays by removing redundant separators and disabled items
use-click-outside React hook for detecting clicks outside an element, useful for dropdowns and modals
uuid UUID v4 generation utility for unique identifiers
add-log Conditionally logs to the browser console or accumulates messages in window.logs based on ClientConfig settings
getTitleWithoutExtension Strips the file extension from a title string, returning the bare name
image-helpers Generates Maps of file extension → SVG icon URL for 24 / 32 / 64 / 96 px icon sizes across document and folder types
presentInArray Checks whether a string exists in an array with optional case-insensitive comparison
socket SocketHelper singleton for managing WebSocket connections, event subscriptions, and message emission with typed event/command enums
typeGuards Type guard that checks whether a value is a Next.js StaticImageData object (src, height, width)

Enums

Shared enums available from @onlyoffice/apps-ui-kit/enums:

Enum Values
ShareAccessRights None, FullAccess, ReadOnly, DenyAccess, Varies, Review, Comment, FormFilling, CustomFilter, RoomManager, Editing, Collaborator
EmployeeType Owner, Admin, RoomAdmin, User, Guest
RoomsType PublicRoom, FormRoom, EditingRoom, VirtualDataRoom, CustomRoom, AIRoom
EmployeeStatus Active, Disabled, Pending
FileType Unknown, Archive, Video, Audio, Image, Spreadsheet, Presentation, Document, etc.
FolderType DEFAULT, CommonDocuments, MyDocuments, Favorites, Recent, Trash, Archive, Rooms, etc.
ThemeKeys BaseStr, DarkStr, SystemStr

Constants

Shared constants from @onlyoffice/apps-ui-kit/constants:

Constant Description
LOADER_STYLE Skeleton loading configuration (width, opacity, speed)
OPERATIONS_NAME Operation type identifiers (trash, download, copy, move, convert)
ROOM_ACTION_KEYS Room editing action keys
EMPTY_ARRAY Frozen empty array for stable references
EMPTY_OBJECT Frozen empty object for stable references
FUNCTION_EMPTY No-op function
LANGUAGE Cookie name constant: "asc_language"

Types

Key TypeScript types from @onlyoffice/apps-ui-kit/types:

Type Description
TFile Comprehensive file object with security, status, and metadata
TFolder Folder object with security and access rights
TUser User/employee data including avatar, status, admin flags, quota
TCreatedBy Author info: avatar, displayName, id, profileUrl
TLogo Logo object with multiple sizes
TFileSecurity Detailed file access rights
TFolderSecurity Detailed folder access rights
TRoomSecurity Detailed room access rights
TViewAs View mode: "tile", "table", "row", "settings", "profile"

Selectors

Variant Item type Description
Users Selector TSelectorItemUser Picks workspace members; rows show avatar, role badge, employee type label, and group membership
Groups Selector TSelectorItemGroup Picks user groups; distinguishes regular groups from system-managed ones
Files Selector TSelectorItemFile Picks files; rows show file-type icon and extension label
Folders Selector TSelectorItemFolder Picks folders; rows show folder icon with nested file and subfolder counts
Rooms Selector TSelectorItemRoom Picks rooms; rows show room icon, cover image, tags, and room-type badge
MCP Selector TSelectorItemMCP Picks Model Context Protocol agents; rows show agent icon and name

Theming

The library ships with globalColors - 100+ named color tokens. It can be imported from the root barrel or from the theme provider entry point:

import { globalColors } from "@onlyoffice/apps-ui-kit";
// or
import { globalColors } from "@onlyoffice/apps-ui-kit/providers/theme";

// Base
const white = globalColors.white; // "#ffffff"
const black = globalColors.black; // "#333333"

const primary = globalColors.lightBlueMain;
const success = globalColors.mainGreen;
const error = globalColors.mainRed;
const warning = globalColors.mainOrange;

i18n Setup

Several components support automatic localization from window.i18n. This includes:

  • Toast - automatic titles for success/error/warning/info notifications
  • DropDownItem - beta and paid badge labels
  • Selector - empty screen texts, button labels, and error messages
  • Error pages - all error messages (Error401, Error403, Error404, etc.)

Setup

Set up window.i18n with your translations:

window.i18n = {
  loaded: {
    "en/Common.json": {
      data: {
        // Toast titles
        Done: "Done",
        Warning: "Warning",
        Alert: "Alert",
        Info: "Info",
        // DropDownItem badges
        BetaLabel: "Beta",
        Paid: "Paid",
        // Selector
        ClearFilter: "Clear filter",
        Back: "Back",
        ContainsSpecCharacter: "Contains special characters",
        NoRoomsFound: "No rooms found",
        SelectorFormRoomEmptyScreenDescription: "Create a form filling room...",
        SelectorVDREmptyScreenDescription: "Create a virtual data room...",
        CreateFormFillingRoom: "Create form filling room",
        CreateVirtualDataRoom: "Create virtual data room",
        // FileInput
        NotSupportedFormat: "Sorry, this file format isn't supported",
      },
    },
    "de/Common.json": {
      data: {
        Done: "Fertig",
        Warning: "Warnung",
        Alert: "Achtung",
        Info: "Info",
        BetaLabel: "Beta",
        Paid: "Kostenpflichtig",
        ClearFilter: "Filter zurücksetzen",
        Back: "Zurück",
        // ... other translations
      },
    },
    // Add more languages as needed
  },
};

Language Detection

Components read the language from the asc_language cookie. The language mapping:

  • en-US, en-GB → en
  • Other values are used as-is (e.g., ru, de, fr)

Translation Keys by Component

Component Translation Keys
Toast Done, Warning, Alert, Info
DropDownItem BetaLabel, Paid
Selector ClearFilter, Back, ContainsSpecCharacter, NoRoomsFound, SelectorFormRoomEmptyScreenDescription, SelectorVDREmptyScreenDescription, CreateFormFillingRoom, CreateVirtualDataRoom

Using getCommonTranslation utility

You can import and use the getCommonTranslation utility directly:

import { getCommonTranslation } from "@onlyoffice/apps-ui-kit/utils";

const title = getCommonTranslation("Done"); // Returns localized "Done" or undefined
const label = getCommonTranslation("BetaLabel"); // Returns localized "BetaLabel" or undefined

Providers with i18n

The Providers component integrates i18next for full internationalization support. This is the recommended approach for applications that need proper i18n with React hooks (useTranslation), automatic language detection, and the window.i18n bridge for standalone components.

How It Works

  1. TranslationProvider initializes an i18next instance with your translations
  2. It wraps children in I18nextProvider from react-i18next
  3. It also sets window.i18n.t and window.i18n.loaded so standalone components (Toast, DropDownItem, Selector, Error pages) can read translations without React context

Translation Data Structure

Translations use a TTranslations type — a nested Map:

type TTranslations = Map<
  string, // language code (e.g., "en", "ru", "fr")
  Map<
    string, // namespace (always "Common")
    Record<string, string> // key-value translation pairs
  >
>;

Step-by-Step Setup

1. Import locale files

The package ships English only -- Common.json, Payments.json and Settings.json under @onlyoffice/apps-ui-kit/locales/en/. Only locales/en is committed (see .gitignore), and pnpm pack ships what is on disk, so a publish from a clean checkout carries English and nothing else:

import enCommon from "@onlyoffice/apps-ui-kit/locales/en/Common.json";

Every other language comes from the host application. The portal apps build their translations map from their own public/locales, and any consumer does the same with its own resources; the kit's components read whatever TranslationProvider is given. The 32 languages the portal carries can be refreshed into a local checkout with pnpm sync-locales, which copies them from a DocSpace-client checkout for Storybook and manual checks -- they are not committed and not published.

2. Build the translations map

import type { TTranslations } from "@onlyoffice/apps-ui-kit/providers/translation";

const translations: TTranslations = new Map([
  ["en", new Map([["Common", enCommon]])],
  ["ru", new Map([["Common", ruCommon]])],
  ["de", new Map([["Common", deCommon]])],
  ["fr", new Map([["Common", frCommon]])],
]);

3. Wrap your app with Providers

import { Providers } from "@onlyoffice/apps-ui-kit/providers";

function App() {
  return (
    <Providers
      url="https://your-docspace.com"
      apiKey="your-api-key"
      translations={translations}
      locale="en"
      initialTheme="BaseStr"
      errorFallback={(error) => <div>Error: {error.message}</div>}
      onError={(error, errorInfo) => console.error(error, errorInfo)}
    >
      <YourApp />
    </Providers>
  );
}

4. Use translations in components

Inside the provider tree, use react-i18next hooks:

import { useTranslation } from "react-i18next";

function MyComponent() {
  const { t } = useTranslation("Common");

  return (
    <div>
      <h1>{t("Settings")}</h1>
      <button>{t("SaveButton")}</button>
      <button>{t("CancelButton")}</button>
    </div>
  );
}

Language Resolution

The TranslationProvider resolves the active language in this priority order:

  1. locale prop (explicit override)
  2. user.cultureName (from user profile)
  3. settings.culture (from portal settings)
  4. "en" (fallback)

If settings and user are not passed as props, they are fetched automatically from the ONLYOFFICE Apps API using the url and apiKey provided.

Props Reference

Prop Type Required Description
url string Yes Base URL of the ONLYOFFICE Apps API
apiKey string Yes API key for authentication
translations TTranslations No Translation resources map
locale string No Locale override (e.g., "en", "ru")
settings SettingsDto No Portal settings (fetched from API if not provided)
user EmployeeFullDto No Current user (fetched from API if not provided)
initialTheme ThemeKeys No Initial theme: "BaseStr", "DarkStr", "SystemStr"
systemTheme ThemeKeys No Override for system theme detection
colorTheme CustomColorThemesSettingsDto No Color theme data
errorFallback ReactNode | ((error: Error) => ReactNode) No Custom error UI
onError (error: Error, errorInfo: ErrorInfo) => void No Error callback
children ReactNode Yes Child components

Using Individual Providers

You can also use sub-providers individually for more control:

import { ApiProvider } from "@onlyoffice/apps-ui-kit/providers/api";
import { TranslationProvider } from "@onlyoffice/apps-ui-kit/providers/translation";
import { ThemeProvider } from "@onlyoffice/apps-ui-kit/providers/theme";
import { ErrorBoundary } from "@onlyoffice/apps-ui-kit/providers/error-boundary";

<ErrorBoundary fallback={<ErrorPage />}>
  <ApiProvider url="https://your-docspace.com" apiKey="your-api-key">
    <TranslationProvider
      translations={translations}
      locale="en"
      settings={settings}
      user={user}
    >
      <ThemeProvider initialTheme="BaseStr" locale="en">
        <App />
      </ThemeProvider>
    </TranslationProvider>
  </ApiProvider>
</ErrorBoundary>;

Using the useApi hook

Inside ApiProvider, access API clients via the useApi hook:

import { useApi } from "@onlyoffice/apps-ui-kit/providers/api";

function MyComponent() {
  const { profilesApi, commonSettingsApi } = useApi();

  useEffect(() => {
    profilesApi.getSelfProfile().then((res) => {
      console.log(res.data.response);
    });
  }, [profilesApi]);
}

Development

This package is developed standalone — clone it and run pnpm install. No DocSpace-client checkout is required for development, Storybook or tests; locales/en is committed so everything works out of the box.

css/fonts.css and fonts/ are vendored here too, for the same reason: Storybook imports the stylesheet, so a fresh clone has to have it. pnpm sync-locales (with DOCSPACE_CLIENT_ROOT pointing at a DocSpace client checkout) refreshes them along with the non-English locales — run it when the upstream fonts or strings change.

Line endings (Windows: one-time migration)

The repository is LF everywhere, enforced by .gitattributes (* text=auto eol=lf). Prettier is configured with endOfLine: "lf" and pnpm format is part of the pre-push gate, so a CRLF working copy fails the push — with every file in the repository listed, which says nothing about what is actually wrong.

.gitattributes only decides what git writes at checkout. A clone made after it landed is already correct and needs nothing. A checkout that predates it keeps its CRLF working copies, so convert it once:

git status                     # commit or stash anything you care about first
git add --renormalize .
git checkout -- .              # rewrites the working tree; discards uncommitted changes

git checkout -- . throws away uncommitted work — that is the point of the git status above. git add --renormalize . on its own is not enough: it updates the index, never the working tree.

To confirm afterwards, this prints nothing when the tree is clean — w/none is an empty file, which has no line endings either way:

git ls-files --eol | grep -vE 'w/lf|w/none|i/-text'

Running any of this from VS Code

Open ui-kit.code-workspace rather than the folder. It adds six grouped buttons to the status bar, each opening a list of tasks:

Button What it runs
📖 Storybook dev server, static build, serve the built site
✅ Check the whole pre-push gate in one go, or tsc / Biome / Vitest / Prettier on their own
📦 Package build, verify:package, both together, pack --dry-run, clean
🔍 Audit the checks nothing else runs — plugin API surface, drift against the plugin skill, undefined tokens and hardcoded hex, manifest invariants, missing docs — plus the component scaffolder
📸 E2E Playwright locally or in Docker, and the screenshot update
🔄 Sync pnpm install, and refreshing locales, fonts and icons from a client checkout

The buttons come from the VsCodeTaskButtons extension (spencerwmiles.vscode-task-buttons), which VS Code offers on first open — it is in .vscode/extensions.json. Without it nothing is lost: the same tasks are in Terminal → Run Task…, and every one of them is a pnpm script or a node .claude/scripts/… command you can type yourself.

.vscode/launch.json adds debuggers for Vitest — the open file or the whole suite — and a browser attached to a Storybook the Storybook button has already started.

Adding a button means editing three files, and missing one leaves a button that appears and does nothing: the script in package.json, the task in .vscode/tasks.json, and the button in ui-kit.code-workspace, whose task field must match the task's label exactly. .claude/rules/vscode-tasks.md has the detail and a one-liner that checks the three agree.

Storybook - interactive component explorer

pnpm storybook

Opens at http://localhost:6006 - browse components, tweak props with the controls panel, and see live previews.

Tests

pnpm test           # run all tests once
pnpm test:watch     # watch mode
pnpm test:coverage  # with coverage report
pnpm test:ui        # Vitest UI dashboard

Visual regression (Playwright)

The specs in __tests__/ drive a Storybook on port 6007 and compare full-page screenshots against the baselines committed next to them. They are not part of the pre-push gate and not run in CI, so they only report what you ask them to.

pnpm test:e2e                      # locally: build Storybook, then run the specs
pnpm test:e2e:ui                   # the interactive Playwright runner

pnpm test:e2e:docker:build         # build the image (once, and after a dependency change)
pnpm test:e2e:docker:start         # run the suite inside it
pnpm test:e2e:docker:dev           # same, with the sources mounted from the working tree
pnpm test:e2e:docker:update-screenshots   # rewrite the baselines -- review every image
pnpm test:e2e:docker:clear         # drop the image

Compare screenshots in Docker, not on the host. Font rendering and browser behaviour differ between macOS and Linux, so a baseline taken on the host fails everywhere else. The image carries the same fonts and the same pinned Chromium for everyone.

Both the report layout and the reporters match the DocSpace client's packages: dot for the console, an HTML report and test-results.json, all under playwright-report/.

pnpm test:e2e:report   # serve the last HTML report on port 9330

WORKERS=1 pnpm test:e2e:docker:start pins the run to one worker, the way CI runs it — worth doing when a spec fails only under parallel load.

Build

pnpm build          # production build (ESM + type declarations; no CJS)
pnpm build:watch    # rebuild on file changes

The build also runs a set of checks against dist/: no bundled dependency compiled into the output, every emitted module an index file (the exports map is one ./* wildcard, and nothing else would resolve), and a "use client" directive preserved for each of the 55 modules that declare one — rollup drops module-level directives while bundling, and without them every Next.js App Router consumer breaks on the first interactive component.

Verifying the package

pnpm verify:package # pack, then run publint + attw against the real tarball
pnpm pack --dry-run # list exactly what would be published

verify:package is what catches defects the lint/tsc/test gate cannot see — a broken build, entry points missing because publishConfig was not applied, or types that misrepresent the JavaScript. It must be run with pnpm: publishConfig field overrides are a pnpm feature, and an npm-packed tarball has no exports/main at all.

Lint & Format

pnpm lint           # Biome - check for lint issues
pnpm lint:fix       # Biome - auto-fix lint issues
pnpm format         # Prettier - check formatting
pnpm format:fix     # Prettier - rewrite files

Linting is Biome and formatting is Prettier: Biome's own formatter is disabled in biome.json. Only lint, tsc and test run on pre-push and in CI, so formatting is not enforced by any gate.

Useful Links

Resource URL
🌐 ONLYOFFICE Website onlyoffice.com
🐙 DocSpace-client Monorepo github.com/ONLYOFFICE/DocSpace-client
📖 ONLYOFFICE API api.onlyoffice.com
💬 Community Forum community.onlyoffice.com
🆘 Help Center helpcenter.onlyoffice.com
📣 Feedback feedback.onlyoffice.com

Contributing

Issues and feature requests are tracked in the DocSpace-client repository. Contributions are welcome - please open an issue or PR there, or start a discussion on the community forum.

Changelog

Release notes are in CHANGELOG.md. Start there before upgrading: 4.0.0 renamed the package, made it ESM-only and put an exports map in front of every subpath.

Authors

AUTHORS.md.

License

AGPL-3.0-only. See LICENSE.

About

React UI component library behind ONLYOFFICE Apps

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages