From 21abf7bd84ac1695a61bc28131ffc5772565e991 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Mon, 27 Oct 2025 13:12:39 +0100 Subject: [PATCH 01/12] docs(www-alert): move Alert to www --- .../components/alert/alert.stories.tsx | 56 +++++++++++- .../app/content/components/alert/en/code.mdx | 65 ++++++++++++-- .../content/components/alert/en/overview.mdx | 87 ++++++++++++++++--- .../app/content/components/alert/no/code.mdx | 61 ++++++++++--- .../content/components/alert/no/overview.mdx | 43 ++------- apps/www/app/routes/components/component.tsx | 16 ++++ 6 files changed, 257 insertions(+), 71 deletions(-) diff --git a/apps/www/app/content/components/alert/alert.stories.tsx b/apps/www/app/content/components/alert/alert.stories.tsx index 0c186c1567..976096214e 100644 --- a/apps/www/app/content/components/alert/alert.stories.tsx +++ b/apps/www/app/content/components/alert/alert.stories.tsx @@ -1,4 +1,5 @@ -import { Alert, Heading, Link, Paragraph } from '@digdir/designsystemet-react'; +import { Alert, Button, Heading, Link, Paragraph } from '@digdir/designsystemet-react'; +import { useState } from 'react'; export const Preview = () => { return En beskjed det er viktig at brukeren ser; @@ -118,3 +119,56 @@ export const MedLenke = () => ( ); + +export const CorrectLiveRegionReact = () => { + const [showAlert, setShowAlert] = useState(false); + return ( + <> + + {/* Korrekt bruk: role="alert" ligger på elementet der varselet dukker opp */} +
+ {showAlert && ( + + + Vi klarer ikke lagre skjemaet + + + Vi har mistet forbindelsen med serveren og får ikke lagret + skjemaet. Vent litt og prøv en gang til. + + + )} +
+ + ); +}; + +export const Variants = () => ( + <> + + Dette er en info alert + + + Dette er en success alert + + + Dette er en warning alert + + + Dette er en danger alert + + +) + diff --git a/apps/www/app/content/components/alert/en/code.mdx b/apps/www/app/content/components/alert/en/code.mdx index 3729e0b89c..6acd85ea46 100644 --- a/apps/www/app/content/components/alert/en/code.mdx +++ b/apps/www/app/content/components/alert/en/code.mdx @@ -1,24 +1,75 @@ --- title: Alert -subtitle: Alerts inform users about important information +subtitle: Used to provide the user with information that is particularly important for them to see and understand. The component is designed to capture the user's attention. The text in the alert should be short and clear. image: Alert.svg cssfile: alert --- - -## Usage +## Use ```tsx -import { Button } from '@digdir/designsystemet-react'; +import { Alert } from '@digdir/designsystemet-react'; -; +You are using the Alert component!; ``` -## Code Examples +## Code examples -### Variants +### Change alert +In code, you change the type of alert by changing `data-color`. +The icon is controlled via CSS. +### Alert in live region + +If you want the alert to be read dynamically, you must place `Alert` in a live region. +The region **should be around** the `Alert` component, not on it. + +Out of the box, `Alert` is presented to screen reader users as regular static content. For alerts that occur dynamically, you can define a *live region* for screen readers, but be aware of the behavior this will cause. +You can read more about this in the [MDN documentation on ARIA live regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions). + +Note in particular that the live region — that is, the element with the attribute `role="alert"`, `role="status"`, or `aria-live` with the value `"assertive"` or `"polite"` — must exist on the page **before** the alert that is to be spoken. + +For dynamic notifications, it is most appropriate to use `role="alert"` for critical notifications or `role="status"` for less critical ones, as described in the [pattern for system notifications](https://designsystemet.no/no/patterns/systemnotifications). See also [alert role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/alert_role) and [status role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/status_role) at MDN. + +**Do not** combine `role="alert"` and `aria-live`, as [this causes the alert to be spoken twice in VoiceOver (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#:~:text=adding%20both%20aria%2Dlive%20and%20role=%22alert%22%20causes%20double%20speaking%20issues%20in%20VoiceOver%20on%20iOS). + +You **should** combine `role="status"` and `aria-live="polite"` [to maximize compatibility (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#roles_with_implicit_live_region_attributes). + + + + +For status messages, implemented using markup language, the following applies: + +**The result of an action shall be encoded with one of the following:** + +- role="status" +- aria-live="polite" + +**Waiting state shall be encoded with one of the following:** + +- role="status" +- aria-live="polite" + +**Error shall be encoded with one of the following:** + +- role="alert" +- aria-live="polite" +- aria-live="assertive" + +**The progress of a process shall be encoded with one of the following:** + +- role="progressbar" +- the `` element +- role="log" +- role="status" and aria-atomic="false" +- aria-live="polite" and aria-atomic="false" + +Source: [4.1.3 Status Messages (Level AA) (uutilsynet.no)](https://www.uutilsynet.no/wcag-standarden/413-statusbeskjeder-niva-aa/152) + + +## CSS variables + diff --git a/apps/www/app/content/components/alert/en/overview.mdx b/apps/www/app/content/components/alert/en/overview.mdx index 7613d16c5b..9d763cb910 100644 --- a/apps/www/app/content/components/alert/en/overview.mdx +++ b/apps/www/app/content/components/alert/en/overview.mdx @@ -1,27 +1,90 @@ --- title: Alert -subtitle: Alerts inform users about important information image: Alert.svg cssfile: alert ---- +subtitle: Used to provide the user with information that is particularly important for them to see and understand. The component is designed to capture the user's attention. The text in the alert should be short and clear. -Buttons let users perform actions. +--- -## Usage +## Examples + +`Alert` can be used for four different messages: Information, success, warnings and error messages. + +### Information + +Use `info` when you want to provide the user with neutral and useful information. + + + +### Success + +Use `success` when you want to confirm that the user has completed a task, that the action was successful. + + + +### Warning + +Use `warning` when you want the user to take a specific action or to warn them about something important. + + + +### Error message + +Use `danger` to inform about something that is critical or that prevents the user from moving forward. + + + +### With and without heading + +If the message is longer than a sentence, it can be useful to use a heading to highlight the most important thing. This can be done using the [Heading](/no/components/heading/overview) components. Remember to choose the correct heading level based on the space the alert has in the content structure of the page. + + + +If the title and description repeat the same thing, it is better to use a simple sentence without a heading. + + + +### With link + +You can have a link in the `Alert` if it helps the user solve the task. But be aware that a link takes the user out of the service, so use links only when absolutely necessary, for example if you want the user to open a form or perform an important task. + + + +## Guidelines +`Alert` is used to display important messages that require attention, but not necessarily action. It can be used to inform the user about the status, changes, or problems in a solution. The message is displayed clearly and visually distinguished from the rest of the content. + +Use the component with caution. Users can confuse alerts with advertising, and thus ignore them. If we use alerts too often, we can exacerbate this problem. + +Make sure that `Alert` has the same look and feel across all services and products. This component should be recognizable everywhere, so we should not adjust it. -```tsx -import { Button } from '@digdir/designsystemet-react'; +**Suitable for** +- provide short and informative time-limited notifications +- inform about errors that only affect one part of the system or a minor function +- inform about connection problems or API errors that are likely to be resolved by reloading the page -; -``` +**Not suitable for** +- validate individual form elements, instead use the component's own error message (See [`ValidationMessage`](/no/components/validation-message/overview)) +- summarize multiple error messages in a form, instead use [`ErrorSummary`](/docs/komponenter-errorsummary--docs) +- display errors that prevent all further use of the service, instead use an error page +- display static information that should be displayed all the time, instead use [`Card`](/docs/komponenter-card--docs) -## Code Examples +## Text -### Variants +It is not always easy to understand the difference between the notifications, even though they have different icons and colors. Therefore, it is important that the text we write in the notification is clear and easy to understand. -Use `primary`, `secondary` or `tertiary` to weight the button correctly. +If there is something users need to or can do to get through their task, the text should convey that. When the message is longer than a sentence, it may be a good idea to include a headline that highlights the most important points. - +Here is a list of the types of information that a notification should contain: +- Tell them what happened +- Example: "Couldn't connect to account." +- Tell them why it happened +- Example: "We were unable to connect to your account due to technical issues on our end." +- Reassure the user +- Example: "Your changes have been saved." +- Give them a way out of the problem +- Example: "If this problem occurs again, contact customer service." +- Help them fix the problem themselves +- Example: "Please try again." diff --git a/apps/www/app/content/components/alert/no/code.mdx b/apps/www/app/content/components/alert/no/code.mdx index dd41dd2d51..f5b6bda124 100644 --- a/apps/www/app/content/components/alert/no/code.mdx +++ b/apps/www/app/content/components/alert/no/code.mdx @@ -1,6 +1,6 @@ --- title: Alert -subtitle: Vi bruker `Alert` til å gi brukeren informasjon som det er ekstra viktig at de ser og forstår. Komponenten er designet for å fange brukernes oppmerksomhet. Teksten i varselet skal være kort og tydelig. +subtitle: Brukes til å gi brukeren informasjon som det er ekstra viktig at de ser og forstår. Komponenten er designet for å fange brukernes oppmerksomhet. Teksten i varselet skal være kort og tydelig. image: Alert.svg cssfile: alert --- @@ -16,28 +16,61 @@ import { Alert } from '@digdir/designsystemet-react'; ## Kodeeksempler -### Informasjon +### Endre varsel - +I kode endrer du typen varsel ved å endre `data-color`. +Ikonet er styrt via CSS. -### Suksess + - +### Alert i live region -### Advarsel +Dersom du vil at varselet skal bli lest opp dynamisk, må du legge `Alert` i en live region. +Regionen **skal være rundt** `Alert`-komponenten, ikke på den. - +Ut av boksen blir `Alert` presentert for skjermleserbrukere som vanlig statisk innhold. For varsler som oppstår dynamisk kan du selv definere en *live region* for skjermlesere, men vær opperksom på hvilken oppførsel dette medfører. +Du kan lese mer om dette i [MDN sin dokumentasjon om ARIA live regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions). -### Feilmelding +Legg spesielt merke til at live-regionen — altså elementet med attributt `role="alert"`, `role="status"` eller `aria-live` med verdi `"assertive"` eller `"polite"` — må eksistere på siden **før** varselet som skal leses opp. - +For dynamiske varsler er det mest aktuelt å bruke `role="alert"` for kritiske varsel eller `role="status"` for mindre kritiske vasel, som beskrevet i [mønsteret for systemvarsler](https://designsystemet.no/no/patterns/systemnotifications). Se også [alert role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/alert_role) og [status role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/status_role) hos MDN. -### Med og uten overskrift +**Ikke** kombiner `role="alert"` og `aria-live`, siden [dette fører at varselet leses opp dobbelt i VoiceOver (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#:~:text=adding%20both%20aria%2Dlive%20and%20role=%22alert%22%20causes%20double%20speaking%20issues%20in%20VoiceOver%20on%20iOS). - +Du **bør** kombinere `role="status"` og `aria-live="polite"` [for å maksimere kompatibilitet (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#roles_with_implicit_live_region_attributes). - -### Med lenke + - + +For statusbeskjeder, som implementeres ved hjelp av oppmerkingsspråk, gjelder følgende: + +**Resultatet av en handling skal kodes med én av følgende:** + +- role="status" +- aria-live="polite" + +**Ventetilstand skal kodes med én av følgende:** + +- role="status" +- aria-live="polite" + +**Feil skal kodes med én av følgende:** + +- role="alert" +- aria-live="polite" +- aria-live="assertive" + +**Fremdriften i en prosess skal kodes med én av følgende:** + +- role="progressbar" +- elementet `` +- role="log" +- role="status" og aria-atomic="false" +- aria-live="polite" og aria-atomic="false" + +Kilde: [4.1.3 Statusbeskjeder (Nivå AA) (uutilsynet.no)](https://www.uutilsynet.no/wcag-standarden/413-statusbeskjeder-niva-aa/152) + + +## CSS variablar + diff --git a/apps/www/app/content/components/alert/no/overview.mdx b/apps/www/app/content/components/alert/no/overview.mdx index 6f11a7a00f..41129acfd8 100644 --- a/apps/www/app/content/components/alert/no/overview.mdx +++ b/apps/www/app/content/components/alert/no/overview.mdx @@ -2,20 +2,13 @@ title: Alert image: Alert.svg cssfile: alert ---- +subtitle: Brukes til å gi brukeren informasjon som det er ekstra viktig at de ser og forstår. Komponenten er designet for å fange brukernes oppmerksomhet. Teksten i varselet skal være kort og tydelig. -Vi bruker `Alert` til å gi brukeren informasjon som det er ekstra viktig at de ser og forstår. Komponenten er designet for å fange brukernes oppmerksomhet. Teksten i varselet skal være kort og tydelig. +--- -## Bruk - -```tsx -import { Alert } from '@digdir/designsystemet-react'; - -You are using the Alert component!; -``` -## Kodeeksempler +## Eksempler `Alert` kan brukes til fire ulike budskap: Informasjon, suksess, advarsler og feilmelding. @@ -45,7 +38,7 @@ Bruk `danger` for å informere om noe som er kritisk eller som hindrer brukeren ### Med og uten overskrift -Hvis meldingen er lenger enn en setning kan det være nyttig å bruke en overskrift til å fremheve det viktigste. Dette kan gjøres ved bruk av [Typografi](/docs/komponenter-typography--docs)-komponentene. Husk å velge riktig overskriftsnivå ut fra plassen alert har i innholdsstrukturen på siden. +Hvis meldingen er lenger enn en setning kan det være nyttig å bruke en overskrift til å fremheve det viktigste. Dette kan gjøres ved bruk av [Heading](/no/components/heading/overview)-komponentene. Husk å velge riktig overskriftsnivå ut fra plassen alert har i innholdsstrukturen på siden. @@ -73,7 +66,7 @@ Pass på at `Alert` har samme utseende og formspråk i alle tjenester og produkt - informere om tilkoblingsproblemer eller API-feil som sannsynligvis løser seg ved å laste inn siden på nytt **Passer ikke til å** -- validere individuelle skjemaelementer, bruk heller komponentens egen feilmelding +- validere individuelle skjemaelementer, bruk heller komponentens egen feilmelding (Se [`ValidationMessage`](/no/components/validation-message/overview)) - oppsummere flere feilmeldinger i et skjema, bruk heller [`ErrorSummary`](/docs/komponenter-errorsummary--docs) - vise feil som hindrer all videre bruk av tjenesten, bruk heller en feilside - vise statisk informasjon som skal vises hele tiden, bruk heller [`Card`](/docs/komponenter-card--docs) @@ -85,7 +78,7 @@ Det er ikke alltid lett å forstå forskjellen på varslene, selv om de har ulik Hvis det er noe brukerne må eller kan gjøre for å komme videre med oppgaven sin, skal teksten formidle dette. Når meldingen er lengre enn en setning, kan det være lurt å ha med en overskrift som fremhever det viktigste. -Her er en liste med hvilken type informasjon en varsel bør inneholde: +Her er en liste med hvilken type informasjon varsel bør inneholde: - Fortell hva som har skjedd - Eksempel: "Kunne ikke koble til konto." @@ -97,27 +90,3 @@ Her er en liste med hvilken type informasjon en varsel bør inneholde: - Eksempel: "Hvis dette problemet oppstår igjen, kontakt kundeservice." - Hjelp dem å fikse problemet selv - Eksempel: "Vennligst prøv igjen." - - -## Tilgjengelighet - -### Interaksjon med skjermleser - -Ut av boksen blir `Alert` presentert for skjermleserbrukere som vanlig statisk innhold. For varsler som oppstår dynamisk kan du selv definere en *live region* for skjermlesere, men vær opperksom på hvilken oppførsel dette medfører. -Du kan lese mer om dette i [MDN sin dokumentasjon om ARIA live regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions). - -Legg spesielt merke til at live-regionen — altså elementet med attributt `role="alert"`, `role="status"` eller `aria-live` med verdi `"assertive"` eller `"polite"` — må eksistere på siden **før** varselet som skal leses opp. - -For dynamiske varsler er det mest aktuelt å bruke `role="alert"` for kritiske varsel eller `role="status"` for mindre kritiske vasel, som beskrevet i [mønsteret for systemvarsler](https:// designsystemet.no/no/patterns/systemnotifications). Se også [alert role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/alert_role) og [status role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/status_role) hos MDN. - -**Ikke** kombiner `role="alert"` og `aria-live`, siden [dette fører at varselet leses opp dobbelt i VoiceOver](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#:~:text=adding%20both%20aria%2Dlive%20and%20role=%22alert%22%20causes%20double%20speaking%20issues%20in%20VoiceOver%20on%20iOS). - -Du **bør** kombinere `role="status"` og `aria-live="polite"` [for å maksimere kompatibilitet](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#roles_with_implicit_live_region_attributes). - -#### Ikke gjør dette - -Ikke definer en *live region* direkte på `Alert`. For statiske varsler har det ingen effekt, og for dynamiske varsler vil det ikke bli tolket riktig av alle skjermlesere, selv om mange skjermlesere har spesialhåndtering som går ut over ARIA-spesifikasjonen for akkurat `role="alert"`. - -#### Gjør dette for dynamiske varsler - -Definer en *live region*, f.eks. med `role="alert"`, for varsler som kan dukke opp dynamisk underveis som følge av brukerens handlinger eller andre faktorer. Dette vil også fungere på samme måte med `role="status"`. diff --git a/apps/www/app/routes/components/component.tsx b/apps/www/app/routes/components/component.tsx index 9ebef68c37..339d6e22dc 100644 --- a/apps/www/app/routes/components/component.tsx +++ b/apps/www/app/routes/components/component.tsx @@ -31,6 +31,8 @@ import { generateFromMdx } from '~/_utils/generate-from-mdx'; import { getComponentDocs } from '~/_utils/get-react-props.server'; import type { Route } from './+types/component'; import classes from './component.module.css'; +import { generateMetadata } from '~/_utils/metadata'; +import i18n from '~/i18next.server'; const require = createRequire(import.meta.url); @@ -114,9 +116,23 @@ export const loader = async ({ params, request }: Route.LoaderArgs) => { overviewLink: `/${lang}/components/${component}/overview`, codeLink: `/${lang}/components/${component}/code`, }, + metadata: generateMetadata({ + title: result.frontmatter.title as string, + description: result.frontmatter.description as string, + }), }; }; +export const meta = ({ loaderData }: Route.MetaArgs) => { + if (!loaderData?.metadata) + return [ + { + title: 'Designsystemet', + }, + ]; + return loaderData.metadata; +}; + export default function Components({ loaderData: { stories, mdxCode, frontmatter, toc, navigation }, }: Route.ComponentProps) { From 11b3b1ea6b7962b3d4a7d91923306124bbb6af05 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Mon, 27 Oct 2025 13:16:21 +0100 Subject: [PATCH 02/12] remove i18n import --- apps/www/app/routes/components/component.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/www/app/routes/components/component.tsx b/apps/www/app/routes/components/component.tsx index 339d6e22dc..adc63436f2 100644 --- a/apps/www/app/routes/components/component.tsx +++ b/apps/www/app/routes/components/component.tsx @@ -32,7 +32,6 @@ import { getComponentDocs } from '~/_utils/get-react-props.server'; import type { Route } from './+types/component'; import classes from './component.module.css'; import { generateMetadata } from '~/_utils/metadata'; -import i18n from '~/i18next.server'; const require = createRequire(import.meta.url); From a6b039ac92d4797401b7900eed23502f9a49ebf8 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Mon, 27 Oct 2025 13:18:31 +0100 Subject: [PATCH 03/12] biome --- .../components/alert/alert.stories.tsx | 27 +++++++++---------- apps/www/app/routes/components/component.tsx | 2 +- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/apps/www/app/content/components/alert/alert.stories.tsx b/apps/www/app/content/components/alert/alert.stories.tsx index 976096214e..7a41acf223 100644 --- a/apps/www/app/content/components/alert/alert.stories.tsx +++ b/apps/www/app/content/components/alert/alert.stories.tsx @@ -1,4 +1,10 @@ -import { Alert, Button, Heading, Link, Paragraph } from '@digdir/designsystemet-react'; +import { + Alert, + Button, + Heading, + Link, + Paragraph, +} from '@digdir/designsystemet-react'; import { useState } from 'react'; export const Preview = () => { @@ -157,18 +163,9 @@ export const CorrectLiveRegionReact = () => { export const Variants = () => ( <> - - Dette er en info alert - - - Dette er en success alert - - - Dette er en warning alert - - - Dette er en danger alert - + Dette er en info alert + Dette er en success alert + Dette er en warning alert + Dette er en danger alert -) - +); diff --git a/apps/www/app/routes/components/component.tsx b/apps/www/app/routes/components/component.tsx index adc63436f2..3aa79ed66c 100644 --- a/apps/www/app/routes/components/component.tsx +++ b/apps/www/app/routes/components/component.tsx @@ -29,9 +29,9 @@ import { extractStories } from '~/_utils/extract-stories.server'; import { getFileFromContentDir } from '~/_utils/files.server'; import { generateFromMdx } from '~/_utils/generate-from-mdx'; import { getComponentDocs } from '~/_utils/get-react-props.server'; +import { generateMetadata } from '~/_utils/metadata'; import type { Route } from './+types/component'; import classes from './component.module.css'; -import { generateMetadata } from '~/_utils/metadata'; const require = createRequire(import.meta.url); From 5f47d9fd5b21885d4f9c698a1e1d7a03ba875ae1 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Mon, 27 Oct 2025 15:11:35 +0100 Subject: [PATCH 04/12] show props --- apps/www/app/content/components/alert/en/code.mdx | 5 +++++ apps/www/app/content/components/alert/no/code.mdx | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/apps/www/app/content/components/alert/en/code.mdx b/apps/www/app/content/components/alert/en/code.mdx index 6acd85ea46..bfe6a82d0a 100644 --- a/apps/www/app/content/components/alert/en/code.mdx +++ b/apps/www/app/content/components/alert/en/code.mdx @@ -6,6 +6,8 @@ cssfile: alert --- + + ## Use ```tsx @@ -14,6 +16,9 @@ import { Alert } from '@digdir/designsystemet-react'; You are using the Alert component!; ``` +### Props + + ## Code examples ### Change alert diff --git a/apps/www/app/content/components/alert/no/code.mdx b/apps/www/app/content/components/alert/no/code.mdx index f5b6bda124..97da36f0b5 100644 --- a/apps/www/app/content/components/alert/no/code.mdx +++ b/apps/www/app/content/components/alert/no/code.mdx @@ -6,6 +6,7 @@ cssfile: alert --- + ## Bruk ```tsx @@ -14,6 +15,9 @@ import { Alert } from '@digdir/designsystemet-react'; You are using the Alert component!; ``` +### Props + + ## Kodeeksempler ### Endre varsel From e0673dd1758dfe07431b924146db619b281f5928 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Tue, 4 Nov 2025 14:18:40 +0100 Subject: [PATCH 05/12] update alert to new structure --- .../css-attributes/css-attributes.tsx | 6 +- .../css-variables/css-variables.tsx | 1 + .../app/content/components/alert/no/code.mdx | 24 +++++-- .../content/components/alert/no/overview.mdx | 64 +++++++++++-------- apps/www/app/routes/components/component.tsx | 8 ++- 5 files changed, 64 insertions(+), 39 deletions(-) diff --git a/apps/www/app/_components/css-attributes/css-attributes.tsx b/apps/www/app/_components/css-attributes/css-attributes.tsx index e8cc2fa625..5d8fa63edb 100644 --- a/apps/www/app/_components/css-attributes/css-attributes.tsx +++ b/apps/www/app/_components/css-attributes/css-attributes.tsx @@ -1,4 +1,4 @@ -import { Table } from '@digdir/designsystemet-react'; +import { Paragraph, Table } from '@digdir/designsystemet-react'; import cl from 'clsx'; import { forwardRef } from 'react'; @@ -10,7 +10,8 @@ type CssAttributesProps = { export const CssAttributes = forwardRef( function CssAttributes({ vars, className, ...rest }, ref) { - if (Object.keys(vars).length === 0) return null; + if (Object.keys(vars).length === 0) + return Ingen relevante data-attributter.; return ( ( {...rest} ref={ref} > + Name diff --git a/apps/www/app/_components/css-variables/css-variables.tsx b/apps/www/app/_components/css-variables/css-variables.tsx index 7a169bbec8..45a7447df9 100644 --- a/apps/www/app/_components/css-variables/css-variables.tsx +++ b/apps/www/app/_components/css-variables/css-variables.tsx @@ -22,6 +22,7 @@ export const CssVariables = forwardRef( {...rest} ref={ref} > + Name diff --git a/apps/www/app/content/components/alert/no/code.mdx b/apps/www/app/content/components/alert/no/code.mdx index 97da36f0b5..c8dd6376d1 100644 --- a/apps/www/app/content/components/alert/no/code.mdx +++ b/apps/www/app/content/components/alert/no/code.mdx @@ -5,9 +5,10 @@ image: Alert.svg cssfile: alert --- +## Bruk -## Bruk + ```tsx import { Alert } from '@digdir/designsystemet-react'; @@ -15,10 +16,7 @@ import { Alert } from '@digdir/designsystemet-react'; You are using the Alert component!; ``` -### Props - - -## Kodeeksempler +## Eksempel ### Endre varsel @@ -43,7 +41,6 @@ For dynamiske varsler er det mest aktuelt å bruke `role="alert"` for kritiske v Du **bør** kombinere `role="status"` og `aria-live="polite"` [for å maksimere kompatibilitet (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#roles_with_implicit_live_region_attributes). - @@ -76,5 +73,18 @@ For statusbeskjeder, som implementeres ved hjelp av oppmerkingsspråk, gjelder f Kilde: [4.1.3 Statusbeskjeder (Nivå AA) (uutilsynet.no)](https://www.uutilsynet.no/wcag-standarden/413-statusbeskjeder-niva-aa/152) -## CSS variablar +## HTML + +For HTML bruker du klassenavnet `ds-alert` og attributtet `data-color` for å endre type varsel. +Les over for når du skal bruke `role` og `aria-live`. + +```html +
+ Dette er en info alert. +
+``` + +## CSS variabler og data-attributter + + diff --git a/apps/www/app/content/components/alert/no/overview.mdx b/apps/www/app/content/components/alert/no/overview.mdx index 41129acfd8..bc51451f84 100644 --- a/apps/www/app/content/components/alert/no/overview.mdx +++ b/apps/www/app/content/components/alert/no/overview.mdx @@ -3,14 +3,25 @@ title: Alert image: Alert.svg cssfile: alert subtitle: Brukes til å gi brukeren informasjon som det er ekstra viktig at de ser og forstår. Komponenten er designet for å fange brukernes oppmerksomhet. Teksten i varselet skal være kort og tydelig. - --- +**Bruk `Alert` når** +- du skal gi korte og informative tidsbegrensede varsler +- du skal informere om feil som kun påvirker én del av systemet eller en mindre funksjon +- du skal informere om tilkoblingsproblemer eller API-feil som sannsynligvis løser seg ved å laste inn siden på nytt + +**Unngå `Alert` når** +- du skal validere individuelle skjemaelementer, bruk heller komponentens egen feilmelding (Se [`ValidationMessage`](/no/components/validation-message/overview)) +- du skal oppsummere flere feilmeldinger i et skjema, bruk heller [`ErrorSummary`](/docs/komponenter-errorsummary--docs) +- du skal vise feil som hindrer all videre bruk av tjenesten, bruk heller en feilside +- du skal vise statisk informasjon som skal vises hele tiden, bruk heller [`Card`](/docs/komponenter-card--docs) + + -## Eksempler +## Eksempel -`Alert` kan brukes til fire ulike budskap: Informasjon, suksess, advarsler og feilmelding. +`Alert` kan brukes til fire ulike budskap: Informasjon, suksess, advarsel og feilmelding. ### Informasjon @@ -38,7 +49,9 @@ Bruk `danger` for å informere om noe som er kritisk eller som hindrer brukeren ### Med og uten overskrift -Hvis meldingen er lenger enn en setning kan det være nyttig å bruke en overskrift til å fremheve det viktigste. Dette kan gjøres ved bruk av [Heading](/no/components/heading/overview)-komponentene. Husk å velge riktig overskriftsnivå ut fra plassen alert har i innholdsstrukturen på siden. +Hvis meldingen er lenger enn en setning kan det være nyttig å bruke en overskrift til å fremheve det viktigste. +Dette kan gjøres ved bruk av [Heading](/no/components/heading/overview)-komponentene. +Husk å velge riktig overskriftsnivå ut fra plassen alert har i innholdsstrukturen på siden. @@ -48,45 +61,40 @@ Dersom tittel og beskrivelse gjentar det samme er det bedre å bruke en enkel se ### Med lenke -Du kan ha en lenke i `Alert` hvis det hjelper brukeren med å løse oppgaven. Men vær obs på at en lenke tar brukeren ut av tjenesten, så bruk lenke kun når det er absolutt nødvendig, for eksempel hvis du vil at brukeren skal åpne et skjema eller utføre en viktig oppgave. +Du kan ha en lenke i `Alert` hvis det hjelper brukeren med å løse oppgaven. +Men vær obs på at en lenke tar brukeren ut av tjenesten, så bruk lenke kun når det er absolutt nødvendig, for eksempel hvis du vil at brukeren skal åpne et skjema eller utføre en viktig oppgave. ## Retningslinjer -`Alert` brukes for å vise viktige meldinger som krever oppmerksomhet, men ikke nødvendigvis handling. Den kan brukes til å informere brukeren om status, endringer eller problemer i en løsning. Meldingen vises tydelig og skiller seg visuelt fra resten av innholdet. -Bruk komponenten varsomt. Brukere kan forveksle varsler med reklame, og dermed overse dem. Hvis vi bruker varsler for ofte, kan vi forverre dette problemet. +`Alert` brukes for å vise viktige meldinger som krever oppmerksomhet, men ikke nødvendigvis handling. +Den kan brukes til å informere brukeren om status, endringer eller problemer i en løsning. +Meldingen vises tydelig og skiller seg visuelt fra resten av innholdet. -Pass på at `Alert` har samme utseende og formspråk i alle tjenester og produkter. Denne komponenten skal være mulig å kjenne igjen over alt, så vi skal ikke justere den. - - -**Passer til å** -- gi korte og informative tidsbegrensede varsler -- informere om feil som kun påvirker én del av systemet eller en mindre funksjon -- informere om tilkoblingsproblemer eller API-feil som sannsynligvis løser seg ved å laste inn siden på nytt - -**Passer ikke til å** -- validere individuelle skjemaelementer, bruk heller komponentens egen feilmelding (Se [`ValidationMessage`](/no/components/validation-message/overview)) -- oppsummere flere feilmeldinger i et skjema, bruk heller [`ErrorSummary`](/docs/komponenter-errorsummary--docs) -- vise feil som hindrer all videre bruk av tjenesten, bruk heller en feilside -- vise statisk informasjon som skal vises hele tiden, bruk heller [`Card`](/docs/komponenter-card--docs) +Bruk komponenten varsomt. +Brukere kan forveksle varsler med reklame, og dermed overse dem. +Hvis vi bruker varsler for ofte, kan vi forverre dette problemet. +Pass på at `Alert` har samme utseende og formspråk i alle tjenester og produkter. +Denne komponenten skal være mulig å kjenne igjen over alt, så vi skal unngå å justere den. ## Tekst -Det er ikke alltid lett å forstå forskjellen på varslene, selv om de har ulike ikoner og farger. Derfor er det viktig at teksten vi skriver i varselet er tydelig og lett å forstå. +Det er ikke alltid lett å forstå forskjellen på varslene, selv om de har ulike ikoner og farger. +Derfor er det viktig at teksten vi skriver i varselet er tydelig og lett å forstå. -Hvis det er noe brukerne må eller kan gjøre for å komme videre med oppgaven sin, skal teksten formidle dette. Når meldingen er lengre enn en setning, kan det være lurt å ha med en overskrift som fremhever det viktigste. +Hvis det er noe brukerne må eller kan gjøre for å komme videre med oppgaven sin, skal teksten formidle dette. +Når meldingen er lengre enn en setning, kan det være lurt å ha med en overskrift som fremhever det viktigste. Her er en liste med hvilken type informasjon varsel bør inneholde: - - Fortell hva som har skjedd - - Eksempel: "Kunne ikke koble til konto." + - **Eksempel:** "Kunne ikke koble til konto." - Fortell hvorfor det skjedde - - Eksempel: "Vi kunne ikke koble til kontoen din på grunn av tekniske problemer fra vår side." + - **Eksempel:** "Vi kunne ikke koble til kontoen din på grunn av tekniske problemer fra vår side." - Forsikre brukeren - - Eksempel: "Endringene dine har blitt lagret." + - **Eksempel:** "Endringene dine har blitt lagret." - Gi dem en vei ut av problemet - - Eksempel: "Hvis dette problemet oppstår igjen, kontakt kundeservice." + - **Eksempel:** "Hvis dette problemet oppstår igjen, kontakt kundeservice." - Hjelp dem å fikse problemet selv - - Eksempel: "Vennligst prøv igjen." + - **Eksempel:** "Vennligst prøv igjen." diff --git a/apps/www/app/routes/components/component.tsx b/apps/www/app/routes/components/component.tsx index 34455d2dcc..ee860b661a 100644 --- a/apps/www/app/routes/components/component.tsx +++ b/apps/www/app/routes/components/component.tsx @@ -270,9 +270,13 @@ const CssVars = () => { const Attributes = () => { const data = useRouteLoaderData('components-page'); - if (!data) return null; + if (!data) return Ingen relevante data-attributter.; const { cssAttrs } = data; - return cssAttrs ? : null; + return cssAttrs ? ( + + ) : ( + Ingen relevante data-attributter. + ); }; From 5d95e19391cb6aa3a8379a41e7349670ee1b5c33 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Tue, 4 Nov 2025 14:34:19 +0100 Subject: [PATCH 06/12] do details as well --- .../content/components/details/no/code.mdx | 84 +++++++++++++++++-- .../components/details/no/overview.mdx | 48 ++++++----- 2 files changed, 104 insertions(+), 28 deletions(-) diff --git a/apps/www/app/content/components/details/no/code.mdx b/apps/www/app/content/components/details/no/code.mdx index 866fe4451c..2ed269e9e0 100644 --- a/apps/www/app/content/components/details/no/code.mdx +++ b/apps/www/app/content/components/details/no/code.mdx @@ -4,20 +4,92 @@ image: Details.svg cssfile: details --- -## Eksempler - -### Standard +## Bruk -### I Card + + +```tsx +/* Utan ramme */ +import { Details } from '@digdir/designsystemet-react'; + +
+ Details heading text + Details content +
+ +/* Med ramme */ + +import { Details, Card } from '@digdir/designsystemet-react'; + + +
+ Details heading text + Details content +
+
+``` + +## Eksempler - +### Ramme -### Med farger +Dersom du legg `Details` som einaste barn av `Card` får du ramme rundt heile `Details`. ### Kontrollert +`Details` held sjølv styr på om den er open eller lukka, men dette kan òg kontrollerast utanfrå. + + +## HTML + +`Details` er bygd på web-komponenten [u-details (github.io)](https://u-elements.github.io/u-elements/elements/u-details), som du kan bruke. +Den er ein bygd funksjonelt lik som `
`, men med betre tilgjengelegheit. + +Du bruker klassenavnet `.ds-details` på hovudelementet. +Du kan velge å ikkje ha ein nøsta `
` rundt hovudinnhaldet, men har du denne får den `margin`. + +```html + + + + Details heading text + +
+ Details content +
+
+ + +
+
+ + Details heading text + +
+ Details content +
+
+
+ + +
+ + + Details heading text + +
+ Details content +
+
+
+``` + +## CSS variabler og data-attributter + + + diff --git a/apps/www/app/content/components/details/no/overview.mdx b/apps/www/app/content/components/details/no/overview.mdx index b1f8d6f58a..310fbaefab 100644 --- a/apps/www/app/content/components/details/no/overview.mdx +++ b/apps/www/app/content/components/details/no/overview.mdx @@ -5,39 +5,43 @@ image: Details.svg cssfile: details --- - - -## Bruk +**Bruk `Details` når** -`Details` består av to delkomponenter: +- du vil samla innhald +- du skal gjera det frivillig å sjå innhald som er mindre viktig +- du skal visa tilleggsinformasjon som kan vera til hjelp for brukarane -- `Details.Summary` - Overskriften som kan klikkes for å vise/skjule innholdet -- `Details.Content` - Innholdet som vises/skjules - -## Retningslinjer +**Unngå `Details` når** -- Bruk Details når du har innhold som ikke alle brukere trenger å se med en gang -- Hold overskriften kort og beskrivende -- Unngå å skjule viktig informasjon som brukeren alltid trenger +- du skal visa viktig innhald som alle bør sjå når dei kjem til sida +- du skal oppsummera feilmeldingar - bruk heller [`ErrorSummary`](/docs/komponenter-errorsummary--docs) -## Tilgjengelighet - -Details-komponenten bruker de native HTML-elementene `
` og ``, som har innebygd tilgjengelighetsstøtte. + -## I Card +## Eksempel -Details kan brukes inne i Card-komponenten for en fin gruppering: +Du kan bruke `Details` i eit kort for å få ramme rundt innhaldet. +Dette passar i tilfeller der `Details` ikkje fyller heile sida, eller når det berre er ei rad. -## Fargevarianter +## Retningslinjer -Details fungerer godt sammen med Card sine fargevarianter: +Ikkje bruk `Details` til å skjula innhald for å gjera sida "ryddigare". +Når vi skjuler innhold er det fare for at brukerne ikke se innholdet i det hele tatt. +Finn ut om du faktisk må skjula innhald og ver klar over kvifor du gjer det. - +### Unngå nøsta lister -## Kontrollert tilstand +Ikkje legg ein `Details` inni ein annan, det vi kallar nøsta lister. +Det kan bli forvirrande for brukaren å forstå kva som er opna og lukka, spesielt når fleire nivå kan opnast samtidig. -Du kan kontrollere om Details er åpen eller lukket: +## Tekst +Sørg for at overskrifta gjev ei god skildring av kva innhaldet i `Details` er. +Overskriftene kan ha stor tyding for om brukarane finn det dei treng, om innhaldet blir lese og om det kan reknast som tilgjengeleg for alle brukarar. +«Vis meir» eller «Les meir her» er ikkje gode nok titlar. +Har du ein `Details` med mange nedtrekk, kan du ha ei hovudoverskrift eller temaoverskrift over heile lista. - +Hold innholdet i `Details` kort for å sikre at det lett kan relateres til overskriften. +Om innhaldet er for langt bør du fordela innhaldet i fleire `Details`. +Ved veldig mykje innhald kan det vere betre å vurdere å lage eigne sider. From a25d81d983284ad858784629149c569863c97a9d Mon Sep 17 00:00:00 2001 From: Barsnes Date: Tue, 4 Nov 2025 14:40:34 +0100 Subject: [PATCH 07/12] update details --- .../components/details/details.stories.tsx | 32 +++---------------- .../content/components/details/no/code.mdx | 31 ++++++++++-------- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/apps/www/app/content/components/details/details.stories.tsx b/apps/www/app/content/components/details/details.stories.tsx index 25f93f3210..588bd01d5a 100644 --- a/apps/www/app/content/components/details/details.stories.tsx +++ b/apps/www/app/content/components/details/details.stories.tsx @@ -38,7 +38,7 @@ export const InCard = () => { export const InCardWithColor = () => { return ( <> - +
Hvordan får jeg tildelt et jegernummer? @@ -61,7 +61,7 @@ export const InCardWithColor = () => {

- +
Hvordan får jeg tildelt et jegernummer? @@ -71,17 +71,6 @@ export const InCardWithColor = () => { Jegerregisteret når du har bestått jegerprøven.
-
- - Jeg har glemt jegernummeret mitt. Hvor finner jeg dette? - - - - Du kan finne dette ved å logge inn på{' '} - Min side - - -
); @@ -90,12 +79,10 @@ export const InCardWithColor = () => { export const Controlled = () => { const [open1, setOpen1] = useState(false); const [open2, setOpen2] = useState(false); - const [open3, setOpen3] = useState(false); - const isOpen = [open1, open2, open3].every(Boolean); + const isOpen = [open1, open2].every(Boolean); const toggleOpen = () => { setOpen1(!isOpen); setOpen2(!isOpen); - setOpen3(!isOpen); }; return ( @@ -104,12 +91,12 @@ export const Controlled = () => { {isOpen ? ( <> - Lukk alle + Close both ) : ( <> - Åpne alle + Open both )} @@ -134,15 +121,6 @@ export const Controlled = () => { organisasjonsform.
-
setOpen3(!open3)}> - Ansvarlig selskap (ANS/DA) - - Er dere minst to personer som skal starte opp egen virksomhet? - Samarbeider du godt med den/de som du skal starte opp sammen med? - Krever virksomheten få investeringer og tar du liten økonomisk risiko? - Da kan du vurdere å etablere et ansvarlig selskap. - -
); }; diff --git a/apps/www/app/content/components/details/no/code.mdx b/apps/www/app/content/components/details/no/code.mdx index 2ed269e9e0..2be0e265cf 100644 --- a/apps/www/app/content/components/details/no/code.mdx +++ b/apps/www/app/content/components/details/no/code.mdx @@ -33,9 +33,10 @@ import { Details, Card } from '@digdir/designsystemet-react'; ## Eksempler -### Ramme +### Ramme og variant Dersom du legg `Details` som einaste barn av `Card` får du ramme rundt heile `Details`. +Du kan også bruke `variant="tinted"` på enten `Details` eller `Card` for å få ein lysare bakgrunn. @@ -48,11 +49,13 @@ Dersom du legg `Details` som einaste barn av `Card` får du ramme rundt heile `D ## HTML `Details` er bygd på web-komponenten [u-details (github.io)](https://u-elements.github.io/u-elements/elements/u-details), som du kan bruke. -Den er ein bygd funksjonelt lik som `
`, men med betre tilgjengelegheit. +Den er bygd funksjonelt lik som native-elementet `
`, men med betre tilgjengelegheit. Du bruker klassenavnet `.ds-details` på hovudelementet. Du kan velge å ikkje ha ein nøsta `
` rundt hovudinnhaldet, men har du denne får den `margin`. +Dersom du vil bruke tinta variant, legg til attributtet `data-variant="tinted"` på hovudelementet eller `.ds-card`. + ```html @@ -64,18 +67,6 @@ Du kan velge å ikkje ha ein nøsta `
` rundt hovudinnhaldet, men har du den
- -
-
- - Details heading text - -
- Details content -
-
-
-
@@ -87,6 +78,18 @@ Du kan velge å ikkje ha ein nøsta `
` rundt hovudinnhaldet, men har du den
+ + +
+
+ + Details heading text + +
+ Details content +
+
+
``` ## CSS variabler og data-attributter From d76f38388b6000fbce8186657f42c2c1894a3eb0 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Thu, 6 Nov 2025 09:10:36 +0100 Subject: [PATCH 08/12] add content to a11y tab --- .../components/alert/no/accessibility.mdx | 48 ++++++++++++++++++ .../app/content/components/alert/no/code.mdx | 50 +------------------ .../content/components/alert/no/overview.mdx | 11 ++-- 3 files changed, 55 insertions(+), 54 deletions(-) diff --git a/apps/www/app/content/components/alert/no/accessibility.mdx b/apps/www/app/content/components/alert/no/accessibility.mdx index 4078f5f3b1..fb75c7a5ba 100644 --- a/apps/www/app/content/components/alert/no/accessibility.mdx +++ b/apps/www/app/content/components/alert/no/accessibility.mdx @@ -6,3 +6,51 @@ cssfile: alert --- ## Tilgjengelighet + +### Alert i live region + +Dersom du vil at varselet skal bli lest opp dynamisk, må du legge `Alert` i en live region. +Regionen **skal være rundt** `Alert`-komponenten, ikke på den. + +Ut av boksen blir `Alert` presentert for skjermleserbrukere som vanlig statisk innhold. For varsler som oppstår dynamisk kan du selv definere en *live region* for skjermlesere, men vær opperksom på hvilken oppførsel dette medfører. +Du kan lese mer om dette i [MDN sin dokumentasjon om ARIA live regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions). + +Legg spesielt merke til at live-regionen — altså elementet med attributt `role="alert"`, `role="status"` eller `aria-live` med verdi `"assertive"` eller `"polite"` — må eksistere på siden **før** varselet som skal leses opp. + +For dynamiske varsler er det mest aktuelt å bruke `role="alert"` for kritiske varsel eller `role="status"` for mindre kritiske vasel, som beskrevet i [mønsteret for systemvarsler](https://designsystemet.no/no/patterns/systemnotifications). Se også [alert role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/alert_role) og [status role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/status_role) hos MDN. + +**Ikke** kombiner `role="alert"` og `aria-live`, siden [dette fører at varselet leses opp dobbelt i VoiceOver (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#:~:text=adding%20both%20aria%2Dlive%20and%20role=%22alert%22%20causes%20double%20speaking%20issues%20in%20VoiceOver%20on%20iOS). + +Du **bør** kombinere `role="status"` og `aria-live="polite"` [for å maksimere kompatibilitet (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#roles_with_implicit_live_region_attributes). + + + + +For statusbeskjeder, som implementeres ved hjelp av oppmerkingsspråk, gjelder følgende: + +**Resultatet av en handling skal kodes med én av følgende:** + +- role="status" +- aria-live="polite" + +**Ventetilstand skal kodes med én av følgende:** + +- role="status" +- aria-live="polite" + +**Feil skal kodes med én av følgende:** + +- role="alert" +- aria-live="polite" +- aria-live="assertive" + +**Fremdriften i en prosess skal kodes med én av følgende:** + +- role="progressbar" +- elementet `` +- role="log" +- role="status" og aria-atomic="false" +- aria-live="polite" og aria-atomic="false" + +Kilde: [4.1.3 Statusbeskjeder (Nivå AA) (uutilsynet.no)](https://www.uutilsynet.no/wcag-standarden/413-statusbeskjeder-niva-aa/152) + diff --git a/apps/www/app/content/components/alert/no/code.mdx b/apps/www/app/content/components/alert/no/code.mdx index c8dd6376d1..6b41cdb222 100644 --- a/apps/www/app/content/components/alert/no/code.mdx +++ b/apps/www/app/content/components/alert/no/code.mdx @@ -25,59 +25,13 @@ Ikonet er styrt via CSS. -### Alert i live region - -Dersom du vil at varselet skal bli lest opp dynamisk, må du legge `Alert` i en live region. -Regionen **skal være rundt** `Alert`-komponenten, ikke på den. - -Ut av boksen blir `Alert` presentert for skjermleserbrukere som vanlig statisk innhold. For varsler som oppstår dynamisk kan du selv definere en *live region* for skjermlesere, men vær opperksom på hvilken oppførsel dette medfører. -Du kan lese mer om dette i [MDN sin dokumentasjon om ARIA live regions](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions). - -Legg spesielt merke til at live-regionen — altså elementet med attributt `role="alert"`, `role="status"` eller `aria-live` med verdi `"assertive"` eller `"polite"` — må eksistere på siden **før** varselet som skal leses opp. - -For dynamiske varsler er det mest aktuelt å bruke `role="alert"` for kritiske varsel eller `role="status"` for mindre kritiske vasel, som beskrevet i [mønsteret for systemvarsler](https://designsystemet.no/no/patterns/systemnotifications). Se også [alert role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/alert_role) og [status role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/status_role) hos MDN. - -**Ikke** kombiner `role="alert"` og `aria-live`, siden [dette fører at varselet leses opp dobbelt i VoiceOver (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#:~:text=adding%20both%20aria%2Dlive%20and%20role=%22alert%22%20causes%20double%20speaking%20issues%20in%20VoiceOver%20on%20iOS). - -Du **bør** kombinere `role="status"` og `aria-live="polite"` [for å maksimere kompatibilitet (mozilla.org)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Guides/Live_regions#roles_with_implicit_live_region_attributes). - - - - -For statusbeskjeder, som implementeres ved hjelp av oppmerkingsspråk, gjelder følgende: - -**Resultatet av en handling skal kodes med én av følgende:** - -- role="status" -- aria-live="polite" - -**Ventetilstand skal kodes med én av følgende:** - -- role="status" -- aria-live="polite" - -**Feil skal kodes med én av følgende:** - -- role="alert" -- aria-live="polite" -- aria-live="assertive" - -**Fremdriften i en prosess skal kodes med én av følgende:** - -- role="progressbar" -- elementet `` -- role="log" -- role="status" og aria-atomic="false" -- aria-live="polite" og aria-atomic="false" - -Kilde: [4.1.3 Statusbeskjeder (Nivå AA) (uutilsynet.no)](https://www.uutilsynet.no/wcag-standarden/413-statusbeskjeder-niva-aa/152) - - ## HTML For HTML bruker du klassenavnet `ds-alert` og attributtet `data-color` for å endre type varsel. Les over for når du skal bruke `role` og `aria-live`. +[Les om `role` og `aria-live` på tilgjengeligheitssiden for `Alert`-komponenten.](/no/components/alert/accessibility#alert-i-live-region) + ```html
Dette er en info alert. diff --git a/apps/www/app/content/components/alert/no/overview.mdx b/apps/www/app/content/components/alert/no/overview.mdx index bc51451f84..7331ee9cb9 100644 --- a/apps/www/app/content/components/alert/no/overview.mdx +++ b/apps/www/app/content/components/alert/no/overview.mdx @@ -5,10 +5,12 @@ cssfile: alert subtitle: Brukes til å gi brukeren informasjon som det er ekstra viktig at de ser og forstår. Komponenten er designet for å fange brukernes oppmerksomhet. Teksten i varselet skal være kort og tydelig. --- + + **Bruk `Alert` når** -- du skal gi korte og informative tidsbegrensede varsler -- du skal informere om feil som kun påvirker én del av systemet eller en mindre funksjon -- du skal informere om tilkoblingsproblemer eller API-feil som sannsynligvis løser seg ved å laste inn siden på nytt +- det er korte og informative tidsbegrensede varsler +- det er informasjon om feil som kun påvirker én del av systemet eller en mindre funksjon +- informasjonen er om tilkoblingsproblemer eller API-feil som sannsynligvis løser seg ved å laste inn siden på nytt **Unngå `Alert` når** - du skal validere individuelle skjemaelementer, bruk heller komponentens egen feilmelding (Se [`ValidationMessage`](/no/components/validation-message/overview)) @@ -16,9 +18,6 @@ subtitle: Brukes til å gi brukeren informasjon som det er ekstra viktig at de s - du skal vise feil som hindrer all videre bruk av tjenesten, bruk heller en feilside - du skal vise statisk informasjon som skal vises hele tiden, bruk heller [`Card`](/docs/komponenter-card--docs) - - - ## Eksempel `Alert` kan brukes til fire ulike budskap: Informasjon, suksess, advarsel og feilmelding. From 9dd3c7a34c9a5ee336ef1bc5166564e5705266ac Mon Sep 17 00:00:00 2001 From: Barsnes Date: Thu, 6 Nov 2025 09:23:18 +0100 Subject: [PATCH 09/12] proper html on details --- .../content/components/details/no/code.mdx | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/www/app/content/components/details/no/code.mdx b/apps/www/app/content/components/details/no/code.mdx index 2be0e265cf..0b2bd85ac1 100644 --- a/apps/www/app/content/components/details/no/code.mdx +++ b/apps/www/app/content/components/details/no/code.mdx @@ -59,7 +59,7 @@ Dersom du vil bruke tinta variant, legg til attributtet `data-variant="tinted"` ```html - + Details heading text
@@ -70,7 +70,7 @@ Dersom du vil bruke tinta variant, legg til attributtet `data-variant="tinted"`
- + Details heading text
@@ -80,16 +80,14 @@ Dersom du vil bruke tinta variant, legg til attributtet `data-variant="tinted"`
-
-
- - Details heading text - -
- Details content -
-
-
+
+ + Details heading text + +
+ Details content +
+
``` ## CSS variabler og data-attributter From 770ecd85ef356577c55f0098ee331717e8510beb Mon Sep 17 00:00:00 2001 From: Barsnes Date: Mon, 10 Nov 2025 11:50:32 +0100 Subject: [PATCH 10/12] generate proper metadata --- apps/www/app/routes/components/component.tsx | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/apps/www/app/routes/components/component.tsx b/apps/www/app/routes/components/component.tsx index 19104bf9c3..7ed8d6c11b 100644 --- a/apps/www/app/routes/components/component.tsx +++ b/apps/www/app/routes/components/component.tsx @@ -1,7 +1,12 @@ import { readFileSync } from 'node:fs'; import { createRequire } from 'node:module'; import { join } from 'node:path'; -import { Alert, Button, Heading } from '@digdir/designsystemet-react'; +import { + Alert, + Button, + Heading, + Paragraph, +} from '@digdir/designsystemet-react'; import cl from 'clsx/lite'; import type { ComponentType, ReactNode } from 'react'; import type { ComponentDoc } from 'react-docgen-typescript'; @@ -128,6 +133,10 @@ export const loader = async ({ params, request }: Route.LoaderArgs) => { image: jsonMetadata.image, subtitle: subtitleFromMetadata.code, }, + linkMetadata: generateMetadata({ + title: jsonMetadata[lang].title, + description: jsonMetadata[lang].subtitle, + }), cssSource, cssVars, cssAttrs, @@ -138,22 +147,18 @@ export const loader = async ({ params, request }: Route.LoaderArgs) => { codeLink: `/${lang}/components/${component}/code`, accessibilityLink: `/${lang}/components/${component}/accessibility`, }, - metadata: generateMetadata({ - title: result.frontmatter.title as string, - description: result.frontmatter.description as string, - }), githubLink: `https://github.com/digdir/designsystemet/tree/main/apps/www/app/content/components/${component}/${lang}/${compPage}.mdx`, }; }; export const meta = ({ loaderData }: Route.MetaArgs) => { - if (!loaderData?.metadata) + if (!loaderData?.linkMetadata) return [ { title: 'Designsystemet', }, ]; - return loaderData.metadata; + return loaderData.linkMetadata; }; export default function Components({ From 5e061f096ceb5f54f6313f9ec42f9405c0b7c889 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Mon, 10 Nov 2025 11:59:23 +0100 Subject: [PATCH 11/12] translations --- .../app/_components/css-variables/css-variables.tsx | 13 ++++++++++--- apps/www/app/locales/en.ts | 6 ++++++ apps/www/app/locales/no.ts | 6 ++++++ apps/www/app/routes/components/component.tsx | 11 +++++++---- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/apps/www/app/_components/css-variables/css-variables.tsx b/apps/www/app/_components/css-variables/css-variables.tsx index 45a7447df9..dc5f33565c 100644 --- a/apps/www/app/_components/css-variables/css-variables.tsx +++ b/apps/www/app/_components/css-variables/css-variables.tsx @@ -1,6 +1,7 @@ import { Table } from '@digdir/designsystemet-react'; import cl from 'clsx'; import { forwardRef } from 'react'; +import { useTranslation } from 'react-i18next'; type CssVariablesProps = { vars: { @@ -10,6 +11,8 @@ type CssVariablesProps = { export const CssVariables = forwardRef( function CssVariables({ vars, className, ...rest }, ref) { + const { t } = useTranslation(); + return (
Data-attributter CSS-variabler
( {...rest} ref={ref} > - + - Name - Value + + {t('components.css-variables.name')} + + + {t('components.css-variables.value')} + diff --git a/apps/www/app/locales/en.ts b/apps/www/app/locales/en.ts index b7ad370487..900f3a3114 100644 --- a/apps/www/app/locales/en.ts +++ b/apps/www/app/locales/en.ts @@ -132,6 +132,12 @@ export default { changelog: { title: 'Changelog', }, + 'css-variables': { + caption: 'CSS Variables', + name: 'Name', + value: 'Value', + }, + 'no-relevant-data-attributes': 'No relevant data attributes found.', }, component: { overview: 'Overview', diff --git a/apps/www/app/locales/no.ts b/apps/www/app/locales/no.ts index ba06987078..d4e4016beb 100644 --- a/apps/www/app/locales/no.ts +++ b/apps/www/app/locales/no.ts @@ -131,6 +131,12 @@ export default { changelog: { title: 'Endringslogg', }, + 'css-variables': { + caption: 'CSS-variabler', + name: 'Navn', + value: 'Verdi', + }, + 'no-relevant-data-attributes': 'Ingen relevante data-attributter funnet.', }, component: { overview: 'Oversikt', diff --git a/apps/www/app/routes/components/component.tsx b/apps/www/app/routes/components/component.tsx index 7ed8d6c11b..5a1a4633c9 100644 --- a/apps/www/app/routes/components/component.tsx +++ b/apps/www/app/routes/components/component.tsx @@ -238,7 +238,7 @@ const Story = ({ story, layout }: LiveComponentProps) => { const { stories } = data; const foundStory = stories.find((s) => s.name === story); - if (!foundStory) return Story not found: {story}; + if (!foundStory) return Story not found: {story}; return ( )`} @@ -263,7 +263,7 @@ const DoDontComponent = ({ const { dodont } = data; const foundStory = dodont.find((s) => s.name === story); - if (!foundStory) return Do/Dont not found: {story}; + if (!foundStory) return Do/Dont not found: {story}; const variant = story.toLowerCase().includes('dont') ? 'dont' : 'do'; return ( { }; const Attributes = () => { + const { t } = useTranslation(); + const data = useRouteLoaderData('components-page'); - if (!data) return Ingen relevante data-attributter.; + if (!data) + return {t('components.no-relevant-data-attributes')}; const { cssAttrs } = data; return cssAttrs ? ( ) : ( - Ingen relevante data-attributter. + {t('components.no-relevant-data-attributes')} ); }; From 3c0bd13d09d1189a065fd95645159924b25f9118 Mon Sep 17 00:00:00 2001 From: Barsnes Date: Mon, 10 Nov 2025 12:01:18 +0100 Subject: [PATCH 12/12] attrs table --- .../css-attributes/css-attributes.tsx | 17 +++++++++++++---- apps/www/app/locales/en.ts | 1 + apps/www/app/locales/no.ts | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/www/app/_components/css-attributes/css-attributes.tsx b/apps/www/app/_components/css-attributes/css-attributes.tsx index 5d8fa63edb..47a074c94a 100644 --- a/apps/www/app/_components/css-attributes/css-attributes.tsx +++ b/apps/www/app/_components/css-attributes/css-attributes.tsx @@ -1,6 +1,7 @@ import { Paragraph, Table } from '@digdir/designsystemet-react'; import cl from 'clsx'; import { forwardRef } from 'react'; +import { useTranslation } from 'react-i18next'; type CssAttributesProps = { vars: { @@ -10,8 +11,12 @@ type CssAttributesProps = { export const CssAttributes = forwardRef( function CssAttributes({ vars, className, ...rest }, ref) { + const { t } = useTranslation(); + if (Object.keys(vars).length === 0) - return Ingen relevante data-attributter.; + return ( + {t('components.no-relevant-data-attributes')} + ); return (
CSS-variabler{t('components.css-variables.caption')}
( {...rest} ref={ref} > - + - Name - Value(s) + + {t('components.css-variables.name')} + + + {t('components.css-variables.value')} + diff --git a/apps/www/app/locales/en.ts b/apps/www/app/locales/en.ts index 900f3a3114..a6e5870db8 100644 --- a/apps/www/app/locales/en.ts +++ b/apps/www/app/locales/en.ts @@ -138,6 +138,7 @@ export default { value: 'Value', }, 'no-relevant-data-attributes': 'No relevant data attributes found.', + 'data-attributes': 'Data Attributes', }, component: { overview: 'Overview', diff --git a/apps/www/app/locales/no.ts b/apps/www/app/locales/no.ts index d4e4016beb..b7ecb61849 100644 --- a/apps/www/app/locales/no.ts +++ b/apps/www/app/locales/no.ts @@ -137,6 +137,7 @@ export default { value: 'Verdi', }, 'no-relevant-data-attributes': 'Ingen relevante data-attributter funnet.', + 'data-attributes': 'Data-attributter', }, component: { overview: 'Oversikt',
Data-attributter{t('components.data-attributes')}