Leave Request Check

Reads a time-off request back day by day, so it doesn't use more leave than the person thinks or leave a gap they didn't intend.

StopsLeave request burns extra days

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/leave-request-check.json

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

Usage

leave-request-check-usage.tsx
import { LeaveRequestCheck } from "@/components/ui/leave-request-check"

<LeaveRequestCheck
  defaultValue={{ start: "2026-12-24", end: "2026-12-29", startPart: "full", endPart: "half" }}
  holidays={HOLIDAYS}
  team={TEAM}
  teamLimit={3}
  balance={4}
  policy={{ sandwich: true }}
  onSubmit={() => new Promise((resolve) => setTimeout(resolve, 600))}
/>

What it catches

  • Weekends or holidays at either end of the range
  • Your policy's sandwich rule charging weekends or holidays in between
  • Half day with no half chosen, or one that leaves a working gap
  • Balance going negative
  • Too many teammates away at once
  • Start after end, and the actual back-at-work date

Props

LeaveRequestCheck props
PropTypeDefault
value

Controlled request.

LeaveRequest—
defaultValue

Initial request when uncontrolled.

Partial<LeaveRequest>—
onValueChange

Called with the new request on every edit or fix.

(request: LeaveRequest) => void—
holidays

Public and company holidays.

Holiday[][]
team

Who on the team is already away.

TeamAbsence[][]
teamLimit

Most people the team allows away on one day, including this person.

number—
policy

Sandwich rule and weekly offs.

LeavePolicy{}
balance

Days of leave left.

number—
locale

Locale for dates.

string"en-IN"
onSubmit

Sends the request. With warnings open, the first press jumps to them and the second sends. May return a Promise.

(request: LeaveRequest) => void | Promise<void>—
showLawNote

Under a sandwich charge, show the note that India's OSH Code 2020 s.32(1)(iv) excludes holidays from leave for covered workers. Defaults to on for Indian locales ("en-IN", "hi-IN"…).

boolean—
messages

Any visible string.

Partial<Omit<LeaveRequestMessages, "kinds">> & { kinds?: Partial<LeaveRequestMessages["kinds"]> }—

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

Accessibility

  • Start and end dates have visible labels; half-day selects have aria-labels
  • Date inputs get aria-invalid for an invalid or reversed range
  • Day-by-day readback is a labelled section with a labelled list
  • Focus moves to the first fix after a change

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

Limitations

  • Holidays, policy and balance come from your props; it doesn't know your HR system
  • The OSH Code note is shown for en-IN by default; whether it applies depends on the worker and establishment
  • Not legal advice

Rules

Rules last verified:

Informational, not legal advice. s.32(1)(iv) wording confirmed. The 21 Nov 2025 commencement (S.O. 5321(E)) was seen in secondary sources only, and the Maharashtra Shops & Establishments s.18(9) reference was not checked. Copied components don't update themselves, so re-check after rule changes (see updating a component).

What it stops

Leave request burns extra days

Also known as

leave · time off · pto · leave application · hrms · sandwich leave · holiday calendar · half day

Field type

Dependencies

Pairs well with