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
komponent kan man bruke <PktAccordion>
som en wrapper rundt flere <PktAccordionItem>
eller <AccordionItem>
som en standalone komponent (dersom man kun trenger én AccordionItem).
Som standard, vil man kunne ha flere åpne rader i Punkt sin Accordion
samtidig.
Per dags dato, er det opptil bruker å begrense antall åpne rader selv i sin løsning om dette er ønsket funksjonalitet.
(Les mer under “Begrens antall åpne rader”)
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>
<pkt-accordion key="acc" :compact="false" skin="borderless">
<pkt-accordion-item
v-for="item in accordionItems"
:key="item.id"
:id="item.id"
:title="item.title"
:toggleProps="{ isOpen: openedItem === item.id, onToggleClick: toggleCurrentOpenItem }"
>
{{ item.content }}
</pkt-accordion-item>
</pkt-accordion>
<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 - det vil si at man må overstyre den automatiske tilstandshåndteringen til komponenten.
Dette gjøres ved å sette en boolean isOpen
og en onClick
/click
funksjon på <AccordionItem>/<pkt-accordion-item>
som styrer åpne-lukke tilstanden til komponenten`.
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 ikonsistens 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. Sjekk eksemplene under!
// Elements
<script>
@state() private openedItem: string = ''
function toggleCurrentOpenItem(e: MouseEvent, id: string) {
e.preventDefault() // Prevent default behavior to ensure controlled state
if (this.openedItem === id) {
this.openedItem = ''
} else {
this.openedItem = id
}
}
</script>
<pkt-accordion skin="blue" aria-labelledby="accordion-standard">
<pkt-accordion-item
id=${item.id}
title=${item.title}
.isOpen=${this.openedItem == item.id}
@click=${(e: MouseEvent) => this.toggleCurrentOpenItem(e, item.id)}
>
${item.content}
<p>Element innhold</p>
</pkt-accordion-item>`
</pkt-accordion>
<template>
<pkt-accordion key="acc" :compact="false" skin="borderless">
<pkt-accordion-item
v-for="item in accordionItems"
:key="item.id"
:id="item.id"
:title="item.title"
:isOpen="openedItem === item.id"
@click="toggleCurrentOpenItem(item.id)"
>
{{ item.content }}
</pkt-accordion-item>
</pkt-accordion>
</template>
<script>
const toggleCurrentOpenItem = (id: string) => {
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">Heading</h3>
<PktAccordion compact skin={'borderless'} aria-labelledby="heading-accordion">
{accordionItems.map((item, index) => {
return (
<PktAccordionItem
id={item.id}
key={item.id}
title={item.title}
defaultOpen={index === 0}
isOpen={openedItem === item.id}
onClick={(e) => toggleCurrentOpenItem(e, item.id)} >
{item.content}
</PktAccordionItem>
)
})}
</PktAccordion>
</>
)
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?
Bruk av enkel <AccordionItem>
AccordionItem
kan brukes som en standalone komponent.Ønsker man annen styling enn standard, kan man sette skin
og compact
direkte på <AccordionItem>
.
Bruker man <PktAccordion>
som wrapper, setter man skin
og compact
direkte på <PktAccordion>
for konsekvent styling.
// React
<AccordionItem skin="blue" compact title="Tittel">
<p>Innholdet i AccordionItem</p>
</AccordionItem>
// Elements
<pkt-accordion-item skin="blue" compact title="Tittel">
<p>Innholdet i AccordionItem</p>
</pkt-accordion-item>
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. | |
className | string | - | Styling klasse | |
children | ReactNode eller ReactNode[] | - | <Accordion> må wrappe rundt <AccordionItem > | |
skin | borderless , outlined , beige , blue | - | borderless | Hvert skin har en egen bakgrunnsfarge og borderfarge. Settes kun dersom <AccordionItem> brukes alene. |
compact | boolean | - | false | Gir en kompakt versjon av <AccordionItem> . Settes kun dersom <AccordionItem> brukes alene. |
isOpen | boolean | - | false | Kontrollerer åpen-lukk tilstanden til <AccordionItem> . Overstyrer automatisk åpne-lukk funksjonalitet. |
onClick | (e: MouseEvent) => void | - | En CallBack funksjon som kjører når <AccordionItem> blir klikket på. |
Hvordan ta i bruk?
// React
import { PktAccordion, PktAccordionItem } from "@oslokommune/punkt-react";
// Custom Element:
import "@oslokommune/punkt-elements/dist/pkt-accordion.js";
import "@oslokommune/punkt-elements/dist/pkt-accordion-item.js";
// Custom Element fra CDN:
<script src="https://punkt-cdn.oslo.kommune.no/latest/elements/pkt-accordion.js"></script>;
<script src="https://punkt-cdn.oslo.kommune.no/latest/elements/pkt-accordion-item.js"></script>;