@comms-id/abn-react
A React hook and a finished component for Comms.ID ABN search. The user types a business name, or an ABN or ASIC number (ACN, ARBN). Accessible, no layout shift, with the data attribution always shown. React 18 or later; it depends on @comms-id/abr-abn-lookup and nothing else.
import { createAbrAbnLookupBrowserClient } from "@comms-id/abr-abn-lookup/browser";
import { AbnAutocomplete } from "@comms-id/abr-abn-lookup-react";
const client = createAbrAbnLookupBrowserClient({ relayUrl: "/api/comms-id/abr-abn-lookup" });
export const Supplier = () => (
<AbnAutocomplete
client={client}
label="Business name or ABN"
onSelect={(business) => console.log(business.name, business.formattedAbn, business.status)}
/>
);
relayUrl is your own server route, set up with @comms-id/relay: your server signs the call as your registered app, so the browser holds no credential.
What the field does
- A name: after the user pauses, it suggests businesses (name, ABN, state and postcode). Choosing one looks it up and calls
onSelect. - An ABN or ASIC number (ACN, ARBN): a whole number (9 or 11 digits, spaces and hyphens allowed) is checked in the browser first. An invalid number sends nothing, and the field says why ("This is not a valid ABN: the check digits do not match."). A valid number is looked up.
- No match is not an outage. "No business found." and "Business search is unavailable" are different messages; an outage offers "Try again".
onSelect(business, timing) gets one AbnBusiness whichever source answered the lookup: abn, formattedAbn, asicNumber with asicNumberType (ACN, ARBN, ARSN or undetermined: ABR never states the kind; v2, #714), name, status, entityType, gstRegistered, state, postcode, source (live or snapshot), asAt and attribution.
Your own markup: useAbn
const abn = useAbn({ client, onSelect });
return (
<>
<input {...abn.getInputProps()} />
<ul {...abn.getListboxProps("Matches")} hidden={!abn.state.open}>
{abn.state.suggestions.map((s, i) => (
<li key={`${s.abn}-${i}`} {...abn.getOptionProps(i)}>{describeSuggestion(s).primary}</li>
))}
</ul>
<p {...abn.getStatusProps()}>{abn.state.announcement}</p>
</>
);
The prop getters carry the WAI-ARIA combobox contract: roles, aria-expanded, aria-controls, aria-activedescendant, key handling (arrows, Enter, Escape, Tab) and a polite live region. Show the attribution yourself when you use the hook: abn.state.attribution.
The component
Props: client and label (required), onSelect, minChars (3), debounceMs (400), limit (8), prefer ({ state, postcode }), idPrefix, name, placeholder, disabled, required, className, listLabel, showTiming (true), renderOption.
Style it with the custom properties --comms-id-text, --comms-id-surface, --comms-id-border, --comms-id-active, --comms-id-radius or the comms-id-abr-abn-lookup__* class names. It needs no stylesheet.
- The list floats under the input; opening it moves nothing. One note line has a reserved height and does not wrap: the result is a summary (name, ABN, status, GST), not a card, so the page never moves. Use
onSelectfor the whole record. - It renders on the server with the same structure, and works under StrictMode.
Data attribution
The component always shows the attribution: the one the reply carried, or the standard text when a reply has none. Do not hide it.
LICENSE is the consumer client licence.