JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 86
  • Score
    100M100P100Q72861F
  • License MIT

Nederlandse adresaanvuller component en hook voor React. Maakt gebruik van de PDOK Locatieserver API.

Package Exports

  • adresaanvuller
  • adresaanvuller/styles.css

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 adresaanvuller

Twee 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.css import 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.css import 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:

  1. Console output — Bij elke adresselectie wordt het volledige JSON-response gelogd in de browser console
  2. Detail weergave (alleen component versie) — Toont een kaart met alle adresgegevens onder het zoekveld

Zet debug op false (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