Skip to main content

PasswordInput

Password field with a reveal eye, a strength tooltip and a generator. It is InputBlock with the eye as its icon and a Tooltip listing the rules the password has to meet.

PasswordInputPasswordInput

Use this when / not when​

  • Use where a password is being set — signing up, resetting, changing — and the rules should be shown as they are met.
  • Use simpleView where a password is only being entered, as at sign-in: it keeps the field and the eye and drops the checking entirely.
  • Not for any other secret. An API key or a token gets no value from the strength rules; InputBlock with an eye of your own is simpler.
  • Not to show the rules on their own. Every tooltip string is a prop, and an empty one is an empty line.

Import​

import { PasswordInput } from "@onlyoffice/apps-ui-kit/components/password-input";

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

PasswordInputProps is not exported; PasswordInputHandle, the type of the ref, is.

Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme. Nothing here is translated for you — every label in the tooltip is a prop.

Stories​

Default​

The field as a sign-up form uses it: type a character to open the rules tooltip and watch each rule turn green as the value meets it; change any other prop live in the Controls panel below.

DefaultDefault

Simple View​

A sign-in form only needs the field and the eye button: the simple view drops the rules tooltip and skips rule checking, so the field accepts any value (simpleView).

Simple ViewSimple View

States​

Three fields a form may need side by side: Normal, ready for input; Disabled, greyed out with typing blocked and no tooltip (isDisabled); With error, drawn with a red border to flag a value the form rejected (hasError).

StatesStates

Custom Validation​

A policy that asks for less: type into the field and the tooltip lists only a minimum length of 8, capital letters and digits, because special characters are switched off (passwordSettings).

Custom ValidationCustom Validation

Sizes​

Pick the height that matches the other fields of the form: base, middle and large (size).

SizesSizes

With Password Generator​

Saves the user from inventing a password that meets every rule: type a character to open the tooltip, then click Generate password at its bottom; the field fills with a random password that passes all rules and shows its characters (generatePasswordTitle, symbols picked from generatorSpecial).

With Password GeneratorWith Password Generator

Right To Left​

The field in a right-to-left layout: the hidden characters line up from the right edge and the eye button moves to the left end. The wrapper carries dir="rtl"; the direction also comes from the theme's interfaceDirection (the Direction toolbar).

Right To LeftRight To Left

Css Customization​

The input variables set on one wrapper -- the variables are listed under CSS variables on this page. The example sets every variable but the tooltip width, which a wrapper cannot reach; hover and focus the field to see the border colors.

Css CustomizationCss Customization

Minimal example​

The field keeps the password itself; onChange's second argument is the value to store.

import { useState } from "react";
import { PasswordInput } from "@onlyoffice/apps-ui-kit/components/password-input";

export function NewPassword() {
const [password, setPassword] = useState("");
const [isStrong, setIsStrong] = useState(false);

return (
<PasswordInput
id="new-password"
inputValue={password}
isDisableTooltip
hasError={Boolean(password) && !isStrong}
onChange={(_event, value) => setPassword(value ?? "")}
onValidateInput={(passes) => setIsStrong(passes)}
/>
);
}

Props​

PropertyTypeDescription
clipActionResource?stringIgnored. It feeds a copy button that is not rendered.
clipCopiedResource?stringIgnored. It feeds a copy button that is not rendered. Default: "Copied".
emailInputName?stringIgnored. It only sets an internal flag for a copy button that is not rendered.
generatePasswordTitle?stringTitle of the password generation button
generatorSpecial?stringCharacters the generator may pick symbols from. Default: "!@#$%^&*".
inputName?stringname of the field, and the fallback for the tooltip's anchor id when no id is given — so two fields on one page need distinct ids. Default: "passwordInput".
inputType?InputType.password | InputType.textWhether the field starts revealed. The eye toggles it from then on, and isDisabled forces it back to hidden. Default: InputType.password.
inputValue?stringValue the field starts with. The component owns the value from then on: changing this later is ignored unless it becomes an empty string, or isSimulateType is set.
inputWidth?stringWidth of the field's wrapper, as a CSS length.
isDisableTooltip?booleanAllows to hide Tooltip. Default: false.
isFullWidth?booleanWhether the wrapper is a full-width block rather than shrinking to the field. Default: false.
isSimulateType?booleanRenders the value as repeated simulateSymbol characters in a text field, keeping the real value in state. It needs the input's id to be conversion-password, which is where it reads the caret from. Default: false.
onChange?(e: React.ChangeEvent<HTMLInputElement>, value?: string) => voidCalled on every change with the DOM event and the value after sanitising. Read the second argument: under isSimulateType the event carries the masking characters, not the password.
onValidateInput?(progressScore: boolean, passwordValidation: TPasswordValidation) => voidCalled after every change with whether every rule passes, and with each rule's own result. It never fires in simpleView, which skips checking.
passwordSettings?TPasswordSettingsThe rules the generator and the checker use. Left out, only a minimum length of 8 is required — digits, capitals and symbols are all off. Default: DEFAULT_PASSWROD_SETTINGS.
ref?React.RefObject<PasswordInputHandle | null>Handle for generating a password and reading the current value.
sanitizeValue?(value: string) => stringRuns on every change before the value is stored — stripping spaces, say.
simpleView?booleanStrips the component down to the field and the reveal eye: no strength tooltip, no generate link, and no validation at all. Default: false.
simulateSymbol?stringThe character drawn for each real one under isSimulateType. Default: "•".
tooltipAllowedCharacters?stringTitle for allowed characters tooltip
tooltipPasswordCapital?stringPrompt for capital letters requirement
tooltipPasswordDigits?stringPrompt for digits requirement
tooltipPasswordLength?stringPrompt for minimum length requirement
tooltipPasswordSpecial?stringPrompt for special characters requirement
tooltipPasswordTitle?stringTitle for password requirements tooltip

Inherited from CommonProps​

Declared by components/input-block and accepted here too.

PropertyTypeDescription
className?stringApplied to the group.
dataTestId?stringdata-testid of the group. Default: "input-block".
forwardedRef?React.Ref<HTMLInputElement>Ref to the <input> element itself.
hoverColor?stringColour of that icon on hover.
iconColor?stringColour of that icon.
iconNode?React.ReactNodeThe icon as an element, instead of iconName.
iconSize?numberSize of that icon in pixels. It falls back to size.
id?stringApplied to the <input>, not to the group around it.
isIconFill?booleanWhether the icon's paths are recoloured to iconColor. Leave it off for a multi-coloured icon. Default: false.
noIcon?booleanWhether the icon box is left out entirely. Without it an empty box is still rendered and still takes its padding. Default: false.
onIconClick?(e: React.MouseEvent) => voidCalled when the icon is clicked. Without it the icon is rendered in the disabled style and does not respond — it is what makes the icon a button.
style?React.CSSPropertiesApplied to the group.
tabIndex?numberUsed as HTML tabindex property of the <input>. Unlike TextInput's, this one defaults to -1, so the field is out of the tab order until you pass 0 — and so is every component built on it that passes its own tabIndex through, SearchInput and PasswordInput among them. Default: -1.
testId?stringdata-testid of the inner <input>, passed through to TextInput.

Inherited from TextInputProps​

Declared by components/text-input and accepted here too.

PropertyTypeDescription
autoComplete?stringUsed as HTML autocomplete property. Default: "off".
dir?stringText direction. Default: "auto".
fontWeight?number | stringSets the font weight
guide?booleanWhen guide is true, Text Mask always shows both placeholder characters and non-placeholder mask characters
hasError?booleanIndicates the input field has an error
hasWarning?booleanIndicates the input field has a warning
inputMode?"decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url"Input mode for virtual keyboard
isAutoFocussed?booleanFocus the input field on initial render
isBold?booleanSets font weight value to 600
isDisabled?booleanIndicates that the field cannot be used
isReadOnly?booleanIndicates that the field is displaying read-only content
keepCharPositions?booleanAllows to add or delete characters without changing the positions of the existing characters
mask?((value: string) => Mask) | MaskInput text mask
maxLength?numberMaximum number of characters the field accepts; further typing is silently dropped. Default: 255.
onBlur?(e: React.FocusEvent<HTMLInputElement>) => voidCalled when field is blurred
onClick?(e: React.MouseEvent<HTMLInputElement>) => voidCalled when clicked
onContextMenu?(e: React.MouseEvent<HTMLInputElement>) => voidCalled when context menu is triggered
onFocus?(e: React.FocusEvent<HTMLInputElement>) => voidCalled when field is focused
onKeyDown?(e: React.KeyboardEvent<HTMLInputElement>) => voidCalled when a key is pressed
placeholder?stringPlaceholder text for the input. The default is a single space, not an empty string, so :placeholder-shown matches even when no placeholder was asked for. Default: " ".
scale?booleanIndicates the input field has scale
size?InputSizeSupported size of the input fields
spellCheck?booleanUsed as HTML spellcheck property
withBorder?booleanIndicates that component contains border

Plus 298 more props inherited from React.AriaAttributes, React.DOMAttributes, React.HTMLAttributes and React.InputHTMLAttributes, forwarded to the element.

Enums​

EnumMembers
InputSizebase, middle, large
InputTypetext, password, email, tel, search, number

Recipes​

The rules tooltip, with a generator​

Every string in the tooltip is a prop; generatePasswordTitle is what adds the generate link, and without it there is no way to reach the generator except through the ref.

import { useState } from "react";
import { PasswordInput } from "@onlyoffice/apps-ui-kit/components/password-input";

const SETTINGS = {
minLength: 8,
upperCase: true,
digits: true,
specSymbols: true,
};

export function SignUpPassword() {
const [password, setPassword] = useState("");
const [isStrong, setIsStrong] = useState(false);

return (
<PasswordInput
id="sign-up-password"
inputValue={password}
passwordSettings={SETTINGS}
hasError={Boolean(password) && !isStrong}
tooltipPasswordTitle="Password must contain:"
tooltipPasswordLength="at least 8 characters"
tooltipPasswordDigits="a digit"
tooltipPasswordCapital="a capital letter"
tooltipPasswordSpecial="a symbol (!@#$%^&*)"
generatePasswordTitle="Generate password"
onChange={(_event, value) => setPassword(value ?? "")}
onValidateInput={(passes) => setIsStrong(passes)}
/>
);
}

Entering an existing password​

simpleView is the sign-in shape: field, eye, nothing else. No tooltip, no generator, and onValidateInput is never called.

import { useState } from "react";
import { PasswordInput } from "@onlyoffice/apps-ui-kit/components/password-input";

export function SignInPassword() {
const [password, setPassword] = useState("");

return (
<PasswordInput
id="sign-in-password"
simpleView
autoComplete="current-password"
inputValue={password}
placeholder="Password"
onChange={(_event, value) => setPassword(value ?? "")}
/>
);
}

Disabled / read-only​

isDisabled greys the field, removes the eye — InputBlock drops its icon when disabled — and forces the value back to hidden if it was revealed.

import { PasswordInput } from "@onlyoffice/apps-ui-kit/components/password-input";

export function LockedPassword({ password }: { password: string }) {
return (
<PasswordInput id="locked-password" inputValue={password} isDisabled />
);
}

Generating from outside​

The ref gives you the generator and the current value, which is how a "generate" button outside the field works.

import { useRef, useState } from "react";
import { Button, ButtonSize } from "@onlyoffice/apps-ui-kit/components/button";
import {
PasswordInput,
type PasswordInputHandle,
} from "@onlyoffice/apps-ui-kit/components/password-input";

export function PasswordWithButton() {
const handle = useRef<PasswordInputHandle | null>(null);
const [password, setPassword] = useState("");

return (
<div>
<PasswordInput
id="generated-password"
ref={handle}
inputValue={password}
isDisableTooltip
onChange={(_event, value) => setPassword(value ?? "")}
/>
<Button
size={ButtonSize.small}
label="Generate"
onClick={(event) => handle.current?.onGeneratePassword(event)}
/>
</div>
);
}

Behaviour the types don't state​

  • inputValue is a seed, not a controlled value. The component holds the password in its own state; setting inputValue to something new is ignored, except when it becomes "" — which does clear the field — or when isSimulateType is on. Read the value back from onChange's second argument or from the ref.
  • The tooltip opens by itself, and needs hasError to close. It opens whenever the value is shorter than minLength, or hasError or hasWarning is set; it closes only when the length is met and hasError is defined and false. Leave hasError out altogether and the tooltip never closes on its own.
  • Two fields on one page need distinct ids. The tooltip is anchored by a selector built from id or, failing that, inputName — which defaults to passwordInput for everyone. Two fields without ids share one anchor and the tooltip attaches to the wrong field.
  • simpleView disables validation, not just the tooltip. The change handler stores the value and returns before checking, so onValidateInput never fires and the strength state stays at its initial value.
  • The default rules check length only. passwordSettings defaults to minLength: 8 with upperCase, digits and specSymbols all false, so a weak password passes unless you pass your own settings.
  • isSimulateType renders a text input. The value shown is simulateSymbol repeated, the real password lives in state, and the caret is restored by looking up document.getElementById("conversion-password") — a literal id. Give the field exactly that id or the caret jumps to the end on every keystroke.
  • Nothing in the tooltip is translated. tooltipPasswordTitle and its siblings are printed as given; an omitted one renders an empty line, and the rules list still reserves its space.
  • The generate link appears only with generatePasswordTitle. Without it the generator is reachable only through the ref.
  • Generating reveals the password. The generated value is written into the field and the type switches to text, so the user sees what was made; the eye hides it again.
  • isDisabled also un-reveals: an effect forces the type back to password, so a revealed field hides itself when it is disabled.
  • scale defaults to true here, unlike InputBlock, and autoComplete to "new-password"; pass "current-password" at sign-in.
  • size falls back to InputSize.middle, not base.
  • emailInputName, clipActionResource and clipCopiedResource are dead: they feed a copy button that is not rendered.
  • A click anywhere outside closes the tooltip, through a mousedown listener on the document.

CSS variables​

The field's colours come from the shared input styles, so they follow TextInput: set its --text-input-bg, --text-input-color, --text-input-border-color, --text-input-border-hover, --text-input-border-focus and --text-input-radius on any ancestor of the field. The tooltip follows Tooltip. The rules in the tooltip are coloured green or red from the kit's status colours, which are not overridable.

VariableDefaultEffect
--password-input-tooltip-width294pxWidth of the rules tooltip on tablet and desktop

The rules tooltip is rendered in a portal at the end of <body>, so a value set on a wrapper around the field never reaches it: set --password-input-tooltip-width on :root or body. On mobile the width is a fixed 320px and the variable is not read.

Accessibility​

  • The eye is InputBlock's icon button, and it carries no label, so a screen reader announces an unnamed control that changes nothing it can perceive.
  • The strength tooltip is not tied to the field. It is opened imperatively and has no aria-describedby, so the rules and whether they are met are invisible to assistive technology — and colour is the only signal that a rule now passes.
  • The field has no label of its own. Use FieldContainer or Label with htmlFor pointing at id.
  • It is not in the tab order unless you pass tabIndex. The prop goes straight to InputBlock, whose own default is -1. Pass tabIndex={0}.
  • isSimulateType puts the password into a type="text" field. Password managers, the browser's own reveal control and assistive technology all treat it as ordinary text; avoid it where a real password field will do.
  • tabIndex comes from InputBlock, which defaults it to -1 — pass tabIndex={0} or the field is not reachable by keyboard.

Test ids​

Elementdata-testid
The wrapperpassword-input, or testId
The tooltip anchortooltipContent
The eyepassword_input_eye_icon, password_input_eye_off_icon
  • InputBlock — the field and icon underneath.
  • TextInput — where most of the inherited props are documented.
  • Tooltip — what the rules are shown in.