adresaanvuller
v2.1.0
Published
Nederlandse adresaanvuller component en hook voor React. Maakt gebruik van de PDOK Locatieserver API.
Downloads
2,002
Maintainers
Readme
Adresaanvuller
Nederlandse adresaanvuller voor React. Zoek en selecteer adressen via de PDOK Locatieserver.
Een abonnement bij Adresaanvuller.nl is vereist om deze package te kunnen gebruiken. Ga naar adresaanvuller.nl om een account aan te maken.
Installatie
npm install adresaanvullerTwee manieren om te gebruiken
De package biedt twee opties:
| | <Adresaanvuller /> | useAdresaanvuller() |
|---|---|---|
| Wat is het? | Kant-en-klaar component | React hook |
| Styling | Ingebouwd (eigen CSS) | Jij bepaalt de styling |
| Dropdown | Automatisch | Zelf renderen |
| Geschikt voor | Snel implementeren | Volledige controle |
Optie 1: Kant-en-klaar component
Gebruik <Adresaanvuller /> als je snel een werkende adreszoeker wilt zonder zelf styling te schrijven. Het component bevat een input, dropdown, spellingssuggesties en een debug-weergave.
Stap 1 — Importeer het component en de stylesheet
import { Adresaanvuller } from "adresaanvuller";
import "adresaanvuller/styles.css";Let op: de
styles.cssimport is vereist voor deze optie. Zonder dit bestand heeft het component geen styling.
Stap 2 — Gebruik het component
export default function MijnPagina() {
return (
<Adresaanvuller
onSelect={(adres) => {
console.log(adres.straatnaam);
console.log(adres.huisnummer);
console.log(adres.postcode);
console.log(adres.woonplaatsnaam);
}}
/>
);
}Dat is alles. Je hebt nu een werkende adresaanvuller.
Volledig voorbeeld
"use client";
import { Adresaanvuller } from "adresaanvuller";
import "adresaanvuller/styles.css";
export default function Checkout() {
const handleAdres = (adres) => {
// Doe iets met het geselecteerde adres
console.log(adres.straatnaam); // "Keizersgracht"
console.log(adres.huis_nlt); // "100"
console.log(adres.postcode); // "1015AA"
console.log(adres.woonplaatsnaam); // "Amsterdam"
console.log(adres.gemeentenaam); // "Amsterdam"
console.log(adres.provincienaam); // "Noord-Holland"
};
return (
<div>
<h1>Bezorgadres</h1>
<Adresaanvuller
placeholder="Vul je adres in..."
onSelect={handleAdres}
/>
</div>
);
}Props
| Prop | Type | Standaard | Beschrijving |
|---|---|---|---|
| onSelect | (adres: AddressDetail) => void | — | Wordt aangeroepen wanneer een adres is geselecteerd |
| placeholder | string | "Zoek een adres..." | Placeholder tekst in het zoekveld |
| className | string | — | Extra CSS class op de container |
| debug | boolean | false | Toont adresdetails en logt JSON in de console |
| rows | number | 8 | Aantal suggesties in de dropdown |
| debounceMs | number | 150 | Vertraging in ms voordat er gezocht wordt |
| minChars | number | 2 | Minimum aantal tekens om te zoeken |
Dark mode
Het component ondersteunt automatisch dark mode. Voeg de class dark toe aan een parent element (bijv. <html class="dark">), en de styling past zich aan. Dit werkt out-of-the-box als je Tailwind CSS gebruikt.
Optie 2: Hook met eigen UI
Gebruik useAdresaanvuller() als je volledige controle wilt over hoe alles eruitziet. De hook geeft je alle data en functies — jij schrijft de HTML en styling.
Stap 1 — Importeer de hook
import { useAdresaanvuller } from "adresaanvuller";Geen
styles.cssimport nodig. Je gebruikt je eigen styling.
Stap 2 — Gebruik de hook
export default function MijnComponent() {
const aa = useAdresaanvuller({
onSelect: (adres) => {
console.log("Gekozen:", adres.weergavenaam);
},
});
return (
<div ref={aa.containerRef}>
<input
ref={aa.inputRef}
value={aa.query}
onChange={(e) => aa.handleChange(e.target.value)}
onKeyDown={aa.handleKeyDown}
placeholder="Zoek een adres..."
/>
</div>
);
}Volledig voorbeeld met dropdown
"use client";
import { useAdresaanvuller } from "adresaanvuller";
import type { AddressDetail } from "adresaanvuller";
import { useState } from "react";
export default function AdresFormulier() {
const [adres, setAdres] = useState<AddressDetail | null>(null);
const aa = useAdresaanvuller({
onSelect: (a) => setAdres(a),
});
return (
<div>
{/* 1. Container (nodig voor click-outside detectie) */}
<div ref={aa.containerRef} style={{ position: "relative" }}>
{/* 2. Input veld */}
<input
ref={aa.inputRef}
value={aa.query}
onChange={(e) => aa.handleChange(e.target.value)}
onFocus={() => aa.results.length > 0 && !aa.selected && aa.setIsOpen(true)}
onKeyDown={aa.handleKeyDown}
placeholder="Zoek een adres..."
/>
{/* 3. Laad-indicator (optioneel) */}
{aa.isLoading && <span>Zoeken...</span>}
{/* 4. Wis-knop (optioneel) */}
{aa.query && !aa.isLoading && (
<button onClick={aa.clear}>✕</button>
)}
{/* 5. Dropdown met resultaten */}
{aa.isOpen && (
<ul style={{ position: "absolute", top: "100%", width: "100%" }}>
{aa.results.length === 0 ? (
<>
<li>Geen resultaten</li>
{aa.suggestions.map((s) => (
<li key={s} onClick={() => aa.handleSuggestionClick(s)}>
Bedoelde je: {s}
</li>
))}
</>
) : (
aa.results.map((doc, i) => (
<li
key={doc.id}
onClick={() => aa.handleSelect(doc)}
onMouseEnter={() => aa.setActiveIndex(i)}
style={{
background: i === aa.activeIndex ? "#f0f0f0" : "white",
}}
>
{/* Gebruik highlighting voor vetgedrukte matches */}
<span
dangerouslySetInnerHTML={{
__html: aa.highlighting[doc.id] || doc.weergavenaam,
}}
/>
<small> ({aa.typeLabel(doc.type)})</small>
</li>
))
)}
</ul>
)}
</div>
{/* 6. Toon het geselecteerde adres */}
{adres && (
<div>
<p>{adres.straatnaam} {adres.huis_nlt}</p>
<p>{adres.postcode} {adres.woonplaatsnaam}</p>
</div>
)}
</div>
);
}Wat geeft de hook terug?
| Property | Type | Beschrijving |
|---|---|---|
| State | | |
| query | string | Huidige zoektekst |
| results | SuggestDoc[] | Lijst met suggesties |
| highlighting | Record<string, string> | HTML met vetgedrukte matches per result-ID |
| isOpen | boolean | Of de dropdown open is |
| isLoading | boolean | Of er gezocht wordt |
| selected | AddressDetail \| null | Het volledig geselecteerde adres |
| isLoadingDetail | boolean | Of de adresdetails worden opgehaald |
| activeIndex | number | Index van het actieve item in de dropdown (-1 = geen) |
| suggestions | string[] | Spellingscorrecties ("bedoelde je...") |
| Functies | | |
| handleChange(value) | (string) => void | Koppel aan onChange van je input |
| handleKeyDown(event) | (KeyboardEvent) => void | Koppel aan onKeyDown voor pijltjes + Enter |
| handleSelect(doc) | (SuggestDoc) => void | Roep aan wanneer een resultaat wordt gekozen |
| handleSuggestionClick(text) | (string) => void | Roep aan bij klik op een spellingsuggestie |
| setIsOpen(open) | (boolean) => void | Open/sluit de dropdown handmatig |
| setActiveIndex(index) | (number) => void | Stel het actieve item in (voor hover) |
| clear() | () => void | Wis alles en focus het input veld |
| typeLabel(type) | (string) => string | Vertaalt type naar label ("adres" → "Adres") |
| Refs | | |
| containerRef | RefObject<HTMLDivElement> | Zet op je buitenste <div> (voor click-outside) |
| inputRef | RefObject<HTMLInputElement> | Zet op je <input> (voor focus-beheer) |
Debug modus
Zet debug op true om te helpen bij ontwikkeling:
// Component versie
<Adresaanvuller debug={true} onSelect={handleAdres} />
// Hook versie
const aa = useAdresaanvuller({ debug: true });Dit doet twee dingen:
- Console output — Bij elke adresselectie wordt het volledige JSON-response gelogd in de browser console
- Detail weergave (alleen component versie) — Toont een kaart met alle adresgegevens onder het zoekveld
Zet
debugopfalse(of laat het weg) voor productie.
Het AddressDetail object
Wanneer een adres wordt geselecteerd via onSelect, ontvang je een object met deze velden:
{
weergavenaam: string; // "Keizersgracht 100, 1015AA Amsterdam"
straatnaam: string; // "Keizersgracht"
huisnummer: number; // 100
huisletter?: string; // "A"
huis_nlt: string; // "100A"
postcode: string; // "1015AA"
woonplaatsnaam: string; // "Amsterdam"
gemeentenaam: string; // "Amsterdam"
provincienaam: string; // "Noord-Holland"
wijknaam: string; // "Centrum-West"
buurtnaam: string; // "Grachtengordel-West"
centroide_ll: string; // "POINT(4.887 52.375)"
// ... en meer
}Zie de TypeScript types voor alle beschikbare velden.
TypeScript types
Alle types worden geëxporteerd en zijn direct beschikbaar:
import type {
AddressDetail, // Volledig adres na selectie
SuggestDoc, // Suggestie in de dropdown
AdresaanvullerConfig, // Configuratie voor hook en component
AdresaanvullerState, // Return type van useAdresaanvuller()
AdresaanvullerProps, // Props van <Adresaanvuller />
SuggestResponse, // Raw API response
} from "adresaanvuller";Vereisten
- React 18 of hoger
- TypeScript (aanbevolen, niet verplicht)
Licentie
MIT
