Staaarter

Billing Vat Validator

A form for collecting and checking a business's VAT number before invoicing. A country selector prefixes the input, an explicit Validate click checks the number against a built-in per-country format pattern, and a short simulated delay stands in for a real VIES lookup. When a valid ID is entered for a country other than your own, a reverse-charge note appears.

By Staaarter Team
Billing
Updated July 9, 2026
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its badge, button, input, label dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/billing-vat-validator.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing147.tsx instead.

Usage

The file also exports billing147Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Billing147, billing147Demo } from "@/components/blocks/billing/billing147";

export default function Page() {
  return <Billing147 {...billing147Demo} />;
}

Props

PropTypeDefaultDescription
headingstring"VAT number validation"Heading at the top of the form.
descriptionstringnoneOptional one-line note under the heading.
baseCountryCodestring"IE"Your business's home country code, used to decide whether a valid ID counts as reverse charge.
countriesVatCountryOption[]noneCountries offered as quick-select chips above the input.
defaultCountryCodestringcountries[0].codeWhich country chip is active on first render.
validateLabelstring"Validate"Label on the validate button.
classNamestringnoneExtra classes for the outer container.

Types

interface VatCountryOption {
  code: string;
  name: string;
}

Behavior notes

  • Validation only runs when the Validate button is clicked, not on every keystroke; typing in the input or switching country resets the result back to idle.
  • Format checking uses a small built-in COUNTRY_DIGIT_PATTERNS map for DE, FR, IE, NL, ES, and IT; any other country code falls back to a generic 5-12 character alphanumeric pattern.
  • A failed format check shows 'Not a valid format' immediately. A passing format check shows a brief 'Checking with VIES...' state for 900ms before flipping to valid, simulating a remote lookup with no real network call.
  • The reverse-charge note only appears once state is 'valid' and the selected country differs from baseCountryCode.
  • Country selection uses a chip-style radiogroup instead of a native select, since the UI kit has no Select primitive.

Frequently asked questions