Gå til innholdet

Popover

Panelet bruker nettleserens egen popover, så det havner i topplaget og legger seg over alt annet uten at noen trenger å finne en z-index som er høy nok.

Resten gjør komponenten. Panelet åpnes i manual-modus, ikke auto, siden nettleserens egen lukking rekker å lukke panelet før knappen får klikket sitt, og knappen da ikke kan brukes til å lukke igjen. Escape, klikk utenfor og fokus tilbake til knappen er derfor skrevet i komponenten.

Plasseringen er også vår. position-anchor finnes ennå ikke i alle nettlesere, så komponenten regner ut posisjonen mot knappen og setter den som to variabler på panelet.

// main.ts, kjøres én gang når appen starter
import { defineFsPopover } from "@fristil/designsystem/popover"
import "@fristil/designsystem/popover.css"
defineFsPopover()
const boks = fs.popover({ id: "handlinger" })
<fs-popover placement="bottom-end">
<button class="fs-button" data-variant="secondary"
aria-expanded="false" aria-controls="handlinger">Handlinger</button>
<ul class="fs-popover" id="handlinger" popover="manual" data-variant="plain">
<li><button class="fs-button" data-variant="ghost" type="button">Arkiver saken</button></li>
<li><button class="fs-button" data-variant="ghost" type="button">Last ned som PDF</button></li>
</ul>
</fs-popover>

Komponenten kjenner igjen delene på koblingen som må være der uansett: panelet er det som har popover, og knappen er den som peker på panelet med aria-controls.

Koblingen, popover-attributtet og klassen kommer fra serveren med fs.popover(). Komponenten setter open på verten, aria-expanded på knappen og posisjonen på panelet, og setter dem tilbake når en oppdatering fra serveren river dem bort. Malen din trenger ingenting ekstra.

Reparasjonen gjelder én vei: har noen bedt om at vinduet er åpent, blir det stående. Sender serveren open, åpnes det, for det er noe serveren faktisk sa.

Lukk med egenskapen, altså meny.open = false, hide() eller toggle(). Det er en beskjed komponenten kan se. Fjerner du attributtet utenfra i stedet, som med Datastars data-attr:open, er det ikke til å skille fra en oppdatering som river det bort, og da setter komponenten det tilbake. Der er server-controlled svaret. Se Markup og oppførsel.

<fs-popover id="meny" placement="bottom-end">
<button class="fs-button" data-variant="secondary"
aria-expanded="false" aria-controls="handlinger">Handlinger</button>
<ul class="fs-popover" id="handlinger" popover="manual" data-variant="plain">
<li><button class="fs-button" data-variant="ghost" type="button">Arkiver saken</button></li>
<li><button class="fs-button" data-variant="ghost" type="button">Last ned som PDF</button></li>
</ul>
</fs-popover>
<script type="module">
import { defineFsPopover } from "@fristil/designsystem/popover"
defineFsPopover()
const meny = document.getElementById("meny")
// Lukk menyen når en handling er valgt
meny.addEventListener("click", (hendelse) => {
if (hendelse.target.closest("[aria-controls='handlinger']")) return
if (hendelse.target.closest("button")) meny.hide()
})
</script>
AttributtTypeEffekt
openboolskOm panelet er åpent. Speiles når brukeren åpner og lukker.
placementstrengbottom-start, bottom-end, top-start eller top-end
server-controlledboolskServeren eier tilstanden. Komponenten setter ikke open tilbake etter en oppdatering.
NavnHva det er
popover-toggleHendelse med { open: boolean } i detail
show(), hide(), toggle()Metoder på elementet
const meny = document.querySelector("fs-popover")
meny.addEventListener("popover-toggle", (hendelse) => {
console.log(hendelse.detail.open ? "åpnet" : "lukket")
})

Panelet flytter seg med siden når brukeren ruller eller endrer vindusstørrelsen. Er det ikke plass under knappen, legger det seg over.

Komponenten rendrer i vanlig DOM, så markupen din treffes av vanlige selektorer:

KlasseHva det er
.fs-popoverPanelet. Komponenten setter klassen på elementet du la inn.
VariabelStandard
--fs-popover-widthmin(20rem, calc(100vw - var(--size-8)))
--fs-popover-paddingvar(--size-3)
--fs-popover-radiusvar(--size-1)
--fs-popover-topsettes av komponenten
--fs-popover-leftsettes av komponenten

Posisjonen settes som --fs-popover-top og --fs-popover-left på elementet. De to er regnet ut fra knappens plass på skjermen, og er de eneste verdiene komponenten skriver inn direkte. Alt annet står i stilarket, så du kan overstyre det uten !important.

Se Tilpasning for hvordan variablene og laget virker.

  • Panelet er ikke en dialog. Fokus flyttes ikke inn automatisk, og resten av siden er fortsatt i bruk. Trenger du å stoppe brukeren, bruk Dialog.
  • Escape lukker og gir fokus tilbake til knappen. Uten det står fokus på noe som ikke finnes lenger.
  • Innholdet i panelet skal kunne nås med Tab, i samme rekkefølge som det står i markupen.
  • Ikke legg et skjema som må fylles ut i et panel som lukker seg ved klikk utenfor.