Salary Input

Catches salaries entered in the wrong period or scale, like monthly typed as yearly or a bare "12" meant as 12 LPA.

StopsMonthly salary entered as yearly

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/salary-input.json

The files land in your project. They're yours to edit.

Usage

salary-input-usage.tsx
import { SalaryInput } from "@/components/ui/salary-input"

<SalaryInput label="Current CTC" defaultValue={{ text: "12", period: "year" }} />

What it catches

  • Monthly figure entered as yearly, and the reverse
  • Bare "12" likely meant as 12 LPA (or 85 as 85k outside India)
  • An extra or missing zero against the expected range
  • Units written in the text (LPA, k, lakh, crore, million) overriding the period picker
  • Read-back per month and per year, in lakh/crore for INR

Props

SalaryInput props
PropTypeDefault
label

Visible label.

string"Expected salary"
value

Controlled value.

SalaryValue—
defaultValue

Initial value when uncontrolled.

Partial<SalaryValue>—
onValueChange

Called with the value and the amount it means per year and per month (null while it isn't an amount).

(value: SalaryValue, amount: { yearly: number; monthly: number } | null) => void—
currency

ISO currency. INR reads back in lakh and crore with Indian digit grouping.

string"INR"
expectedRange

The yearly range expected for this role, e.g. [800000, 1400000]. Enables the extra-zero check.

[number, number]—
plausibleRange

Yearly range any salary in this currency falls in, used when there is no expectedRange. Defaults by currency; null turns the generic check off.

[number, number] | null—
delay

Pause in ms before warnings appear while typing. Leaving the field shows them at once.

number600
messages

Override any message or label.

Partial<typeof SALARY_MESSAGES>—

* required. Also accepts the native props of <input> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Visible <label> on the input; read-back and status linked via aria-describedby
  • Period picker is a roving-tabindex radiogroup with arrow keys
  • Status in a polite live region; dismiss has an aria-label
  • After a fix, focus returns to the input

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Checks plausibility against the ranges you pass; it can't know the real offer
  • Parses common English and Indian shorthand only
  • Does not handle tax, CTC components or variable pay

What it stops

Monthly salary entered as yearly

Also known as

salary · expected ctc · current ctc · lpa · lakh · job application · naukri · monthly salary

Field type

Dependencies

Pairs well with