ColorInput
Hex field with a swatch that opens a colour picker. It is the form-field form of
ColorPicker, with the drop-down already wired up.
Use this when / not when
- Use as a form field where someone picks or types a colour — a room cover, a brand accent, a tag.
- Not when the colour must be confirmed before it counts. There is no apply step here; every keystroke and every drag reports a new value.
- Not for a fixed palette. Build that from
DropDownItems; this field offers the whole spectrum. - Not when you need the picker on its own —
ColorPickeris that.
Import
import { ColorInput } from "@onlyoffice/apps-ui-kit/components/color-input";
Also exported from the root barrel @onlyoffice/apps-ui-kit.
ColorInputProps is not exported — type a wrapper's props yourself.
Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme, and TranslationProvider
from @onlyoffice/apps-ui-kit/providers/translation for the picker's "Custom" title.
Stories
Default
The field on its own, starting on the kit's blue. Type a hex code or click the swatch to pick one, and change any other prop live in the Controls panel below.
Sizes
Pick the size that matches the other fields in the same form: base, middle and large differ in width, and large also in text size and padding, while all three keep the same height (size).

States
Show whether the entered color is accepted: the first field is in its normal state, the second has a red border (hasError), the third an orange one (hasWarning), and the fourth is greyed out and its swatch no longer opens the picker (isDisabled).
Scaled Input
Use it where the field shares a column with full-width inputs: the field stretches across its container and the swatch stays at its end (scale).
Css Customization
Every overridable variable but --dropdown-bg set on one field -- the variables are listed under CSS variables on this page. Hover and focus it to see the border colors, and click its swatch to open the popup.
Minimal example
The field owns the colour; handleChange is how you hear about it.
import { useState } from "react";
import { ColorInput } from "@onlyoffice/apps-ui-kit/components/color-input";
import { InputSize } from "@onlyoffice/apps-ui-kit/components/text-input";
export function CoverColour() {
const [colour, setColour] = useState("#4781D1");
return (
<div>
<ColorInput
defaultColor={colour}
size={InputSize.base}
handleChange={setColour}
/>
<p>Saved value: {colour}</p>
</div>
);
}
Props
Recipes
Disabled / read-only
isDisabled disables the text field and stops the swatch opening the picker. There is no
read-only state.
import { ColorInput } from "@onlyoffice/apps-ui-kit/components/color-input";
import { InputSize } from "@onlyoffice/apps-ui-kit/components/text-input";
export function LockedColour({ colour }: { colour: string }) {
return <ColorInput defaultColor={colour} size={InputSize.base} isDisabled />;
}
Error
hasError and hasWarning recolour the field. Neither prints a message.
import { useState } from "react";
import { ColorInput } from "@onlyoffice/apps-ui-kit/components/color-input";
import { Text } from "@onlyoffice/apps-ui-kit/components/text";
import { InputSize } from "@onlyoffice/apps-ui-kit/components/text-input";
const TOO_LIGHT = /^#(?:[E-Fe-f][0-9A-Fa-f]){3}$/;
export function AccentColour() {
const [colour, setColour] = useState("#4781D1");
const problem = TOO_LIGHT.test(colour)
? "Too light to read against white"
: "";
return (
<div>
<ColorInput
defaultColor="#4781D1"
size={InputSize.base}
hasError={Boolean(problem)}
handleChange={setColour}
/>
{problem ? <Text fontSize="12px">{problem}</Text> : null}
</div>
);
}
Behaviour the types don't state
defaultColoris read once. The component seeds its own state on mount and never looks at the prop again, so it cannot be driven from outside. Remount it with akeyif the colour has to follow something else.- There is no apply step.
handleChangefires on every keystroke in the hex field and on every pointer move in the picker, so the value you store is whatever the user last touched. Debounce it before saving. - The picker opens from the swatch, not the field. Clicking the text only puts the caret in it; the square at the end is the control.
- The picker is positioned 48px below the field with
manualY, so a field of a different height leaves a gap or an overlap. - The drop-down has a backdrop, which closes the picker on an outside click — and covers the page while it is open. The picker's own close button closes it too.
- The field accepts hex only. It is
react-colorful's own input; named colours andrgb()are rejected as you type, and the value always comes back prefixed with#. Any character that is not a hex digit is dropped as it is typed, and the field holds six digits at most. - A partial code is not reported.
handleChangewaits until the field holds a complete 3- or 6-digit code; leave the field with anything shorter and it puts back the last valid colour. - The value is upper-cased for display but reported to
handleChangeexactly as typed. hasErrorandhasWarningare written as data attributes on the field, so they colour the border and nothing else.
CSS variables
The field's border, background and sizes come from the shared input styles, so they follow
TextInput: --text-input-color, --text-input-border-color,
--text-input-border-hover, --text-input-border-focus and --text-input-radius set on a
wrapper reach it. The popup is a DropDown and reads
--dropdown-border-style, --dropdown-shadow and --dropdown-radius (default 6px);
--dropdown-bg shows only in the 8px strips above and below the picker, whose own panel stays
white (black in the dark theme).
Accessibility
- The swatch is a bare
<span>with anonClick. It is not focusable, has no role and no name, so the picker cannot be opened from the keyboard at all. - Once open, the picker itself is pointer-only — see
ColorPicker. The hex field is the only keyboard path to a colour, and it is reachable. - The field has no label. Pair it with
LabelorFieldContainer;idlands on the wrapper, not the input, sohtmlForwill not reach it. hasErrorchanges a colour only; announce the problem yourself.
Test ids
The picker inside carries its own ids — see ColorPicker.
Related
ColorPicker— the picker this opens.TextInput— where the field's look comes from.DropDown— what the picker is shown in.