@comms-id/acnc-charity-lookup-react
A React hook and a finished component for the Comms.ID Charity field: the user types the 11-digit ABN of a charity. Accessible, no layout shift, with the data attribution always shown. React 18 or later; it depends on @comms-id/acnc-charity-lookup and nothing else.
import { createAcncCharityLookupBrowserClient } from "@comms-id/acnc-charity-lookup/browser";
import { AcncCharityLookupLookup } from "@comms-id/acnc-charity-lookup-react";
const client = createAcncCharityLookupBrowserClient({ relayUrl: "/api/comms-id/charity" });
export const Form = () => (
<AcncCharityLookupLookup
client={client}
onSelect={(record, timing) => console.log(record, `${timing.ms} ms`)}
/>
);
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
- An ABN: eleven digits (spaces and hyphens allowed) are looked up at once in the ACNC register. Letters, or more than eleven digits, are refused in the browser and nothing is sent. Charities are not searched by name.
- The result is one summary line (legal name, ABN, state and postcode) on a fixed note line, so the page never moves.
- "No charity found." (the ABN is not an ACNC-registered charity) and "Charity lookup is unavailable" are different messages; an outage offers "Try again".
Your own markup: useAcncCharityLookup
const field = useAcncCharityLookup({ client, onSelect });
return (
<>
<input {...field.getInputProps()} />
<ul {...field.getListboxProps("Matches")} hidden={!field.state.open}>
{field.state.suggestions.map((s, i) => (
<li key={s.key} {...field.getOptionProps(i)}>{s.primary}</li>
))}
</ul>
<p {...field.getStatusProps()}>{field.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. Render the attribution yourself when you use the hook: it is field.state.attribution.
The component
Props: client (required), label (default "Charity ABN"), onSelect, minChars (3), debounceMs (400), limit (8), settings, 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-acnc-charity-lookup__* class names. It needs no stylesheet.
- The list floats under the input; opening it moves nothing. The note line has a reserved height.
- A failed lookup says why and offers "Try again"; it is never shown as "no match".
- It renders on the server with the same structure, and works under StrictMode.
Data attribution
Charity data comes from the Australian Charities and Not-for-profits Commission (ACNC), via data.gov.au (CC BY 3.0 AU). The component always shows the attribution. Do not hide it.
LICENSE is the consumer client licence. src/ is generated by @comms-id/forge-transformers and is never edited by hand.