Om komponenten
Tabs er i utgangspunktet ment Ä brukes til Ä erstatte innhold i et begrenset omrÄde under fanerekken, uten Ä navigere vekk fra siden, men i enkelte tilfeller ser vi at vÄre brukere Þnsker Ä bruke denne komponenten som en navigasjonsrekke med lenker. Disse to bruksomrÄdene har forskjellige hensyn nÄr det kommer til semantikk og tilgjengelighet, og komponenten kommer derfor med to forskjellige interaksjonsmÞnstre.
Dersom du Þnsker Ä bruke den som en inline navigasjon av innhold pÄ siden, sÄ vil fanene oppfÞre seg slik som WAI-ARIA-kravene sier de skal, og ellers vil de bare vÊre som en rekke med lenker.
Avhengigheter
Ved bruk av tag eller ikon i fanene:
- pkt-tag
- pkt-icon
Bruk uten Vue eller React
Dersom denne komponenten skal oppfylle krav for universell utforming mÄ den utvides med noe JavaScript for Ä kontrollere tastaturnavigasjonen. Dette kommer bakt inn i Vue- og Reactkomnponentene, men mÄ legges til spesielt ellers.
Vi har laget en klasse som kan brukes âut av boksenâ dersom dere ikke Ăžnsker Ă„ skrive denne funksjonaliteten selv. Den kan dere finne pĂ„ vĂ„r CDN eller i pakken punkt-css under /dist/scripts/pkt-tags.js
.
Eksempel pÄ bruk:
import PktTabs from "@oslokommune/punkt-css/dist/scripts/pkt-tabs.js";
const tabList1 = new PktTabs(
document.getElementById("MineTabs"),
document.getElementById("MineTabsPaneler"),
);
document.querySelectorAll("#MineTabs [role=tab]").forEach((tab, index) => {
tab.addEventListener("click", (event) => {
event.preventDefault();
tabList1.setActiveByIndex(index);
});
});
Varianter
For Ä endre innhold pÄ siden
<div class="pkt-tabs" id="PktTabs1">
<div class="pkt-tabs__list" role="tablist">
<button
id="tab-1"
type="button"
class="pkt-tabs__button pkt-link-button active"
aria-selected="true"
aria-controls="panel-1"
role="tab"
>
Tab 1<span class="pkt-tag pkt-tag--yellow pkt-tag--small">Tag</span>
</button>
<button
id="tab-2"
type="button"
class="pkt-tabs__button pkt-link-button"
role="tab"
aria-controls="panel-2"
aria-selected="false"
>
Tab 2
</button>
...
<button
id="tab-5"
type="button"
class="pkt-tabs__button pkt-link-button"
aria-selected="false"
role="tab"
aria-controls="panel-5"
>
<span class="pkt-icon pkt-icon--small">
<svg viewBox="0 0 32 32">
<use href="#user"></use>
</svg>
</span>
Tab 5
</button>
</div>
</div><div class="pkt-tabpanels" id="PktTabs1Panels" aria-live="polite">
<div
id="panel-1"
class="p-size-20"
role="tabpanel"
aria-labelledby="tab-1"
>
One morning, when Gregor Samsa woke from troubled dreams, he found
himself transformed in his bed into a horrible vermin.
</div>
<div
id="panel-2"
class="p-size-20 pkt-hide"
role="tabpanel"
aria-labelledby="tab-2"
>
He lay on his armour-like back, and if he lifted his head a little he
could see his brown belly, slightly domed and divided by arches into
stiff sections.
</div>
...
<div
id="panel-5"
class="p-size-20 pkt-hide"
role="tabpanel"
aria-labelledby="tab-5"
>
"Whatâs happened to me?" he thought. It wasnât a dream.
</div>
</div>
<script>
import PktTabs from "@oslokommune/punkt-css/dist/scripts/pkt-tabs.js";
const tabList1 = new PktTabs(
document.getElementById("PktTabs1"),
document.getElementById("PktTabs1Panels")
)
document.querySelectorAll("#PktTabs1 [role=tab]").forEach((tab, index) => {
tab.addEventListener("click", (event) => {
event.preventDefault()
tabList1.setActiveByIndex(index)
})
})
</script>
<template>
<PktTabs :tabs="tabs" @onTabSelected="changeContent" />
<div :id="`tabpanel-${visibleContent}`" role="tabpanel" aria-live="polite">
{{ content[visibleContent] }}
</div>
</template>
<script setup>
const visibleContent = ref(0);
const changeContent = (index) => {
visibleContent = index;
};
const tabs = [
{
text: "Tab 1",
tag: {
text: "Tag",
},
active: i === visibleContent,
},
{
text: "Tab 2",
active: i === visibleContent,
},
{
text: "Tab 3",
active: i === visibleContent,
},
{
text: "Tab 4",
active: i === visibleContent,
},
{
text: "Tab 5",
icon: "user",
active: i === visibleContent,
},
];
const content = [
"One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.",
"He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.",
"The bedding was hardly able to cover it and seemed ready to slide off any moment.",
"His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked.",
'"Whatâs happened to me?" he thought. It wasnât a dream.',
"His room, a proper human room although a little too small, lay peacefully between its four familiar walls.",
"A collection of textile samples lay spread out on the table - Samsa was a travelling salesman - and above it there hung a picture that he had recently cut out of an illustrated magazine,",
];
</script>
const [visibleContent, setVisibleContent] = useState(0)
const [tabs, setTabs] = useState([
{
text: 'Tab 1',
tag: {
text: 'Tag',
},
active: i === visibleContent,
},
{
text: 'Tab 2',
active: i === visibleContent,
},
{
text: 'Tab 3',
active: i === visibleContent,
},
{
text: 'Tab 4',
active: i === visibleContent,
},
{
text: 'Tab 5',
icon: 'user',
active: i === visibleContent,
},
])
const content = [
'One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.',
'He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.',
'The bedding was hardly able to cover it and seemed ready to slide off any moment.',
'His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked.',
'"Whatâs happened to me?" he thought. It wasnât a dream.',
'His room, a proper human room although a little too small, lay peacefully between its four familiar walls.',
'A collection of textile samples lay spread out on the table - Samsa was a travelling salesman - and above it there hung a picture that he had recently cut out of an illustrated magazine,',
]
const changeContent = (id) => {
setTabs(tabs.map((tab, i) => ({...tab, active: i === visibleContent})))
}
return (
{" "}
<PktTabs tabs={tabs} onTabSelected={changeContent} />
<div
id={`tabpanel-${visibleContent}`}
role="tabpanel"
aria-live="polite"
>
{content[visibleContent]}
</div>
)
For Ă„ navigere til en annen side (navigasjon)
<div class="pkt-tabs">
<div class="pkt-tabs__list" role="navigation">
<a class="pkt-tabs__link active" href="#">Tab 1</a>
<a class="pkt-tabs__link" href="#">Tab 2</a>
<a class="pkt-tabs__link" href="#">Tab 3</a>
<a class="pkt-tabs__link" href="#">Tab 4</a>
<a class="pkt-tabs__link" href="#">Tab 5</a>
<a class="pkt-tabs__link" href="#">Tab 6</a>
<a class="pkt-tabs__link" href="#">Tab 7</a>
<a class="pkt-tabs__link" href="#">Tab 8</a>
<a class="pkt-tabs__link" href="#">Tab 9</a>
<a class="pkt-tabs__link" href="#">Tab 10</a>
<a class="pkt-tabs__link" href="#">Tab 11</a>
<a class="pkt-tabs__link" href="#">Tab 12</a>
<a class="pkt-tabs__link" href="#">Tab 13</a>
<a class="pkt-tabs__link" href="#">Tab 14</a>
<a class="pkt-tabs__link" href="#">Tab 15</a>
</div>
</div>
<template>
<PktTabs :tabs="tabs" , :arrowNav="false" />
</template>
<script setup>
const tabs = [
{
text: 'Tab 1',
href: '#',
active: true,
},
{
text: 'Tab 2',
href: '#',
},
{
text: 'Tab 3',
href: '#',
},
...
]
</script>
const tabs = [
{
text: 'Tab 1',
href: '#',
active: true,
},
{
text: 'Tab 2',
href: '#',
},
{
text: 'Tab 3',
href: '#',
},
...
]
return (
<PktTabs tabs={tabs} arrowNav={false} />
)
CSS-klasser
Block:
- .pkt-tabs
Elements:
- .pkt-tabs__list
- .pkt-tabs__link
- .pkt-tabs__button
- .pkt-link-button
- .pkt-tag
- .pkt-icon
Modifiers:
- .pkt-icon
--
small - .pkt-tag
--
small
Props og events
Props | Type | Validation | Default | Beskrivelse |
---|---|---|---|---|
tabs | array | Required | - | Liste av objekter som utgjĂžr fanene â Se neste tabell |
arrowNav | boolean | - | true | Settes denne til false vil fanerekken vĂŠre navigasjon med lenker istedenfor tablist |
onTabSelected (React) | function | - | - | Callback-funksjon som kalles med index av valgt fane |
tab-objektet i tabs
Key | Type | Validation | Default | Beskrivelse |
---|---|---|---|---|
text | string | Required | - | Tekst som vises i fanen |
href | string | - | - | Valgfri lenke-URL til bruk dersom dette er navigasjon, eller for fallback |
action | function | - | - | Valgfri funksjon som skal kalles ved klikk pÄ denne fanen |
icon | string | - | - | Ikon fra vÄrt ikonbibliotek som skal vises i fanen |
controls | string | - | - | ID til innholdspanelen som denne fanen styrer (aria-controls-attributt) |
tag | object | Som PktTag | - | Tar text - og skin -verdier som matcher det som kan sendes til PktTag |
active | boolean | - | - | Er denne fanen aktiv? true /false |
Events
Events | Type | Returns | Beskrivelse |
---|---|---|---|
onTabSelected | Vue | integer | Returnerer index pÄ valgt fane |
Les mer