docx-editor

Styling

The stylesheet, the CSS custom properties an application may set, and font fallbacks.

The editor ships one stylesheet and expects it to be imported once:

import "@portone/docx-editor/styles.css";

It carries the ProseMirror base styles it needs, so there is nothing else to import. The paper itself is drawn from the open document: page size, margins, default font, and default line height all come from that document rather than from the stylesheet, so a document keeps its own appearance whatever the surrounding application looks like.

The frame

DocxEditor renders an outer frame that already looks finished without a wrapper: a neutral border and rounded corners around the toolbar and the paper. Both are read from custom properties, so an application restyles them in place instead of wrapping the editor in a box of its own.

.my-editor {
  --docx-editor-border: none;
  --docx-editor-radius: 0;
}

Pass that class through className, or set the properties on any ancestor. style reaches the same frame, which is where a height comes from when the surrounding layout does not give one.

Properties you may set

PropertyDefaultWhat it controls
--docx-editor-border1px solid rgb(0 0 0 / 12%)The frame's border. none removes it.
--docx-editor-radius12pxThe frame's corner radius.
--docx-editor-comments-width320pxThe width of the comment rail. The package narrows it to 240, 200, and 180 pixels as the viewport crosses 840, 720, and 560 pixels, so an override for small screens needs a query of its own.
--docx-editor-horizontal-scrollbar-size10pxThe space kept clear below the comment rail for the horizontal scrollbar a zoomed page brings.

Properties the editor writes

The editor sets several other properties of its own on the elements it renders, and an application should read them rather than assign them. --docx-editor-zoom carries the current zoom factor, published so that panels outside the zoomed page layer can scale with the paper; the page size, margins, sheet height, default font, default line height, list marker width, and tab width are all measured from the open document and change as the document changes. Setting one of them by hand puts the visible layout out of step with the measurements the editor made, which is what the page guides and the comment positions are drawn from.

--docx-editor-zoom is worth reading when custom controls sit next to the paper and should scale with it. Custom controls covers the zoom props themselves.

Font fallbacks

A document names the fonts it was written with, and a reader's machine usually carries only some of them. The editor keeps the declared name first and appends a fallback stack after it, so text lands on a font of the right shape rather than on the browser's default. The built-in set knows the CJK and Latin office font names and ends on a Latin sans for everything else.

Pass fontFallbacks to stand different fonts in:

import {
  DEFAULT_FONT_FALLBACKS,
  DocxEditor,
  type FontFallbacks,
} from "@portone/docx-editor";

const fallbacks: FontFallbacks = {
  groups: [{ stack: '"Inter", sans-serif', names: ["arial", "helvetica"] }],
  defaultStack: '"Inter", sans-serif',
  defaultFontName: "Inter",
};

<DocxEditor document={file} fontFallbacks={fallbacks} />;

A group is one family: every name in it is drawn with the same stack, and matching ignores letter case because documents vary in how they write a font name. defaultStack covers a name in no group and the paper of a document that declares no font at all, and defaultFontName is the name the toolbar shows in that case, so it should be a font defaultStack really renders. DEFAULT_FONT_FALLBACKS is exported for a set built by extending the built-in one.

The package names fonts and never downloads them. The built-in Korean stacks name Pretendard first, for instance, but loading it is the application's own business; a machine without it falls through to the operating system's fonts.

Fallbacks are display only. The exported document keeps the fonts it declared, and fontFallbacks is read once when the editor mounts, so building the object inline on every render is harmless. The paragraph style picker and the HTML written to the clipboard keep the built-in set, which is shared beyond a single editor.

On this page