跳到主要内容

Label

Caption for a form field, with an optional required asterisk and an error colour. It is a <label> element rendered through Text at weight 600.

LabelLabel

Use this when / not when​

  • Use to caption a field you have laid out yourself, tying the two together with htmlFor.
  • Not inside FieldContainer — it renders its own label from labelText, and a second one would double the caption.
  • Not for a line of text that captions nothing. Text is that; a <label> with no field attached is noise for a screen reader.
  • Not to show a validation message. error only recolours the caption; the message is yours to render.

Import​

import { Label } from "@onlyoffice/apps-ui-kit/components/label";

Also exported from the root barrel @onlyoffice/apps-ui-kit.

LabelProps is not exported — type a wrapper's props yourself.

Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme for the text colour.

Stories​

Default​

The plain caption for a field, in semibold text; rest the pointer on it to read the tooltip (title), and change any other prop live in the Controls panel below.

DefaultDefault

Required Labels​

For fields a form cannot be sent without: each caption ends with a red asterisk (isRequired). The asterisk is hidden from screen readers, so the input needs required as well.

Required LabelsRequired Labels

Error State​

For a field that failed validation: the caption turns red (error), with or without the asterisk. The error message is not part of the label; render it next to the field.

Error StateError State

Truncated Label​

For a caption longer than the space it gets: in a 150px box the text stays on one line and ends with an ellipsis (truncate, with display: block so the label takes the box's width). Rest the pointer on it to read the full text in the tooltip (title), which needs RootTooltip mounted, as this story does.

Truncated LabelTruncated Label

Inline Label​

For a caption beside its field rather than above it: the label sits on the same line as the input (isInline).

Inline LabelInline Label

With Children​

For a note that belongs to the caption, such as "(optional)": content passed as children follows the text inside the same label (children).

With ChildrenWith Children

Form Example​

How the states read together in a form: a required field, a required field in error and an optional one, each label tied to its input by htmlFor, so clicking a caption focuses its field.

Form ExampleForm Example

Css Customization​

Both colours and the font size set on one wrapper -- the variables are listed under CSS variables on this page.

  • Display name shows the asterisk colour (--label-required-color) and the font size.
  • Email address adds error to show the text colour in the error state (--label-error-color).
Css CustomizationCss Customization

Minimal example​

htmlFor is what makes the caption clickable and announces it with the field; without it this is a styled paragraph.

import { Label } from "@onlyoffice/apps-ui-kit/components/label";
import {
InputSize,
InputType,
TextInput,
} from "@onlyoffice/apps-ui-kit/components/text-input";

export function NameField({
value,
onChange,
}: {
value: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}) {
return (
<div>
<Label
text="First name"
htmlFor="first-name"
style={{ display: "block" }}
isRequired
/>
<TextInput
id="first-name"
type={InputType.text}
size={InputSize.base}
value={value}
onChange={onChange}
required
/>
</div>
);
}

Props​

PropertyTypeDescription
children?React.ReactNodeRendered after the text and the asterisk, inside the same label.
className?stringApplied to the label.
display?stringWritten onto the label as an HTML display attribute, which changes nothing about its layout. Set display through style instead.
error?booleanTurns the text red and sets aria-invalid on the label. The error message is not part of this component. Default: false.
htmlFor?stringfor attribute, which points at the id of the field this labels.
id?stringApplied to the label.
isInline?booleanMakes the label an inline block, so it keeps its own width and padding on the line beside the field. Without it the label is a plain inline element. Default: false.
isRequired?booleanAppends a red asterisk to the text and sets aria-required on the label. It does not mark the field itself — put required on your input too. Default: false.
style?React.CSSPropertiesApplied to the label.
text?React.ReactNodeThe label's text.
title?stringText of the kit's shared tooltip, opened when the pointer rests on the label. It shows only while RootTooltip is mounted.
tooltipMaxWidth?stringIgnored. Nothing reads this prop; the shared tooltip sizes itself.
truncate?booleanCuts text that does not fit on one line with an ellipsis. The label is inline, so it also needs display: block (through style) and a width to cut against. Default: false.

Recipes​

Error​

error recolours the caption and sets aria-invalid on it. Pair it with the field's own hasError and a message of your own — the label prints neither.

import { Label } from "@onlyoffice/apps-ui-kit/components/label";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
import {
InputSize,
InputType,
TextInput,
} from "@onlyoffice/apps-ui-kit/components/text-input";

export function EmailField({
value,
problem,
onChange,
}: {
value: string;
problem?: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}) {
return (
<div>
<Label
text="Email"
htmlFor="email"
style={{ display: "block" }}
error={Boolean(problem)}
/>
<TextInput
id="email"
type={InputType.email}
size={InputSize.base}
value={value}
onChange={onChange}
hasError={Boolean(problem)}
/>
{problem ? <Text fontSize="12px">{problem}</Text> : null}
</div>
);
}

Behaviour the types don't state​

  • It has no margin of its own. The label sits flush against whatever follows it; the gap is yours to add. FieldContainer is the component that brings spacing.
  • A space is always rendered between the text, the asterisk and the children, because the three are joined with literal spaces in the markup. A child meant to sit tight against the text will not.
  • aria-required and aria-invalid are set on the label, not on the field. Assistive technology reads those states from the input, so set required and aria-invalid there as well; the label's copies are decoration.
  • The asterisk is aria-hidden, so "required" reaches a screen reader only through the field's own required.
  • truncate needs a block and a width. It sets text-overflow: ellipsis on a <label>, which is inline and as wide as its content, so on its own it changes nothing. Give it style={{ display: "block" }} and a width, or a parent that constrains one.
  • display is not CSS. It lands on the element as an HTML display attribute and leaves the layout alone; style={{ display: "block" }} is what puts the label on its own line.
  • isInline makes an inline block, not an inline element — the label already is one. The block keeps its own width and padding on the line beside the field.
  • title opens the kit's shared tooltip, not the browser's. Once mounted, the label drops the native title attribute and opens the tooltip rendered by RootTooltip when the pointer rests on it; with no RootTooltip on the page nothing appears at all.
  • error wins over any color the theme would apply, and uses --label-error-color with the kit's error red as the fallback.
  • tooltipMaxWidth is dead. Nothing reads it, and the shared tooltip sizes itself.

CSS variables​

VariableDefaultEffect
--label-error-colorkit error red (#F24724)Colour of the text when error
--label-required-colorkit error red (#F24724)Colour of the required asterisk
--text-size13pxFont size; read by Text, not here

Both colours fall back to the light theme's error red in either theme; set them yourself for a dark one.

Accessibility​

  • htmlFor is the whole point: without it the element is a <label> attached to nothing, and clicking it does not focus the field.
  • Set required on the input as well as isRequired here — the asterisk is hidden from assistive technology on purpose, and aria-required on a label is not announced.
  • The same holds for error: the field needs its own aria-invalid, and the message needs to be tied to it with aria-describedby.
  • truncate hides text visually but keeps it in the accessibility tree; title gives pointer users the full string back in the shared tooltip, and no one else — it is not a native title a screen reader could read.

Test ids​

Elementdata-testid
The labellabel
The asteriskrequired-mark

Neither can be overridden by a prop.

  • FieldContainer — label, field and error message together.
  • Text — what this renders through.
  • TextInput — the field this most often captions.