FileTile
Tile for a document: a thumbnail with badges over it, and a name row with a checkbox and a menu. It is the card form of one file in the DocSpace listing, and the only tile in the family with a preview image.

Use this when / not when
- Use for a document in a tile listing, with a thumbnail when you have one and an icon when you do not.
- Not for a folder —
FolderTilehas its own two layouts and no thumbnail fallback chain. - Not for a room or a template —
RoomTileandTemplateTile. - Not for a card of your own —
BaseTileis the shell without the file-specific click handling. - A plain click selects the file; it does not open it. Opening is up to the link you put in
the content, or to
thumbnailClick. See the note about the class names that make a click harmless.
Import
import { FileTile } from "@onlyoffice/apps-ui-kit/components/tiles/file-tile";
components/index.ts does not list this folder, but it lists tiles, and export *
is transitive — so the name arrives from @onlyoffice/apps-ui-kit/components/tiles and from
the root barrel @onlyoffice/apps-ui-kit as well.
Needs ThemeProvider for its colours and TranslationProvider for the three-dot button's
tooltip, which it asks the kit's own translation hook for under the key TitleShowActions.
Stories
Default
A document with no preview yet: a placeholder picture, a badge and a quick action over it, and the name row with the menu. Click the tile to select it, Ctrl- or Shift-click it to see the other callbacks in the Actions panel, and change any other prop live in the Controls panel below.

Checked
A selected file, as it looks among others the reader has picked: the checkbox stays ticked in place of the icon and the whole tile is tinted (checked).

In Progress
A file that is busy, being uploaded or converted: a small loader stands where the icon and the checkbox were (inProgress).

With Thumbnail
A document with a preview: the image fills the upper part, cropped from the top, and the badges sit over it (thumbnail). If the image fails to load, the placeholder from temporaryIcon takes its place.
With Hotkey Border
The tile the keyboard is on while the reader moves through the grid with the arrow keys: its border turns the accent colour (showHotkeyBorder). The tile does not handle the keys itself.

Renaming State
A file whose name is being edited: the icon and the checkbox go, so the name row can hold a text field (isEdit).

Css Customization
The variables are listed under CSS variables on this page.
Two instances:
- Document.docx — a preview, a badge and a quick action, for every variable except
--file-tile-border-style,--tile-icon-display,--tile-hotkey-colorand--highlightColor; hover it for the hover variables. - Report.docx —
showHotkeyBorder, for--tile-hotkey-color, in a wrapper of its own that sets--file-tile-border-styleto a thicker border and--tile-icon-displaytonone.
--highlightColor is not set here: the highlight plays once, on mount, and is gone before a reader looks.

Minimal example
import { Link } from "@onlyoffice/apps-ui-kit/components/link";
import { FileTile } from "@onlyoffice/apps-ui-kit/components/tiles/file-tile";
import { TileContent } from "@onlyoffice/apps-ui-kit/components/tiles/tile-content";
const file = {
id: "d1",
title: "Report.docx",
fileExst: ".docx",
contextOptions: [],
};
export function DocumentTile() {
return (
<FileTile item={file} contextOptions={[]} temporaryIcon="/icons/docx.svg">
<TileContent>
<Link className="item-file-name">{file.title}</Link>
</TileContent>
</FileTile>
);
}
Props
Recipes
Selection, including Ctrl and Shift
A plain click calls onSelect with the opposite of checked. Ctrl or Cmd and Shift are diverted
to their own callbacks and never select on their own — if you do not pass them, those clicks do
nothing.
import { useState } from "react";
import { Link } from "@onlyoffice/apps-ui-kit/components/link";
import { FileTile } from "@onlyoffice/apps-ui-kit/components/tiles/file-tile";
import { TileContent } from "@onlyoffice/apps-ui-kit/components/tiles/tile-content";
const file = { id: "d1", title: "Report.docx", contextOptions: [] };
export function SelectableFileTile() {
const [checked, setChecked] = useState(false);
return (
<FileTile
item={file}
checked={checked}
contextOptions={[]}
element={<span aria-hidden="true">📄</span>}
onSelect={(next) => setChecked(next)}
withCtrlSelect={() => setChecked((c) => !c)}
withShiftSelect={() => setChecked(true)}
>
<TileContent>
<Link className="item-file-name">{file.title}</Link>
</TileContent>
</FileTile>
);
}
Opening the file
The name and the thumbnail need to be exempt from the selecting click. The component checks the
target for a handful of literal class names — item-file-name, badges, tag,
not-selectable, expandButton — so put one of them on anything that should do something else.
import { Link } from "@onlyoffice/apps-ui-kit/components/link";
import { FileTile } from "@onlyoffice/apps-ui-kit/components/tiles/file-tile";
import { TileContent } from "@onlyoffice/apps-ui-kit/components/tiles/tile-content";
const file = { id: "d1", title: "Report.docx", contextOptions: [] };
export function OpenableFileTile({ open }: { open: () => void }) {
return (
<FileTile
item={file}
contextOptions={[]}
thumbnail="/thumbs/report.png"
thumbnailClick={open}
>
<TileContent>
<Link className="item-file-name" onClick={open}>
{file.title}
</Link>
</TileContent>
</FileTile>
);
}
Badges and quick actions
badges sits over the thumbnail and contentElement sits above it. Give the badges the class
badges so that clicking one does not select the tile.
import { Link } from "@onlyoffice/apps-ui-kit/components/link";
import { Badge } from "@onlyoffice/apps-ui-kit/components/badge";
import { FileTile } from "@onlyoffice/apps-ui-kit/components/tiles/file-tile";
import { TileContent } from "@onlyoffice/apps-ui-kit/components/tiles/tile-content";
const file = { id: "d1", title: "Report.docx", contextOptions: [] };
export function BadgedFileTile() {
return (
<FileTile
item={file}
contextOptions={[]}
thumbnail="/thumbs/report.png"
badges={
<div className="badges">
<Badge label="New" />
</div>
}
>
<TileContent>
<Link className="item-file-name">{file.title}</Link>
</TileContent>
</FileTile>
);
}
Behaviour the types don't state
- Which picture is drawn follows a fixed chain: a plugin icon when
item.isPluginanditem.fileTileIconare both set, otherwise thethumbnailuntil it fails to load, otherwisetemporaryIcon. The failure is sticky for as long as the component stays mounted. - A plain click selects, with exceptions by class name. The handler walks up from the click
target looking for
.badges,.item-file-name,.tag,.not-selectable,.expandButton,.p-contextmenuand the internal checkbox class; finding any of them cancels the selection. Those strings are the contract between this tile and your content. setSelection([])runs first, clearing the rest of the selection, unless the click landed on animg, aninputor an SVG shape.- A double click selects once. The handler requires
e.detail === 1, so the second click of a pair is ignored rather than toggling back. thumbSizedoes nothing. The only test on it isthumbSize !== null, which anumber | undefinedalways satisfies, so the branch it guards is unreachable and the value is never used as a size.contextButtonSpacerWidthandsideColorare dead and leak. Neither is read, and because the component spreads its remaining props onto the outer element, both arrive in the DOM as unknown attributes.- Only the first child is rendered. Everything after it in
childrenis dropped without a word. - The three-dot button needs the flag on the item as well as the prop — see
BaseTile, which has the same gate; and the right-click menu still needsgetContextModel. - The picture is wrapped in a link with no
href, so it is an<a>that is not focusable and is not announced as a link. - A tap on the icon selects, but only below 600px.
isBlockingOperationcurrently does nothing. It adds a class the stylesheet only matches on a descendant of the tile, not on the tile itself, so hover, clicks and right-clicks still reach a blocked file. Guard your handlers yourself while an operation runs.- The checkbox replaces the icon when the pointer is over the icon, not over the whole tile,
and stays while
checked; underisDraggingorinProgresshovering the icon changes nothing.
CSS variables
isHighlight shows nothing on its own. The kit sets no --highlightColor; set one on the tile
or an ancestor, and the fade plays once, for two seconds, when the tile mounts.
Accessibility
- The tile is a plain
<div>with click and context-menu handlers: no role, notabindex, no key handling. The only focusable things are the checkbox and whatever you put in the content. - The thumbnail's
altis the fixed English stringThumbnail-img, which is neither descriptive nor translated and cannot be changed. - Ctrl-click and Shift-click have no keyboard equivalent, so range and additive selection are pointer-only.
- The badges and quick actions are your own elements; they are not announced as belonging to the file unless you label them.
- The name is the one thing that should be a real link — make it one, rather than relying on the tile's click handler, so that the file can be opened from the keyboard.
Test ids
The checkbox, the three-dot button and the menu carry their own components' ids.
Related
Tiles— the family this belongs to.FolderTile— the same idea for a folder.TileContent— what goes inchildren.