diff --git a/apps/www/app/_components/css-attributes/css-attributes.tsx b/apps/www/app/_components/css-attributes/css-attributes.tsx index e8cc2fa625..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 { Table } from '@digdir/designsystemet-react'; +import { Paragraph, Table } from '@digdir/designsystemet-react'; import cl from 'clsx'; import { forwardRef } from 'react'; +import { useTranslation } from 'react-i18next'; type CssAttributesProps = { vars: { @@ -10,7 +11,12 @@ type CssAttributesProps = { export const CssAttributes = forwardRef( function CssAttributes({ vars, className, ...rest }, ref) { - if (Object.keys(vars).length === 0) return null; + const { t } = useTranslation(); + + if (Object.keys(vars).length === 0) + return ( + {t('components.no-relevant-data-attributes')} + ); return ( ( {...rest} ref={ref} > + - Name - Value(s) + + {t('components.css-variables.name')} + + + {t('components.css-variables.value')} + diff --git a/apps/www/app/_components/css-variables/css-variables.tsx b/apps/www/app/_components/css-variables/css-variables.tsx index 7a169bbec8..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 (
{t('components.data-attributes')}
( {...rest} ref={ref} > + - Name - Value + + {t('components.css-variables.name')} + + + {t('components.css-variables.value')} + diff --git a/apps/www/app/content/components/alert/alert.stories.tsx b/apps/www/app/content/components/alert/alert.stories.tsx index 0c186c1567..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,11 @@ -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 +125,47 @@ 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 1877abcfe8..4019a097ed 100644 --- a/apps/www/app/content/components/alert/en/code.mdx +++ b/apps/www/app/content/components/alert/en/code.mdx @@ -1,17 +1,73 @@ -## Usage + +## Use ```tsx -import { Button } from '@digdir/designsystemet-react'; +import { Alert } from '@digdir/designsystemet-react'; -; +You are using the Alert component!; ``` -## Code Examples +### Props + + +## 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 3bfb7885c8..27e6e8bf41 100644 --- a/apps/www/app/content/components/alert/en/overview.mdx +++ b/apps/www/app/content/components/alert/en/overview.mdx @@ -2,19 +2,83 @@ Buttons let users perform actions. -## Usage +## Examples -```tsx -import { Button } from '@digdir/designsystemet-react'; +`Alert` can be used for four different messages: Information, success, warnings and error messages. -; -``` +### Information -## Code Examples +Use `info` when you want to provide the user with neutral and useful information. -### Variants + -Use `primary`, `secondary` or `tertiary` to weight the button correctly. +### 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. + +**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) + +## Text + +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. + +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/accessibility.mdx b/apps/www/app/content/components/alert/no/accessibility.mdx index 444391a642..374fce7c59 100644 --- a/apps/www/app/content/components/alert/no/accessibility.mdx +++ b/apps/www/app/content/components/alert/no/accessibility.mdx @@ -1 +1,49 @@ ## 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 d8b0c47579..29dfda7bae 100644 --- a/apps/www/app/content/components/alert/no/code.mdx +++ b/apps/www/app/content/components/alert/no/code.mdx @@ -1,5 +1,7 @@ - ## Bruk + + + ```tsx import { Alert } from '@digdir/designsystemet-react'; @@ -7,30 +9,29 @@ import { Alert } from '@digdir/designsystemet-react'; You are using the Alert component!; ``` -## Kodeeksempler - -### Informasjon +## Eksempel - +### Endre varsel -### Suksess +I kode endrer du typen varsel ved å endre `data-color`. +Ikonet er styrt via CSS. - + -### Advarsel +## 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`. -### Feilmelding +[Les om `role` og `aria-live` på tilgjengeligheitssiden for `Alert`-komponenten.](/no/components/alert/accessibility#alert-i-live-region) - - -### Med og uten overskrift - - - - +```html +
+ Dette er en info alert. +
+``` -### Med lenke +## 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 21bd4a10eb..1d7fd7c81d 100644 --- a/apps/www/app/content/components/alert/no/overview.mdx +++ b/apps/www/app/content/components/alert/no/overview.mdx @@ -1,17 +1,19 @@ -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'; +**Bruk `Alert` når** +- 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 -You are using the Alert component!; -``` +**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) -## Kodeeksempler +## 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 @@ -39,7 +41,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 [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. @@ -49,69 +53,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. - -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 +`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. -**Passer ikke til å** -- validere individuelle skjemaelementer, bruk heller komponentens egen feilmelding -- 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. - -Her er en liste med hvilken type informasjon en varsel bør inneholde: +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." - - -## 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"`. + - **Eksempel:** "Vennligst prøv igjen." 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 d4710c6ce3..f4d57087b9 100644 --- a/apps/www/app/content/components/details/no/code.mdx +++ b/apps/www/app/content/components/details/no/code.mdx @@ -1,17 +1,90 @@ -## 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'; -### Med farger + +
+ Details heading text + Details content +
+
+``` + +## Eksempler + +### 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. ### 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 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 + + + + 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 fdd895b406..445c2bbcab 100644 --- a/apps/www/app/content/components/details/no/overview.mdx +++ b/apps/www/app/content/components/details/no/overview.mdx @@ -1,36 +1,40 @@ - - -## 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. diff --git a/apps/www/app/locales/en.ts b/apps/www/app/locales/en.ts index b7ad370487..a6e5870db8 100644 --- a/apps/www/app/locales/en.ts +++ b/apps/www/app/locales/en.ts @@ -132,6 +132,13 @@ export default { changelog: { title: 'Changelog', }, + 'css-variables': { + caption: 'CSS Variables', + name: 'Name', + 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 ba06987078..b7ecb61849 100644 --- a/apps/www/app/locales/no.ts +++ b/apps/www/app/locales/no.ts @@ -131,6 +131,13 @@ export default { changelog: { title: 'Endringslogg', }, + 'css-variables': { + caption: 'CSS-variabler', + name: 'Navn', + value: 'Verdi', + }, + 'no-relevant-data-attributes': 'Ingen relevante data-attributter funnet.', + 'data-attributes': 'Data-attributter', }, component: { overview: 'Oversikt', diff --git a/apps/www/app/routes/components/component.tsx b/apps/www/app/routes/components/component.tsx index bdb7e40d84..5a1a4633c9 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'; @@ -28,6 +33,7 @@ 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'; @@ -127,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, @@ -141,6 +151,16 @@ export const loader = async ({ params, request }: Route.LoaderArgs) => { }; }; +export const meta = ({ loaderData }: Route.MetaArgs) => { + if (!loaderData?.linkMetadata) + return [ + { + title: 'Designsystemet', + }, + ]; + return loaderData.linkMetadata; +}; + export default function Components({ loaderData: { stories, mdxCode, metadata, toc, navigation, githubLink }, }: Route.ComponentProps) { @@ -218,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 ( )`} @@ -243,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 null; + if (!data) + return {t('components.no-relevant-data-attributes')}; const { cssAttrs } = data; - return cssAttrs ? : null; + return cssAttrs ? ( + + ) : ( + {t('components.no-relevant-data-attributes')} + ); };
{t('components.css-variables.caption')}