Om komponenten
Accordion
er en komponent som lar brukeren åpne og lukke innhold.
Vi har valgt å bruke de semantiske details
og summary
-taggene for å lage en accordion. Dette er en enkel og
semantisk måte å lage en accordion på da tastaturnavigering skjer sømløst. Det finnes ulike måter å lage en Accordion
på,
og du kan lese mer om avgjørelsen under universell utforming”-fanen.
For å bruke Punkt sin Accordion
er det viktig at <Accordion>
brukes som en wrapper rundt <AccordionItem>
.
Som standard, kan man ha flere åpne rader i Punkt sin Accordion
samtidig.
Ofte stilte spørsmål
Kan jeg digge Punkt like mye som jeg gjør nå?
Hvordan kan jeg kontakte Punkt?
Hva er MøtePunkt?
<h2 id="accordion-heading-1">Borderless</h2>
<div
data-testid="pkt-accordion"
class="pkt-accordion pkt-accordion--borderless"
aria-labelledby="accordion-heading-1"
>
<details
aria-controls="pkt-accordion-item-content-1"
class="pkt-accordion-item"
id="pkt-accordion-item-header-1"
>
<summary
aria-labelledby="pkt-accordion-item-header-1"
class="pkt-accordion-item__title"
id="pkt-accordion-item-summary-1"
>
Item summary 1
<span class="pkt-icon pkt-accordion-item__icon">
<svg viewBox="0 0 32 32" aria-hidden="true">
<use href="#chevron-thin-down"></use>
</svg>
</span>
</summary>
<div
id="pkt-accordion-item-content-1"
role="region"
class="pkt-accordion-item__content"
>
Item Content 1
</div>
</details>
<details
aria-controls="pkt-accordion-item-content-2"
class="pkt-accordion-item"
id="pkt-accordion-item-header-2"
>
<summary
aria-labelledby="pkt-accordion-item-header-2"
class="pkt-accordion-item__title"
id="pkt-accordion-item-summary-2"
>
Item summary 1
<span class="pkt-icon pkt-accordion-item__icon">
<svg viewBox="0 0 32 32" aria-hidden="true">
<use href="#chevron-thin-down"></use>
</svg>
</span>
</summary>
<div
id="pkt-accordion-item-content-1"
role="region"
class="pkt-accordion-item__content"
>
Item Content 1
</div>
</details>
</div>
<template>
<PktAccordion key="acc" :compact="false" skin="borderless">
<PktAccordionItem
v-for="item in accordionItems"
:key="item.id"
:id="item.id"
:title="item.title"
:toggleProps="{ isOpen: openedItem === item.id, onToggleClick: toggleCurrentOpenItem }"
>
{{ item.content }}
</PktAccordionItem>
</PktAccordion>
</template>
<PktAccordion compact={false} skin="blue">
{accordionItems.map((item, index) => (
<PktAccordionItem id={item.id} key={item.id} title={item.title}>
{item.content}
</PktAccordionItem>
))}
</PktAccordion>
Avhengigheter
Ikoner:
- chevron-thin-down
Begrens antall åpne rader
Som standard, støtter Accordion
åpning av flere rader samtidig.
For å styre at kun én rad kan være åpen om gangen, må man styre alle radene sin toggle tilstand lokalt i Vue eller React.
Dette kan gjøres ved å sette toggleProps
på <AccordionItem>
.
Ingen eksempel i ren HTML. Se Vue eller React eksempel
<template>
<PktAccordion key="acc" :compact="false" skin="borderless">
<PktAccordionItem
v-for="item in accordionItems"
:key="item.id"
:id="item.id"
:title="item.title"
:toggleProps="{ isOpen: openedItem === item.id, onToggleClick: toggleCurrentOpenItem }"
>
{{ item.content }}
</PktAccordionItem>
</PktAccordion>
</template>
<script>
const accordionItems = [
{
id: 'apningstid',
title: 'Hva er åpningstidene?',
content: 'Accordion item 1 content Accordion item 1 content',
},
{ id: 'dresscode', title: 'Hva er dressscode for eventet?', content: 'Accordion item 2 content' },
{ id: 'lokale', title: 'Kan jeg ta med mat og drikke til lokalet?', content: 'Accordion item 3 content' },
{ id: 'kjæledyr', title: 'Kan jeg ta med kjæledyr?', content: 'Accordion item content' },
]
const openedItem = ref<string>('')
const toggleCurrentOpenItem = (id: string) => {
// Close the current open item if it's the same as the clicked item
// Override the value, if it's a new item
openedItem.value = openedItem.value === id ? '' : id
}
</script>
const [openedItem, setOpenedItem] = useState<string>('')
const toggleCurrentOpenItem = (e: React.MouseEvent, id: string) => {
if (openedItem.includes(id)) {
setOpenedItem('')
} else {
setOpenedItem(id)
}
}
return (
<>
<h3 id="heading-accordion">
<PktAccordion
compact={false}
skin="blue"
>
{accordionItems.map((item, index) => (
<PktAccordionItem id={item.id} key={item.id} title={item.title}>
{item.content}
</PktAccordionItem>
))}
</PktAccordion>
</h3>
</>
)
Varianter
Accordion
har fire ulike skins
:
borderless
(standard)outlined
beige
blue
Accordion
kommer også i en compact
versjon. Som standard, er compact
satt til false
.
Kan jeg digge Punkt like mye som jeg gjør nå?
Hvordan kan jeg kontakte Punkt?
Hva er MøtePunkt?
Kan jeg digge Punkt like mye som jeg gjør nå?
Hvordan kan jeg kontakte Punkt?
Hva er MøtePunkt?
Kan jeg digge Punkt like mye som jeg gjør nå?
Hvordan kan jeg kontakte Punkt?
Hva er MøtePunkt?
Kan jeg digge Punkt like mye som jeg gjør nå?
Hvordan kan jeg kontakte Punkt?
Hva er MøtePunkt?
CSS oversikt
I Punkt brukes BEM-styling. Under er Accordion
sin CSS-struktur.
Block:
- .pkt-accordion
- .pkt-accordion-item
Elements:
- .pkt-accordion-item__title
- .pkt-accordion-item__icon
- .pkt-accordion-item__content
Modifiers:
- .pkt-accordion
--
borderless - .pkt-accordion
--
outlined - .pkt-accordion
--
beige - .pkt-accordion
--
blue - .pkt-accordion-item
--
open
Props og slots
<Accordion/>
Props | Type | Validation | Default | Description |
---|---|---|---|---|
className | string | Styling klasse | ||
children | ReactNode eller ReactNode[] | <Accordion> må wrappe rundt <AccordionItem > | ||
compact | boolean | false | Mindre padding og tekststørrelse | |
skin | borderless , outlined , beige , blue | borderless | Hvert skin har en egen bakgrunnsfarge og borderfarge |
<AccordionItem/>
Props | Type | Validation | Default | Description |
---|---|---|---|---|
id | string | Påkrevd | Settes til en unik id per item for å koble item-header med item-content slik at skjermlesere leser opp innhold korrekt | |
title | string | Påkrevd | En tittel/oppsummering av innholdet i <AccordionItem> | |
defaultOpen | boolean | - | false | Sett til true dersom man ønsker å la spesifikk <AccordionItem> være åpen når man først laster inn siden |
ref | LegacyRef<HTMLDivElement> | - | Tillater å hente en ref til komponent instansen. | |
toggleProps | isOpen, onToggleClick() | - | Sett både isOpen og onToggleClick dersom du ønsker å overskrive den lokale togglingen. F.eks. dersom man ønsker å begrense antall <AccordionItem> som kan være åpne samtidig. | |
className | string | - | Styling klasse | |
children | ReactNode eller ReactNode[] | - | <Accordion> må wrappe rundt <AccordionItem > |
toggleProps
i Vue og React
Ønsker man å override den lokale togglingen, kan man gjøre det ved å sende inn toggleProps
til <AccordionItem>
.
Da må man sende inn både en boolean
isOpen og en onToggleClick
funksjon med
argumenter som varierer litt avhengig om det er Vue eller React.
Props | Type | Validation | Default | Description |
---|---|---|---|---|
isOpen | boolean | Påkrevd | false | Bestemmer om en spesifikk <AccordionItem> er åpen eller lukket |
onToggleClick() [vue] | (id: string) => void | Påkrevd | - | Lar deg kontrollere åpne-lukke tilstanden til en spesifikk <AccordionItem> vha id . |
onToggleClick() [react] | (e: React.MouseEvent, id: string) => void | Påkrevd | - | Lar deg kontrollere åpne-lukke tilstanden til en spesifikk <AccordionItem> vha id . React trenger at event sendes inn for å forhindre inkonsistent oppførsel. |
I React, trenger man å sende inn event
for å forhindre inkonsistent oppførsel. Dette er fordi <details>
-elementet har sin egen
innebygde toggle
-funksjon som kan føre til inkonsistent når vi prøver å sette isOpen
-propen i React. I <AccordionItem>
kjører vi e.preventDefault()
for å forhindre at <details>
-elementet sin innebygde toggle
-funksjon kjører.