Toast
Elementet er beholderen, ikke meldingen. Du legger det inn én gang i appen og kaller show() når noe skal meldes.
Beholderen er en role="status"-region, ikke role="alert". En melding som dukker opp i hjørnet skal ikke avbryte det skjermleseren holder på med. Er beskjeden så viktig at den må avbryte, hører den hjemme i en Alert i selve siden.
// main.ts, kjøres én gang når appen starterimport { defineFsToast } from "@fristil/designsystem/toast"import "@fristil/designsystem/toast.css"
defineFsToast()Markupen
Section titled “Markupen”fs.toast() gir tre attributtsett, og bare det første skriver du selv:
const varsler = fs.toast({ label: "Meldinger" })<fs-toast role="status" aria-live="polite" aria-label="Meldinger" data-ignore-morph></fs-toast>I JSX sprer du region, ikke hele objektet:
<fs-toast {...fs.toast().region} />varsler.toast og varsler.close er klassene på selve meldingen og lukkeknappen. Dem lager komponenten, så du trenger dem bare hvis serveren patcher inn en melding, som i en Datastar-app.
data-ignore-morph er ikke valgfri. Komponenten lager og fjerner sine egne meldinger inne i regionen, og uten attributtet river en oppdatering fra serveren dem bort, fordi serverens utgave av regionen er tom. Se Markup og oppførsel.
Meldinger
Section titled “Meldinger”<fs-toast id="meldinger" label="Meldinger"></fs-toast>
<script type="module"> import { defineFsToast } from "@fristil/designsystem/toast" defineFsToast()
const meldinger = document.getElementById("meldinger")
document.getElementById("lagre").addEventListener("click", async () => { await lagre() meldinger.show("Søknaden er lagret", { color: "success" }) })</script>I en app
Section titled “I en app”Beholderen legges inn én gang, og meldingene kommer fra koden. Det er forskjellen fra de andre komponentene: her kaller du en metode framfor å sette et attributt.
<fs-toast id="meldinger" label="Meldinger"></fs-toast>
<button class="fs-button" id="lagre" type="button">Lagre søknaden</button>
<script type="module"> import { defineFsToast } from "@fristil/designsystem/toast" defineFsToast()
const meldinger = document.getElementById("meldinger")
document.getElementById("lagre").addEventListener("click", async () => { try { await lagre() meldinger.show("Søknaden er lagret", { color: "success" }) } catch { meldinger.show("Klarte ikke å lagre. Prøv igjen.", { color: "danger", duration: 0 }) } })</script>En feilmelding står til brukeren lukker den, derfor duration: 0.
// main.tsx, kjøres én gang når appen starterimport { defineFsToast } from "@fristil/designsystem/toast"import "@fristil/designsystem/toast.css"
defineFsToast()Legg beholderen i rotkomponenten, og del referansen med en context:
import { createContext, useContext, useRef } from "react"import type { FsToast } from "@fristil/designsystem"
const Meldinger = createContext<(tekst: string, farge?: "success" | "danger") => void>( () => {},)
export function MeldingerProvider({ children }: { children: React.ReactNode }) { const kø = useRef<FsToast>(null)
const meld = (tekst: string, farge?: "success" | "danger") => { kø.current?.show(tekst, { color: farge, duration: farge === "danger" ? 0 : undefined }) }
return ( <Meldinger.Provider value={meld}> {children} <fs-toast ref={kø} label="Meldinger" /> </Meldinger.Provider> )}
export const useMeldinger = () => useContext(Meldinger)const meld = useMeldinger()
<button {...fs.button()} onClick={() => meld("Søknaden er lagret", "success")}> Lagre søknaden</button>Meldingene lever i DOM-en, ikke i Reacts tilstand. Det er med vilje: de skal ikke forsvinne fordi en komponent ble rendret på nytt.
---// Legg beholderen i sideoppsettet, så finnes den på hver side---
<slot />
<fs-toast id="meldinger" label="Meldinger"></fs-toast>
<script> import { defineFsToast } from "@fristil/designsystem/toast" defineFsToast()
// Gjør køen tilgjengelig for øyene på siden window.meld = (tekst, valg) => document.getElementById("meldinger").show(tekst, valg)</script>Beholderen er tom fra serveren, og fylles bare av kode som kjører i nettleseren. Den koster derfor ingenting på en side som ikke bruker den.
<fs-toast id="meldinger" label="Meldinger"></fs-toast>
<button class="fs-button" type="button" data-on:click="document.getElementById('meldinger').show('Søknaden er lagret', { color: 'success' })"> Lagre søknaden</button>
<script type="module"> import { defineFsToast } from "@fristil/designsystem/toast" defineFsToast()</script>Meldingene er ikke en tilstand som skal speiles i et signal. De er noe som skjer, og derfor kaller data-on:click metoden direkte.
Attributter og metoder
Section titled “Attributter og metoder”| Navn | Hva det er |
|---|---|
duration | Standard levetid i millisekunder. 0 lar meldingene bli stående. |
label | Tekst som sier hva regionen er. Blir aria-label. |
show(tekst, valg) | Viser en melding og returnerer elementet |
dismiss(melding) | Fjerner én melding |
clear() | Fjerner alle |
Valgene til show():
| Valg | Standard | Effekt |
|---|---|---|
color | neutral | success, warning eller danger gir en farget kant |
duration | fra elementet | Millisekunder før meldingen forsvinner |
closeLabel | Lukk melding | Tekst på lukkeknappen |
Meldinger som forsvinner
Section titled “Meldinger som forsvinner”En melding som forsvinner av seg selv er en tilgjengelighetsfelle: den som leser sakte, bruker forstørrelse eller skjermleser rekker ikke å lese den. Komponenten gjør to ting med det:
- Lukkeknappen er alltid der.
- Tiden stopper mens musa er over meldingen, eller mens fokus er inne i den.
Skal beskjeden kunne leses igjen senere, hører den ikke hjemme her. En kvittering skal stå i siden.
Klasser du kan style
Section titled “Klasser du kan style”| Klasse | Hva det er |
|---|---|
.fs-toast | Én melding. Fargen kommer fra data-color. |
.fs-toast__close | Lukkeknappen |
| Variabel | Standard |
|---|---|
--fs-toast-space | var(--size-4) |
--fs-toast-width | min(24rem, calc(100vw - var(--size-8))) |
--fs-toast-padding | var(--size-3) var(--size-4) |
--fs-toast-radius | var(--size-1) |
Beholderen slipper klikk gjennom når den er tom, så den ikke stenger for knapper under seg.
Se Tilpasning for hvordan variablene og laget virker.
Tilgjengelighet
Section titled “Tilgjengelighet”- Én ting om gangen. Fem meldinger oppå hverandre leses opp etter hverandre, og ingen av dem får oppmerksomhet.
- Ikke legg viktige handlinger i en melding som forsvinner. Angre-knappen bør stå i siden.
- Feil som stopper brukeren hører i en Alert eller en Error Summary, ikke i hjørnet.
- Teksten skal si hva som skjedde, ikke bare «Ferdig».