TemplateTile
Tile for a room template: the name on top, and an owner and storage pair along the bottom. It is
BaseTile with a two-column caption in its lower half, where the room
tile puts its tags.

Use this when / not when
- Use for a room template in a tile listing, where the owner matters and the tags do not.
- Not for a room —
RoomTileshows the tags and the room type. - Not for a folder or a document —
FolderTileandFileTile. - Not for a card of your own —
BaseTileis the same shell with an empty lower half. - The labels are not yours to choose. "Owner" and "Storage" come from the kit's own translations under exactly those keys; there is no prop for either.
- The storage figure is not rendered by this component.
showStorageInfoadds the label; the value needs aSpaceQuotaComponentof your own beside it.
Import
import { TemplateTile } from "@onlyoffice/apps-ui-kit/components/tiles/template-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 two captions and the
three-dot button's tooltip, which it asks the kit's own translation hook for; without it the lower
half is two empty lines.
Stories
Default
A template with its owner and the storage it uses: the icon, the name with a create-room button, the menu, and the two lines below. Hover the icon and tick the checkbox to select it, click the owner to see openUser in the Actions panel, and change any other prop live in the Controls panel below.

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

With Space Quota
A template with a storage limit the reader may change: the storage line shows the space used and a drop-down with the limit, both drawn by the host's quota component (showStorageInfo, SpaceQuotaComponent, security.EditRoom).

With Read Only Quota
The same template for a reader who may not edit it: the tile tells the quota component the figure is read-only, so it shows the used space and the limit as plain text (security.EditRoom: false).

Blocking Operation
A template an operation is running over, which must not be picked or opened until it ends: hover it, click it or right-click it and nothing happens (isBlockingOperation). It looks the same as an idle template, so show the operation somewhere else.

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

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 template whose name is being edited: the icon and the checkbox go, so the name can become a text field, and hovering no longer tints the tile (isEdit).

Css Customization
The variables are listed under CSS variables on this page.
Two instances:
- Sample Template — for every variable but the hotkey colour; hover it for
--tile-hover-bg. - Team Template —
showHotkeyBorder, for--tile-hotkey-color.

Minimal example
import { TemplateTile } from "@onlyoffice/apps-ui-kit/components/tiles/template-tile";
import { TileContent } from "@onlyoffice/apps-ui-kit/components/tiles/tile-content";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
const template = {
id: "t1",
title: "Onboarding template",
isTemplate: true,
createdBy: { id: "u1", displayName: "Anna Petrova" },
contextOptions: [],
};
export function SimpleTemplateTile() {
return (
<TemplateTile
item={template}
contextOptions={[]}
columnCount={2}
openUser={() => {}}
>
<TileContent>
<Text truncate>{template.title}</Text>
</TileContent>
</TemplateTile>
);
}
Props
Recipes
With the storage figure
Both pieces are needed: showStorageInfo draws the caption, SpaceQuotaComponent draws the value
beside it. Your component is handed the item, the literal type "room" and whether editing is
allowed, which is taken from item.security.EditRoom.
import { TemplateTile } from "@onlyoffice/apps-ui-kit/components/tiles/template-tile";
import type { SpaceQuotaProps } from "@onlyoffice/apps-ui-kit/components/tiles/template-tile";
import { TileContent } from "@onlyoffice/apps-ui-kit/components/tiles/tile-content";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
const template = {
id: "t1",
title: "Onboarding template",
createdBy: { id: "u1", displayName: "Anna Petrova" },
security: { EditRoom: true },
contextOptions: [],
};
function Quota({ isReadOnly, className }: SpaceQuotaProps) {
return (
<Text className={className} fontSize="13px">
{isReadOnly ? "1.2 GB" : "1.2 GB of 10 GB"}
</Text>
);
}
export function TemplateTileWithQuota() {
return (
<TemplateTile
item={template}
contextOptions={[]}
columnCount={2}
showStorageInfo
SpaceQuotaComponent={Quota}
openUser={() => {}}
>
<TileContent>
<Text truncate>{template.title}</Text>
</TileContent>
</TemplateTile>
);
}
Selection
The checkbox appears beside element and reports through onSelect. A template whose title is
not a string is dropped before the callback runs, so the item you get back is always a real
template.
import { useState } from "react";
import { TemplateTile } from "@onlyoffice/apps-ui-kit/components/tiles/template-tile";
import { TileContent } from "@onlyoffice/apps-ui-kit/components/tiles/tile-content";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
const template = { id: "t1", title: "Onboarding template", contextOptions: [] };
export function SelectableTemplateTile() {
const [checked, setChecked] = useState(false);
return (
<TemplateTile
item={template}
checked={checked}
contextOptions={[]}
columnCount={2}
element={<span aria-hidden="true">🗂️</span>}
onSelect={(next) => setChecked(next)}
openUser={() => {}}
>
<TileContent>
<Text truncate>{template.title}</Text>
</TileContent>
</TemplateTile>
);
}
Behaviour the types don't state
columnCountis required and does nothing. It is not read here and it is not read by the base tile either; the lower half is a two-column caption, not a grid. Pass any number.openUseris required even when there is no owner. The link it belongs to is rendered only whenitem.createdByis set, so on a template without one the prop is never called.thumbnailClickis dead. It reaches the base tile, which declares it and reads it nowhere.- There is no
dataTestIdprop, unlike every other tile in the family: the outer element keeps the base tile's defaulttile. - The owner's name is a link with no
href, so it is an<a>that is not focusable even though it is the one thing in the lower half that does something. onSelectfilters the item on the way out. The base tile hands back its ownTileItem; this component checks that it has a stringtitleand drops the call otherwise.- The captions are fixed keys. They are asked for as
OwnerandStoragein the kit's common namespace — not props, and not overridable. - The three-dot button needs the flag on the item as well as the prop, and the right-click menu
needs
getContextModel— seeBaseTile, which this component wraps. isBlockingOperationturns off the pointer and nothing else: hover, clicks and right-clicks stop reaching the tile, but it looks exactly like an idle one, so show the operation elsewhere.- Only the first child is rendered, above the badges; the rest of
childrenis dropped.
CSS variables
All but --tile-sub-color are read by BaseTile, which this component
wraps. Its --tile-padding and --tile-row-gap do not reach a template tile: this
component's stylesheet fixes both at 12px, and the tile is capped at 128px high.
Accessibility
- The tile is a plain
<div>with click and context-menu handlers: no role, notabindex, no key handling. Only the checkbox and whatever you put in the content are focusable. - The owner's name is not keyboard-reachable: it is a link without an
hrefcarrying a click handler. If opening the owner's profile matters, render your own button in the content instead. - The captions and their values are separate elements with nothing tying them together, so a screen reader reads "Owner", "Storage", the name and the figure as four unrelated pieces of text.
- Nothing here sets
aria-busyoraria-disabled.inProgresschanges only the appearance;isBlockingOperationturns off the pointer but not the keyboard, so a busy template's checkbox can still be toggled from it.
Test ids
It cannot be changed from here.