Row
One row of the file list: an optional checkbox, a start element, the content and a context menu. Which parts appear is decided by which props you pass at all, not by their values.
Use this when / not when
- Use inside a
RowContainer, with aRowContentas its child — the shape the portal's file list is made of. - Not as a generic list row. It reads
itemoff its child's props to build its context menu's header, and it renders a right-click menu whether or not you want one. - Not for tabular data the user sorts:
Table. - Not for a clickable card or a menu entry —
DropDownItemor markup of your own is smaller and says what it is.
Import
import { Row } from "@onlyoffice/apps-ui-kit/components/rows/row";
components/index.ts does not list this folder, but it lists rows, and export *
is transitive — so the name arrives from @onlyoffice/apps-ui-kit/components/rows and from
the root barrel @onlyoffice/apps-ui-kit as well.
RowProps is not exported — type a wrapper's props yourself, or import the type from its
file path.
Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme, and
TranslationProvider from @onlyoffice/apps-ui-kit/providers/translation for the context
menu's own labels.
Stories
Default
The row as a file list shows it: click the checkbox to tick and untick it, click the text, open the menu from the three-dot button or with a right-click anywhere on the row, and watch each call in the Actions panel. Change any other prop live in the Controls panel below.
Modern Layout
A row that keeps its start element where the checkbox would be, so an unselected list shows icons rather than a column of empty boxes (mode="modern"). Hover the icon and the checkbox takes its place; tick it and the checkbox stays. Both checked and element have to be passed, or neither is shown.
Indeterminate State
A half-ticked checkbox, for a row that stands for a group of which only some items are selected (indeterminate).
Disabled State
A row that cannot be selected: the checkbox is greyed out and ignores clicks (isDisabled), while a click on the text still reaches onRowClick and the three-dot menu still opens.
Loading State
A row that is busy, for example while its file is being copied: a spinner stands in for the checkbox and the icon (inProgress), and the text and the three-dot button stay as they are.
Index Editing
A row whose place in a hand-ordered list is being changed: the three-dot button gives way to an up and a down arrow (isIndexEditingMode). Click either and the direction arrives in the Actions panel (onChangeIndex); moving the row is up to the host.
With Badges
Extra information at the end of the row, before the three-dot button: the New badge (badgesComponent) and the 2 versions note after it (contentElement).
Without Border
The last row of a list, or a row that stands alone, usually needs no divider under it: With a divider keeps the one-pixel line, Without a divider drops it (withoutBorder).

Context Menu Header
A menu that names what it acts on, on a phone-sized screen: tap the three-dot button and a menu taller than 210px opens from the bottom of the screen under a header reading Quarterly report.docx with its icon. The row takes the header from the item prop of its content, so the content has to accept and carry one; a shorter menu, or any menu on a wide screen, opens beside the row without a header.
Right To Left
The row in a right-to-left interface: the checkbox and the icon move to the right edge, the text starts from the right, and the badge and the three-dot button sit at the left edge.
Minimal example
contextOptions is what decides whether a context button is rendered; an empty array means no.
import { Row } from "@onlyoffice/apps-ui-kit/components/rows/row";
import { RowContent } from "@onlyoffice/apps-ui-kit/components/rows/row-content";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
export function FileRow({ name }: { name: string }) {
return (
<Row contextOptions={[]}>
<RowContent>
<Text fontWeight={600}>{name}</Text>
<span />
</RowContent>
</Row>
);
}
Props
Recipes
Selection
import { useState } from "react";
import { Row } from "@onlyoffice/apps-ui-kit/components/rows/row";
import { RowContent } from "@onlyoffice/apps-ui-kit/components/rows/row-content";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
export function SelectableRow({ name }: { name: string }) {
const [checked, setChecked] = useState(false);
return (
<Row
checked={checked}
contextOptions={[]}
onSelect={(next) => setChecked(next)}
onRowClick={() => setChecked(!checked)}
>
<RowContent>
<Text fontWeight={600}>{name}</Text>
<span />
</RowContent>
</Row>
);
}
Loading
inProgress replaces the checkbox and the start element with a spinner; the content and the
context menu stay.
import { Row } from "@onlyoffice/apps-ui-kit/components/rows/row";
import { RowContent } from "@onlyoffice/apps-ui-kit/components/rows/row-content";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
export function UploadingRow({ name, done }: { name: string; done: boolean }) {
return (
<Row checked={false} inProgress={!done} contextOptions={[]}>
<RowContent>
<Text fontWeight={600}>{name}</Text>
<span />
</RowContent>
</Row>
);
}
Disabled
isDisabled disables the checkbox alone. The row stays clickable and its context menu still
opens.
import { Row } from "@onlyoffice/apps-ui-kit/components/rows/row";
import { RowContent } from "@onlyoffice/apps-ui-kit/components/rows/row-content";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
export function LockedRow({ name }: { name: string }) {
return (
<Row checked={false} isDisabled contextOptions={[]}>
<RowContent>
<Text fontWeight={600}>{name}</Text>
<span />
</RowContent>
</Row>
);
}
Behaviour the types don't state
- A prop being present is what renders a part. The row asks whether
checked,elementandcontentElementare keys of its props, not whether they hold anything, sochecked={undefined}still renders a checkbox and omitting the prop is the only way to have none. - The context menu's header comes from the child's
itemprop. The row reaches intochildren.props.itemfor the title, icon, avatar and logo — so the header is empty unless the child accepts and carries anitem. The row's ownitemprop is not read at all. - Options may come from two places.
data.contextOptionswins overcontextOptionswhen it has any;getContextModelis what the menu calls when it opens. With no options the button is replaced by an empty spacer ofcontextButtonSpacerWidth. - The whole row opens the menu on right-click, and if the menu is not mounted yet the row clicks itself first to mount it — a workaround left in the source.
onRowClickis bound to the content and the start element, not to the row: a click on the checkbox, the badges or the context button does not reach it.- On a touch device a click on the start element also selects the row, calling
onSelect(true). mode="modern"puts the checkbox in the start element's place and needs bothcheckedandelementpresent, or neither is rendered. The start element shows until the row is checked or the pointer is over it; then the checkbox takes its place. The hover swap is off on a touch device and in index-editing mode, where only checking the row shows the checkbox.- On a phone-sized screen the context menu opens behind a backdrop, and a menu taller than
210px opens as a sheet from the bottom, under the header built from the child's
item. idandstyleare declared and never read;classNameis the way in.- The component is memoised with a deep comparison of all its props.
Accessibility
- The row is a
<div>with no role, not focusable, and its click handlers are on inner elements. TheCheckboxis the only part a keyboard reaches. - The context menu opens on right-click or from a
ContextMenuButton, which is itself a<div>— there is no keyboard route to it. - Nothing announces selection: the row carries no
aria-selected, only a class.
Test ids
Related
RowContent— the child this expects, and whereitemlives.RowContainer— the list around it.ContextMenu— the menu it renders for every row.