# Password Caps Lock Warning

> A password field that warns when Caps Lock is on, read from key events, announced politely, linked to the field and gone on blur or when the key is toggled off.

A shadcn/ui block from the [@tealmac](https://ui.tealmac.com/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/tealmac/password-caps-lock-warning).

- Page, with a live preview: https://shadcn.exchange/r/tealmac/password-caps-lock-warning
- Screenshot: https://shadcn.exchange/shot/tealmac/password-caps-lock-warning/light.png
- Registry item: https://ui.tealmac.com/r/password-caps-lock-warning.json
- Listed: 2026-11-01, source last changed 2026-11-01

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/tealmac/password-caps-lock-warning.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `input`, `label`

## Files

### `registry/patterns/password-caps-lock-warning/password-caps-lock-warning.tsx`

```tsx
"use client"

import * as React from "react"

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export interface PasswordCapsLockWarningProps extends Omit<
  React.ComponentProps<typeof Input>,
  "type" | "id"
> {
  label?: string
  autoComplete?: string
}

/**
 * A password field that warns when Caps Lock is on, the commonest reason a
 * correct password fails. The state comes from `getModifierState("CapsLock")`
 * on key events, so it is only known after a key was pressed; the warning is a
 * polite status linked to the field, goes away when the key is toggled off or
 * the field loses focus, and never blocks typing.
 */
export function PasswordCapsLockWarning({
  label = "Password",
  autoComplete = "current-password",
  onKeyDown,
  onKeyUp,
  onBlur,
  ...props
}: PasswordCapsLockWarningProps) {
  const [caps, setCaps] = React.useState(false)
  const id = React.useId()
  const update = (event: React.KeyboardEvent<HTMLInputElement>) =>
    setCaps(event.getModifierState?.("CapsLock") ?? false)
  return (
    <div className="grid gap-2">
      <Label htmlFor={id}>{label}</Label>
      <Input
        id={id}
        type="password"
        autoComplete={autoComplete}
        aria-describedby={`${id}-caps`}
        onKeyDown={(event) => {
          update(event)
          onKeyDown?.(event)
        }}
        onKeyUp={(event) => {
          update(event)
          onKeyUp?.(event)
        }}
        onBlur={(event) => {
          setCaps(false)
          onBlur?.(event)
        }}
        {...props}
      />
      <p
        id={`${id}-caps`}
        role="status"
        className="text-xs font-medium text-amber-700 dark:text-amber-400"
      >
        {caps ? "Caps Lock is on" : ""}
      </p>
    </div>
  )
}
```
