@letar/forms

Russian Documents

INN, OGRN, BIK, SNILS, passport fields with checksum validation

Overview

Every B2B form in Russia requires INN, OGRN, BIK, bank account numbers. These fields have checksums — a simple mask is useless without validation. @letar/forms provides both headless validators and ready-to-use UI components.

Architecture: Two Layers

Layer 1: zRu Validators (headless)

Pure Zod schemas with checksum validation. Work on server and client, no UI dependency.

import { zRu } from '@letar/forms/validators/ru'

const CompanySchema = z.object({
  inn: zRu.inn(), // 10 or 12 digits + checksum
  kpp: zRu.kpp(), // 9 characters
  ogrn: zRu.ogrn(), // 13 digits + checksum
  bik: zRu.bik(), // 9 digits, starts with "04"
  account: zRu.bankAccount(), // 20 digits
  snils: zRu.snils(), // 11 digits + checksum
})

// INN variants
zRu.inn.legal() // legal entity only (10 digits)
zRu.inn.individual() // individual only (12 digits)

Layer 2: Form.Document.* (UI)

Ready-to-use fields with input masks, icons, and real-time checksum validation.

<Form.Document.INN name="inn" label="INN" />
<Form.Document.KPP name="kpp" label="KPP" />
<Form.Document.OGRN name="ogrn" label="OGRN" />
<Form.Document.BIK name="bik" label="BIK" />
<Form.Document.BankAccount name="account" label="Bank Account" />
<Form.Document.CorrAccount name="corrAccount" label="Corr. Account" />
<Form.Document.SNILS name="snils" label="SNILS" />
<Form.Document.Passport name="passport" label="Passport" />

Available Fields

ComponentFormatChecksum
Form.Document.INN10 or 12 digitsWeighted sum mod 11
Form.Document.KPP9 charactersFormat check (NNNNPPXXX)
Form.Document.OGRN13 digitsFirst 12 mod 11
Form.Document.BIK9 digitsStarts with "04"
Form.Document.BankAccount20 digitsControl key (with BIK)
Form.Document.CorrAccount20 digitsStarts with "301"
Form.Document.SNILSXXX-XXX-XXX YYModule 101
Form.Document.PassportXX XX XXXXXXFormat check

Custom Document Fields

Use createDocumentField to create your own document fields:

import { createDocumentField } from '@letar/forms'
import { LuFileText } from 'react-icons/lu'

const FieldCustomDoc = createDocumentField({
  displayName: 'FieldCustomDoc',
  mask: '999-999-999',
  placeholder: '123-456-789',
  icon: <LuFileText />,
  validate: (value) => {
    if (value.length < 9) return 'Too short'
    return undefined
  },
})

Live Example

Try the interactive example on forms-example.letar.best.

On this page