From 208cd81a8f4f463cef14f064fdd8721dfa415494 Mon Sep 17 00:00:00 2001 From: Tobias Barsnes Date: Tue, 15 Oct 2024 11:56:22 +0200 Subject: [PATCH 1/2] chore(storefront): fix issues (#2545) resolves #1788 --- .../src/CodeSnippet/CodeSnippet.tsx | 9 +- apps/_components/src/Header/Header.module.css | 53 ++- apps/_components/src/Header/Header.tsx | 98 ++++-- apps/_components/src/index.ts | 3 + apps/_components/src/logos/Figma.tsx | 30 ++ apps/_components/src/logos/Github.tsx | 33 ++ apps/_components/src/logos/Slack.tsx | 47 +++ apps/storefront/app/(frontpage)/page.mdx | 8 +- .../page.mdx | 1 + .../app/bloggen/2024/altinn-studio/page.mdx | 4 + .../bloggen/2024/fluid-typography/page.mdx | 1 + .../app/bloggen/2024/v1rc2/page.mdx | 1 + .../PostLayout/PostLayout.module.css | 9 + .../_components/PostLayout/PostLayout.tsx | 2 +- .../tilgjengelighet/kontrast/page.mdx | 18 +- .../for-utviklere/komposisjon/page.mdx | 2 +- apps/storefront/app/layout.tsx | 8 +- .../app/monstre/feilmeldinger/page.mdx | 8 +- .../obligatoriske-og-valgfrie-felt/page.mdx | 7 +- .../app/monstre/systemvarsler/page.mdx | 2 +- apps/storefront/components/Banner/Banner.tsx | 2 +- .../ComponentCard/ComponentCard.module.css | 1 + .../components/Footer/Footer.module.css | 71 ++-- apps/storefront/components/Footer/Footer.tsx | 52 +-- .../components/GithubLink/GithubLink.tsx | 19 +- .../components/Image/Image.module.css | 7 +- apps/storefront/components/Image/Image.tsx | 15 +- .../ImageBanner/ImageBanner.module.css | 7 - .../components/ImageBanner/ImageBanner.tsx | 47 ++- .../ImageSection/ImageSection.module.css | 114 ------- .../components/ImageSection/ImageSection.tsx | 115 ------- .../components/ImageSection/index.ts | 5 - .../MdxContent/MdxContent.module.css | 307 ++++++++++-------- .../components/MdxContent/MdxContent.tsx | 9 +- .../NavigationCard/NavigationCard.module.css | 14 +- .../NavigationCard/NavigationCard.tsx | 25 +- .../ResponsiveIframe.module.css | 6 +- .../ResponsiveIframe/ResponsiveIframe.tsx | 1 + .../SidebarMenu/SidebarMenu.module.css | 1 + .../components/SidebarMenu/SidebarMenu.tsx | 70 ++-- .../TeaserCard/TeaserCard.module.css | 2 +- .../components/TeaserCard/TeaserCard.tsx | 9 +- .../components/Tokens/TokenList/TokenList.tsx | 42 +-- .../VersionBanner/VersionBanner.module.css | 2 + apps/storefront/components/index.ts | 5 - apps/storefront/globals.css | 138 +------- .../MenuPageLayout/MenuPageLayout.module.css | 8 +- .../layouts/MenuPageLayout/MenuPageLayout.tsx | 4 +- .../layouts/NavPageLayout/NavPageLayout.tsx | 17 +- .../layouts/PageLayout/PageLayout.module.css | 1 + .../layouts/PageLayout/PageLayout.tsx | 14 +- apps/storefront/mdx-components.tsx | 9 +- 52 files changed, 679 insertions(+), 804 deletions(-) create mode 100644 apps/_components/src/logos/Figma.tsx create mode 100644 apps/_components/src/logos/Github.tsx create mode 100644 apps/_components/src/logos/Slack.tsx delete mode 100644 apps/storefront/components/ImageSection/ImageSection.module.css delete mode 100644 apps/storefront/components/ImageSection/ImageSection.tsx delete mode 100644 apps/storefront/components/ImageSection/index.ts diff --git a/apps/_components/src/CodeSnippet/CodeSnippet.tsx b/apps/_components/src/CodeSnippet/CodeSnippet.tsx index 7d28697d77..4f729ffa7d 100644 --- a/apps/_components/src/CodeSnippet/CodeSnippet.tsx +++ b/apps/_components/src/CodeSnippet/CodeSnippet.tsx @@ -28,16 +28,16 @@ const plugins = [ type CodeSnippetProps = { language?: 'css' | 'html' | 'ts' | 'markdown' | 'json'; - children?: string; - className?: string; syntax?: string; -}; + children: string; +} & React.HTMLAttributes; const CodeSnippet = ({ language = 'markdown', - children = '', className, syntax = 'js', + children, + ...rest }: CodeSnippetProps) => { const [toolTipText, setToolTipText] = useState('Kopier'); const [snippet, setSnippet] = useState(''); @@ -76,6 +76,7 @@ const CodeSnippet = ({
{snippet && ( <> diff --git a/apps/_components/src/Header/Header.module.css b/apps/_components/src/Header/Header.module.css index 9a55d54eee..70fdcc6c6f 100644 --- a/apps/_components/src/Header/Header.module.css +++ b/apps/_components/src/Header/Header.module.css @@ -49,6 +49,8 @@ display: flex; margin: 0; padding: 0; + max-width: 100%; + align-items: flex-start; } .item { @@ -113,8 +115,8 @@ border-color: var(--ds-color-neutral-border-strong); } -@media (max-width: 991.98px) { - .header { +.hamburger { + &.header { height: 72px; } @@ -134,6 +136,53 @@ flex-direction: column; display: none; padding: 20px 0; + width: 100%; + } + + .item { + padding: 20px 0; + margin-left: 16px; + } + + .active { + display: block; + } + + .item .active { + display: inline-block; + } + + .linkIcon { + place-items: start; + } + + .logo { + height: 26px; + } +} + +@media (max-width: 900px) { + &.header { + height: 72px; + } + + .toggle { + display: block; + } + + .menu { + border-top: 1px solid #e2e2e2; + position: absolute; + z-index: 1; + left: 0; + right: 0; + top: 71px; + background-color: white; + box-shadow: var(--ds-shadow-lg); + flex-direction: column; + display: none; + padding: 20px 0; + width: 100%; } .item { diff --git a/apps/_components/src/Header/Header.tsx b/apps/_components/src/Header/Header.tsx index 034add7d02..ef257177c4 100644 --- a/apps/_components/src/Header/Header.tsx +++ b/apps/_components/src/Header/Header.tsx @@ -1,10 +1,10 @@ 'use client'; -import { SkipLink } from '@digdir/designsystemet-react'; +import { Paragraph, SkipLink } from '@digdir/designsystemet-react'; import { MenuHamburgerIcon, XMarkIcon } from '@navikt/aksel-icons'; import cl from 'clsx/lite'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; -import { useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import classes from './Header.module.css'; import { DsLogo } from './logos/ds-logo'; @@ -14,19 +14,69 @@ import { GithubLogo } from './logos/github-logo'; type HeaderProps = { menu: { name: string; href: string }[]; betaTag?: boolean; + skipLink?: boolean; +}; + +/** + * Detect if any items have wrapped to a new line + */ +const detectWrap = (items: HTMLCollection) => { + const wrappedItems = []; + let prevItem: DOMRect | null = null; + + for (let i = 0; i < items.length; i++) { + const currItem = items[i].getBoundingClientRect(); + + if (prevItem) { + const prevItemTop = prevItem.bottom; + const currItemTop = currItem.bottom; + + // if current's item top position is different from previous + // that means that the item is wrapped + if (prevItemTop < currItemTop) { + wrappedItems.push(items[i]); + } + } + + prevItem = currItem; + } + + return wrappedItems; }; /** * Only works in next.js projects */ -const Header = ({ menu, betaTag }: HeaderProps) => { +const Header = ({ menu, betaTag, skipLink = true }: HeaderProps) => { const [open, setOpen] = useState(false); + const [isHamburger, setIsHamburger] = useState(false); + const menuRef = useRef(null); + const headerRef = useRef(null); const pathname = usePathname(); + useEffect(() => { + const handleResize = () => { + if (isHamburger) return; + if (menuRef.current && headerRef.current) { + const wrappedItems = detectWrap(menuRef.current.children); + setIsHamburger(wrappedItems.length > 0); + } + }; + + handleResize(); + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, [menu, isHamburger]); + return ( <> - Hopp til hovedinnhold -
+ {skipLink ? ( + Hopp til hovedinnhold + ) : null} +
{ -
    +
      {menu.map((item, index) => (
    • - setOpen(false)} - prefetch={false} - className={cl( - pathname.includes(item.href) && classes.active, - classes.link, - 'ds-paragraph--md', - 'ds-focus', - )} - > - {item.name} - + + setOpen(false)} + prefetch={false} + className={cl( + pathname.includes(item.href) && classes.active, + classes.link, + 'ds-focus', + )} + > + {item.name} + +
    • ))}
    • { > @@ -90,7 +143,6 @@ const Header = ({ menu, betaTag }: HeaderProps) => {
    • diff --git a/apps/_components/src/index.ts b/apps/_components/src/index.ts index 09c0ab936d..529b44bed3 100644 --- a/apps/_components/src/index.ts +++ b/apps/_components/src/index.ts @@ -3,3 +3,6 @@ export { Container } from './Container/Container'; export { ClipboardButton } from './ClipboardButton/ClipboardButton'; export { ColorModal } from './ColorModal/ColorModal'; export { Header } from './Header/Header'; +export { Figma } from './logos/Figma'; +export { Github } from './logos/Github'; +export { Slack } from './logos/Slack'; diff --git a/apps/_components/src/logos/Figma.tsx b/apps/_components/src/logos/Figma.tsx new file mode 100644 index 0000000000..b8cb9f1daf --- /dev/null +++ b/apps/_components/src/logos/Figma.tsx @@ -0,0 +1,30 @@ +type FigmaProps = React.HTMLAttributes; + +export function Figma(rest: FigmaProps) { + return ( + + + + + + + + + + + + ); +} diff --git a/apps/_components/src/logos/Github.tsx b/apps/_components/src/logos/Github.tsx new file mode 100644 index 0000000000..824c8908e3 --- /dev/null +++ b/apps/_components/src/logos/Github.tsx @@ -0,0 +1,33 @@ +type GithubProps = React.HTMLAttributes; + +export function Github(rest: GithubProps) { + return ( + + + + + + + + + + + ); +} diff --git a/apps/_components/src/logos/Slack.tsx b/apps/_components/src/logos/Slack.tsx new file mode 100644 index 0000000000..0b16c6d928 --- /dev/null +++ b/apps/_components/src/logos/Slack.tsx @@ -0,0 +1,47 @@ +type SlackProps = React.HTMLAttributes; + +export function Slack(rest: SlackProps) { + return ( + + + + + + + + + + + ); +} diff --git a/apps/storefront/app/(frontpage)/page.mdx b/apps/storefront/app/(frontpage)/page.mdx index cff8a3d4b8..276890a671 100644 --- a/apps/storefront/app/(frontpage)/page.mdx +++ b/apps/storefront/app/(frontpage)/page.mdx @@ -22,7 +22,6 @@ export const metadata = { imgSrc='/img/Toolbox.svg' headingLevel='h2' imgWidth={1195} - imgHeight={270} link={{ text: 'Les mer om designsystemet', href: '/grunnleggende/introduksjon/om-designsystemet', @@ -36,7 +35,6 @@ export const metadata = { imgPosition='right' headingLevel='h2' imgWidth={1195} - imgHeight={270} fallbackImgSrc='/img/reduced-motion/Page.png' fallbackImgAlt='Designskisse av en mobiltelefon som har komponenter fra designsystemet i seg.' /> @@ -47,7 +45,6 @@ export const metadata = { videoSrc='/animations/Theme' headingLevel='h2' imgWidth={1195} - imgHeight={270} fallbackImgSrc='/img/reduced-motion/Theme.png' fallbackImgAlt='Designskisse av en nettside som viser hvordan designsystemet kan tilpasses ulike identiteter.' /> @@ -90,6 +87,7 @@ export const metadata = { imgSrc='/img/Logotest.svg' headingLevel='h2' imgWidth='small' + className="ds-logo-image" buttons={[ { text: 'Bli med på Slack', @@ -115,5 +113,9 @@ export const metadata = { header:first-of-type { background-color: transparent; } + +.ds-logo-image img { + width: 85%; +} `} diff --git a/apps/storefront/app/bloggen/2023/derfor-trenger-vi-et-felles-designsystem/page.mdx b/apps/storefront/app/bloggen/2023/derfor-trenger-vi-et-felles-designsystem/page.mdx index e37ec0d8ab..95fe8c224b 100644 --- a/apps/storefront/app/bloggen/2023/derfor-trenger-vi-et-felles-designsystem/page.mdx +++ b/apps/storefront/app/bloggen/2023/derfor-trenger-vi-et-felles-designsystem/page.mdx @@ -39,6 +39,7 @@ Noen er bekymret for at merkevarene forsvinner, mens andre påpeker at de offent src='/img/bloggen/miro-sammenstilling.png' alt='Skjermdump fra Miro som viser at lappene er omskrevet til ren tekst.' caption='Vi har gjennomgått og sammenstilt alle lappene som ble delt i workshopen.' + dataUnstyled /> ## Felles designsystem er ikke en ny ide diff --git a/apps/storefront/app/bloggen/2024/altinn-studio/page.mdx b/apps/storefront/app/bloggen/2024/altinn-studio/page.mdx index 1be02681d0..03fbcff76a 100644 --- a/apps/storefront/app/bloggen/2024/altinn-studio/page.mdx +++ b/apps/storefront/app/bloggen/2024/altinn-studio/page.mdx @@ -51,6 +51,7 @@ Designsystemet tilbyr en hel rekke av grunnleggende komponenter, som kan utforme alt='Illustrasjonen viser flere knapper i ulike varianter og farger.' boxShadow={false} caption='Figur 1: Illustrasjon som viser varianter av knapper.' + dataUnstyled /> Selv om knappkomponenten kommer i mange varianter betyr ikke det at du og ditt team skal ta i bruk alle variantene. Designsystemet tilbyr disse mulighetene for at det skal være fleksibelt, og kunne tilby deg funksjonalitet som både er ofte brukt men også kjente mønstre. @@ -90,6 +91,7 @@ Eksempelvis har Altinn Studio behov for en [ExpressionEditor](https://components alt='Illustrasjonen viser eksempel på en sammensatt komponent av flere komponenter fra designsystemet' boxShadow={false} caption='Figur 2. Eksempel på en sammensatt komponent av flere komponenter fra designsystemet' + dataUnstyled /> **_Designsystemet er utviklet på en slik måte at det er enkelt å ta i bruk og utvide komponentene til de mer komplekse der det er behov._** @@ -107,6 +109,7 @@ For å oppnå trygghet og sikkerhet ved oppdateringer av tredjepart er det vikti alt='Illustrasjon som viser direkte avhengigheter til designsystemet' boxShadow={false} caption='Figur 3. Illustrasjon som viser direkte avhengigheter til designsystemet.' + dataUnstyled /> Hvrdan kan vi løse denne problemstillingen? Helt riktig — vi kan løse det med isolering av komponentene ved hjelp av fasademønsteret. @@ -122,6 +125,7 @@ Når vi isolerer komponentene våre, eliminerer vi behovet for å endre den eksi alt=' Illustrasjon som viser isolering av designsystemet. Illustrasjonen viser også hvordan man kan håndtere breaking chnage, uten å mått endre de 4 side-komponentene.' boxShadow={false} caption='Figur 4. Illustrasjon som viser isolering av designsystemet. Illustrasjonen viser også hvordan man kan håndtere breaking chnage, uten å mått endre de 4 side-komponentene.' + dataUnstyled /> Nå som Team Altinn Studio har oppnådd isolering av sammensatte komponenter, kan frontend-utivklere og designere jobbe tettere sammen mellom det som er teknisk implementert og skissene i Figma. Det vil si at Figma skissene kan gjenspeile komponentnavnene i `studio-components`. diff --git a/apps/storefront/app/bloggen/2024/fluid-typography/page.mdx b/apps/storefront/app/bloggen/2024/fluid-typography/page.mdx index 7f30d78a4f..2c5326b8d3 100644 --- a/apps/storefront/app/bloggen/2024/fluid-typography/page.mdx +++ b/apps/storefront/app/bloggen/2024/fluid-typography/page.mdx @@ -32,6 +32,7 @@ Tekststørrelsene øker gradvis fra viewport-bredde 320px helt til det treffer m alt='Illustrasjonen viser at en 16px tekststørrelser på små skjermer øker gradvis opp til 18px på store skjermer.' caption='Tekststørrelsen tilpasser seg automatisk bredden på skjermen.' boxShadow={false} + dataUnstyled /> ## Fordeler diff --git a/apps/storefront/app/bloggen/2024/v1rc2/page.mdx b/apps/storefront/app/bloggen/2024/v1rc2/page.mdx index ea27f53253..60902153f4 100644 --- a/apps/storefront/app/bloggen/2024/v1rc2/page.mdx +++ b/apps/storefront/app/bloggen/2024/v1rc2/page.mdx @@ -38,6 +38,7 @@ Vi har identifisert at arbeidet med å utvikle et solid CSS-rammeverk vil påvir alt='Flyt-illustrasjon av Designsystemets produkter og verktøy.' caption='Designsystemet består i dag av flere produkter, inkludert Temabygger, Design-tokens, Figma bibliotek, CSS rammeverk, React bibliotek, Tema pakke og CLI (Kommandoverktøy). Alle disse delene av systemet skal fungere sømløst sammen og gi en sammenhengende opplevelse for brukerne.' boxShadow={false} + dataUnstyled /> diff --git a/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.module.css b/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.module.css index 09ba846d15..ed65974fd2 100644 --- a/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.module.css +++ b/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.module.css @@ -20,6 +20,7 @@ gap: var(--ds-spacing-5); text-align: center; margin: 0 auto; + margin-top: var(--ds-spacing-12); } .ingress { @@ -64,6 +65,14 @@ background-color: var(--ds-color-neutral-background-subtle); } +.content video, +.content [data-iframe-video] { + display: block; + width: 860px; + margin-left: calc((100% - 860px) / 2) !important; + background-color: var(--ds-color-neutral-background-subtle); +} + .main > figure { margin: auto; width: 100%; diff --git a/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.tsx b/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.tsx index a8805e2d06..a1c575b450 100644 --- a/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.tsx +++ b/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.tsx @@ -64,7 +64,7 @@ function PostLayout({ caption={imageCaption} boxShadow={false} /> - + {content}
      diff --git a/apps/storefront/app/god-praksis/tilgjengelighet/kontrast/page.mdx b/apps/storefront/app/god-praksis/tilgjengelighet/kontrast/page.mdx index 8cf700241b..80befa6805 100644 --- a/apps/storefront/app/god-praksis/tilgjengelighet/kontrast/page.mdx +++ b/apps/storefront/app/god-praksis/tilgjengelighet/kontrast/page.mdx @@ -36,13 +36,11 @@ For å sikre god lesbarhet skal all tekst ha tilstrekkelig kontrast mot bakgrunn Alle brukerne, også de med svekket syn, skal kunne se innholdet i digitale tjenester. Web Content Accessibility Guidelines (WCAG) inneholder suksesskriterier og forslag til løsninger for å lykkes. Men det er ikke samsvar mellom dagens kontrastregler og kravet om at alle skal kunne se innholdet. - + - Gjeldende regelverk, WCAG 2.1 - + >Gjeldende regelverk, WCAG 2.1 **1.4.3 Kontrast (minimum) (Nivå AA)**: Kontrastforholdet mellom @@ -62,13 +60,11 @@ Alle brukerne, også de med svekket syn, skal kunne se innholdet i digitale tjen
      - + - Fremtidig eller strengere: - + >Fremtidig eller strengere: **1.4.6 Kontrast** (forbedret) (Nivå AAA): Den visuelle presentasjonen @@ -127,7 +123,7 @@ Vi vet at selv om en løsning oppfyller de konkrete kravene fra regelverket om u Hvis vi oppfyller metoden i WCAG 2, etterlever vi teknisk sett kravet til universell utforming, men det betyr ikke at innholdet er tilgjengelig eller universelt utformet. Derfor strekker vi oss langt i å også oppfylle de fremtidige WCAG-3 kravene som bruker APCA-metoden. - + **Kontrast i WCAG 2 «luminosity contrast algorithm**
      _«I WCAG 2 er kontrast en måleenhet for forskjellen i den opplevde lysintensiteten mellom to farger. Denne forskjellen er beskrevet som et forhold fra 1:1 (for @@ -139,7 +135,7 @@ Hvis vi oppfyller metoden i WCAG 2, etterlever vi teknisk sett kravet til univer
      - + **Kontrast i WCAG 3 «visual contrast algorithm»**
      I WCAG 3 benyttes en visuell-kontrast algoritme som kalles for APCA, det er fremdeles fargeverdiene som benyttes for å kalkulere kontrasten, men også om fargen er @@ -179,7 +175,7 @@ I variant B er teksten svart, og bakgrunnen er farge #6D7879. Teksten er noe min

      - + **Bidra til artikkelen?**
      Vi vil gjerne ha dine innspill og tilbakemeldinger på artikkelen. Send oss en e-post på: designsystem@digdir.no eller [kontakt oss i Github](https://github.com/digdir/designsystemet/issues/new). diff --git a/apps/storefront/app/grunnleggende/for-utviklere/komposisjon/page.mdx b/apps/storefront/app/grunnleggende/for-utviklere/komposisjon/page.mdx index 2640d6da0c..d7cdbc8135 100644 --- a/apps/storefront/app/grunnleggende/for-utviklere/komposisjon/page.mdx +++ b/apps/storefront/app/grunnleggende/for-utviklere/komposisjon/page.mdx @@ -23,7 +23,7 @@ export default ({ children }) => ( Nokre gonger må du kanskje byte ut ein komponent med ein anna, for eksempel `Button` skulle vore ein `Link`. Det er her `asChild` kjem inn i biletet. - + {` import { Button, Link } from '@digdir/designsystemet-react'; diff --git a/apps/storefront/app/layout.tsx b/apps/storefront/app/layout.tsx index bdb1cae62b..448d18c645 100644 --- a/apps/storefront/app/layout.tsx +++ b/apps/storefront/app/layout.tsx @@ -6,6 +6,7 @@ import { Header } from '@repo/components'; import type { Metadata } from 'next'; import { VersionBanner } from '@components'; +import { SkipLink } from '@digdir/designsystemet-react'; import Script from 'next/script'; import { Footer } from '../components/Footer/Footer'; @@ -45,6 +46,10 @@ const menu = [ name: 'Komponenter', href: '/komponenter', }, + /* { + name: 'Temabygger', + href: 'https://next.theme.designsystemet.no', + }, */ ]; export default function RootLayout({ @@ -58,8 +63,9 @@ export default function RootLayout({
      + Hopp til hovedinnhold -
      +
      {children}
      {process.env.VERCEL_ENV === 'production' && ( diff --git a/apps/storefront/app/monstre/feilmeldinger/page.mdx b/apps/storefront/app/monstre/feilmeldinger/page.mdx index 91943476af..d7ec70abe0 100644 --- a/apps/storefront/app/monstre/feilmeldinger/page.mdx +++ b/apps/storefront/app/monstre/feilmeldinger/page.mdx @@ -49,6 +49,7 @@ Vi skal kunne vise feilmeldinger sammen med alle typer felt i et skjema. Melding src='/img/errormessage-co-1.png' alt='Skjermbilde av skjema med en feilmelding. Brukeren har skrevet "fdgdfgfdg" inn i et felt for fødselsnummer. Feilmeldingen sier at Fødselsnummer skal inneholde 11 siffer.' boxShadow={false} + dataUnstyled /> ### Oppsummering av flere feilmeldinger @@ -74,6 +75,7 @@ Pass på at src='/img/errormessage-co-3.png' alt='Skjermbilde av skjema med en feilmelding. Brukeren har skrevet "fdgdfgfdg" inn i et felt for fødselsnummer. Feilmeldingen sier at Fødselsnummer skal inneholde 11 siffer.' boxShadow={false} + dataUnstyled /> ### Det er best om vi kan unngå å gi feilmeldinger @@ -135,6 +137,7 @@ Når det oppstår feil i et felt er det viktig at feltet blir godt synlig, slik src='/img/errormessage-design.png' alt='Et skjemafelt som viser feil på informasjonen som er fylt ut. På feltet blir de visuelle elementene som skiller det fra et vanlig felt fremhevet: Det er tykkere kant rundt feltet, det er farget rødt og det er en rød tekst med et tilhørende fareikon som beskriver feilen på feltet.' boxShadow={false} + dataUnstyled /> Når den tekniske løsningen sjekker for feil, det vi kaller validerer, ønsker vi å vise hvilke felt som har feil. Til det kan vi bruke flere virkemidler. @@ -154,6 +157,7 @@ Vi viser feilmeldingen under feltet med feil. Dette er det vanligste mønsteret, Merk: Vi ønsker å holde oss oppdatert om andre anbefalinger om plassering, og har [pågående diskusjon om dette på Git](https://github.com/digdir/designsystemet/discussions/1684#discussioncomment-9339006). @@ -241,7 +245,7 @@ Vi kan bruke disse aria-attributtene og rollene: - Vi setter `aria-invalid="true"` på felt med feil, for å si fra om at det er en feil der. - Vi bruker `aria-describedby` for å koble feilmelding til feltet. - + Vi unngår inntill videre å bruke `aria-errormessage` da den ikke har full støtte av hjelpemidler per nå. Men vi kommer til å oppdatere retningslinjene om støtten blir bedre i fremtiden. [Se diskusjon på github](https://github.com/digdir/designsystemet/discussions/1684) @@ -267,7 +271,7 @@ For feilmeldinger som dukker opp dynamisk må vi bruke `aria-live` for at meldin

      - + Retningslinjene er utarbeidet i en tverretatlig arbeidsgruppe med deltakere fra Digdir, Nav, Skatt, Brreg, Politiet, KS DIF og Oslo kommune. Du kan påvirke arbeidet i [Github](https://github.com/digdir/designsystemet/discussions/1684) eller i [#Mønster-kanalen](https://designsystemet.slack.com/archives/C05RBGB92MC/p1712751837722749) på [Slack](https://join.slack.com/t/designsystemet/shared_invite/zt-2438eotl3-a4266Vd2IeqMWO8TBw5PrQ). diff --git a/apps/storefront/app/monstre/obligatoriske-og-valgfrie-felt/page.mdx b/apps/storefront/app/monstre/obligatoriske-og-valgfrie-felt/page.mdx index 06982f6a6e..6e434378fb 100644 --- a/apps/storefront/app/monstre/obligatoriske-og-valgfrie-felt/page.mdx +++ b/apps/storefront/app/monstre/obligatoriske-og-valgfrie-felt/page.mdx @@ -1,4 +1,4 @@ -import { Card, CardContent, Heading, Paragraph } from '@digdir/designsystemet-react'; +import { Card, Heading, Paragraph } from '@digdir/designsystemet-react'; import { MenuPageLayout } from '@layouts'; import { Image } from '@components'; @@ -36,6 +36,7 @@ Hvis vi kan holde oss til ett spørsmål per side, så er det det aller enkleste src='/img/obligatorisk-eks1.png' alt='Skjermbilde av skjema med ett spørsmål på en side, der spørsmålet er obligatorisk' boxShadow={false} + dataUnstyled /> Dersom det er frivillig å fylle ut en av sidene, kan dette også komme frem i beskrivelsen. @@ -44,6 +45,7 @@ Dersom det er frivillig å fylle ut en av sidene, kan dette også komme frem i b src='/img/obligatorisk-eks1b.png' alt='Skjermbilde av skjema med ett spørsmål på en side, der spørsmålet er valgfritt' boxShadow={false} + dataUnstyled /> ## 2. Når vi _må_ ha flere spørsmål per side @@ -58,6 +60,7 @@ Hvis vi _må_ ha flere spørsmål på en side, kan vi informere tydelig i toppen src='/img/obligatorisk-eks2.png' alt='Skjermbilde av skjema med flere spørsmål per side.' boxShadow={false} + dataUnstyled /> ## 3. Når vi _må_ ha en kombinasjon av obligatoriske og valgfrie felt @@ -73,6 +76,7 @@ En kombinasjon av obligatoriske og valgfrie felt er ikke ideellt! Men det vil v src='/img/obligatorisk-eks3.png' alt='Skjermbilde av skjema med flere spørsmål per side, både obligatoriske og valgfrie.' boxShadow={false} + dataUnstyled />
      @@ -89,6 +93,7 @@ En kombinasjon av obligatoriske og valgfrie felt er ikke ideellt! Men det vil v *Retningslinjene er utarbeidet i en tverretatlig arbeidsgruppe med deltakere fra Digdir, Nav, Skatt, Brreg og Oslo Origo. Du kan påvirke arbeidet i [Github](https://github.com/digdir/designsystemet/issues/new) eller i [#Mønster-kanalen](https://designsystemet.slack.com/archives/C05RBGB92MC/p1712751837722749) på [Slack](https://join.slack.com/t/designsystemet/shared_invite/zt-2438eotl3-a4266Vd2IeqMWO8TBw5PrQ). diff --git a/apps/storefront/app/monstre/systemvarsler/page.mdx b/apps/storefront/app/monstre/systemvarsler/page.mdx index 7ae721f7fd..a6a98d76f7 100644 --- a/apps/storefront/app/monstre/systemvarsler/page.mdx +++ b/apps/storefront/app/monstre/systemvarsler/page.mdx @@ -18,7 +18,7 @@ export default ({ children }) => ( /> ); - + *Retningslinjene er under arbeid fra 5. juni 2024 i en tverretatlig arbeidsgruppe med deltakere fra Digdir, Nav, Skatt, Brreg, Politiet, KS DIF og Oslo kommune. Alle er velkommen til å påvirke arbeidet i [Github](https://github.com/digdir/designsystemet/discussions/1801) eller i [#Mønster-kanalen](https://designsystemet.slack.com/archives/C05RBGB92MC/p1712751837722749) på [Slack](https://join.slack.com/t/designsystemet/shared_invite/zt-2438eotl3-a4266Vd2IeqMWO8TBw5PrQ). diff --git a/apps/storefront/components/Banner/Banner.tsx b/apps/storefront/components/Banner/Banner.tsx index 899ed9834a..d4fab70795 100644 --- a/apps/storefront/components/Banner/Banner.tsx +++ b/apps/storefront/components/Banner/Banner.tsx @@ -46,7 +46,7 @@ const BannerIngress = ({ className, ...props }: BannerIngressProps) => { return ( ); diff --git a/apps/storefront/components/ComponentCard/ComponentCard.module.css b/apps/storefront/components/ComponentCard/ComponentCard.module.css index bcc52f1793..cb36a76aee 100644 --- a/apps/storefront/components/ComponentCard/ComponentCard.module.css +++ b/apps/storefront/components/ComponentCard/ComponentCard.module.css @@ -2,6 +2,7 @@ display: block; text-align: center; background-color: white; + color: var(--ds-color-neutral-text-default); padding: var(--ds-spacing-10); border-radius: var(--ds-border-radius-md); box-shadow: var(--ds-shadow-xs); diff --git a/apps/storefront/components/Footer/Footer.module.css b/apps/storefront/components/Footer/Footer.module.css index 4eece97c90..e88b263b78 100644 --- a/apps/storefront/components/Footer/Footer.module.css +++ b/apps/storefront/components/Footer/Footer.module.css @@ -1,7 +1,5 @@ .footer { background-color: var(--ds-color-neutral-background-subtle); - font-weight: 300; - letter-spacing: 0.3px; } .container { @@ -14,16 +12,6 @@ margin-bottom: var(--ds-spacing-4); } -.footer .logos img { - height: 26px; - width: auto; - margin-right: var(--ds-spacing-2); - - &.udir { - height: 32px; - } -} - .logos { display: flex; flex-direction: column; @@ -47,9 +35,43 @@ } .link { - --dsc-link-color-visited: var(--ds-color-neutral-text-default); + --dsc-link-color--visited: var(--ds-color-neutral-text-default); + + & svg { + max-width: 24px; + + & * { + fill: var(--dsc-link-color); + } + } + + &:focus-visible { + & svg * { + fill: var(--dsc-link-color--focus); + } + } - gap: var(--ds-spacing-2); + &:hover { + & svg * { + fill: var(--dsc-link-color--hover); + } + } + + &:active { + & svg * { + fill: var(--dsc-link-color--active); + } + } +} + +.footer .logos img { + height: 26px; + width: auto; + margin-right: var(--ds-spacing-2); + + &.udir { + height: 32px; + } } .top { @@ -62,20 +84,11 @@ } .button { - display: inline-flex; - align-items: center; - justify-content: center; - text-decoration: none; - height: 48px; - padding: 0 var(--ds-spacing-5); - margin-top: var(--ds-spacing-7); - border-radius: 2px; - color: var(--color-text-on_inverted-subtle); - border: 1px dashed var(--color-text-on_inverted-subtle); -} + --dsc-button-color: var(--ds-color-neutral-text-default); + --dsc-button-padding-block: var(--ds-spacing-4); + --dsc-button-padding-inline: var(--ds-spacing-5); -.button:hover { - background-color: var(--color-surface-neutral-inverted-darker); - border-color: white; - color: white; + border: 2px dashed var(--ds-color-neutral-border-strong); + width: fit-content; + margin-top: var(--ds-spacing-8); } diff --git a/apps/storefront/components/Footer/Footer.tsx b/apps/storefront/components/Footer/Footer.tsx index 91c49a42a0..4959f5727a 100644 --- a/apps/storefront/components/Footer/Footer.tsx +++ b/apps/storefront/components/Footer/Footer.tsx @@ -1,7 +1,6 @@ -import { Heading, Link, Paragraph } from '@digdir/designsystemet-react'; +import { Button, Heading, Link, Paragraph } from '@digdir/designsystemet-react'; import { EnvelopeClosedIcon } from '@navikt/aksel-icons'; -import { Container } from '@repo/components'; -import cl from 'clsx/lite'; +import { Container, Figma, Github, Slack } from '@repo/components'; import Image from 'next/image'; import NextLink from 'next/link'; import type { ReactNode } from 'react'; @@ -32,38 +31,17 @@ const rightLinks = [ { text: 'Bli invitert til slack', url: 'https://join.slack.com/t/designsystemet/shared_invite/zt-2438eotl3-a4266Vd2IeqMWO8TBw5PrQ', - prefix: ( - - ), + prefix: , }, { text: 'Github', url: 'https://github.com/digdir/designsystemet', - prefix: ( - - ), + prefix: , }, { text: 'Figma', url: 'https://www.figma.com/@designsystemet', - prefix: ( - - ), + prefix: , }, ]; @@ -129,16 +107,14 @@ const Footer = () => { className={classes.udir} >
      - - Din etat? Ta kontakt! - +
      @@ -154,7 +130,7 @@ const Footer = () => {
-
+
© {getCurrentYear()} Designsystemet diff --git a/apps/storefront/components/GithubLink/GithubLink.tsx b/apps/storefront/components/GithubLink/GithubLink.tsx index 32efcc8560..f59a4dd0ac 100644 --- a/apps/storefront/components/GithubLink/GithubLink.tsx +++ b/apps/storefront/components/GithubLink/GithubLink.tsx @@ -1,6 +1,6 @@ 'use client'; import { Link } from '@digdir/designsystemet-react'; -import Image from 'next/image'; +import { Github } from '@repo/components'; import { usePathname } from 'next/navigation'; import type { HTMLAttributes } from 'react'; @@ -11,14 +11,15 @@ const GithubLink = ({ const href = `https://github.com/digdir/designsystemet/tree/next/apps/storefront/app${pathName}/page.mdx`; return ( - - github logo - Rediger denne siden på Github + + + Rediger denne siden på Github (åpnes i ny fane) ); }; diff --git a/apps/storefront/components/Image/Image.module.css b/apps/storefront/components/Image/Image.module.css index 9a9b73192f..9e7e56d791 100644 --- a/apps/storefront/components/Image/Image.module.css +++ b/apps/storefront/components/Image/Image.module.css @@ -7,11 +7,12 @@ gap: var(--ds-spacing-4); } -.container .img { - box-shadow: none; +.image { margin: 0; + width: 100%; + box-shadow: none; } -.boxShadow .img { +.boxShadow .image { box-shadow: var(--ds-shadow-md); } diff --git a/apps/storefront/components/Image/Image.tsx b/apps/storefront/components/Image/Image.tsx index 0b78978572..11578de899 100644 --- a/apps/storefront/components/Image/Image.tsx +++ b/apps/storefront/components/Image/Image.tsx @@ -6,15 +6,24 @@ import classes from './Image.module.css'; interface ImageProps extends React.ImgHTMLAttributes { boxShadow: boolean; caption: string; + dataUnstyled?: boolean; } -const Image = ({ alt, src, boxShadow, caption, ...rest }: ImageProps) => { +const Image = ({ + alt, + src, + boxShadow = false, + caption, + dataUnstyled = false, + ...rest +}: ImageProps) => { return (
{alt}; -type ImageSectionButtonProps = { +type ImageBannerButtonProps = { text: string; prefix?: React.ReactNode; href: string; @@ -53,21 +53,14 @@ const ImageBanner = ({ headingLevel = 'h1', fallbackImgSrc, fallbackImgAlt, -}: ImageSectionProps) => { - const [heading, setHeading] = useState(null); - - useEffect(() => { - setHeading( - createElement( - headingLevel, - { className: cl(classes.title, 'ds-heading--lg') }, - title, - ), - ); - }, [headingLevel, title]); - + className, + ...rest +}: ImageBannerProps) => { return ( -
+
{imgPosition === 'left' && (
- {title && heading} - {description && ( -

- {description} -

- )} + {title ? ( + + {title} + + ) : null} + {description && {description}} {content && content} {link && ( @@ -155,5 +148,5 @@ const ImageBanner = ({ ); }; -export type { ImageSectionButtonProps, ImageSectionProps }; +export type { ImageBannerButtonProps, ImageBannerProps }; export { ImageBanner }; diff --git a/apps/storefront/components/ImageSection/ImageSection.module.css b/apps/storefront/components/ImageSection/ImageSection.module.css deleted file mode 100644 index a4aa6a5363..0000000000 --- a/apps/storefront/components/ImageSection/ImageSection.module.css +++ /dev/null @@ -1,114 +0,0 @@ -.section { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - gap: var(--ds-spacing-14); - padding-top: var(--ds-spacing-14); - padding-bottom: var(--ds-spacing-14); -} - -.blue { - background-color: var(--ds-color-brand3-3); -} - -.red { - background-color: var(--ds-color-brand1-3); -} - -.yellow { - background-color: var(--ds-color-brand2-3); -} - -.grey { - background-color: var(--ds-color-neutral-background-subtle); -} - -.white { - background-color: var(--ds-color-neutral-background-default); -} - -.imgContainer { - flex-basis: calc(35% - (var(--ds-spacing-18) / 2)); - flex-grow: 1; -} - -.textContainer { - flex-basis: calc(65% - (var(--ds-spacing-18) / 2)); - flex-grow: 1; - display: flex; - flex-direction: column; -} - -.title { - margin-bottom: var(--ds-spacing-4); -} - -.desc { - margin-top: 0; - margin-bottom: 0; -} - -.img { - width: 360px; - display: block; -} - -.buttons { - display: flex; - flex-wrap: wrap; - gap: var(--ds-spacing-5); - margin-top: var(--ds-spacing-5); -} - -.button { - height: 48px; - padding: 0 var(--ds-spacing-4); - border: 1px solid #c0c0c0; - display: flex; - align-items: center; - background-color: white; - border-radius: 4px; - cursor: pointer; - transition: 0.1s all; - color: var(--ds-color-neutral-text-default); - text-decoration: none; -} - -@media (max-width: 480px) { - .button { - width: 100%; - } -} - -.button:hover { - background-color: #dbedff; -} - -.button svg { - margin-right: var(--ds-spacing-2); - color: #1e2b3c; -} - -.button img { - height: 20px; - margin-right: var(--ds-spacing-2); - border-radius: 50%; -} - -.link { - text-underline-offset: 5px; - color: var(--ds-color-neutral-text-default); - display: flex; - align-items: center; - margin-top: var(--ds-spacing-5); -} - -.link:hover { - text-decoration-thickness: 2px; -} - -.link svg { - margin-right: var(--ds-spacing-2); - color: var(--ds-color-neutral-text-default); -} diff --git a/apps/storefront/components/ImageSection/ImageSection.tsx b/apps/storefront/components/ImageSection/ImageSection.tsx deleted file mode 100644 index f7c12e2cd5..0000000000 --- a/apps/storefront/components/ImageSection/ImageSection.tsx +++ /dev/null @@ -1,115 +0,0 @@ -'use client'; -import { Container } from '@repo/components'; -import cl from 'clsx/lite'; -import Image from 'next/image'; -import { createElement, useEffect, useState } from 'react'; -import type { ReactNode } from 'react'; - -import classes from './ImageSection.module.css'; - -interface ImageSectionProps { - title?: string; - description?: string; - imgSrc: string; - imgAlt?: string; - headingLevel?: 'h1' | 'h2'; - content?: ReactNode; - children?: ReactNode; - imgWidth: number; - imgHeight: number; - backgroundColor?: 'blue' | 'yellow' | 'red' | 'white'; - buttons?: ImageSectionButtonProps[]; - link?: { text: string; href: string; prefix: ReactNode }; - imgPosition?: 'left' | 'right'; -} - -type ImageSectionButtonProps = { - text: string; - prefix?: ReactNode; - href: string; -}; - -const ImageSection = ({ - title, - description, - imgSrc, - content, - imgHeight, - imgWidth, - backgroundColor = 'white', - children, - buttons, - link, - imgPosition = 'left', - imgAlt = '', - headingLevel = 'h1', -}: ImageSectionProps) => { - const [heading, setHeading] = useState(null); - - useEffect(() => { - setHeading( - createElement( - headingLevel, - { className: cl(classes.title, 'ds-heading-md') }, - title, - ), - ); - }, [headingLevel, title]); - - return ( -
- - {imgPosition === 'left' && ( -
- {imgAlt} -
- )} -
- {title && heading} - {description && ( -

{description}

- )} - {content && content} - {link && ( - - {link.prefix} {link.text} - - )} - - {buttons && ( -
- {buttons.map((item, index) => ( - - {item.prefix} - {item.text} - - ))} -
- )} - - {children} -
- {imgPosition === 'right' && ( -
- {imgAlt} -
- )} -
-
- ); -}; - -export type { ImageSectionButtonProps, ImageSectionProps }; -export { ImageSection }; diff --git a/apps/storefront/components/ImageSection/index.ts b/apps/storefront/components/ImageSection/index.ts deleted file mode 100644 index 7e33fb144a..0000000000 --- a/apps/storefront/components/ImageSection/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { ImageSection } from './ImageSection'; -export type { - ImageSectionButtonProps, - ImageSectionProps, -} from './ImageSection'; diff --git a/apps/storefront/components/MdxContent/MdxContent.module.css b/apps/storefront/components/MdxContent/MdxContent.module.css index 8bd83b2c1a..6b0e2e7c2a 100644 --- a/apps/storefront/components/MdxContent/MdxContent.module.css +++ b/apps/storefront/components/MdxContent/MdxContent.module.css @@ -1,144 +1,167 @@ .content { - width: 100%; -} - -.content p, -.content h2, -.content h3, -.content h4, -.content ul, -.content ol, -.content [class^='ds-accordion'], -.content [class^='ds-card'] { - max-width: 740px; -} - -/* A

tag that comes directly after

will be treated as an ingress */ -.content h1 + p { - font: var(--ds-typography-ingress-md); - margin-top: 0; - margin-bottom: var(--ds-spacing-8); -} - -/* Heading styling with anchor link */ -.content > h1, -.content > h2, -.content > h3, -.content > h4 { - position: relative; - padding-left: 26px; - margin-left: -26px; -} - -.content > h2, -.content > h3, -.content > h4 { - margin-top: var(--ds-spacing-10); - margin-bottom: var(--ds-spacing-3); -} - -/* Anchor link styling */ -.content > h1 a, -.content > h2 a, -.content > h3 a, -.content > h4 a { - width: 20px; - height: 20px; - position: absolute; - left: 0; - color: var(--ds-color-neutral-text-subtle); - opacity: 0; - transition: 0.08s all; -} - -/* Anchor link styling for

*/ -.content > h1 a { - height: 24px; - width: 24px; - margin-top: -2px; - left: -4px; -} - -/* Anchor links appear on heading hover */ -.content > h1:hover a, -.content > h2:hover a, -.content > h3:hover a, -.content > h4:hover a { - opacity: 1; -} - -.content img { - width: 100%; - margin: var(--ds-spacing-5) 0; - border-radius: var(--ds-border-radius-md); - box-shadow: var(--ds-shadow-md); -} - -.content strong { - display: inline-block; - margin-top: var(--ds-spacing-1); - font-weight: 500; -} - -.content > ul > li, -.content > ol > li { - font: var(--ds-typography-paragraph-md); - line-height: 1.9em; -} - -.content > ul > li > ol, -.content > ol > li > ul { - margin-top: var(--ds-spacing-1); -} - -.content > p > a:hover, -.content > ul > li a:hover, -.content > ol > li a:hover { - text-decoration-thickness: 2px; -} - -.content pre { - background-color: var(--ds-color-neutral-background-subtle); - padding: var(--ds-spacing-5); - margin: var(--ds-spacing-7) 0; - border-radius: var(--ds-border-radius-md); -} - -.content > iframe { - box-shadow: var(--ds-shadow-md); - margin: var(--ds-spacing-5); - border-radius: var(--ds-border-radius-md); -} - -.content > table { - width: 100%; - margin: var(--ds-spacing-7) 0; - border-collapse: collapse; -} - -.content p code, -.content ul code, -.content ol code { - padding: 0.2em 0.5em; - margin: 1px; - font-size: 0.9em; - white-space: break-spaces; - background-color: var(--ds-color-neutral-surface-default); - border-radius: var(--ds-border-radius-md); -} - -.content > *:first-child { - margin-top: 0; -} - -.content > *:last-child { - margin-bottom: 0; -} - -.content [class~='ds-card'] p { - margin: 0; -} - -.content [class~='ds-card'] { - margin: var(--ds-spacing-3) 0; + & > *:first-child { + margin-top: 0; + } + + & > *:last-child { + margin-bottom: 0; + } + + & p { + margin-bottom: var(--ds-spacing-4); + } + + & > h1, + & > h2, + & > h3, + & > h4 { + position: relative; + padding-left: 26px; + margin-left: -26px; + } + + & > h2, + & > h3, + & > h4 { + margin-top: var(--ds-spacing-10); + margin-bottom: var(--ds-spacing-3); + } + + /* Anchor link styling */ + & > h1 a, + & > h2 a, + & > h3 a, + & > h4 a { + width: fit-content; + height: 1em; + font-size: 0.7em; + position: absolute; + color: var(--ds-color-neutral-text-subtle); + opacity: 0; + transition: 0.08s all; + display: grid; + place-items: center; + padding: 0 0.2em; + left: 0; + top: 50%; + transform: translateY(-50%); + + & svg { + margin: 0; + } + } + + /* Anchor link styling for

*/ + & > h1 a { + height: 24px; + width: 24px; + margin-top: -2px; + left: -4px; + } + + /* Anchor links appear on heading hover */ + & > h1:hover a, + & > h2:hover a, + & > h3:hover a, + & > h4:hover a { + opacity: 1; + } + + & > ul > li, + & > ol > li { + font: var(--ds-typography-paragraph-md); + line-height: 1.9em; + } + + & > ul > li > ol, + & > ol > li > ul { + margin-top: var(--ds-spacing-1); + } + + & > p > a:hover, + & > ul > li a:hover, + & > ol > li a:hover { + text-decoration-thickness: 2px; + } + + /* A

tag that comes directly after

will be treated as an ingress */ + & > h1 + p { + font: var(--ds-body-long-md-font-size); + margin-top: 0; + margin-bottom: var(--ds-spacing-8); + } + + & > iframe { + box-shadow: var(--ds-shadow-md); + margin: var(--ds-spacing-5); + border-radius: var(--ds-border-radius-md); + } + + & > table { + width: 100%; + margin: var(--ds-spacing-7) 0; + border-collapse: collapse; + } + + & > img { + width: 100%; + margin: var(--ds-spacing-5) 0; + border-radius: var(--ds-border-radius-md); + box-shadow: var(--ds-shadow-md); + } + + & > code, + & > p code { + padding: 0.2em 0.5em; + margin: 1px; + font-size: 0.9em; + white-space: break-spaces; + background-color: var(--ds-color-neutral-surface-default); + border-radius: var(--ds-border-radius-md); + } + + & > pre, + & > p pre { + background-color: var(--ds-color-neutral-background-subtle); + padding: var(--ds-spacing-5); + margin: var(--ds-spacing-7) 0; + border-radius: var(--ds-border-radius-md); + } + + & > div + p { + margin-top: var(--ds-spacing-5); + } + + & *[data-unstyled] { + & p { + margin: unset; + } + } + + & *:not([data-unstyled]) { + & p, + & h2, + & h3, + & h4, + & ul, + & ol, + & [class^='ds-accordion'], + & [class^='ds-card'] { + max-width: 740px; + } + + & img { + width: 100%; + margin: var(--ds-spacing-5) 0; + border-radius: var(--ds-border-radius-md); + box-shadow: var(--ds-shadow-md); + } + + &:is(strong), + & strong { + display: inline-block; + margin-top: var(--ds-spacing-1); + font-weight: 500; + } + } } diff --git a/apps/storefront/components/MdxContent/MdxContent.tsx b/apps/storefront/components/MdxContent/MdxContent.tsx index 1720da445d..fd5c38a5c3 100644 --- a/apps/storefront/components/MdxContent/MdxContent.tsx +++ b/apps/storefront/components/MdxContent/MdxContent.tsx @@ -4,13 +4,10 @@ import type * as React from 'react'; import classes from './MdxContent.module.css'; -interface MdxContentProps { - children: React.ReactNode; - classname?: string; -} +type MdxContentProps = React.HTMLAttributes; -const MdxContent = ({ children, classname }: MdxContentProps) => { - return
{children}
; +const MdxContent = ({ className, ...rest }: MdxContentProps) => { + return
; }; export { MdxContent }; diff --git a/apps/storefront/components/NavigationCard/NavigationCard.module.css b/apps/storefront/components/NavigationCard/NavigationCard.module.css index 93baf2e0ff..714584ad33 100644 --- a/apps/storefront/components/NavigationCard/NavigationCard.module.css +++ b/apps/storefront/components/NavigationCard/NavigationCard.module.css @@ -1,10 +1,7 @@ .card { - background-color: white; - padding: var(--ds-spacing-8); - display: block; - color: inherit; text-decoration: none; box-shadow: var(--ds-shadow-sm); + border: none; border-radius: 8px; transition: 0.2s transform, 0.2s box-shadow; position: relative; @@ -16,7 +13,13 @@ color: inherit; box-shadow: var(--ds-shadow-md); transform: translateY(-4px); - cursor: pointer; +} + +.card:focus-visible { + transition: none; + box-shadow: var(--dsc-focus-boxShadow); + outline: var(--dsc-focus-outline); + outline-offset: var(--dsc-focus-border-width); } .iconContainer { @@ -72,5 +75,4 @@ .desc { text-align: center; - line-height: 1.7em; } diff --git a/apps/storefront/components/NavigationCard/NavigationCard.tsx b/apps/storefront/components/NavigationCard/NavigationCard.tsx index a817ed800a..c3c64d4d2f 100644 --- a/apps/storefront/components/NavigationCard/NavigationCard.tsx +++ b/apps/storefront/components/NavigationCard/NavigationCard.tsx @@ -1,5 +1,5 @@ 'use client'; -import { Heading } from '@digdir/designsystemet-react'; +import { Card, Heading, Paragraph } from '@digdir/designsystemet-react'; import cl from 'clsx/lite'; import Link from 'next/link'; import type * as React from 'react'; @@ -26,17 +26,22 @@ const NavigationCard = ({ level = 3, }: NavigationCardProps) => { return ( - -
{icon}
- - {title} - -
{description}
- + +
{icon}
+ + + {title} + + + + {description} + + + ); }; diff --git a/apps/storefront/components/ResponsiveIframe/ResponsiveIframe.module.css b/apps/storefront/components/ResponsiveIframe/ResponsiveIframe.module.css index dfe6a25a6d..6b9df95fcc 100644 --- a/apps/storefront/components/ResponsiveIframe/ResponsiveIframe.module.css +++ b/apps/storefront/components/ResponsiveIframe/ResponsiveIframe.module.css @@ -2,16 +2,14 @@ position: relative; overflow: hidden; width: 100%; - max-width: var(--media-max-width); - padding-top: 56.25%; - box-shadow: var(--ds-shadow-md); border-radius: 4px; margin-top: var(--ds-spacing-10); margin-bottom: var(--ds-spacing-10); + aspect-ratio: 16 / 9; } .aspectFourThree { - padding-top: 75%; + aspect-ratio: 4 / 3; } .iframe { diff --git a/apps/storefront/components/ResponsiveIframe/ResponsiveIframe.tsx b/apps/storefront/components/ResponsiveIframe/ResponsiveIframe.tsx index 508a7753fa..a51a33b68f 100644 --- a/apps/storefront/components/ResponsiveIframe/ResponsiveIframe.tsx +++ b/apps/storefront/components/ResponsiveIframe/ResponsiveIframe.tsx @@ -20,6 +20,7 @@ const ResponsiveIframe = ({ className={cl(classes.container, { [classes.aspectFourThree]: aspectRatio === '4-3', })} + data-iframe-video >