Gå til innholdet

Tabs

Komponenten tar piltastene, og kobler fanene til panelene når markupen kommer uten koblingen.

I en fanerad skal Tab hoppe forbi hele raden og inn i panelet, mens piltastene flytter mellom fanene. Et sett knapper uten den koblingen gir én tabbestopp per fane, og skjermleseren sier «knapp» der den skulle sagt «fane, 2 av 3, valgt».

Skriver serveren hidden på panelene, står det. Kommer markupen uten, viser tabs.css bare det første synlige panelet til komponenten er registrert, og komponenten skjuler resten i det den kobles til. Innholdet hopper derfor ikke i noen av tilfellene.

selected sier hvilken fane som er valgt når markupen lages, og er indeksen i lista:

const faner = fs.tabs({ id: "sak", count: 3, selected: 1, label: "Deler av saken" })

Serveren bestemmer altså utgangspunktet. Etterpå er det aria-selected i markupen som gjelder, og komponenten leser derfra. Mangler aria-selected, som i markup skrevet uten JavaScript, leser den valget fra panelene: det første som ikke har hidden hører til den valgte fanen. Sier markupen ingenting, eller skjuler den alle panelene, er det den første. Det komponenten selv har skrevet teller ikke som markupens svar: bytter serveren fane ved bare å flytte hidden, følger markeringen med.

server-controlled slår av at komponenten setter brukerens valg tilbake etter en patch. Den skriver fortsatt ut det markupen sier, altså aria-selected, tabbestoppet og hidden i takt, så en bar rad får rollene og valget også der.

Komponenten har ikke noe selected-attributt. Svaret står i markupen, som aria-selected på fanen, og leses derfra. To steder å holde i synk er ett for mye.

const faner = document.querySelector("fs-tabs")
if (!faner) throw new Error("fant ikke elementet")
faner.selected // 0
faner.select(1) // velger «Vedlegg» og sender `tab-select`
faner.selected = 2 // det samme som select(2)

Komponenten finner panelet til hver fane gjennom aria-controls. Panelene kan derfor stå i en annen rekkefølge enn fanene, og utenfor <fs-tabs>. Et panel utenfor ligger likevel ikke i det komponenten observerer, så river en patch hidden av det, kommer det ikke tilbake av seg selv. Peker aria-controls på en id som ikke finnes, sier komponenten fra i konsollen. Markup uten aria-controls kobles etter rekkefølgen, og komponenten skriver da koblingen inn, med id-er den lager selv og husker: en patch som river dem bort får de samme tilbake.

Panelene står i siden før defineFsTabs() har kjørt. fs.tabs() skriver hidden på alle unntatt det valgte, så markupen er riktig fra første tegning.

Er markupen bar, viser fs-tabs:not(:defined) i tabs.css bare det første panelet som ikke er skjult. Regelen rekker bare panelene inne i <fs-tabs>: et panel utenfor må ha hidden fra serveren.

Se Markup og oppførsel.

KlasseHva det er
.fs-tabs__listRaden med knapper. Får role="tablist" av serveren eller komponenten
.fs-tabs__panelEtt panel. Den valgte er uten hidden

Knappene har ingen egen klasse, de styles som .fs-tabs__list button.

VariabelReserve
--fs-tabs-gapvar(--fs-spacing-1)
--fs-tabs-paddingvar(--fs-spacing-2) var(--fs-spacing-4)
--fs-tabs-panel-spacevar(--fs-spacing-4)
.fs-tabs__list {
--fs-tabs-gap: 0;
}

Fanene er role="tab" i en role="tablist", og panelene er role="tabpanel" pekt til med aria-labelledby. Skriver serveren dem med fs.tabs(), står de i HTML-en før skriptet har kjørt. Kommer markupen uten, setter komponenten dem i det den registreres, og setter dem tilbake om en patch tar dem.

TastGjør
PiltasteneFlytter mellom fanene, og går rundt fra siste til første
Home og EndFørste og siste fane
TabUt av raden og inn i det valgte panelet

En fane med disabled hoppes over, og i en side med dir="rtl" bytter venstre og høyre pil retning, slik at neste fane alltid er den som står ved siden av i leseretningen.

Én fane har tabindex="0", normalt den valgte. Er den valgte deaktivert, flyttes tabbestoppet til den neste aktive. Panelet har tabindex="0" slik at det får fokus også når det ikke har noe fokuserbart i seg, ellers hopper Tab rett forbi innholdet som nettopp ble vist.