Components
ElvixLegalEntities

ElvixLegalEntities

Single-frame multi-step wizard for legal entities (individual, sole prop, company) with VAT live-validation and tap-to-edit.

app/account/legal-entities/page.tsx
"use client";
import { ElvixLegalEntities } from "@elvix.is/sdk/react";
export function LegalEntitiesPane() {
return (
<ElvixLegalEntities
width={420}
height={580}
onChange={(entities) => {
// Re-read the entity you want to invoice from after every save.
const primary = entities[0];
console.log("primary legal entity:", primary?.id);
}}
onResult={(r) => {
if (!r.ok) return console.warn(r.error, r.message);
console.log(`legal entities now holds ${r.count} records`);
}}
/>
);
}

Props

PropTypeRequiredDefaultDescription
heightnumberoptional580Fixed frame height in pixels. When omitted the frame clamps to min(540px, 66dvh) so it never overflows shorter viewports.
widthnumber | stringoptional"100%"Frame width. Pass a number for fixed pixels, a string for any CSS width.
onChange(entities: LegalEntityRecord[]) => voidoptional—Fires after every successful save or delete with the full list of rows. Use this to refresh host summaries or pick a default for invoicing.
onResult(result: ElvixLegalEntitiesResult) => voidoptional—Terminal callback for every attempt. Safe payload only: { ok: true, count } or { ok: false, error, message }. Never carries the entity rows.

Detail rows are tap-to-edit. Tapping any field on the detail view re-enters the matching pane with the row prefilled and switches the terminal confirm from POST to PATCH. The full lifecycle (add, edit, delete, set default) runs inside the frame, the SDK never navigates the host.

onResult never carries the entity rows. If you need the actual records (for an invoicing dropdown, a server sync, anything), read them from onChange(entities) instead. The split is deliberate: onResult is the safe analytics hook, onChange is the data hook.

VAT ID first, checked by elvix

A sole proprietor or company starts at its VAT ID (0.18): the country comes from the prefix, the register is asked, and the legal name and the address search are prefilled from what it shares (VIES shares nothing for Germany). The verdict on the record (vatIdValidation, vatIdValidatedName, vatIdValidatedAddress) is elvix's own, asked again on every save that changes the number: a browser cannot set it. A business needs its address in parts (line, postal code, city, country) for an invoice, and a sole proprietor without a VAT ID gives its tax number.

To let a user pick one of these for an invoice in your app, and read it on your backend, mount <ElvixLegalEntityPicker>. Its Theming section lists the CSS variables, which style this component too.

Related