Om komponenten
Formål
Gir en fullverdig søkeside over et hvilket som helst flatt JSON-datasett: fritekstsøk, avkrysningsbaserte type-/kategori-filtre, et ARIA-mønster-filter og fire sorteringsvalg (relevans, navn, sist endret, mest brukt). Bygger selv de riktige avkrysningsboksene (med treff-antall) fra det faktiske datasettet - ingen fasetter må konfigureres manuelt.
Merk: Brukes i dag av designsystemets egen /designsystem/sok/index.html-side (over sok-indeks.json), men vet ingenting om designsystemet spesifikt - kilde/data kan peke på et hvilket som helst datasett med samme feltnavn.
Egner seg for
- En dedikert søkeside som skal la brukeren finne fram i et større, kategorisert katalog (komponenter, artikler, produkter, dokumentasjon).
- Datasett som allerede finnes som en flat, statisk generert JSON-fil - ingen server-søk eller paginering trengs.
Egner seg ikke for
- Et lite, raskt "hopp til side"-hurtigsøk i en sidebar - se den enklere, håndskrevne implementasjonen i
designsystem.js/.designsystem-sokfor det behovet. - Datasett med tusenvis av rader der server-side søk/paginering er nødvendig av ytelsesgrunner - komponenten laster og filtrerer hele datasettet i nettleseren.
Bruk
Enkleste bruk peker kilde på en ferdig generert JSON-indeks:
<script type="module" src="/designsystem/komponenter/navigasjon/sok/sok.js"></script>
<lm-sok kilde="/designsystem/sok-indeks.json" synk-url></lm-sok>
Sette data direkte (hopper over henting via kilde)
const sok = document.querySelector("lm-sok");
sok.data = await fetch("/mitt-eget-datasett.json").then((r) => r.json());
sok.addEventListener("sok:oppdatert", (e) => {
document.title = `Søk (${e.detail.antall} treff) - Mitt nettsted`;
});
Prøv selv
Rediger koden under - resultatet oppdateres live.
Attributter
| Attributt | Type | Standard | Beskrivelse |
|---|---|---|---|
kilde | string (URL) | null | Attributt/property. URL til søkeindeksen (JSON-array av {navn, type, kategori, synonymer, beskrivelse, lenke, sistEndret, brukesAvAntall, harAriaMonster}). Hentes automatisk når attributtet settes/endres. |
synk-url | boolean | false | Attributt. Når til stede, synkroniseres søkeord/filtre/sortering med URL-ens spørrestreng (?q=...&type=...&kategori=...&sortering=...&aria=1) via history.replaceState, slik at et søk kan lenkes/deles og fungerer med nettleserens fram/tilbake. |
plassholder | string | "Søk (f.eks. «modal», «avstand», «tabell»)" | Attributt. Overstyrer plassholderteksten i søkefeltet. |
data | Array<object> | [] | Property. Elementene som søkes/filtreres i - kan settes direkte for å hoppe over henting via kilde (f.eks. når data allerede er hentet av forbrukeren). |
Events
| Event | Type | Beskrivelse |
|---|---|---|
sok:oppdatert | CustomEvent<{antall: number, totalt: number}> | Sendes hver gang det synlige resultatsettet endres (nytt søkeord, filter eller sortering) - detail.antall er antall synlige treff, detail.totalt er hele datasettets størrelse. |
Parts
| Part | Beskrivelse |
|---|---|
verktoylinje | Den øverste raden med søkefelt, filtre og sortering. |
felt | Selve søkefeltet (<input type="search">). |
type-filter | <fieldset>-en med type-avkrysningsboksene (Komponent/Funksjon/Token). |
kategori-filter | <fieldset>-en med kategori-avkrysningsboksene. |
kategori-liste | Den skrollbare listen av kategori-avkrysningsbokser inni kategori-filter. |
sortering | <select>-en for sorteringsvalg. |
nullstill | «Nullstill filter»-knappen (skjult når ingen filter er aktive). |
antall-treff | Den «X av Y treff»-teksten (role="status", kunngjøres av skjermlesere). |
resultater | <ul>-en med treffene. |
resultat | Hvert enkelt treff (<li>) i resultatlisten. |
Styling med ::part()
Hver part over kan restyles direkte fra et vanlig, ytre stilark - uten å måtte endre selve komponenten eller duplisere den:
lm-sok::part(verktoylinje) {
/* egne stiler for "Den øverste raden med søkefelt, filtre og sortering." */
}
lm-sok::part(felt) {
/* egne stiler for "Selve søkefeltet (`<input type="search">`)." */
}
lm-sok::part(type-filter) {
/* egne stiler for "`<fieldset>`-en med type-avkrysningsboksene (Komponent/Funksjon/Token)." */
}
lm-sok::part(kategori-filter) {
/* egne stiler for "`<fieldset>`-en med kategori-avkrysningsboksene." */
}
lm-sok::part(kategori-liste) {
/* egne stiler for "Den skrollbare listen av kategori-avkrysningsbokser inni kategori-filter." */
}
lm-sok::part(sortering) {
/* egne stiler for "`<select>`-en for sorteringsvalg." */
}
lm-sok::part(nullstill) {
/* egne stiler for "«Nullstill filter»-knappen (skjult når ingen filter er aktive)." */
}
lm-sok::part(antall-treff) {
/* egne stiler for "Den «X av Y treff»-teksten (`role="status"`, kunngjøres av skjermlesere)." */
}
lm-sok::part(resultater) {
/* egne stiler for "`<ul>`-en med treffene." */
}
lm-sok::part(resultat) {
/* egne stiler for "Hvert enkelt treff (`<li>`) i resultatlisten." */
}
Tilgjengelighet
Alle filterkontroller er native og tastaturoperable (checkboxer, select). Treff-antallet står i et role="status"-element som kunngjør endringer for skjermlesere uten å flytte fokus. Fasett-avkrysningsboksene bygges kun én gang per datasett (ikke ved hvert tastetrykk), slik at fokus/tastaturposisjon aldri mistes når en boks krysses av.
- Type-/kategori-/ARIA-mønster-filtre er native
<input type="checkbox">i<fieldset>/<legend>-grupper - full tastaturstøtte og skjermleser-gruppering uten egen ARIA. - Sorteringsvalget er en native
<select>. - Treff-antallet (
role="status") kunngjøres automatisk av skjermlesere når det endres, uten å stjele fokus fra søkefeltet eller filtrene. - Fasett-avkrysningsboksene bygges kun én gang per datasett (
#byggFasetter()kalles fradata-setteren, ikke fra søkefeltetsinput-lytter) - dette er bevisst, for å unngå at et helt nytt sett med DOM-noder (og dermed tapt fokus) opprettes hver gang brukeren krysser av en boks.
Detaljer
- Søkefeltet er debouncet (150ms) - filtrering skjer ikke ved hvert eneste tastetrykk under rask skriving.
- Fasett-tellerne ("Komponent (32)") viser alltid antallet i hele datasettet, ikke et tall som endrer seg etter hvert som andre filtre justeres - et bevisst enkelt valg som unngår kompleks "faceted count"-omregning og den destruktive re-rendringen den ville krevd (se tilgjengelighetDetaljer).
synk-urlbrukerhistory.replaceState(ikkepushState) - hvert tastetrykk/filtervalg skal ikke skape en egen oppføring i nettleserhistorikken.- Relevans-sortering (standard når det søkes) rangerer eksakt navnetreff først, så "navn starter med søket", så resten - alfabetisk innad i hver gruppe.
Referanser
Se også:
../../innhold/tag/index.html - brukes internt til å vise type- og kategori-merkelapper på hvert treff.../../../funksjoner/dom/koble-datalist-sok/index.html - for et enkelt "velg ett forslag fra en liste"-felt inni et skjema - et helt annet behov enn en filtrerbar resultatside.../../innhold/data-table/index.html - for tabelldata som skal sorteres/vises i rader og kolonner fremfor en fritekst-/fasett-filtrert liste.
Brukes av:
designsystem/sok/index.html - designsystemets egen søkeside, over designsystem/sok-indeks.json.
Avhengigheter: designsystem/komponenter/innhold/tag/tag.js