Compare commits

...
Author SHA1 Message Date
github-actions[bot]andgithub-actions[bot] 989a97a8bc Version Packages (#1880)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-29 10:53:19 +02:00
Ken 8de6ba22c3 🎨 Bedre tokens for accordion 2023-03-29 10:49:39 +02:00
Ken f664370826 🎨 Accordion tokens for header-bakgrunn 2023-03-29 10:38:19 +02:00
Ken 55b5856183 🐛 Select text-color (#1879) 2023-03-29 10:21:44 +02:00
Ken 5a72a62190 🐛 Fikset preview for komponentsider
🔥 Fjernet JSX.Element type fra gammel nextjs config
2023-03-28 10:46:37 +02:00
Ken d89eaccd44 ♻️ Refactor query-struktur og typer for /pages
♻️ refaktorert forside-setup

🏷️ Flyttet ts-typer

🚚 Inlinet Template-sider

🚚 Inlinet prinsipp-template

♻️ Refactor god-praksis sider

♻️ Refakorert typer for blogg, komponenter og grunnleggende
2023-03-27 16:56:10 +02:00
Ken 7cffc0bf12 ♿ Bruker native ol-liste da skjermleser nå feilet 2023-03-24 16:12:09 +01:00
Ken 8d4966c83f 💄 Erstattet li-element med css 2023-03-24 16:06:50 +01:00
Ken edcc4e5071 🐛 Sourcemap fungerte ikke i Aksel-icons 2023-03-24 15:43:22 +01:00
Ken a5821578a0 📝 Etterlevelse i footer 2023-03-24 15:09:00 +01:00
Ken 7ff8ce7e3b Merge branch 'next' 2023-03-24 14:20:07 +01:00
Ken fa0c07e04a 📝 Tekst på /god-praksis 2023-03-24 13:06:57 +01:00
Ken e97b31ea94 📝 Assigner issues til annen bruker 2023-03-24 12:49:15 +01:00
Ken d1549cb5ff 🔥 Fjernet redaktør fra komponent/grunnleggende highlight 2023-03-24 12:45:41 +01:00
Ken 01bcbbf1ff 🐛 Fjernet duplikat footer-lenke 2023-03-24 12:36:26 +01:00
Ken 41fd9e7b25 ♻️ Typer-refactor for blogg 2023-03-24 12:35:19 +01:00
Ken e468f9d93e ♻️ Refaktorert standalone-page 2023-03-24 11:05:39 +01:00
Ken ccd9e73446 🏷️ Egne typer for Artikler 2023-03-24 00:16:19 +01:00
Ken eb2c7ab777 🔥 Fjernet ubrukte filer 2023-03-23 23:40:31 +01:00
Ken 0ccee41b7c 🔥 Fjernet stæsj kategori fra sanity 2023-03-23 23:37:33 +01:00
Ken 865a19c681 ♻️ Rename plugins-folder 2023-03-23 23:32:12 +01:00
Ken eabad5af35 ♻️ inlinet css 2023-03-23 23:27:02 +01:00
Ken 7ab07f3f46 🐛 Fikset OL-lenker med 10+ elementer 2023-03-23 15:52:08 +01:00
Ken 5ead5f9cde 🎨 Flyttet masonary liste ut i egen func 2023-03-23 13:20:12 +01:00
Ken 1fb56a32d0 Merge branch 'main' into next 2023-03-23 13:13:52 +01:00
github-actions[bot]andgithub-actions[bot] 1609604073 Version Packages (#1876)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-23 13:04:48 +01:00
Ken f862aa9c2e 🌐 Textarea-tekster (#1875) 2023-03-23 13:01:49 +01:00
Ken c88632d92c 🎨 Justert spacing mellom blokker 2023-03-22 15:55:29 +01:00
Ken 70bf09a4d6 🔥 Fjernet toolcard 2023-03-22 15:10:20 +01:00
Ken 0cce29182b ♿ Wrappet nyeste artikler seksjon i section 2023-03-22 14:54:07 +01:00
Ken a7b619dd18 🎨 Dynamisk riktekst i expansioncard 2023-03-22 14:48:26 +01:00
Ken 945ea68414 🐛 Fikset lenker 2023-03-22 10:08:27 +01:00
Ken 9e5b5a461f 🎨 henter inn artikler fra grunnleggende også 2023-03-21 15:26:10 +01:00
Ken 66dc7e41ed 🎨 Bruker nå SEO-bilder for blogg-cards også 2023-03-21 15:11:27 +01:00
Ken 8fce648c79 🔥 Fjernet unødvendig kommentar 2023-03-21 14:36:39 +01:00
Ken f85a2bd834 ♿ Semantisk seksjonering av cards på forside 2023-03-21 14:32:10 +01:00
Ken 6812a18a34 🏗️ Query fjerner artikkel fra masonary hvis den er highlighted 2023-03-21 14:27:01 +01:00
github-actions[bot]andgithub-actions[bot] 34f421835c Version Packages (#1871)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-21 14:22:57 +01:00
Ken 9c495cf503 💄 Dynamisk typografi for Expansioncard, flere token-muligheter (#1870)
Resolves #1869
2023-03-21 14:20:30 +01:00
Ken 721a315f67 🎨 riktig plassering av toolcard 2023-03-21 13:33:38 +01:00
Ken d508423406 ✨ v1 av ny rigg for forside-blokker 2023-03-21 13:27:22 +01:00
Ken c9c8bf72e8 🎨 Card-visning med riktig tagg 2023-03-21 12:57:04 +01:00
Ken d9bb32ace0 🎨 Card-komponent for masonary 2023-03-21 11:57:21 +01:00
Ken 6082485287 🎨 Card-komponent for masonary 2023-03-21 11:56:52 +01:00
Ken 2b2b3aa819 Merge branch 'main' into next 2023-03-21 11:27:03 +01:00
Ken 5628f1c4dd 🎨 Kortet ned aksel-icons script-lengde 2023-03-21 11:12:54 +01:00
Ken b5666ed040 ⬆️ Oppdatert storybook til rc.5 (#1867) 2023-03-21 10:25:20 +01:00
Ken 72aa6325ed 🎨 Highlights støtter 2 artikler 2023-03-20 12:41:23 +01:00
Ken e1f2a46ae0 🎨 Highlighting av siste fra aksel 2023-03-20 12:14:33 +01:00
Ken 489c6678d2 Merge branch 'main' into next 2023-03-20 09:27:41 +01:00
github-actions[bot]andgithub-actions[bot] be4a951962 Version Packages (#1866)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-17 14:53:51 +01:00
Ken 1276b4d7ef 🐛 ExpansionCard hadde feil default-title size 2023-03-17 14:49:50 +01:00
Ken 8880b0dfb5 🎨 Expansioncard-modul 2023-03-17 14:37:15 +01:00
github-actions[bot]andgithub-actions[bot] bfe60a9a62 Version Packages (#1865)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-17 14:03:13 +01:00
Ken 9c70200962 Merge branch 'main' into next 2023-03-17 13:53:31 +01:00
Ken 33aef230b0 💄 Bedre grid-break i footer 2023-03-17 13:11:29 +01:00
Ken 88243f76de 💄 God-praksis header aligner med tema-liste på forside 2023-03-17 12:09:19 +01:00
Ken c00112e3e6 ♿ Accessible ExpansionCard-icon 2023-03-17 11:59:24 +01:00
Ken 3c66b00c24 ♻️ Refaktorert ExpansionCard før release
💄 Mer spacing-bottom for content i small expansioncard

🔥 Fjernet clickarea-prop

🔥 Fjernet avatar-prop

💄 Header-title margin

💄 Chevron-alignment til toppen

📝 Fikset nextjs demoer
2023-03-17 11:49:17 +01:00
Ken db8303af42 📝 Justert beta-tekster 2023-03-17 10:07:55 +01:00
Ken 5fbd2e1814 🎨 Kan nå tagge beta som unsafe 2023-03-17 09:46:41 +01:00
Ken c1360da7d7 🎨 Oppdatert queries og lagt til masonary 2023-03-17 08:59:23 +01:00
Ken de2a3990dc 🔥 Fjernet forside-variant av latestbloggposts 2023-03-16 23:23:43 +01:00
Ken 46433118b2 🔥 Fjernet forside-variant av latestbloggposts 2023-03-16 23:23:04 +01:00
Ken de861e469c Merge branch 'main' into next 2023-03-16 23:20:26 +01:00
Ken 85697be305 🐛 Fikset demo-bug for expansioncard 2023-03-16 21:03:22 +01:00
Ken ae64920a34 Merge branch 'main' into next 2023-03-16 20:47:24 +01:00
Ken 36fb35533d ♻️ Bedre ikoner for expansioncard 2023-03-16 20:45:14 +01:00
Ken 3709e432bb 📝 Oppdatert ExpansionCard til å bruke bare section-element 2023-03-16 16:12:43 +01:00
Ken c6077a03fa 🎨 Suggestion-lenker åpnes nå i ny fane 2023-03-16 15:42:02 +01:00
Ken c6d51a0190 [Ny komponent] ExpansionCard (#1820) 2023-03-16 15:40:30 +01:00
github-actions[bot]andgithub-actions[bot] 777d94b3d4 Version Packages (#1864)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-16 15:03:50 +01:00
Vegard Haugstvedt 7ace69f215 Bugfix/missing focus indicator for tabpanel (#1863)
* Add focus-visible for tabpanel

* Set focus-indicator width to 2px instead of 3px. This is a change that will probably be applied throughout the design system in time.

* New version for DS-CSS adding focus indicator to tabpanels
2023-03-16 14:53:49 +01:00
Ken 6724bb8f71 💄 Fikset header-logo farge 2023-03-16 10:24:40 +01:00
Ken 59253e992f 📝 Datepicker description 2023-03-16 09:59:32 +01:00
Ken 91b6e0be18 🔥 Fjernet ekstra console.log 2023-03-16 09:12:53 +01:00
Ken 02f5c29723 Oppdatert forside, footer (#1858) 2023-03-15 14:24:56 +01:00
Ken 2221b2e01d 💄 Dodont wrapping fikset 2023-03-15 12:13:42 +01:00
Ken b31b1b3533 💄 Inlinet blogg-cards 2023-03-14 14:58:52 +01:00
Ken ff8bcb870e 💄 Bedre alignment av blogg-bilder 2023-03-14 14:47:23 +01:00
Ken 0a7e6311de 📝 Justert search-button, tekster 2023-03-14 14:26:04 +01:00
Ken 961d97ef0d 📝 Justert tekster på feedback i sanity 2023-03-14 14:05:39 +01:00
Ken f2477e772d 🎨 Logging av footer-lenker 2023-03-14 13:56:30 +01:00
Ken bad960be56 🎨 Oppdatert Footer til ny variant 2023-03-14 13:53:13 +01:00
Ken c53e3a050b 💄 Fjernet maksbredde på intro-cards for komponentside 2023-03-14 13:09:59 +01:00
Ken d9e40b71b1 💄 Justert bloggvisning og cards på forside 2023-03-14 13:06:35 +01:00
Ken c1828f992f 🎉 Next router fungerer nå i storybook 2023-03-14 11:39:23 +01:00
Ken 522bb95ddb 🐛 Footer story funker ikke i storybook 2023-03-14 10:15:31 +01:00
Ken 7ab690d210 Merge branch 'main' into next 2023-03-14 10:11:56 +01:00
Ken 859d5d6407 🐛 Pageheader-story manglet default export 2023-03-14 10:11:42 +01:00
Ken de741ce8a8 🎨 Footer story 2023-03-14 10:10:15 +01:00
Ken 918d21c3ba 🎨 Fikset kom i gang med kode lenke 2023-03-14 10:08:03 +01:00
Ken 121a678fa0 💄 Justert farger på headings fra 800 -> 700 2023-03-14 09:42:58 +01:00
Ken 576790a2ff 💄 Justert maksbredder 2023-03-14 09:36:22 +01:00
Ken 6609631f46 Merge branch 'main' into next 2023-03-14 09:28:50 +01:00
Ken 7c37e3af56 🔍 Gjemmer dev fra SEO 2023-03-13 16:54:32 +01:00
Ken 9703f082f1 🔍 Gjemmer dev fra SEO 2023-03-13 16:53:09 +01:00
Ken 18005f89a2 🔥 Fjernet ubrukt sanity-kode for ny forside 2023-03-13 16:34:35 +01:00
Ken 8a4321ebd3 🐛 Artikkelcard mistet padding på desktop 2023-03-13 16:31:27 +01:00
Ken 28938dd4a6 ⚡ Filterer ut WIP-tema 2023-03-13 16:29:00 +01:00
Ken bb3a431e2a 💄 mobiltilpasset cards 2023-03-13 16:24:19 +01:00
Ken 00e787a400 💄 Tekst-størrelser 2023-03-13 16:12:09 +01:00
Ken 04215daf7e 🎨 Ny visning for god-praksis lenker 2023-03-13 16:04:37 +01:00
Ken 2c722e3a7d 💄 Justert spacing forside-blokker 2023-03-13 15:58:00 +01:00
Ken 8d511c90f1 🎨 Nye forsidelenker god praksis 2023-03-13 15:53:33 +01:00
Ken 8be270c8c5 💄 Oppdatert visning av intro-lenker 2023-03-13 15:31:42 +01:00
Ken 426f4d54a1 🔥 Linter 2023-03-13 14:12:55 +01:00
Ken 8ff68266c8 🎨 Lenker på komponentside 2023-03-13 14:11:44 +01:00
189 changed files with 5250 additions and 3261 deletions

No files matched your search

+1 -1
View File
@@ -3,7 +3,7 @@ description: Send et ønske om en eller flere nye komponenter
title: "[Ny komponent]: "
labels: ["nytt ✨", "forespørsel 🥰", "komponenter 🧩"]
assignees:
- olejorgenbakken
- KenAJoh
body:
- type: markdown
attributes:
+1 -1
View File
@@ -3,7 +3,7 @@ description: Send et ønske om et eller flere nye ikoner
title: "[Nytt ikon]: "
labels: ["nytt ✨", "ikoner 🖼", "forespørsel 🥰"]
assignees:
- olejorgenbakken
- KenAJoh
body:
- type: markdown
attributes:
+1 -1
View File
@@ -3,7 +3,7 @@ description: Send inn innspill til komponent
title: "[Innspill til komponent]: "
labels: ["forespørsel 🥰", "komponenter 🧩", "nytt ✨", "beta 🧪"]
assignees:
- olejorgenbakken
- KenAJoh
body:
- type: markdown
attributes:
+1 -1
View File
@@ -3,7 +3,7 @@ description: Send inn innspill til ikon
title: "[Tilbakemelding på ikon]: "
labels: ["forespørsel 🥰", "ikoner 🖼️"]
assignees:
- olejorgenbakken
- KenAJoh
body:
- type: markdown
attributes:
+4
View File
@@ -54,6 +54,10 @@ jobs:
echo "SANITY_PRIVATE_NO_DRAFTS=${{ secrets.SANITY_PRIVATE_NO_DRAFTS }}" >> aksel.nav.no/website/.env
echo "USE_CDN_ASSETS=true" >> aksel.nav.no/website/.env
- name: Hide page from search engines
run: |
echo "User-agent: *\nDisallow: /" > aksel.nav.no/website/public/robots.txt
- name: Restore cache
uses: actions/cache@v3
with:
+25
View File
@@ -23,6 +23,8 @@ module.exports = {
addons: [
"@storybook/addon-a11y",
"@whitespace/storybook-addon-html",
"storybook-addon-next-router",
{
name: "@storybook/addon-storysource",
options: {
@@ -74,8 +76,31 @@ module.exports = {
"../aksel.nav.no/website/components"
),
},
{
find: "@utils",
replacement: path.resolve(
__dirname,
"../aksel.nav.no/website/components/website-modules/utils/index.ts"
),
},
{
find: "@lib",
replacement: path.resolve(
__dirname,
"../aksel.nav.no/website/lib/index.ts"
),
},
],
},
});
},
};
/* "@/components": ["components/index.ts"],
"@/lib": ["lib/index.ts"],
"@/pages/*": ["pages/*"],
"@/sanity-block": ["components/SanityBlockContent.tsx"],
"@/utils": ["components/website-modules/utils/index.ts"],
"@/layout": ["components/layout/index.ts"],
"@/error-boundary": ["components/website-modules/ErrorBoundary.tsx"],
"@/sanity-client": ["lib/sanity/sanity.server"] */
+4
View File
@@ -1,3 +1,4 @@
import { RouterContext } from "next/dist/shared/lib/router-context";
import "@navikt/ds-css/index.css";
import "@navikt/ds-css-internal/index.css";
import "./layout.css";
@@ -23,6 +24,9 @@ export const parameters = {
},
],
},
nextRouter: {
Provider: RouterContext.Provider,
},
};
export const globalTypes = {
+18
View File
@@ -1,5 +1,23 @@
# @navikt/aksel-icons
## 2.8.5
## 2.8.4
### Patch Changes
- Fikset Sourcemap-bug i Aksel-icons
## 2.8.3
## 2.8.2
## 2.8.1
## 2.8.0
## 2.7.8
## 2.7.7
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-icons",
"version": "2.7.7",
"version": "2.8.5",
"author": "Aksel | NAV",
"homepage": "https://aksel.nav.no/ikoner",
"repository": {
@@ -53,9 +53,9 @@
"create-icons": "svgr --silent --index-template config/index-template.js --out-dir src icons",
"copy-util": "copyfiles util/* src",
"copy-svg": "copyfiles -f icons/*.svg dist/svg/",
"copy": "yarn copy-util && yarn copy-svg",
"update-metadata": "node config/metadata.js",
"build": "yarn copy-util && yarn copy-svg && yarn create-icons && concurrently \"tsc\" \"tsc -p tsconfig.esm.json\" && node config/cleanTypes.js && yarn update-metadata",
"build:old": "copyfiles util/* src && yarn create-icons && concurrently \"tsc\" \"tsc -p tsconfig.esm.json\" && node cleanTypes.js && yarn create-package-json-pointers-to-esm",
"build": "yarn copy && yarn create-icons && concurrently \"tsc\" \"tsc -p tsconfig.esm.json\" && node config/cleanTypes.js && yarn update-metadata",
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
"fetch-new:icons": "node config/figma/index.mjs",
"zip:icons": "node config/zip.js"
+1 -1
View File
@@ -3,7 +3,7 @@
"compilerOptions": {
"outDir": "./dist/react/esm",
"module": "esnext",
"sourceMap": true,
"sourceMap": false,
"declaration": true
}
}
+14
View File
@@ -1,5 +1,19 @@
# @navikt/ds-codemod
## 2.8.5
## 2.8.4
## 2.8.3
## 2.8.2
## 2.8.1
## 2.8.0
## 2.7.8
## 2.7.7
## 2.7.6
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-codemod",
"version": "2.7.7",
"version": "2.8.5",
"description": "Aksel codemods for NAVs designsystem",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
+2 -2
View File
@@ -39,8 +39,8 @@
"build-pict": "svgr --silent --index-template index-template.js --out-dir src/pictograms pictograms"
},
"dependencies": {
"@navikt/ds-icons": "^2.7.7",
"@navikt/ds-react": "^2.7.7",
"@navikt/ds-icons": "^2.8.5",
"@navikt/ds-react": "^2.8.5",
"clsx": "^1.1.1"
},
"devDependencies": {
@@ -1,4 +1,3 @@
/* import React from "react";
import { PageHeader } from ".";
export default {
@@ -14,11 +13,3 @@ export default {
},
},
};
export const Default = {
render: (props) => <PageHeader>{props.children}</PageHeader>,
args: {
children: "Id elit esse enim reprehenderit enim nisi veniam nostrud.",
},
}; */
+32
View File
@@ -1,5 +1,37 @@
# @navikt/ds-css
## 2.8.5
### Patch Changes
- [`f66437082`](https://github.com/navikt/aksel/commit/f664370826ed51bda7ad681e1f1799c26d2c1f0a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :art: Accordion-tokens for header bakgrunn
- [#1879](https://github.com/navikt/aksel/pull/1879) [`55b585618`](https://github.com/navikt/aksel/commit/55b585618341a4d8bf26ed9b9e129d897b1600dc) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset tekstfarge i select på iphone
## 2.8.4
## 2.8.3
## 2.8.2
### Patch Changes
- [#1870](https://github.com/navikt/aksel/pull/1870) [`9c495cf50`](https://github.com/navikt/aksel/commit/9c495cf5037a7453e51e273ab93e4232576f4958) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert typografi for ExpansioCard
## 2.8.1
## 2.8.0
### Minor Changes
- [#1820](https://github.com/navikt/aksel/pull/1820) [`c6d51a019`](https://github.com/navikt/aksel/commit/c6d51a01902e4fd7916a422e17ed175f39acd458) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Ny komponent! ExpansionCard. Oppfølger fra gammel Ekspanderbartpanel.
## 2.7.8
### Patch Changes
- [#1863](https://github.com/navikt/aksel/pull/1863) [`7ace69f21`](https://github.com/navikt/aksel/commit/7ace69f215760bbb5bf997670c897403d8ee558d) Thanks [@it-vegard](https://github.com/it-vegard)! - Added focus indicator for tabpanel
## 2.7.7
## 2.7.6
+7 -2
View File
@@ -11,7 +11,7 @@
padding: 14px var(--a-spacing-3) var(--a-spacing-3);
margin: 0;
text-align: left;
background: transparent;
background: var(--ac-accordion-header-bg, var(--a-surface-transparent));
cursor: pointer;
border: none;
border-bottom: 2px solid var(--ac-accordion-header-border, var(--a-border-divider));
@@ -25,6 +25,7 @@
.navds-accordion__header:hover {
color: var(--ac-accordion-header-text-hover, var(--a-text-action-on-action-subtle));
border-color: var(--ac-accordion-header-border-hover, var(--a-border-default));
background: var(--ac-accordion-header-bg-hover, var(--a-surface-transparent));
}
.navds-accordion__header-content {
@@ -33,10 +34,14 @@
}
.navds-accordion__item--open > .navds-accordion__header {
background-color: var(--ac-accordion-item-bg-open, var(--a-surface-action-subtle));
background-color: var(--ac-accordion-header-bg-open, var(--ac-accordion-item-bg-open, var(--a-surface-action-subtle)));
border-color: var(--ac-accordion-item-border-open, var(--a-surface-action-subtle));
}
.navds-accordion__item--open > :where(.navds-accordion__header:hover) {
background-color: var(--ac-accordion-header-bg-open-hover, var(--a-surface-action-subtle));
}
.navds-accordion__content {
padding: var(--a-spacing-3) var(--a-spacing-3) 18px;
border-bottom: 2px solid var(--ac-accordion-content-border, var(--a-border-divider));
+194
View File
@@ -0,0 +1,194 @@
.navds-expansioncard {
--__ac-expansioncard-border-color: var(--ac-expansioncard-border-color, var(--a-border-default));
--__ac-expansioncard-border-radius: var(--ac-expansioncard-border-radius, var(--a-border-radius-large));
--__ac-expansioncard-border-width: 1px;
border-radius: var(--__ac-expansioncard-border-radius);
background-color: var(--ac-expansioncard-bg, var(--a-surface-default));
height: fit-content;
}
.navds-expansioncard--open {
--__ac-expansioncard-border-color: var(
--ac-expansioncard-border-open-color,
var(--ac-expansioncard-border-color, var(--a-border-default))
);
}
.navds-expansioncard:hover {
--__ac-expansioncard-border-color: var(--ac-expansioncard-border-hover-color, var(--a-border-strong));
}
:where(.navds-expansioncard.navds-expansioncard--open):hover {
--__ac-expansioncard-border-color: var(--ac-expansioncard-border-hover-color, var(--a-border-strong));
}
/*************************
* Header *
*************************/
.navds-expansioncard__header {
width: 100%;
display: flex;
gap: var(--a-spacing-4);
padding: var(--a-spacing-4) var(--a-spacing-6);
border-radius: var(--__ac-expansioncard-border-radius);
background-color: var(--ac-expansioncard-header-bg, var(--a-surface-transparent));
position: relative;
border: var(--__ac-expansioncard-border-width) solid var(--__ac-expansioncard-border-color);
justify-content: space-between;
}
.navds-expansioncard--small > :where(.navds-expansioncard__header) {
padding: var(--a-spacing-3) var(--a-spacing-4);
}
.navds-expansioncard__header:hover {
background-color: var(--ac-expansioncard-header-bg-hover, var(--a-surface-hover));
box-shadow: 0 0 0 1px var(--__ac-expansioncard-border-color);
}
.navds-expansioncard--open > :where(.navds-expansioncard__header) {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
border: var(--__ac-expansioncard-border-width) solid var(--__ac-expansioncard-border-color);
border-bottom: none;
background-color: var(--ac-expansioncard-header-open-bg, var(--a-surface-transparent));
}
.navds-expansioncard--open > :where(.navds-expansioncard__header):hover {
background-color: var(--ac-expansioncard-header-bg-hover, var(--a-surface-hover));
box-shadow: 1px 0 0 0 var(--__ac-expansioncard-border-color), -1px 0 0 0 var(--__ac-expansioncard-border-color),
0 -1px 0 0 var(--__ac-expansioncard-border-color);
}
/*************************
* Header/Typography *
*************************/
.navds-expansioncard__title--small {
margin-top: 10px;
}
.navds-expansioncard__title--medium {
margin-top: var(--a-spacing-2);
}
.navds-expansioncard__title--large {
margin-top: var(--a-spacing-1);
}
.navds-expansioncard--small :where(.navds-expansioncard__title--small) {
margin-top: var(--a-spacing-05);
}
.navds-expansioncard--small :where(.navds-expansioncard__title--medium, .navds-expansioncard__title--large) {
margin-top: 0;
}
/*************************
* Header/Button *
*************************/
.navds-expansioncard__header-button {
display: grid;
place-content: center;
cursor: pointer;
margin: 0;
background: transparent;
border: none;
border-radius: var(--ac-expansioncard-button-border-radius, var(--a-border-radius-medium));
min-height: 3rem;
min-width: 3rem;
font-size: 1.5rem;
align-self: flex-start;
}
.navds-expansioncard--small > :where(.navds-expansioncard__header) > :where(.navds-expansioncard__header-button) {
min-height: 2rem;
min-width: 2rem;
}
:where(.navds-expansioncard__header):hover > :where(.navds-expansioncard__header-button) {
background-color: var(--a-surface-hover);
}
.navds-expansioncard__header-chevron {
transition: transform 150ms ease-in-out;
}
.navds-expansioncard--open :where(.navds-expansioncard__header-chevron) {
transform: translateY(0) rotate(180deg);
}
.navds-expansioncard__header-button:hover > :where(.navds-expansioncard__header-chevron) {
transform: translateY(1px);
}
.navds-expansioncard__header-button:focus {
outline: none;
}
.navds-expansioncard__header-button:focus-visible {
box-shadow: var(--a-shadow-focus);
}
.navds-expansioncard--open :where(.navds-expansioncard__header-button):hover :where(.navds-expansioncard__header-chevron) {
transform: translateY(-1px) rotate(180deg);
}
.navds-expansioncard__header-button::after {
inset: 0;
z-index: 1;
position: absolute;
content: "";
height: 100%;
width: 100%;
cursor: pointer;
}
/*************************
* Content *
*************************/
.navds-expansioncard__content {
border-end-end-radius: var(--__ac-expansioncard-border-radius);
border-end-start-radius: var(--__ac-expansioncard-border-radius);
padding: var(--a-spacing-3) var(--a-spacing-6) var(--a-spacing-6);
border: var(--__ac-expansioncard-border-width) solid var(--__ac-expansioncard-border-color);
border-top: none;
}
.navds-expansioncard--small > :where(.navds-expansioncard__content) {
padding: var(--a-spacing-3) var(--a-spacing-4) var(--a-spacing-4);
}
.navds-expansioncard__content--closed {
display: none;
}
:where(.navds-expansioncard__header):hover + .navds-expansioncard__content {
box-shadow: 1px 0 0 0 var(--__ac-expansioncard-border-color), -1px 0 0 0 var(--__ac-expansioncard-border-color),
0 1px 0 0 var(--__ac-expansioncard-border-color);
}
.navds-expansioncard__content-inner {
animation: fadeExpansionCard 250ms ease;
}
.navds-expansioncard--no-fade :where(.navds-expansioncard__content-inner) {
animation: none;
}
@keyframes fadeExpansionCard {
0% {
opacity: 0;
transform: translateY(-8px);
}
40% {
opacity: 0.7;
}
100% {
opacity: 1;
transform: translateY(0);
}
}
+1
View File
@@ -3,6 +3,7 @@
background-color: var(--ac-select-bg, var(--a-surface-default));
border-radius: var(--a-border-radius-medium);
border: 1px solid var(--ac-select-border, var(--a-border-default));
color: var(--ac-select-text, var(--a-text-default));
width: 100%;
box-sizing: border-box;
min-height: 48px;
+1
View File
@@ -8,6 +8,7 @@
@import "content-container.css";
@import "chat.css";
@import "chips.css";
@import "expansioncard.css";
@import "guide-panel.css";
@import "form/index.css";
@import "help-text.css";
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "2.7.7",
"version": "2.8.5",
"description": "CSS for NAV Designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -20,7 +20,7 @@
"watch": "postcss --watch --use postcss-import -o dist/index.css index.css"
},
"devDependencies": {
"@navikt/ds-tokens": "^2.7.7",
"@navikt/ds-tokens": "^2.8.5",
"normalize.css": "^8.0.1",
"postcss": "^8.4.0",
"postcss-cli": "^9.0.0",
+2 -1
View File
@@ -108,6 +108,7 @@
font-size: 1.5rem;
}
.navds-tabs__tabpanel:focus {
.navds-tabs__tabpanel:focus-visible {
outline: none;
box-shadow: inset 0 0 0 2px var(--a-border-focus);
}
+16
View File
@@ -10,10 +10,14 @@
"--ac-alert-success-bg": "--a-surface-success-subtle"
},
"accordion": {
"--ac-accordion-header-bg": "--ac-surface-transparent",
"--ac-accordion-header-bg-hover": "--ac-surface-transparent",
"--ac-accordion-header-border": "--a-border-divider",
"--ac-accordion-header-text-hover": "--a-text-action-on-action-subtle",
"--ac-accordion-header-border-hover": "--a-border-default",
"--ac-accordion-item-bg-open": "--a-surface-action-subtle",
"--ac-accordion-header-bg-open": "--ac-accordion-item-bg-open",
"--ac-accordion-header-bg-open-hover": "--a-surface-action-subtle",
"--ac-accordion-item-border-open": "--a-surface-action-subtle",
"--ac-accordion-content-border": "--a-border-divider",
"--ac-accordion-content-border-open": "--a-border-default"
@@ -106,6 +110,17 @@
"--ac-date-input-error-border": "--a-border-danger",
"--ac-date-input-button-text": "--a-text-default"
},
"expansioncard": {
"--ac-expansioncard-bg": "--a-surface-default",
"--ac-expansioncard-header-bg": "--a-surface-transparent",
"--ac-expansioncard-header-bg-hover": "--a-surface-hover",
"--ac-expansioncard-header-open-bg": "--a-surface-transparent",
"--ac-expansioncard-border-color": "--a-border-default",
"--ac-expansioncard-border-open-color": "--a-border-default",
"--ac-expansioncard-border-radius": "--a-border-radius-large",
"--ac-expansioncard-button-border-radius": "--a-border-radius-medium",
"--ac-expansioncard-border-hover-color": "--a-border-strong"
},
"guidepanel": {
"--ac-guide-panel-bg": "--a-surface-default",
"--ac-guide-panel-border": "--a-border-action",
@@ -301,6 +316,7 @@
},
"select": {
"--ac-select-bg": "--a-surface-default",
"--ac-select-text": "--a-text-default",
"--ac-select-border": "--a-border-default",
"--ac-select-hover-bg": "--a-border-action",
"--ac-select-error-border": "--a-surface-danger"
+65
View File
@@ -1,5 +1,70 @@
# @navikt/ds-react
## 2.8.5
### Patch Changes
- Updated dependencies []:
- @navikt/aksel-icons@2.8.5
- @navikt/ds-icons@2.8.5
## 2.8.4
### Patch Changes
- Updated dependencies []:
- @navikt/aksel-icons@2.8.4
- @navikt/ds-icons@2.8.4
## 2.8.3
### Patch Changes
- [#1875](https://github.com/navikt/aksel/pull/1875) [`f862aa9c2`](https://github.com/navikt/aksel/commit/f862aa9c2ec71ffdb295708dc6dad6b77af9519e) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Textarea har oppdatert counter-tekst + mulighet for lokalisering
- Updated dependencies []:
- @navikt/aksel-icons@2.8.3
- @navikt/ds-icons@2.8.3
## 2.8.2
### Patch Changes
- [#1870](https://github.com/navikt/aksel/pull/1870) [`9c495cf50`](https://github.com/navikt/aksel/commit/9c495cf5037a7453e51e273ab93e4232576f4958) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert typografi for ExpansioCard
- Updated dependencies []:
- @navikt/aksel-icons@2.8.2
- @navikt/ds-icons@2.8.2
## 2.8.1
### Patch Changes
- [`1276b4d7e`](https://github.com/navikt/aksel/commit/1276b4d7efd831d20345292dbb21a11d100a0ddd) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Endret default title-size til medium for ExpansionCard
- Updated dependencies []:
- @navikt/aksel-icons@2.8.1
- @navikt/ds-icons@2.8.1
## 2.8.0
### Minor Changes
- [#1820](https://github.com/navikt/aksel/pull/1820) [`c6d51a019`](https://github.com/navikt/aksel/commit/c6d51a01902e4fd7916a422e17ed175f39acd458) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Ny komponent! ExpansionCard. Oppfølger fra gammel Ekspanderbartpanel.
### Patch Changes
- Updated dependencies []:
- @navikt/aksel-icons@2.8.0
- @navikt/ds-icons@2.8.0
## 2.7.8
### Patch Changes
- Updated dependencies []:
- @navikt/ds-icons@2.7.8
## 2.7.7
### Patch Changes
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "2.7.7",
"version": "2.8.5",
"description": "Aksel react-components for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -37,7 +37,8 @@
},
"dependencies": {
"@floating-ui/react": "0.17.0",
"@navikt/ds-icons": "^2.7.7",
"@navikt/aksel-icons": "^2.8.5",
"@navikt/ds-icons": "^2.8.5",
"@radix-ui/react-tabs": "1.0.0",
"@radix-ui/react-toggle-group": "1.0.0",
"clsx": "^1.2.1",
@@ -0,0 +1,121 @@
import cl from "clsx";
import React, { createContext, forwardRef, useRef, useState } from "react";
import ExpansionCardContent, {
ExpansionCardContentType,
} from "./ExpansionCardContent";
import {
ExpansionCardDescription,
ExpansionCardDescriptionType,
} from "./ExpansionCardDescription";
import ExpansionCardHeader, {
ExpansionCardHeaderType,
} from "./ExpansionCardHeader";
import {
ExpansionCardTitle,
ExpansionCardTitleType,
} from "./ExpansionCardTitle";
interface ExpansionCardComponent
extends React.ForwardRefExoticComponent<
ExpansionCardProps & React.RefAttributes<HTMLDivElement>
> {
Header: ExpansionCardHeaderType;
Title: ExpansionCardTitleType;
Description: ExpansionCardDescriptionType;
Content: ExpansionCardContentType;
}
export interface ExpansionCardProps
extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
/**
* Callback for when Card is toggled open/closed
*/
onToggle?: (open: boolean) => void;
/**
* Controlled open-state
* Using this removes automatic control of open-state
*/
open?: boolean;
/**
* Defaults to open if not controlled
* @default false
*/
defaultOpen?: boolean;
/**
* @default "medium"
*/
size?: "medium" | "small";
/**
* Since ExpansionCard is a section-element, accessible name is required.
*/
["aria-label"]: string;
}
export type ExpansionCardContextProps = {
open: boolean;
toggleOpen: () => void;
size: "medium" | "small";
};
export const ExpansionCardContext = createContext<ExpansionCardContextProps>({
open: false,
toggleOpen: () => {},
size: "medium",
});
export const ExpansionCard = forwardRef<HTMLDivElement, ExpansionCardProps>(
(
{
className,
onToggle,
open,
defaultOpen = false,
size = "medium",
...rest
},
ref
) => {
const [_open, _setOpen] = useState(defaultOpen);
const shouldFade = useRef<boolean>(!(Boolean(open) || defaultOpen));
const handleOpen = () => {
if (open === undefined) {
const newOpen = !_open;
_setOpen(newOpen);
onToggle?.(newOpen);
} else {
onToggle?.(!open);
}
shouldFade.current = true;
};
return (
<ExpansionCardContext.Provider
value={{ open: open ?? _open, toggleOpen: handleOpen, size }}
>
<section
{...rest}
className={cl(
"navds-expansioncard",
className,
`navds-expansioncard--${size}`,
{
"navds-expansioncard--open": open ?? _open,
"navds-expansioncard--no-fade": !shouldFade.current,
}
)}
ref={ref}
/>
</ExpansionCardContext.Provider>
);
}
) as ExpansionCardComponent;
ExpansionCard.Header = ExpansionCardHeader;
ExpansionCard.Content = ExpansionCardContent;
ExpansionCard.Title = ExpansionCardTitle;
ExpansionCard.Description = ExpansionCardDescription;
export default ExpansionCard;
@@ -0,0 +1,43 @@
import cl from "clsx";
import React, { forwardRef, useContext } from "react";
import { BodyLong } from "../typography/BodyLong";
import { ExpansionCardContext } from "./ExpansionCard";
export interface ExpansionCardContentProps
extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
export type ExpansionCardContentType = React.ForwardRefExoticComponent<
ExpansionCardContentProps & React.RefAttributes<HTMLDivElement>
>;
const ExpansionCardContent: ExpansionCardContentType = forwardRef(
({ children, className, ...rest }, ref) => {
const panelContext = useContext(ExpansionCardContext);
if (panelContext === null) {
console.error(
"<ExpansionCard.Content> has to be used within an <ExpansionCard>"
);
return null;
}
return (
<BodyLong
{...rest}
ref={ref}
as="div"
className={cl("navds-expansioncard__content", {
"navds-expansioncard__content--closed": !panelContext.open,
})}
aria-hidden={!panelContext.open}
size={panelContext.size}
>
<div className="navds-expansioncard__content-inner">{children}</div>
</BodyLong>
);
}
);
export default ExpansionCardContent;
@@ -0,0 +1,35 @@
import React, { forwardRef, useContext } from "react";
import cl from "clsx";
import { BodyLong } from "../typography/BodyLong";
import { ExpansionCardContext } from "./ExpansionCard";
interface ExpansionCardDescriptionProps
extends React.HTMLAttributes<HTMLParagraphElement> {
children: React.ReactNode;
}
export type ExpansionCardDescriptionType = React.ForwardRefExoticComponent<
ExpansionCardDescriptionProps & React.RefAttributes<HTMLParagraphElement>
>;
export const ExpansionCardDescription: ExpansionCardDescriptionType =
forwardRef(({ className, ...rest }, ref) => {
const panelContext = useContext(ExpansionCardContext);
if (panelContext === null) {
console.error(
"<ExpansionCard.Header> has to be used within an <ExpansionCard>"
);
return null;
}
return (
<BodyLong
{...rest}
as="p"
ref={ref}
className={cl("navds-link-panel__description", className)}
size={panelContext.size}
/>
);
});
@@ -0,0 +1,50 @@
import cl from "clsx";
import React, { forwardRef, useContext } from "react";
import { ExpansionCardContext } from "./ExpansionCard";
import { ChevronDownIcon } from "@navikt/aksel-icons";
export interface ExpansionCardHeaderProps
extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
export type ExpansionCardHeaderType = React.ForwardRefExoticComponent<
ExpansionCardHeaderProps & React.RefAttributes<HTMLDivElement>
>;
const ExpansionCardHeader: ExpansionCardHeaderType = forwardRef(
({ children, className, ...rest }, ref) => {
const panelContext = useContext(ExpansionCardContext);
if (panelContext === null) {
console.error(
"<ExpansionCard.Header> has to be used within an <ExpansionCard>"
);
return null;
}
return (
<div
ref={ref}
{...rest}
className={cl("navds-expansioncard__header", className)}
>
<div className="navds-expansioncard__header-content">{children}</div>
<button
className="navds-expansioncard__header-button"
onClick={() => panelContext.toggleOpen()}
type="button"
aria-expanded={panelContext.open}
>
<ChevronDownIcon
className="navds-expansioncard__header-chevron"
title="Vis mer"
/>
</button>
</div>
);
}
);
export default ExpansionCardHeader;
@@ -0,0 +1,34 @@
import React, { forwardRef } from "react";
import cl from "clsx";
import { OverridableComponent } from "../util/OverridableComponent";
interface ExpansionCardTitleProps
extends React.HTMLAttributes<HTMLHeadingElement> {
children: React.ReactNode;
/**
* Changes text-sizing
* @default medium
*/
size?: "large" | "medium" | "small";
}
export type ExpansionCardTitleType = OverridableComponent<
ExpansionCardTitleProps,
HTMLHeadingElement
>;
export const ExpansionCardTitle: ExpansionCardTitleType = forwardRef(
({ className, as: Component = "h3", size = "medium", ...rest }, ref) => (
<Component
{...rest}
ref={ref}
className={cl(
"navds-expansioncard__title",
`navds-expansioncard__title--${size}`,
"navds-heading",
`navds-heading--${size}`,
className
)}
/>
)
);
@@ -0,0 +1,269 @@
import { PlantIcon } from "@navikt/aksel-icons";
import React, { useState } from "react";
import { ExpansionCard } from ".";
import { BodyLong } from "../typography";
import ExpansionCardContent from "./ExpansionCardContent";
import ExpansionCardHeader from "./ExpansionCardHeader";
export default {
title: "ds-react/ExpansionCard",
component: ExpansionCard,
subcomponents: [ExpansionCardHeader, ExpansionCardContent],
decorators: [
(Story) => (
<div
style={{
width: "600px",
minHeight: "100vh",
padding: "10rem 0",
display: "flex",
flexDirection: "column",
gap: "1rem",
}}
>
<Story />
</div>
),
],
};
const Content = () => (
<ExpansionCard.Content>
<BodyLong spacing>
På ditt faste arbeidssted vil du ha yrkesskadedekning også i hvilepauser,
lunsjpauser, trimaktiviteter og lignende i arbeidstiden.
</BodyLong>
<BodyLong spacing>
Som hovedregel er du som arbeidstaker ikke yrkesskadedekket på veien til
og fra arbeid eller første og siste oppdragssted. Du er heller ikke
yrkesskadedekket på fritiden eller under private gjøremål i arbeidstiden.
</BodyLong>
<BodyLong spacing>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Fuga suscipit
voluptatum expedita earum id, aperiam deleniti molestiae eveniet
doloremque explicabo perspiciatis quasi repellendus! Est dolore a nemo
aspernatur obcaecati dicta.
</BodyLong>
<BodyLong spacing>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Fuga suscipit
voluptatum expedita earum id, aperiam deleniti molestiae eveniet
doloremque explicabo perspiciatis quasi repellendus! Est dolore a nemo
aspernatur obcaecati dicta.
</BodyLong>
<BodyLong>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Fuga suscipit
voluptatum expedita earum id, aperiam deleniti molestiae eveniet
doloremque explicabo perspiciatis quasi repellendus! Est dolore a nemo
aspernatur obcaecati dicta.
</BodyLong>
</ExpansionCard.Content>
);
export const Default = {
render: (props) => {
return (
<ExpansionCard
{...props}
open={props?.open || undefined}
size={props.size}
aria-label="default-demo"
>
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
{props.description && (
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav
til tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
)}
</ExpansionCard.Header>
<Content />
</ExpansionCard>
);
},
args: {
open: false,
size: "medium",
description: false,
variant: "neutral",
},
argTypes: {
size: { control: "select", options: ["medium", "small"] },
},
};
export const Description = {
render: () => (
<ExpansionCard aria-label="bare description">
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav til
tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
),
};
export const Sizes = {
render: () => (
<>
<h2>Medium</h2>
<ExpansionCard aria-label="Demo med description">
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav
til tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
<ExpansionCard aria-label="Demo">
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
<h2>Small</h2>
<ExpansionCard size="small" aria-label="small-demo">
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav
til tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
<ExpansionCard
size="small"
aria-label="small-demo med avatar uten description"
>
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
</>
),
};
export const HeadingSizing = {
render: () => (
<>
{(["large", "medium", "small"] as const).map((x) => (
<ExpansionCard aria-label={`demo-${x}`}>
<ExpansionCard.Header key={x}>
<ExpansionCard.Title size={x}>{x}</ExpansionCard.Title>
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav
til tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
))}
</>
),
};
export const DefaultOpen = {
render: () => (
<ExpansionCard defaultOpen aria-label="defaultOpen demo">
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav til
tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
),
};
export const ControlledState = {
render: () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [open, setOpen] = useState(false);
return (
<ExpansionCard
open={open}
onToggle={setOpen}
aria-label="Controlled-state demo"
>
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav
til tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
);
},
};
export const Customization = {
render: () => (
<div className="subtle-card">
<ExpansionCard aria-label="custom-styling demo">
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav
til tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
<style>{`
.subtle-card {
--ac-expansioncard-bg: var(--a-surface-subtle);
--ac-expansioncard-border-open-color: var(--a-border-alt-3);
}`}</style>
</div>
),
};
export const Icon = {
render: () => (
<div>
<ExpansionCard aria-label="custom-styling demo">
<ExpansionCard.Header>
<div className="with-icon">
<div className="icon">
<PlantIcon aria-hidden />
</div>
<div>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel
krav til tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
</div>
</div>
</ExpansionCard.Header>
<Content />
</ExpansionCard>
<style>{`
.with-icon {
display: flex;
align-items: center;
gap: 1rem;
}
.icon {
font-size: 3rem;
flex-shrink: 0;
display: grid;
place-content: center;
}`}</style>
</div>
),
};
@@ -0,0 +1,4 @@
export {
type ExpansionCardProps,
default as ExpansionCard,
} from "./ExpansionCard";
+14 -3
View File
@@ -45,6 +45,15 @@ export interface TextareaProps
* Enables resizing of field
*/
resize?: boolean;
/**
* i18n-translations for counter-text
*/
i18n?: {
/** @default Antall tegn igjen */
counterLeft?: string;
/** @default tegn for mye */
counterTooMuch?: string;
};
}
export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
@@ -65,6 +74,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
maxLength,
hideLabel = false,
resize,
i18n,
...rest
} = props;
@@ -166,6 +176,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
maxLength={maxLength}
currentLength={props.value?.length ?? controlledValue?.length}
size={size}
i18n={i18n}
/>
</>
)}
@@ -185,7 +196,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
}
);
export const Counter = ({ maxLength, currentLength, size }) => {
export const Counter = ({ maxLength, currentLength, size, i18n }) => {
const difference = maxLength - currentLength;
return (
@@ -197,8 +208,8 @@ export const Counter = ({ maxLength, currentLength, size }) => {
size={size}
>
{difference < 0
? `Antall tegn for mye ${Math.abs(difference)}`
: `Antall tegn igjen ${difference}`}
? `${Math.abs(difference)} ${i18n?.counterLeft ?? "tegn for mye"}`
: `${difference} ${i18n?.counterTooMuch ?? "tegn igjen"}`}
</BodyShort>
);
};
+1
View File
@@ -5,6 +5,7 @@ export * from "./chat";
export * from "./chips";
export * from "./date";
export * from "./form";
export * from "./expansion-card";
export * from "./grid";
export * from "./guide-panel";
export * from "./help-text";
@@ -3,9 +3,6 @@ import cl from "clsx";
export interface PopoverContentProps
extends React.HTMLAttributes<HTMLDivElement> {
/**
* Modal.Content content
*/
children: React.ReactNode;
}
+14
View File
@@ -1,5 +1,19 @@
# @navikt/ds-tailwind
## 2.8.5
## 2.8.4
## 2.8.3
## 2.8.2
## 2.8.1
## 2.8.0
## 2.7.8
## 2.7.7
## 2.7.6
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tailwind",
"version": "2.7.7",
"version": "2.8.5",
"description": "Tailwind config based on @navikt/ds-tokens",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -22,7 +22,7 @@
"directory": "@navikt/core/tailwind"
},
"devDependencies": {
"@navikt/ds-tokens": "^2.7.7",
"@navikt/ds-tokens": "^2.8.5",
"@types/jest": "^29.0.0",
"color": "4.2.3",
"jest": "^29.0.0",
+14
View File
@@ -1,5 +1,19 @@
# @navikt/ds-tokens
## 2.8.5
## 2.8.4
## 2.8.3
## 2.8.2
## 2.8.1
## 2.8.0
## 2.7.8
## 2.7.7
## 2.7.6
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tokens",
"version": "2.7.7",
"version": "2.8.5",
"description": "Design-tokens for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
+14
View File
@@ -1,5 +1,19 @@
# @navikt/ds-icons
## 2.8.5
## 2.8.4
## 2.8.3
## 2.8.2
## 2.8.1
## 2.8.0
## 2.7.8
## 2.7.7
## 2.7.6
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-icons",
"version": "2.7.7",
"version": "2.8.5",
"description": "Aksel icons for NAV",
"author": "Aksel | NAV designsystem team",
"repository": {
+14
View File
@@ -1,5 +1,19 @@
# @navikt/ds-css-internal
## 2.8.5
## 2.8.4
## 2.8.3
## 2.8.2
## 2.8.1
## 2.8.0
## 2.7.8
## 2.7.7
## 2.7.6
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css-internal",
"version": "2.7.7",
"version": "2.8.5",
"description": "CSS for NAV internal Designsystem-components",
"author": "Aksel | NAV designsystem team",
"keywords": [
+56
View File
@@ -1,5 +1,61 @@
# @navikt/ds-react-internal
## 2.8.5
### Patch Changes
- Updated dependencies []:
- @navikt/ds-react@2.8.5
- @navikt/ds-icons@2.8.5
## 2.8.4
### Patch Changes
- Updated dependencies []:
- @navikt/ds-react@2.8.4
- @navikt/ds-icons@2.8.4
## 2.8.3
### Patch Changes
- Updated dependencies [[`f862aa9c2`](https://github.com/navikt/aksel/commit/f862aa9c2ec71ffdb295708dc6dad6b77af9519e)]:
- @navikt/ds-react@2.8.3
- @navikt/ds-icons@2.8.3
## 2.8.2
### Patch Changes
- Updated dependencies [[`9c495cf50`](https://github.com/navikt/aksel/commit/9c495cf5037a7453e51e273ab93e4232576f4958)]:
- @navikt/ds-react@2.8.2
- @navikt/ds-icons@2.8.2
## 2.8.1
### Patch Changes
- Updated dependencies [[`1276b4d7e`](https://github.com/navikt/aksel/commit/1276b4d7efd831d20345292dbb21a11d100a0ddd)]:
- @navikt/ds-react@2.8.1
- @navikt/ds-icons@2.8.1
## 2.8.0
### Patch Changes
- Updated dependencies [[`c6d51a019`](https://github.com/navikt/aksel/commit/c6d51a01902e4fd7916a422e17ed175f39acd458)]:
- @navikt/ds-react@2.8.0
- @navikt/ds-icons@2.8.0
## 2.7.8
### Patch Changes
- Updated dependencies []:
- @navikt/ds-react@2.7.8
- @navikt/ds-icons@2.7.8
## 2.7.7
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react-internal",
"version": "2.7.7",
"version": "2.8.5",
"description": "Aksel react components for internal UIs in NAV",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -35,8 +35,8 @@
"watch": "tsc --watch -p tsconfig.esm.json"
},
"dependencies": {
"@navikt/ds-icons": "^2.7.7",
"@navikt/ds-react": "^2.7.7",
"@navikt/ds-icons": "^2.8.5",
"@navikt/ds-react": "^2.8.5",
"clsx": "^1.1.1",
"copy-to-clipboard": "^3.3.1"
},
+9 -9
View File
@@ -15,15 +15,15 @@
"website"
],
"dependencies": {
"@navikt/aksel-icons": "^2.7.7",
"@navikt/ds-codemod": "^2.7.7",
"@navikt/ds-css": "^2.7.7",
"@navikt/ds-css-internal": "^2.7.7",
"@navikt/ds-icons": "^2.7.7",
"@navikt/ds-react": "^2.7.7",
"@navikt/ds-react-internal": "^2.7.7",
"@navikt/ds-tailwind": "^2.7.7",
"@navikt/ds-tokens": "^2.7.7"
"@navikt/aksel-icons": "^2.8.5",
"@navikt/ds-codemod": "^2.8.5",
"@navikt/ds-css": "^2.8.5",
"@navikt/ds-css-internal": "^2.8.5",
"@navikt/ds-icons": "^2.8.5",
"@navikt/ds-react": "^2.8.5",
"@navikt/ds-react-internal": "^2.8.5",
"@navikt/ds-tailwind": "^2.8.5",
"@navikt/ds-tokens": "^2.8.5"
},
"devDependencies": {
"prettier-plugin-tailwindcss": "^0.2.3"
@@ -3,6 +3,7 @@ import { BodyLong, Detail, Heading, Ingress, Link } from "@navikt/ds-react";
import BlockContent from "@sanity/block-content-to-react";
import cl from "clsx";
import InnholdsKort from "components/sanity-modules/cards/InnholdsKort";
import ExpansionCard from "components/sanity-modules/ExpansionCard";
import NextLink from "next/link";
import React, { createContext, useContext } from "react";
import {
@@ -49,6 +50,7 @@ const serializers = {
do_dont: ({ node }) => <DoDont node={node} />,
bilde: ({ node }) => <Bilde node={node} />,
alert: ({ node }) => <Alert node={node} />,
expansioncard: ({ node }) => <ExpansionCard node={node} />,
kode: ({ node }) => <Kode node={node} />,
tabell_v2: ({ node }) => <Tabell node={node} />,
accordion: ({ node }) => <Accordion node={node} />,
@@ -83,6 +83,52 @@ export const GithubIcon = ({ ...props }) => (
</svg>
);
export const SlackIcon = ({ ...props }) => (
<svg
width="20"
height="21"
viewBox="0 0 20 21"
fill="none"
xmlns="http://www.w3.org/2000/svg"
focusable={false}
aria-hidden
{...props}
>
<path
d="M4.92656 12.8086C4.92625 13.1721 4.81818 13.5274 4.616 13.8295C4.41382 14.1316 4.12661 14.3669 3.79068 14.5058C3.45475 14.6447 3.08518 14.6809 2.72869 14.6098C2.37221 14.5387 2.0448 14.3635 1.78787 14.1063C1.53094 13.8492 1.35601 13.5216 1.28521 13.1651C1.2144 12.8085 1.2509 12.439 1.39008 12.1032C1.52926 11.7674 1.76488 11.4804 2.06715 11.2784C2.36942 11.0765 2.72477 10.9688 3.08828 10.9688H4.92656V12.8086Z"
fill="currentColor"
/>
<path
d="M5.85303 12.8086C5.85303 12.3211 6.0467 11.8535 6.39145 11.5088C6.73619 11.164 7.20377 10.9703 7.69131 10.9703C8.17885 10.9703 8.64643 11.164 8.99117 11.5088C9.33591 11.8535 9.52959 12.3211 9.52959 12.8086V17.4117C9.52959 17.8993 9.33591 18.3669 8.99117 18.7116C8.64643 19.0563 8.17885 19.25 7.69131 19.25C7.20377 19.25 6.73619 19.0563 6.39145 18.7116C6.0467 18.3669 5.85303 17.8993 5.85303 17.4117V12.8086Z"
fill="currentColor"
/>
<path
d="M7.69146 5.42656C7.32794 5.42625 6.97269 5.31818 6.67059 5.116C6.36849 4.91382 6.13312 4.62661 5.99422 4.29068C5.85532 3.95475 5.81914 3.58518 5.89025 3.22869C5.96136 2.87221 6.13656 2.5448 6.39371 2.28787C6.65086 2.03094 6.97841 1.85601 7.33496 1.78521C7.69151 1.7144 8.06105 1.7509 8.39686 1.89008C8.73267 2.02926 9.01968 2.26488 9.2216 2.56715C9.42353 2.86942 9.5313 3.22477 9.5313 3.58828V5.42656H7.69146Z"
fill="currentColor"
/>
<path
d="M7.69141 6.35315C8.17895 6.35315 8.64652 6.54682 8.99127 6.89157C9.33601 7.23631 9.52969 7.70389 9.52969 8.19143C9.52969 8.67897 9.33601 9.14655 8.99127 9.49129C8.64652 9.83604 8.17895 10.0297 7.69141 10.0297H3.08828C2.60074 10.0297 2.13316 9.83604 1.78842 9.49129C1.44368 9.14655 1.25 8.67897 1.25 8.19143C1.25 7.70389 1.44368 7.23631 1.78842 6.89157C2.13316 6.54682 2.60074 6.35315 3.08828 6.35315H7.69141Z"
fill="currentColor"
/>
<path
d="M15.0735 8.19139C15.0738 7.82788 15.1819 7.47263 15.3841 7.17053C15.5862 6.86843 15.8734 6.63305 16.2094 6.49416C16.5453 6.35526 16.9149 6.31908 17.2714 6.39019C17.6278 6.4613 17.9552 6.6365 18.2122 6.89365C18.4691 7.1508 18.644 7.47835 18.7148 7.8349C18.7856 8.19145 18.7491 8.56099 18.61 8.8968C18.4708 9.23261 18.2352 9.51962 17.9329 9.72154C17.6306 9.92346 17.2753 10.0312 16.9118 10.0312H15.0735V8.19139Z"
fill="currentColor"
/>
<path
d="M14.1468 8.19141C14.1468 8.67895 13.9531 9.14652 13.6084 9.49127C13.2636 9.83601 12.796 10.0297 12.3085 10.0297C11.821 10.0297 11.3534 9.83601 11.0086 9.49127C10.6639 9.14652 10.4702 8.67895 10.4702 8.19141V3.58828C10.4702 3.10074 10.6639 2.63316 11.0086 2.28842C11.3534 1.94368 11.821 1.75 12.3085 1.75C12.796 1.75 13.2636 1.94368 13.6084 2.28842C13.9531 2.63316 14.1468 3.10074 14.1468 3.58828V8.19141Z"
fill="currentColor"
/>
<path
d="M12.3086 15.5734C12.6721 15.5737 13.0274 15.6818 13.3295 15.884C13.6316 16.0862 13.8669 16.3734 14.0058 16.7093C14.1447 17.0452 14.1809 17.4148 14.1098 17.7713C14.0387 18.1278 13.8635 18.4552 13.6063 18.7121C13.3492 18.9691 13.0216 19.144 12.6651 19.2148C12.3085 19.2856 11.939 19.2491 11.6032 19.1099C11.2674 18.9707 10.9804 18.7351 10.7784 18.4328C10.5765 18.1306 10.4688 17.7752 10.4688 17.4117V15.5734H12.3086Z"
fill="currentColor"
/>
<path
d="M12.3085 14.6469C11.821 14.6469 11.3534 14.4532 11.0086 14.1085C10.6639 13.7637 10.4702 13.2962 10.4702 12.8086C10.4702 12.3211 10.6639 11.8535 11.0086 11.5088C11.3534 11.164 11.821 10.9703 12.3085 10.9703H16.9116C17.3992 10.9703 17.8667 11.164 18.2115 11.5088C18.5562 11.8535 18.7499 12.3211 18.7499 12.8086C18.7499 13.2962 18.5562 13.7637 18.2115 14.1085C17.8667 14.4532 17.3992 14.6469 16.9116 14.6469H12.3085Z"
fill="currentColor"
/>
</svg>
);
export const YarnIcon = () => (
<svg
width="20"
@@ -128,23 +174,26 @@ export const StorybookIcon = ({ ...props }) => (
<g id="storybook-icon" transform="translate(1.000000, 1.000000)">
<path
id="Combined-Shape"
fill="var(--a-gray-600)"
fill="currentColor"
fillRule="nonzero"
d="M50.2729096,2.92285771 C50.2769973,2.98759391 50.2790429,3.05244063 50.2790429,3.11730315 L50.2790429,58.8828028 C50.2790429,60.6043831 48.8689636,62 47.1295431,62 C47.0824212,62 47.0353056,61.9989534 46.9882313,61.9968606 L4.94876437,60.1280997 C3.31149338,60.0553189 2.00425692,58.751918 1.94279175,57.1309472 L0.0022554267,5.95476663 C-0.0618328758,4.26461814 1.24754196,2.83223697 2.95307926,2.72673418 L37.427,0.594 L37.1272753,7.62078766 C37.1238721,7.70179664 37.1419373,7.78178731 37.179031,7.85305525 L37.2223772,7.92113026 C37.3791917,8.12573637 37.6738999,8.16578288 37.880626,8.0105767 L37.880626,8.0105767 L40.6382617,5.94019678 L42.9673936,7.75618537 C43.0546693,7.82423279 43.1634862,7.85946584 43.2745216,7.85562813 C43.5338374,7.84666553 43.7367132,7.6313391 43.7276576,7.37468316 L43.7276576,7.37468316 L43.467,0.22 L46.9330824,0.00617628491 C48.6691159,-0.10121296 50.1644074,1.2046298 50.2729096,2.92285771 Z"
className="group-focus:text-surface-inverted text-surface-default"
/>
<path
id="S"
fill="#fff"
fill="currentColor"
fillRule="nonzero"
d="M29.4029796,23.368648 C29.4029796,24.58142 37.6567008,24.00017 38.7646901,23.1482813 C38.7646901,14.8895929 34.2873503,10.5497821 26.0885852,10.5497821 C17.88982,10.5497821 13.2961856,14.9571143 13.2961856,21.5681161 C13.2961856,33.0822778 28.9959487,33.3026444 28.9959487,39.5830962 C28.9959487,41.3460299 28.1237396,42.3927719 26.2048797,42.3927719 C23.7045471,42.3927719 22.7160434,41.1289316 22.832338,36.8317805 C22.832338,35.8995698 13.2961856,35.6089448 13.0054493,36.8317805 C12.2651161,47.2453073 18.8201763,50.248968 26.3211742,50.248968 C33.5895831,50.248968 39.2880157,46.4144645 39.2880157,39.4729126 C39.2880157,27.132376 23.3556634,27.4629261 23.3556634,21.3477494 C23.3556634,18.8686237 25.2163761,18.5380737 26.3211742,18.5380737 C27.4841196,18.5380737 29.5774214,18.7409467 29.4029796,23.368648 Z"
mask="url(#mask-2)"
className="text-deepblue-700 group-focus:text-text-on-inverted"
/>
<path
id="bookmark"
fill="#fff"
fill="currentColor"
fillRule="nonzero"
d="M37.1272753,7.62078766 L37.4276823,0.591583333 L43.4674595,0.218291667 L43.7276576,7.37468316 C43.7367132,7.6313391 43.5338374,7.84666553 43.2745216,7.85562813 C43.1634862,7.85946584 43.0546693,7.82423279 42.9673936,7.75618537 L40.6382617,5.94019678 L37.880626,8.0105767 C37.6738999,8.16578288 37.3791917,8.12573637 37.2223772,7.92113026 C37.1563661,7.83500129 37.1227378,7.72879963 37.1272753,7.62078766 Z"
mask="url(#mask-2)"
className="text-deepblue-700 group-focus:text-text-on-inverted"
/>
</g>
</g>
@@ -1,7 +1,7 @@
import React from "react";
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
const Logo = (props): JSX.Element => (
const Logo = (props) => (
<svg
width="119"
height="26"
@@ -13,33 +13,33 @@ const Logo = (props): JSX.Element => (
>
<path
d="M56.9682 23.3413L48.1959 1.94542C47.9106 1.30354 47.2687 0.839966 46.5199 0.839966C45.8067 0.839966 45.1292 1.30354 44.8795 1.94542L36.1072 23.3413C36.0359 23.5196 36.0002 23.6623 36.0002 23.7692C36.0002 24.3398 36.4638 24.839 37.07 24.839C37.498 24.839 37.9259 24.5537 38.0685 24.1615L40.1724 18.8838H52.903L55.0069 24.1615C55.1496 24.5537 55.5418 24.839 56.0054 24.839C56.6116 24.839 57.0752 24.3398 57.0752 23.7692C57.0752 23.5909 57.0039 23.4483 56.9682 23.3413ZM40.9213 17.0295L46.5199 2.9439L52.1541 17.0295H40.9213Z"
fill="#004367"
fill="currentColor"
/>
<path
d="M75.0623 23.2343L68.1086 15.3179L74.884 8.93474C75.0623 8.75645 75.1693 8.50683 75.1693 8.29287C75.1693 7.82929 74.8127 7.40137 74.3135 7.40137C74.0995 7.40137 73.8855 7.47269 73.7072 7.61533L63.4729 17.3148V1.76712C63.4729 1.26788 63.045 0.839966 62.5457 0.839966C62.0465 0.839966 61.6186 1.26788 61.6186 1.76712V23.9119C61.6186 24.4111 62.0465 24.839 62.5457 24.839C63.045 24.839 63.4729 24.4111 63.4729 23.9119V19.5614L66.6823 16.5303L73.6003 24.5181C73.7786 24.732 74.0282 24.839 74.3491 24.839C74.884 24.839 75.2763 24.4111 75.2763 23.8762C75.2763 23.6266 75.205 23.4126 75.0623 23.2343Z"
fill="#004367"
fill="currentColor"
/>
<path
d="M79.0353 22.9491C80.747 24.5181 82.6726 25.16 85.1331 25.16C89.448 25.16 91.5876 22.8777 91.5876 20.0963C91.5876 16.4233 88.2712 15.6031 85.3114 14.8543C82.9222 14.2481 80.7113 13.7132 80.7113 11.7519C80.7113 9.96888 82.3517 8.64947 85.0262 8.64947C86.9518 8.64947 88.5565 9.327 89.6619 10.3968C89.7689 10.5038 89.9829 10.6108 90.1612 10.6108C90.6247 10.6108 90.9813 10.2185 90.9813 9.79058C90.9813 9.5053 90.8744 9.327 90.6961 9.1487C89.4123 7.93627 87.5937 7.08043 85.0262 7.08043C81.1392 7.08043 78.8927 9.22002 78.8927 11.8589C78.8927 15.2109 82.0664 15.9597 84.9548 16.6729C87.4154 17.3148 89.7689 17.9567 89.7689 20.1676C89.7689 22.1645 88.0572 23.5909 85.1688 23.5909C83.0649 23.5909 81.3532 22.7708 80.1408 21.6296C79.9981 21.487 79.8198 21.4157 79.6059 21.4157C79.1066 21.4157 78.7144 21.8079 78.7144 22.3072C78.7144 22.5568 78.857 22.8064 79.0353 22.9491Z"
fill="#004367"
fill="currentColor"
/>
<path
d="M95.2069 16.1024C95.2069 21.4157 98.8086 25.16 103.837 25.16C106.404 25.16 108.365 24.3398 110.077 22.8421C110.255 22.6638 110.362 22.4855 110.362 22.2359C110.362 21.7723 110.041 21.4513 109.614 21.4513C109.435 21.4513 109.257 21.487 109.15 21.594C107.688 22.9134 105.941 23.5553 103.979 23.5553C99.914 23.5553 97.4179 20.4529 97.2396 16.7086H110.541C111.254 16.7086 111.646 16.3163 111.646 15.6745C111.646 11.2526 108.758 7.08043 103.516 7.08043C98.7373 7.08043 95.2069 11.11 95.2069 16.1024ZM103.48 8.68513C107.795 8.68513 109.72 12.3224 109.756 15.2465H97.2396C97.3822 12.2511 99.4148 8.68513 103.48 8.68513Z"
fill="#004367"
fill="currentColor"
/>
<path
d="M117.365 24.839C117.865 24.839 118.293 24.4111 118.293 23.9119V1.76712C118.293 1.26788 117.865 0.839966 117.365 0.839966C116.866 0.839966 116.438 1.26788 116.438 1.76712V23.9119C116.438 24.4111 116.866 24.839 117.365 24.839Z"
fill="#004367"
fill="currentColor"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M0.292684 8.54331C-0.0977248 8.15267 -0.0975372 7.5195 0.293103 7.1291L5.44967 1.97558C5.47463 1.95063 5.4999 1.92606 5.52546 1.90187L5.52289 1.8993C6.03155 1.39065 6.65771 1.07111 7.314 0.9407C7.59976 0.874273 7.89433 0.839967 8.19243 0.839967L20.12 0.839966C22.2629 0.839967 24 2.5771 24 4.71997V16.6435C24 16.9198 23.9705 17.1931 23.9133 17.4591C23.7914 18.1347 23.4693 18.7813 22.9471 19.3035L22.9458 19.3022C22.9189 19.3309 22.8915 19.3592 22.8636 19.3871L17.7071 24.5435C17.3166 24.934 16.6834 24.934 16.2929 24.5435C15.9024 24.153 15.9024 23.5198 16.2929 23.1293L21.4494 17.9728C21.6986 17.7236 21.8706 17.4116 21.9501 17.074C22.0233 16.6182 21.8843 16.1349 21.5329 15.7835L9.06289 3.31352C8.70098 2.95161 8.20044 2.81283 7.73221 2.89716C7.40619 2.97949 7.10531 3.14852 6.86347 3.39021L1.7069 8.54373C1.31626 8.93414 0.683092 8.93395 0.292684 8.54331ZM11.4178 2.83997L22 13.4222V4.71997C22 3.68167 21.1583 2.83997 20.12 2.83997L11.4178 2.83997Z"
fill="#004367"
fill="currentColor"
/>
<path
d="M0.292893 24.5435C-0.0976311 24.153 -0.0976311 23.5198 0.292893 23.1293L9.29289 14.1293C9.68342 13.7388 10.3166 13.7388 10.7071 14.1293C11.0976 14.5198 11.0976 15.153 10.7071 15.5435L1.70711 24.5435C1.31658 24.934 0.683417 24.934 0.292893 24.5435Z"
fill="#004367"
fill="currentColor"
/>
</svg>
);
@@ -1,5 +1,5 @@
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
const NAVLogoDark = (props): JSX.Element => (
const NAVLogoDark = (props) => (
<svg
width="3.25em"
height="3.25em"
@@ -1,5 +1,5 @@
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
const NAVLogoWhite = (props): JSX.Element => (
const NAVLogoWhite = (props) => (
<svg
width="3.25em"
height="3.25em"
-1
View File
@@ -1,5 +1,4 @@
export * from "./assets";
export { default as LayoutPicker } from "./layout/TemplatePicker";
export { default as Accordion } from "./sanity-modules/Accordion";
export { default as Alert } from "./sanity-modules/Alert";
export { default as Bilde } from "./sanity-modules/bilde/Bilde";
@@ -1,53 +0,0 @@
import Error from "next/error";
import React from "react";
import { SanityT } from "@/lib";
import AkselArtikkelTemplate from "./page-templates/AkselArtikkel";
import AkselPrinsippTemplate from "./page-templates/AkselPrinsipp";
type aksel_artikkel = {
aksel_artikkel: (props: {
data: SanityT.Schema.aksel_artikkel;
title: string;
}) => JSX.Element;
};
type aksel_prinsipp = {
aksel_prinsipp: (props: {
data: SanityT.Schema.aksel_prinsipp;
title: string;
}) => JSX.Element;
};
type templateT = aksel_artikkel | aksel_prinsipp;
const templates: templateT = {
aksel_artikkel: (props) => <AkselArtikkelTemplate {...props} />,
aksel_prinsipp: (props) => <AkselPrinsippTemplate {...props} />,
};
const TemplatePicker = ({
data,
title,
}: {
data: SanityT.Schema.aksel_artikkel | SanityT.Schema.aksel_prinsipp;
title: string;
}): JSX.Element => {
if (!Object.keys(templates).includes(data?._type)) {
console.warn(
`${data?._type} does not have a valid template to use, please create one.`
);
return (
<Error
statusCode={404}
title="Sanity-side mangler template, kontakt utvikler"
/>
);
}
const Template = templates[data?._type];
return <Template data={data} title={title} />;
};
export default TemplatePicker;
@@ -1,4 +1,4 @@
import { PageTypeT, SidebarT, urlFor } from "@/lib";
import { urlFor } from "@/lib";
import { Detail, Heading, Link } from "@navikt/ds-react";
import Footer from "components/layout/footer/Footer";
import { Header } from "components/layout/header/Header";
@@ -10,6 +10,7 @@ import NextLink from "next/link";
import { capitalize } from "@/utils";
import Image from "next/legacy/image";
import { TableOfContentsv2 } from "components/website-modules/TOCv2";
import { AkselSidebarT } from "@/types";
const HeaderCube = ({ ...props }) => (
<svg
@@ -59,8 +60,11 @@ export const WithSidebar = ({
footer,
}: {
children: ReactNode;
sidebar: SidebarT;
pageType: PageTypeT;
sidebar: AkselSidebarT;
pageType: {
type: "Komponenter" | "Grunnleggende";
title: string;
};
pageProps: any;
intro?: ReactNode;
footer?: ReactNode;
@@ -1,7 +1,8 @@
import { BodyShort, Heading, Link } from "@navikt/ds-react";
import NextLink from "next/link";
import { EditButton, ScrollTop } from "../..";
import { FigmaIcon, GithubIcon, SlackIcon } from "components/assets";
import Logo from "components/assets/Logo";
import { logNav } from "components/website-modules/utils/amplitude";
import { EditButton } from "../..";
import FooterForm from "./FooterForm";
const Footer = () => {
@@ -12,164 +13,116 @@ const Footer = () => {
data-theme="dark"
className="toc-ignore text-text-on-inverted bg-deepblue-800 relative flex w-full justify-center"
>
<div className="relative z-10 mx-auto grid w-full max-w-screen-2xl gap-16 px-4 pt-12 pb-16 md:px-6">
<div className="grid gap-12 xl:grid-cols-3 xl:gap-6">
<ScrollTop />
<div>
<Heading level="2" size="small">
Aksel
</Heading>
<BodyShort as="ul" className="mt-5 grid gap-2">
<li>
<NextLink
href="/god-praksis/artikler/om-aksel"
passHref
legacyBehavior
>
<Link className="text-text-on-inverted focus:shadow-focus focus:text-text-default focus:bg-blue-200 focus:shadow-blue-200">
Om Aksel
</Link>
</NextLink>
</li>
<li>
<NextLink
href="/god-praksis/artikler/skriv-for-aksel"
passHref
legacyBehavior
>
<Link className="text-text-on-inverted focus:shadow-focus focus:text-text-default focus:bg-blue-200 focus:shadow-blue-200">
Skriv for Aksel
</Link>
</NextLink>
</li>
<li>
<Link
className="text-text-on-inverted focus:shadow-focus focus:text-text-default focus:bg-blue-200 focus:shadow-blue-200"
href="https://nav-it.slack.com/archives/C7NE7A8UF"
>
#Aksel-designsystemet på Slack
</Link>
</li>
<li>
<Link
className="text-text-on-inverted focus:shadow-focus focus:text-text-default focus:bg-blue-200 focus:shadow-blue-200"
href="/prinsipper/brukeropplevelse"
>
Prinsipper for brukeropplevelse
</Link>
</li>
<li>
<Link
className="text-text-on-inverted focus:shadow-focus focus:text-text-default focus:bg-blue-200 focus:shadow-blue-200"
href="/side/tilgjengelighetserklaring-for-aksel"
>
Tilgjengelighet
</Link>
</li>
{/* <li>
<Link
className="text-text-on-inverted focus:shadow-focus focus:text-text-default focus:bg-blue-200 focus:shadow-blue-200"
href="https://nav-it.slack.com/archives/C7NE7A8UF"
>
Designsystemet på Slack
</Link>
</li> */}
</BodyShort>
</div>
<FooterForm />
</div>
<div className="grid xl:grid-cols-3 xl:gap-6">
<div className="mb-4 grid gap-2 xl:mb-0">
<svg
width="64"
height="20"
viewBox="0 0 64 20"
fill="none"
aria-hidden
focusable="false"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_2259_53938)">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M63.4798 1H56.8198C56.8198 1 56.3608 1 56.1988 1.406L52.5138 12.693L48.8318 1.406C48.6688 1.001 48.2078 1.001 48.2078 1.001H35.4038C35.2694 1.00203 35.1407 1.05569 35.0454 1.15046C34.9501 1.24523 34.8956 1.37359 34.8938 1.508V5.341C34.8938 2.301 31.6608 1.001 29.7668 1.001C25.5268 1.001 22.6888 3.795 21.8048 8.044C21.7568 5.225 21.5228 4.215 20.7638 3.181C20.4148 2.674 19.9118 2.249 19.3638 1.896C18.2338 1.234 17.2188 1.001 15.0398 1.001H12.4798C12.4798 1.001 12.0178 1.001 11.8548 1.406L9.52582 7.18V1.508C9.52452 1.37411 9.47082 1.24606 9.37624 1.15128C9.28165 1.05651 9.15371 1.00256 9.01982 1.001H3.09682C3.09682 1.001 2.63982 1.001 2.47282 1.406L0.0528186 7.41C0.0528186 7.41 -0.189181 8.01 0.362819 8.01H2.63982V19.45C2.63982 19.734 2.86282 19.96 3.14782 19.96H9.01782C9.08466 19.9599 9.15082 19.9466 9.21253 19.9209C9.27423 19.8952 9.33027 19.8576 9.37744 19.8102C9.42462 19.7629 9.462 19.7067 9.48746 19.6449C9.51291 19.5831 9.52595 19.5168 9.52582 19.45V8.01H11.8148C13.1278 8.01 13.4048 8.046 13.9158 8.284C14.2238 8.401 14.5008 8.636 14.6528 8.907C14.9628 9.49 15.0398 10.19 15.0398 12.255V19.45C15.0398 19.734 15.2678 19.96 15.5498 19.96H21.1758C21.1758 19.96 21.8118 19.96 22.0628 19.33L23.3098 16.247C24.9678 18.571 27.6968 19.959 31.0888 19.959H31.8298C31.8298 19.959 32.4698 19.959 32.7228 19.331L34.8948 13.95V19.45C34.8948 19.5853 34.9485 19.715 35.0442 19.8106C35.1398 19.9063 35.2696 19.96 35.4048 19.96H41.1478C41.1478 19.96 41.7818 19.96 42.0358 19.33C42.0358 19.33 44.3328 13.625 44.3418 13.582H44.3458C44.4338 13.107 43.8348 13.107 43.8348 13.107H41.7848V3.316L48.2348 19.331C48.4858 19.959 49.1208 19.959 49.1208 19.959H55.9068C55.9068 19.959 56.5448 19.959 56.7968 19.331L63.9478 1.615C64.1948 1.001 63.4788 1.001 63.4788 1.001L63.4798 1ZM34.8928 13.108H31.0348C30.2962 13.108 29.5878 12.8146 29.0655 12.2923C28.5432 11.77 28.2498 11.0616 28.2498 10.323C28.2498 9.58437 28.5432 8.876 29.0655 8.35371C29.5878 7.83142 30.2962 7.538 31.0348 7.538H32.1138C32.8517 7.54012 33.5586 7.83465 34.0797 8.35706C34.6008 8.87946 34.8936 9.58713 34.8938 10.325V13.108H34.8928Z"
fill="white"
/>
</g>
<defs>
<clipPath id="clip0_2259_53938">
<rect width="63.9997" height="20" fill="white" />
</clipPath>
</defs>
</svg>
Arbeids- og velferdsetaten
</div>
<span className="mb-1 self-end xl:mb-0" />
<div className="hidden self-end xl:block">
<p>&copy; {new Date().getFullYear()} NAV</p>
<NextLink
href="/side/personvernerklaering"
className="focus:bg-border-focus-on-inverted focus:text-text-default focus:ring-border-focus-on-inverted outline-none hover:underline focus:no-underline focus:ring"
>
Personvernerklæring og informasjonskapsler
</NextLink>
</div>
<div className="block self-end xl:hidden">
&copy; {new Date().getFullYear()} NAV |{" "}
<NextLink
href="/side/personvernerklaering"
className="focus:bg-border-focus-on-inverted focus:ring-border-focus-on-inverted outline-none hover:underline focus:no-underline focus:ring"
>
Personvernerklæring og informasjonskapsler
</NextLink>
</div>
</div>
<div className="relative z-10 mx-auto grid w-full max-w-screen-2xl gap-12 px-4 pt-12 pb-16 md:grid-cols-2 md:px-6 lg:grid-cols-4 xl:grid-cols-5 xl:gap-6">
<LogoBlock />
<Snarveier />
<SideLenker />
<Kontakt />
<FooterForm />
</div>
<EditButton />
<svg
width="548"
height="422"
viewBox="0 0 548 422"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="absolute right-0 bottom-0 z-0"
aria-hidden
focusable={false}
>
<path
d="M664.991 350.212L431.631 116.852L664.64 116.852L898 350.212L664.991 350.212Z"
stroke="#004367"
strokeWidth="2.9687"
strokeLinejoin="round"
/>
<path
d="M625.456 156.037L392.097 389.396L625.456 622.756L858.816 389.396L625.456 156.037Z"
stroke="#004367"
strokeWidth="2.9687"
strokeLinejoin="round"
/>
<path
d="M353.262 195.222L119.903 428.581H352.912L586.271 195.222H353.262Z"
stroke="#004367"
strokeWidth="2.9687"
strokeLinejoin="round"
/>
<path
d="M314.076 234.407L80.7169 467.767L314.076 701.126L547.436 467.767L314.076 234.407Z"
stroke="#004367"
strokeWidth="2.9687"
strokeLinejoin="round"
/>
<path
d="M508.251 506.951L274.892 740.31H507.901L741.261 506.951H508.251Z"
stroke="#004367"
strokeWidth="2.9687"
strokeLinejoin="round"
/>
</svg>
</footer>
);
};
function LogoBlock() {
return (
<div>
<Logo className="fill-white" />
<p className="mt-4">&copy; {new Date().getFullYear()} NAV</p>
<p>Arbeids- og velferdsetaten</p>
</div>
);
}
function Snarveier() {
return (
<div>
<Heading level="2" size="xsmall">
Snarveier
</Heading>
<BodyShort as="ul" className="mt-3 grid gap-3">
<FooterLink href="/god-praksis/artikler/om-aksel">
Hva er Aksel?
</FooterLink>
<FooterLink href="/god-praksis/artikler/skriv-for-aksel">
Skriv for Aksel
</FooterLink>
<FooterLink href="/prinsipper/brukeropplevelse">
Prinsipper for brukeropplevelse
</FooterLink>
<FooterLink href="https://identitet.nav.no/">Identitet</FooterLink>
<FooterLink href="https://sikkerhet.nav.no/">
Security Playbook
</FooterLink>
<FooterLink href="https://etterlevelse.intern.nav.no/">
Etterlevelse
</FooterLink>
</BodyShort>
</div>
);
}
function Kontakt() {
return (
<div>
<Heading level="2" size="xsmall">
Finn oss
</Heading>
<BodyShort as="ul" className="mt-3 grid gap-3">
<FooterLink href="https://www.figma.com/@nav_aksel">
<FigmaIcon />
Figma
</FooterLink>
<FooterLink href="https://github.com/navikt/aksel">
<GithubIcon />
Github
</FooterLink>
<FooterLink href="https://nav-it.slack.com/archives/C7NE7A8UF">
<SlackIcon />
Slack
</FooterLink>
</BodyShort>
</div>
);
}
function SideLenker() {
return (
<div>
<Heading level="2" size="xsmall">
Om nettstedet
</Heading>
<BodyShort as="ul" className="mt-3 grid gap-3">
<FooterLink href="/side/personvernerklaering">
Personvernserklæring
</FooterLink>
<FooterLink href="/side/tilgjengelighetserklaring-for-aksel">
Tilgjengelighetserklæring
</FooterLink>
</BodyShort>
</div>
);
}
function FooterLink({ children, href }) {
return (
<li>
<Link
className="text-text-on-inverted focus:shadow-focus focus:text-text-default flex w-fit items-center gap-1 no-underline hover:underline focus:bg-blue-200 focus:shadow-blue-200"
href={href}
onClick={(e) =>
logNav(
"footer",
window.location.pathname,
e.currentTarget.getAttribute("href")
)
}
>
{children}
</Link>
</li>
);
}
export default Footer;
@@ -1,6 +1,6 @@
import { FeedbackT } from "@/lib";
import { IdContext } from "@/utils";
import { Button, Heading, Label, Textarea } from "@navikt/ds-react";
import { Button, Label, Textarea } from "@navikt/ds-react";
import { IdContext } from "components/website-modules/utils/contexts/id-context";
import { FeedbackT } from "@/types";
import { useRouter } from "next/router";
import { useContext, useEffect, useState } from "react";
@@ -55,7 +55,10 @@ const FooterForm = () => {
return (
<>
<div className="flex w-full max-w-md flex-col gap-8" data-theme="dark">
<div
className="flex w-full max-w-md flex-col lg:col-span-2 xl:col-span-1"
data-theme="dark"
>
<div aria-live="polite">
{sent.status && (
<Label spacing as="p">
@@ -65,15 +68,12 @@ const FooterForm = () => {
</div>
{!sent.status && (
<form onSubmit={(e) => handleSubmit(e)} className="w-full">
<div className="mb-4 flex flex-col gap-4">
<Heading level="2" size="small">
Gi en tilbakemelding
</Heading>
<div className="mb-3 flex flex-col gap-4">
<Textarea
className="textarea-override"
error={contentError.content}
autoComplete="off"
label="Melding"
label="Gi oss en tilbakemelding"
value={contactForm.content}
onChange={(e) => {
setContactForm({
@@ -85,13 +85,14 @@ const FooterForm = () => {
e.target.value.trim().length !== 0 &&
setContentError({ ...contentError, content: "" });
}}
description="Ikke skriv inn navn eller andre personopplysninger"
description="Ikke skriv inn personopplysninger"
minRows={2}
/>
</div>
{contactForm.hasWritten && <Button>Send melding</Button>}
<Button size="small">Send melding</Button>
<style>{`.textarea-override {
--ac-textarea-bg: var(--a-deepblue-800);
--ac-textarea-bg: var(--a-surface-default);
--ac-textarea-text: var(--a-text-default);
}`}</style>
</form>
)}
@@ -0,0 +1,31 @@
import Footer from "./Footer";
import { Meta } from "@storybook/react";
import { NextDecorator } from "../../StoryDecorator";
const MetaData: Meta = {
component: Footer,
tags: ["autodocs"],
decorators: [
(Story) => (
<NextDecorator>
<Story />
</NextDecorator>
),
],
parameters: {
layout: "fullscreen",
},
};
export default MetaData;
export const FooterDemo = {
render: () => <Footer />,
nextRouter: {
path: "/profile/[id]",
asPath: "/profile/lifeiscontent",
query: {
id: "lifeiscontent",
},
},
};
@@ -72,7 +72,7 @@ export const Header = ({
}
className="focus-visible:shadow-focus grid h-full place-items-center rounded px-2 focus:outline-none"
>
<Logo />
<Logo className="text-deepblue-800" />
<span className="sr-only">Aksel</span>
</Link>
</div>
@@ -1,5 +1,5 @@
import { Label } from "@navikt/ds-react";
import { GroupedHits, SearchHit, options } from "lib/types/search";
import { GroupedHitsT, SearchHitT, searchOptions } from "@/types";
import { Hit, IconHit, IconPageHit } from "./Hit";
import React from "react";
@@ -9,7 +9,7 @@ export function Group({
startIndex,
logSuccess,
}: {
groups: GroupedHits;
groups: GroupedHitsT;
query: string;
startIndex: number;
logSuccess: (index: number, url: string) => void;
@@ -21,7 +21,7 @@ export function Group({
return (
<>
{Object.entries(groups)
.sort((a, b) => options[a[0]].index - options[b[0]].index)
.sort((a, b) => searchOptions[a[0]].index - searchOptions[b[0]].index)
.map(([key, val], index, arr) => {
const prev = arr.slice(0, index);
const total =
@@ -32,7 +32,7 @@ export function Group({
logSuccess={logSuccess}
startIndex={total}
key={key}
heading={`${options[key].display} (${val.length})`}
heading={`${searchOptions[key].display} (${val.length})`}
hits={val}
query={query}
/>
@@ -50,7 +50,7 @@ export function GroupComponent({
logSuccess,
}: {
heading: React.ReactNode;
hits: SearchHit[];
hits: SearchHitT[];
query: string;
startIndex: number;
logSuccess: (index: number, url: string) => void;
@@ -4,7 +4,7 @@ import { Tag } from "@navikt/ds-react";
import cl from "classnames";
import Image from "next/legacy/image";
import { StatusTag } from "components/website-modules/StatusTag";
import { SearchHit } from "lib/types/search";
import { SearchHitT } from "@/types";
import NextLink from "next/link";
export function Hit({
@@ -13,7 +13,7 @@ export function Hit({
index,
logSuccess,
}: {
hit: SearchHit;
hit: SearchHitT;
query: string;
index: number;
logSuccess: (index: number, url: string) => void;
@@ -81,7 +81,7 @@ export function IconHit({
index,
logSuccess,
}: {
hit: SearchHit;
hit: SearchHitT;
query: string;
index: number;
logSuccess: (index: number, url: string) => void;
@@ -139,7 +139,7 @@ export function IconPageHit({
index,
logSuccess,
}: {
hit: SearchHit;
hit: SearchHitT;
query: string;
index: number;
logSuccess: (index: number, url: string) => void;
@@ -9,7 +9,7 @@ import {
Search,
} from "@navikt/ds-react";
import { ChangeLogIconOutline } from "components/assets";
import { options, SearchResults } from "lib/types/search";
import { searchOptions, SearchResultsT } from "@/types";
import { useRouter } from "next/router";
import React, { useCallback, useEffect, useRef, useState } from "react";
import ReactModal from "react-modal";
@@ -24,10 +24,10 @@ import styles from "../header.module.css";
*/
export const GlobalSearch = () => {
const [results, setResults] = useState<SearchResults>(null);
const [results, setResults] = useState<SearchResultsT>(null);
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);
const [activeTags, setTags] = useState<Array<keyof typeof options>>([]);
const [activeTags, setTags] = useState<Array<keyof typeof searchOptions>>([]);
const [os, setOs] = useState<"mac" | "windows">("windows");
const inputRef = useRef(null);
@@ -104,7 +104,6 @@ export const GlobalSearch = () => {
)
.then((x) => x.json())
.then((res) => {
console.log(res);
setResults(res);
logSearchAttempt(res?.hits?.totalHits ?? 0, "standard");
setLoading(false);
@@ -193,7 +192,7 @@ export const GlobalSearch = () => {
<div className="z-[1050] mr-4 ml-auto flex justify-center lg:mr-0 lg:ml-0">
<Button
variant="primary"
className="hover:bg-deepblue-600 bg-deepblue-500 focus-visible:shadow-focus-gap h-11 focus:shadow-none"
className="hover:bg-deepblue-700 bg-deepblue-600 focus-visible:shadow-focus-gap h-11 focus:shadow-none"
aria-keyshortcuts="Control+b"
icon={
<SearchIcon
@@ -224,7 +223,7 @@ export const GlobalSearch = () => {
</button>
<div className="search-grid-filter mt-8">
<CheckboxGroup legend="Filter" onChange={setTags}>
{Object.entries(options)
{Object.entries(searchOptions)
.filter((x) => !x[1].hidden)
.map(([key, val]) => (
<Checkbox
@@ -285,7 +284,7 @@ export const GlobalSearch = () => {
{`${results?.totalHits} treff på "${query}"${
activeTags.length > 0
? ` i ${activeTags
.map((x) => options[x].display.toLowerCase())
.map((x) => searchOptions[x].display.toLowerCase())
.join(", ")}`
: ""
}`}
@@ -1,214 +0,0 @@
import { SanityT, urlFor } from "@/lib";
import { SanityBlockContent } from "@/sanity-block";
import { Next } from "@navikt/ds-icons";
import { BodyShort, Detail, Heading, Ingress, Label } from "@navikt/ds-react";
import ArtikkelCard from "components/sanity-modules/cards/ArtikkelCard";
import Head from "next/head";
import NextLink from "next/link";
import {
abbrName,
BreadCrumbs,
dateStr,
Feedback,
TableOfContents,
} from "../..";
import { NoSidebarLayout } from "./wrappers/NoSidebar";
const AkselArtikkelTemplate = ({
data,
title,
}: {
data: SanityT.Schema.aksel_artikkel;
title: string;
}): JSX.Element => {
if (!data.content || !data.heading) {
console.warn(
`Artikkelen har ikke ${
!data.content ? "innhold" : "overskrift"
}, så den kan ikke vises.`
);
return null;
}
const date = data?.updateInfo?.lastVerified
? data?.updateInfo?.lastVerified
: data?.publishedAt
? data.publishedAt
: data._updatedAt;
const authors = (data?.contributors as any)?.map((x) => x?.title) ?? [];
const hasTema = "tema" in data && data.tema && data?.tema.length > 0;
const aside = data?.relevante_artikler?.length > 0 && (
<aside
className="overflow-x-clip py-8"
aria-labelledby="relevante-artikler-aside"
>
<div className="relativept-12 pb-16">
<div className="dynamic-wrapper">
<Heading
level="2"
size="medium"
className="text-deepblue-700 px-4"
id="relevante-artikler-aside"
>
{data?.relevante_artikler?.length === 1
? `Les også`
: `Relevante artikler`}
</Heading>
<div className="card-grid-3-1 mt-6 px-4">
{data.relevante_artikler.map((x: any) =>
x && x?._id ? <ArtikkelCard level="3" {...x} key={x._id} /> : null
)}
</div>
</div>
</div>
</aside>
);
const filteredTema =
hasTema && data?.tema?.filter((x: any) => x?.title && x?.slug);
return (
<>
<Head>
<title>{`${data?.heading} - ${title}`}</title>
<meta
property="og:title"
content={`${data?.heading} - ${title}`}
key="ogtitle"
/>
<meta
name="description"
content={data?.seo?.meta ?? data?.ingress}
key="desc"
/>
<meta
property="og:description"
content={data?.seo?.meta ?? data?.ingress}
key="ogdesc"
/>
<meta property="og:type" content="article" />
<meta
property="og:image"
content={
data?.seo?.image
? urlFor(data?.seo?.image)
.width(1200)
.height(630)
.fit("crop")
.quality(100)
.url()
: hasTema && (data.tema[0] as any)?.seo?.image
? urlFor((data.tema[0] as any)?.seo?.image)
.width(1200)
.height(630)
.fit("crop")
.quality(100)
.url()
: ""
}
key="ogimage"
/>
</Head>
<NoSidebarLayout aside={aside}>
<div className="mx-auto mb-16 max-w-prose lg:ml-0">
<BreadCrumbs auto />
<Heading
level="1"
size="large"
className="text-deepblue-800 mt-4 md:text-5xl"
>
{data.heading}
</Heading>
{data?.ingress && (
<Ingress className="override-text-700 mt-4 text-2xl">
{data?.ingress}
</Ingress>
)}
<div className="mt-6 inline-flex flex-wrap items-center gap-2 text-base">
<Detail uppercase as="span">
{dateStr(date)}
</Detail>
{authors?.length > 0 && (
<>
<span className="bg-deepblue-700 h-2 w-2 rotate-45 rounded-[1px] opacity-25" />
<BodyShort
size="small"
as="div"
className="flex flex-wrap gap-1"
>
<address className="not-italic">{authors?.[0]}</address>
</BodyShort>
</>
)}
</div>
{hasTema && (
<div className="mt-8 flex flex-wrap gap-2">
{filteredTema.map(({ title, slug }: any) => (
<span key={title}>
<NextLink
key={title}
href={`/god-praksis/${slug.current}`}
passHref
legacyBehavior
>
<BodyShort
size="small"
as="a"
className="min-h-8 text-deepblue-800 focus-visible:shadow-focus flex items-center justify-center gap-[2px] rounded-full bg-gray-200 pl-4 pr-1 capitalize no-underline hover:underline focus:outline-none"
>
{title}
<Next aria-hidden />
</BodyShort>
</NextLink>
</span>
))}
</div>
)}
</div>
<div className="relative mx-auto mt-4 max-w-prose lg:ml-0 lg:grid lg:max-w-none lg:grid-flow-row-dense lg:grid-cols-3 lg:items-start lg:gap-x-12">
<TableOfContents
changedState={data?.content ?? []}
hideToc={false}
aksel
/>
<div className="max-w-prose lg:col-span-2 lg:col-start-1">
<SanityBlockContent blocks={data?.content ?? []} variant="aksel" />
<div className="mt-12">
{authors?.length > 0 && (
<Label className="text-deepblue-700 mb-2" as="p">
Bidragsytere
</Label>
)}
{authors?.length > 0 && (
<BodyShort
as="div"
className="text-text-subtle mb-1 flex flex-wrap gap-1"
>
{authors.map(abbrName).map((x, y) => (
<address className="not-italic" key={x}>
{x}
{y !== authors.length - 1 && ", "}
</address>
))}
</BodyShort>
)}
<BodyShort as="span" className="text-text-subtle">
Publisert: {dateStr(data?.publishedAt ?? data?._updatedAt)}
</BodyShort>
</div>
<div className="mt-12 md:mt-16">
<Feedback akselFeedback docId={data?._id} docType={data?._type} />
</div>
</div>
</div>
</NoSidebarLayout>
</>
);
};
export default AkselArtikkelTemplate;
@@ -1,189 +0,0 @@
import { SanityT, urlFor } from "@/lib";
import { SanityBlockContent } from "@/sanity-block";
import { BodyShort, Heading, Ingress, Label } from "@navikt/ds-react";
import cl from "clsx";
import { Header } from "components/layout/header/Header";
import Head from "next/head";
import { Footer } from "..";
import {
abbrName,
Bilde,
BreadCrumbs,
dateStr,
Feedback,
TableOfContents,
} from "../..";
const AkselPrinsippTemplate = ({
data,
title,
}: {
data: SanityT.Schema.aksel_prinsipp;
title: string;
}): JSX.Element => {
if (!data.content || !data.heading) {
console.warn(
`Artikkelen har ikke ${
!data.content ? "innhold" : "overskrift"
}, så den kan ikke vises.`
);
return null;
}
const authors = (data?.contributors as any)?.map((x) => x?.title) ?? [];
const mainPage = data?.prinsipp?.hovedside;
return (
<>
<Head>
<title>{`${data?.heading} - Prinsipp - ${title}`}</title>
<meta
property="og:title"
content={`${data?.heading} - ${title}`}
key="ogtitle"
/>
<meta
property="og:description"
content={data?.seo?.meta ?? data?.ingress}
key="ogdesc"
/>
<meta property="og:type" content="article" />
<meta
property="og:image"
content={
data?.seo?.image
? urlFor(data?.seo?.image)
.width(1200)
.height(630)
.fit("crop")
.quality(100)
.url()
: ""
}
key="ogimage"
/>
</Head>
<Header variant={mainPage ? "default" : "subtle"} />
<main
tabIndex={-1}
id="hovedinnhold"
className={cl("aksel-artikkel pt-4 focus:outline-none", {
"bg-white": mainPage,
"bg-surface-subtle": !mainPage,
})}
>
<article className="overflow-x-clip">
<div
className={cl("max-w-aksel mx-auto px-4 sm:w-[90%]", {
"pb-32": mainPage,
})}
>
<div className="pt-12">
<div className="mx-auto mb-16 max-w-prose lg:ml-0 ">
{!mainPage && (
<BreadCrumbs
text={`Prinsipper for ${data?.prinsipp?.prinsippvalg}`}
href={`/prinsipper/${data?.prinsipp?.prinsippvalg}`}
/>
)}
<Heading
level="1"
size="large"
className="text-deepblue-700 mt-4 md:text-5xl"
>
{data.heading}
</Heading>
{data?.ingress && (
<Ingress className="override-text-700 mt-5 text-2xl">
{data?.ingress}
</Ingress>
)}
<div className="mt-6 flex gap-3 text-base">
<BodyShort
size="small"
as="span"
className="text-text-subtle "
>
{dateStr(data?._updatedAt)}
</BodyShort>
{authors?.length > 0 && (
<BodyShort
size="small"
as="div"
className="flex flex-wrap gap-1"
>
<address className="not-italic">{authors[0]}</address>
</BodyShort>
)}
</div>
</div>
</div>
</div>
<div
className={cl("pt-32", {
"bg-gray-100": mainPage,
})}
>
<div className="max-w-aksel mx-auto px-4 sm:w-[90%]">
<div className="pb-16 md:pb-32">
<div className="relative mx-auto mt-4 max-w-prose lg:ml-0 lg:grid lg:max-w-none lg:grid-flow-row-dense lg:grid-cols-3 lg:items-start lg:gap-x-12">
<TableOfContents
changedState={data?.content ?? []}
hideToc={false}
aksel
/>
<div className="max-w-prose lg:col-span-2 lg:col-start-1">
{data?.hero_bilde && (
<Bilde
node={data.hero_bilde as any}
className="-mt-36 mb-10 sm:-mt-72"
/>
)}
<SanityBlockContent
blocks={data?.content ?? []}
variant="aksel"
/>
<div className="mt-12">
{authors?.length > 0 && (
<Label className="text-deepblue-700 mb-2" as="p">
Bidragsytere
</Label>
)}
{authors?.length > 0 && (
<BodyShort
as="div"
className="text-text-subtle mb-1 flex flex-wrap gap-1"
>
{authors.map(abbrName).map((x, y) => (
<address className="not-italic" key={x}>
{x}
{y !== authors.length - 1 && ", "}
</address>
))}
</BodyShort>
)}
<BodyShort as="span" className="text-text-subtle ">
Publisert:{" "}
{dateStr(data?.publishedAt ?? data?._updatedAt)}
</BodyShort>
</div>
<div className="mt-12 md:mt-16">
<Feedback
akselFeedback
docId={data?._id}
docType={data?._type}
/>
</div>
</div>
</div>
</div>
</div>
</div>
</article>
</main>
<Footer />
</>
);
};
export default AkselPrinsippTemplate;
@@ -1,28 +0,0 @@
import { Footer } from "@/layout";
import { Header } from "components/layout/header/Header";
import React from "react";
export const NoSidebarLayout = ({
children,
aside = null,
}: {
children: React.ReactNode;
aside?: React.ReactNode;
}) => {
return (
<>
<Header variant="subtle" />
<main
tabIndex={-1}
id="hovedinnhold"
className="aksel-artikkel bg-surface-subtle pt-4 focus:outline-none"
>
<div className="max-w-aksel mx-auto px-4 sm:w-[90%]">
<article className="pt-12 pb-16 md:pb-32">{children}</article>
</div>
{aside}
</main>
<Footer />
</>
);
};
@@ -1,4 +1,4 @@
import { SidebarT } from "@/lib";
import { AkselSidebarT } from "@/types";
import { logNav } from "@/utils";
import { Expand } from "@navikt/ds-icons";
import { BodyShort, Detail, Tag } from "@navikt/ds-react";
@@ -80,7 +80,13 @@ const NavItem = ({
);
};
const Dropdown = ({ title, links }: { title: string; links: SidebarT }) => {
const Dropdown = ({
title,
links,
}: {
title: string;
links: AkselSidebarT;
}) => {
const [open, setOpen] = useState(true);
const { asPath } = useRouter();
@@ -125,7 +131,7 @@ export const Sidebar = ({
links,
}: {
kategori: "Komponenter" | "Grunnleggende";
links: SidebarT;
links: AkselSidebarT;
}) => {
const sections = useMemo(
() =>
@@ -4,11 +4,7 @@ import { SanityT } from "@/lib";
import { withErrorBoundary } from "@/error-boundary";
import { SanityBlockContent } from "@/sanity-block";
const Accordion = ({
node,
}: {
node: SanityT.Schema.accordion;
}): JSX.Element => {
const Accordion = ({ node }: { node: SanityT.Schema.accordion }) => {
if (!node || node.list.length === 0) {
return null;
}
@@ -3,11 +3,7 @@ import React from "react";
import { SanityT } from "@/lib";
import { SanityBlockContent } from "@/sanity-block";
const Alert = ({
node,
}: {
node: SanityT.Schema.alert & { _key: string };
}): JSX.Element => {
const Alert = ({ node }: { node: SanityT.Schema.alert & { _key: string } }) => {
return (
<div className="mb-7 max-w-2xl">
<DsAlert variant={node.variant}>
@@ -1,21 +1,13 @@
/* eslint-disable @next/next/no-img-element */
import { SanityT, urlFor } from "@/lib";
import { urlFor } from "@/lib";
import { Heading } from "@navikt/ds-react";
import Nextlink from "next/link";
import cl from "clsx";
import Image from "next/legacy/image";
import { StatusTag } from "components/website-modules/StatusTag";
import { ArticleListT } from "@/types";
const ComponentOverview = ({
node,
}: {
node: {
_id: string;
heading: string;
slug: { current: string };
status?: SanityT.Schema.komponent_artikkel["status"];
}[];
}): JSX.Element => {
const ComponentOverview = ({ node }: { node: ArticleListT }) => {
if (!node || node.length === 0) {
return null;
}
@@ -40,7 +32,7 @@ const ComponentOverview = ({
return (
<div className="mb-8">
<ul className="component-card-grid">
<ul className="grid grid-cols-[repeat(auto-fill,_minmax(min(17rem,_100%),_1fr))] gap-6">
{sorted.map((x) => (
<li key={x._id}>
<div className="bg-surface-subtle focus-within:ring-border-focus ring-border-subtle hover:shadow-medium min-h-56 group relative rounded-2xl focus-within:ring-[3px] hover:ring-1">
@@ -38,20 +38,17 @@ const Element = ({
block,
}: {
block: Sanity.Keyed<SanityT.Schema.do_dont_block>;
}): JSX.Element => {
}) => {
if (!block.picture) return null;
return (
<figure
className={cl(
"flex min-w-full flex-1 flex-col rounded-t sm:min-w-[320px]",
{
"basis-full": block?.fullwidth,
"max-w-sm": !block?.fullwidth,
}
)}
className={cl("sm:min-w-80 flex min-w-full flex-1 flex-col rounded-t", {
"basis-full": block?.fullwidth,
"max-w-sm": !block?.fullwidth,
})}
>
<img
className="rounded-t bg-gray-50 shadow-[0_0_0_1px_var(--a-border-divider)]"
className="ring-border-subtle rounded-t bg-gray-50 ring-1"
alt={block.alt}
loading="lazy"
decoding="async"
@@ -61,9 +58,9 @@ const Element = ({
className={cl(
"z-10 -ml-[1px] w-[calc(100%_+_2px)] rounded-b border-t-8",
{
"border-t-green-400": block.variant === "do",
"border-t-red-400": block.variant === "dont",
"border-t-orange-500": block.variant === "warning",
"border-t-border-success": block.variant === "do",
"border-t-border-danger": block.variant === "dont",
"border-t-border-warning": block.variant === "warning",
}
)}
/>
@@ -87,7 +84,7 @@ const DoDont = ({ node }: { node: SanityT.Schema.do_dont }) => {
return (
<div className="mb-8 last:mb-0">
{node?.blokker?.length > 0 && (
<div className="last flex flex-wrap justify-start gap-8">
<div className="last flex flex-wrap justify-start gap-6">
{node.blokker.map((x) => (
<Element key={x._key} block={x} />
))}
@@ -0,0 +1,41 @@
import { SanityBlockContent } from "@/sanity-block";
import { ExpansionCard as DsExpansionCard } from "@navikt/ds-react";
import { withErrorBoundary } from "@/error-boundary";
const ExpansionCard = ({
node,
}: {
node: {
heading: string;
heading_level: "h3" | "h4";
description?: string;
body: any[];
};
}) => {
if (!node.heading || !node.body || !node.heading_level) {
return null;
}
return (
<DsExpansionCard className="mb-7 max-w-2xl" aria-label={node.heading}>
<DsExpansionCard.Header>
<DsExpansionCard.Title
as={node.heading_level}
size={node.heading_level === "h3" ? "medium" : "small"}
>
{node.heading}
</DsExpansionCard.Title>
{node?.description && (
<DsExpansionCard.Description>
{node.description}
</DsExpansionCard.Description>
)}
</DsExpansionCard.Header>
<DsExpansionCard.Content>
<SanityBlockContent blocks={node.body} noLastMargin />
</DsExpansionCard.Content>
</DsExpansionCard>
);
};
export default withErrorBoundary(ExpansionCard, "ExpansionCard");
@@ -1,15 +1,15 @@
import { LevelTwoHeading } from "@/components";
import { withErrorBoundary } from "@/error-boundary";
import { SanityT } from "@/lib";
import { SanityBlockContent } from "@/sanity-block";
import { AkselGrunnleggendeDocT, AkselKomponentDocT } from "@/types";
import { Label } from "@navikt/ds-react";
import React from "react";
const Intro = ({
node,
}: {
node: SanityT.Schema.intro_komponent;
}): JSX.Element => {
node: AkselKomponentDocT["intro"] | AkselGrunnleggendeDocT["intro"];
}) => {
if (!node || !node.body || !node.brukes_til) {
return null;
}
@@ -2,7 +2,7 @@ import { Snippet } from "@/components";
import { withErrorBoundary } from "@/error-boundary";
import { SanityT } from "@/lib";
const Kode = ({ node }: { node: SanityT.Schema.kode }): JSX.Element => {
const Kode = ({ node }: { node: SanityT.Schema.kode }) => {
if (!node || !node.code) {
return null;
}
@@ -12,7 +12,7 @@ type SpesialT = {
token?: { title: string; kategori: string };
};
const SideModul = ({ node }: { node: SpesialT }): JSX.Element => {
const SideModul = ({ node }: { node: SpesialT }) => {
if (!node || !node.modul) {
return null;
}
@@ -2,11 +2,7 @@ import { withErrorBoundary } from "@/error-boundary";
import { SanityT } from "@/lib";
import { Table } from "@navikt/ds-react";
const TableComponent = ({
node,
}: {
node: SanityT.Schema.tabell_v2;
}): JSX.Element => {
const TableComponent = ({ node }: { node: SanityT.Schema.tabell_v2 }) => {
if (!node || !node.rows || node.rows.length < 2) {
return null;
}
@@ -12,11 +12,7 @@ const KBD = (props: React.HTMLAttributes<HTMLElement>) => (
/>
);
const UuSeksjon = ({
node,
}: {
node: SanityT.Schema.tastatur_modul;
}): JSX.Element => {
const UuSeksjon = ({ node }: { node: SanityT.Schema.tastatur_modul }) => {
if (!node || !node?.tastatur) {
return null;
}
@@ -1,4 +1,4 @@
import { FeedbackT } from "@/lib";
import { FeedbackT } from "@/types";
import { IdContext } from "@/utils";
import { Button, Heading, Textarea } from "@navikt/ds-react";
import cl from "classnames";
@@ -16,7 +16,7 @@ const Video = ({
transkripsjon?: string;
caption?: string;
};
}): JSX.Element => {
}) => {
const [open, setOpen] = useState(false);
if (
@@ -19,7 +19,7 @@ const Bilde = ({
dekorativt?: boolean;
};
className?: string;
}): JSX.Element => {
}) => {
if (!node || !node.asset) {
return null;
}
@@ -1,5 +1,11 @@
import { withErrorBoundary } from "@/error-boundary";
import { SanityT } from "@/lib";
import {
ResolveContributorsSingleT,
ResolveTemaT,
ResolveSlugT,
AkselGodPraksisDocT,
} from "@/types";
import { BodyShort, Detail, Heading } from "@navikt/ds-react";
import NextLink from "next/link";
import { abbrName, dateStr, logNav } from "../..";
@@ -16,16 +22,9 @@ const ArtikkelCard = ({
tema,
level = "2",
...rest
}: Partial<
(SanityT.Schema.aksel_artikkel | SanityT.Schema.aksel_blogg) & {
slug: string;
tema: string[];
source?: string;
contributor: { title: string } | null;
variant?: "god-praksis" | "tema";
level?: "2" | "3" | "4";
}
>) => {
}: ResolveContributorsSingleT<
ResolveTemaT<ResolveSlugT<AkselGodPraksisDocT>>
> & { source: string; variant: string; level?: "2" | "3" }) => {
const date = (rest as any)?.updateInfo?.lastVerified
? (rest as any)?.updateInfo?.lastVerified
: publishedAt
@@ -33,7 +32,7 @@ const ArtikkelCard = ({
: _updatedAt;
return (
<div className="hover:shadow-small focus-within:ring-border-focus bg-surface-default ring-border-subtle group relative rounded-lg p-5 pb-16 ring-1 focus-within:ring-[3px]">
<div className="hover:shadow-small focus-within:ring-border-focus bg-surface-default ring-border-subtle group relative rounded-lg p-3 pb-16 ring-1 focus-within:ring-[3px] sm:p-5 sm:pb-16">
<NextLink
href={{
pathname: `/${slug}`,
@@ -1,5 +1,5 @@
import { withErrorBoundary } from "@/error-boundary";
import { SanityT } from "@/lib";
import { AkselBloggDocT, ResolveContributorsT, ResolveSlugT } from "@/types";
import { BodyLong, BodyShort, Heading, Link } from "@navikt/ds-react";
import { getAuthors } from "components/website-modules/LatestBloggs";
import NextLink from "next/link";
@@ -8,17 +8,13 @@ import { dateStr, logNav } from "../..";
const BloggCard = ({
blog,
}: {
blog: Partial<
SanityT.Schema.aksel_blogg & {
slug: string;
contributors?: {
title?: string;
}[];
}
>;
blog: ResolveContributorsT<ResolveSlugT<AkselBloggDocT>>;
}) => {
return (
<li key={blog._id} className="border-b-border-subtle h-fit border-b pb-8">
<li
key={blog._id}
className="border-b-border-subtle flex h-full flex-col place-content-start border-b pb-8"
>
<Heading size="medium" as="div">
<NextLink href={`/${blog.slug}`} passHref legacyBehavior>
<Link
@@ -35,9 +31,12 @@ const BloggCard = ({
</Link>
</NextLink>
</Heading>
<BodyLong className="mt-2">{blog?.ingress}</BodyLong>
<BodyLong className="my-2">{blog?.ingress}</BodyLong>
{getAuthors(blog).length > 0 && (
<BodyShort size="small" className="text-text-subtle mt-6 flex gap-2">
<BodyShort
size="small"
className="text-text-subtle mt-auto flex gap-2 justify-self-end"
>
<span className="font-semibold">{getAuthors(blog)[0]}</span>
<span>{dateStr(blog?.publishedAt ?? blog._createdAt)}</span>
</BodyShort>
@@ -1,14 +1,11 @@
import { withErrorBoundary } from "@/error-boundary";
import { urlFor } from "@/lib";
import { AkselTemaT } from "@/types";
import { logNav } from "@/utils";
import { BodyShort } from "@navikt/ds-react";
import cl from "clsx";
import NextLink from "next/link";
import Image from "next/legacy/image";
import { logNav } from "@/utils";
import { SanityT, urlFor } from "@/lib";
interface AkselTemaT extends SanityT.Schema.aksel_tema {
refCount: number;
}
import NextLink from "next/link";
const GodPraksisCard = ({ node }: { node: AkselTemaT }) => {
if (
@@ -0,0 +1,43 @@
import { withErrorBoundary } from "@/error-boundary";
import { urlFor } from "@/lib";
import { AkselTemaT } from "@/types";
import { logNav } from "@/utils";
import Image from "next/legacy/image";
import NextLink from "next/link";
const GodPraksisCardSimple = ({ node }: { node: Partial<AkselTemaT> }) => {
if (!node?.pictogram || !node?.slug?.current || !node?.title) {
return null;
}
return (
<li className="flex items-center gap-2 px-2 py-4 sm:gap-4 sm:px-6">
<div className="relative h-8 w-8 shrink-0 sm:h-12 sm:w-12">
<Image
src={urlFor(node?.pictogram).auto("format").url()}
decoding="sync"
layout="fill"
objectFit="contain"
aria-hidden
priority
/>
</div>
<NextLink
href={`/god-praksis/${node.slug.current}`}
passHref
onClick={(e) =>
logNav(
"card",
window.location.pathname,
e.currentTarget.getAttribute("href")
)
}
className="navds-heading--small navds-link text-deepblue-700 navds-heading flex-wrap break-all no-underline hover:underline focus:outline-none"
>
{node.title}
</NextLink>
</li>
);
};
export default withErrorBoundary(GodPraksisCardSimple, "GodPraksisCardSimple");
@@ -10,7 +10,7 @@ const RelatertInnhold = ({
node,
}: {
node: SanityT.Schema.relatert_innhold;
}): JSX.Element => {
}) => {
if (!node || node?.lenker?.length === 0) {
return null;
}
@@ -16,7 +16,7 @@ const ComponentExamples = ({
dir?: SanityT.Schema.kode_eksempler_fil;
filnavn?: SanityT.Schema.kode_eksempler_fil;
};
}): JSX.Element => {
}) => {
const [activeExample, setActiveExample] = useState(null);
const [frameState, setFrameState] = useState(300);
const [unloaded, setUnloaded] = useState(true);
@@ -13,7 +13,7 @@ const CodeSnippet = ({
node: SanityT.Schema.kode;
className?: string;
style?: any;
}): JSX.Element => {
}) => {
if (!code || !code.code) {
return null;
}
@@ -0,0 +1,136 @@
import { abbrName, dateStr } from "@/utils";
import { BodyShort, Detail, Heading } from "@navikt/ds-react";
import { logNav } from "components/website-modules/utils/amplitude";
import NextLink from "next/link";
import NextImage from "next/legacy/image";
import { Tag } from "./Tag";
import cl from "clsx";
import { urlFor } from "lib/sanity/santiy";
import { getImage } from "components/website-modules/utils/get-image";
export type ArticleT = {
_key: string;
_type: string;
_createdAt: string;
_updatedAt: string;
_id: string;
heading: string;
ingress?: string;
slug: { current: string };
seo?: {
meta?: string;
image?: any;
};
tema?: string[];
status?: { tag: string; bilde?: any };
publishedAt: string;
contributors?: { title: string }[];
};
export const Card = ({ article }: { article: ArticleT }) => {
const date = article.publishedAt ? article.publishedAt : article._updatedAt;
const showFooter = ["aksel_artikkel", "aksel_blogg"].includes(article._type);
const showImage = [
"ds_artikkel",
"komponent_artikkel",
"aksel_blogg",
].includes(article._type);
return (
<div
className={cl(
"bg-surface-default group relative rounded-lg",
"focus-within:ring-border-focus ring-border-subtle-hover focus-within:ring-[3px]",
"shadow-[0_0_1px_rgb(0_0_0/0.3),0_1px_3px_rgb(0_0_0/0.15)]"
)}
>
{showImage && (
<div
className={cl(
"flex max-h-80 items-center justify-center overflow-hidden rounded-t-lg",
"bg-deepblue-200 filter",
{
"hue-rotate-[65deg]": article?.status?.tag === "beta",
}
)}
>
{article.status?.bilde ?? article.seo?.image ? (
article.status?.bilde ? (
<NextImage
src={urlFor(article.status?.bilde).auto("format").url()}
width="200"
height="200"
alt={article.heading + " thumbnail"}
aria-hidden
/>
) : (
<div className="relative h-[200px] w-full">
<NextImage
src={urlFor(article.seo?.image).auto("format").url()}
layout="fill"
objectFit="cover"
alt={article.heading + " thumbnail"}
aria-hidden
className="rounded-t-lg"
/>
</div>
)
) : (
<div className="relative h-[200px] w-full">
<NextImage
layout="fill"
objectFit="cover"
src={getImage(article?.heading ?? "", "thumbnail")}
alt={article.heading + " thumbnail"}
aria-hidden
className="rounded-t-lg"
/>
</div>
)}
</div>
)}
<div className={cl("p-3 sm:p-5", showFooter && "pb-16 sm:pb-16")}>
<div className="flex flex-col-reverse">
<NextLink
href={`/${article.slug}`}
passHref
className="after:absolute after:inset-0 after:z-10 after:rounded-lg focus:outline-none"
onClick={(e) =>
logNav(
"forside-masonary",
window.location.pathname,
e.currentTarget.getAttribute("href")
)
}
>
<Heading level="3" size="small" className="group-hover:underline">
{article.heading}
</Heading>
</NextLink>
<Tag
type={article._type}
text={article.tema ? article.tema[0] : undefined}
size="small"
beta={article.status?.tag === "beta"}
/>
</div>
{article.ingress ? (
<BodyShort className="mt-2">{article.ingress}</BodyShort>
) : article.seo.meta ? (
<BodyShort className="mt-2">{article.seo.meta}</BodyShort>
) : null}
{showFooter && (
<span className="text-text-subtle absolute bottom-5 flex gap-2">
{article?.contributors && (
<Detail as="span" className="font-semibold">
{abbrName(article?.contributors[0]?.title)}
</Detail>
)}
<Detail as="span">{dateStr(date)}</Detail>
</span>
)}
</div>
</div>
);
};
@@ -0,0 +1,23 @@
import Latest, { LatestT } from "./Latest";
import { withErrorBoundary } from "@/error-boundary";
export type BlocksT = LatestT;
export const FrontpageBlock = ({ blocks }: { blocks: BlocksT[] }) => {
if (!blocks || !blocks.length) {
return null;
}
return (
<div className="lg:px-18 px-2">
{blocks.map((x) => {
switch (x._type) {
case "nytt_fra_aksel":
return <Latest block={x} key={x._key} />;
default:
return null;
}
})}
</div>
);
};
export default withErrorBoundary(FrontpageBlock, "FrontpageBlock");
@@ -0,0 +1,166 @@
import { BodyLong, BodyShort, Heading, Link } from "@navikt/ds-react";
import Masonry, { ResponsiveMasonry } from "react-responsive-masonry";
import { withErrorBoundary } from "@/error-boundary";
import Image from "next/legacy/image";
import NextLink from "next/link";
import { urlFor } from "lib/sanity/santiy";
import { getImage } from "components/website-modules/utils/get-image";
import { getAuthors } from "components/website-modules/LatestBloggs";
import { dateStr, logNav } from "@/utils";
import { Tag } from "./Tag";
import { Card, ArticleT } from "./Card";
import cl from "clsx";
export type LatestT = {
_type: "nytt_fra_aksel";
_key: string;
highlights: ArticleT[];
curatedResent: {
artikler: ArticleT[];
bloggposts: ArticleT[];
komponenter: ArticleT[];
};
};
const Latest = ({ block }: { block: LatestT }) => {
const highlights = block.highlights?.length;
const articles = getList(block);
return (
<>
<Heading level="2" size="xlarge" className="text-deepblue-800 mb-10">
Siste fra Aksel
</Heading>
{highlights && <Highlights highlights={block.highlights} />}
<section aria-label="Nyeste artikler fra Aksel" className="mt-20">
<ResponsiveMasonry
columnsCountBreakPoints={{ 480: 1, 768: 2, 1024: 3 }}
>
<Masonry gutter="1.5rem">
{articles.map((x) => (
<Card key={x._id} article={x} />
))}
</Masonry>
</ResponsiveMasonry>
</section>
</>
);
};
function Highlights({ highlights }: { highlights: ArticleT[] }) {
return (
<div
className={cl({ "grid gap-8 md:grid-cols-2": highlights?.length === 2 })}
>
{highlights.map((x, idx) => {
const showFooter = ["aksel_artikkel", "aksel_blogg"].includes(x._type);
const useStatusImage =
["ds_artikkel", "komponent_artikkel"].includes(x._type) &&
x.status?.bilde;
return (
<section
aria-label={`Fremhevet artikkel: ${x?.heading}`}
key={idx}
className={cl({
"grid content-start gap-8 md:grid-cols-2":
highlights?.length === 1,
"grid content-start gap-6": highlights?.length === 2,
})}
>
<div className="relative block aspect-video">
{useStatusImage ? (
<Image
src={urlFor(x.status.bilde).quality(100).auto("format").url()}
quality={100}
layout="fill"
aria-hidden
priority
className={cl(
"bg-deepblue-200 rounded-lg object-cover sm:object-contain",
{
"hue-rotate-[65deg]": x?.status?.tag === "beta",
}
)}
decoding="sync"
/>
) : x?.seo?.image ? (
<Image
src={urlFor(x.seo.image).quality(100).auto("format").url()}
quality={100}
layout="fill"
objectFit="cover"
aria-hidden
priority
className={cl("rounded-lg", {
"hue-rotate-[65deg]": x?.status?.tag === "beta",
})}
decoding="sync"
/>
) : (
<Image
src={getImage(x?.heading ?? "", "thumbnail")}
layout="fill"
objectFit="contain"
aria-hidden
priority
className="rounded-lg"
decoding="sync"
/>
)}
</div>
<div>
<Tag
type={x._type}
text={x.tema ? x.tema[0] : undefined}
beta={x?.status?.tag === "beta"}
/>
<NextLink href={`/${x.slug.current}`} passHref legacyBehavior>
<Link
onClick={(e) =>
logNav(
"artikkel-kort",
window.location.pathname,
e.currentTarget.getAttribute("href")
)
}
className="text-text-default mb-5 mt-2 no-underline hover:underline"
>
<Heading size="large" level="3">
{x?.heading}
</Heading>
</Link>
</NextLink>
<BodyLong className="mb-4" size="small">
{x?.ingress ?? x.seo?.meta}
</BodyLong>
{showFooter && getAuthors(x as any).length > 0 && (
<BodyShort size="small" className="text-text-subtle flex gap-2">
<span className="font-semibold">
{getAuthors(x as any)[0]}
</span>
<span>{dateStr(x?.publishedAt ?? x._createdAt)}</span>
</BodyShort>
)}
</div>
</section>
);
})}
</div>
);
}
function getList(block: LatestT) {
return [
...block.curatedResent.artikler,
...block.curatedResent.bloggposts,
...block.curatedResent.komponenter,
].sort((a, b) => {
return (
new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime()
);
});
}
export default withErrorBoundary(Latest, "Latest");
@@ -0,0 +1,60 @@
import { Heading, Label, Tag as DsTag } from "@navikt/ds-react";
import cl from "clsx";
export const Tag = ({
type,
text,
size = "medium",
beta = false,
}: {
type: string;
text?: string;
size?: "medium" | "small";
beta?: boolean;
}) => {
const Comp = ({ ...props }: any) =>
size === "medium" ? (
<Heading {...props} as="div" size="medium" />
) : (
<Label
{...props}
as="div"
size="small"
className={cl(props?.className, "mb-2")}
/>
);
switch (type) {
case "aksel_artikkel":
return (
<Comp className="text-teal-600">{text ? text : "God praksis"}</Comp>
);
case "aksel_blogg":
return <Comp className="text-pink-600">Blogg</Comp>;
case "komponent_artikkel":
return (
<Comp className="text-deepblue-600 flex items-center gap-3">
Komponent
{beta && (
<DsTag variant="alt1" size="small">
Beta
</DsTag>
)}
</Comp>
);
case "ds_artikkel":
return (
<Comp className="text-deepblue-600 flex items-center gap-3">
Grunnleggende
{beta && (
<DsTag variant="alt1" size="small">
Beta
</DsTag>
)}
</Comp>
);
default:
return null;
}
};
@@ -4,7 +4,7 @@ export const Highlighter = ({
}: {
type: string;
prev?: string;
}): JSX.Element => {
}) => {
const isString = type === "string" || type.match(/^["][^"]+"$/) !== null;
const isType =
@@ -51,7 +51,7 @@ const List = ({ prop, parent }: { prop: any; parent: string }) => {
);
};
const PropTable = ({ komponent }: { komponent: PropT }): JSX.Element => {
const PropTable = ({ komponent }: { komponent: PropT }) => {
return (
<div>
<Heading
@@ -2,7 +2,7 @@ import React from "react";
import { withErrorBoundary } from "@/error-boundary";
import PropTableV2, { PropT } from "./PropTabell";
const PropsSeksjon = ({ node }: { node: any }): JSX.Element => {
const PropsSeksjon = ({ node }: { node: any }) => {
if (
!node ||
(node?.elementer?.length === 0 && node?.komponenter?.length === 0)
@@ -7,7 +7,7 @@ import cl from "clsx";
import React from "react";
import style from "./tips.module.css";
const Tips = ({ node }: { node: SanityT.Schema.tips }): JSX.Element => {
const Tips = ({ node }: { node: SanityT.Schema.tips }) => {
if (!node || !node.body) {
return null;
}
@@ -23,7 +23,7 @@ export const Frame = ({
{hasDescription && <th>Beskrivelse</th>}
</tr>
</thead>
<tbody className="component-token-grid">
<tbody className="component-token-grid grid grid-cols-[repeat(auto-fill,_minmax(min(20rem,_100%),_1fr))] gap-4">
{tokens.map((c) => (
<tr
key={c.name}
@@ -57,7 +57,7 @@ const CubeSmall = () => (
export const BloggAd = () => {
return (
<div className="full-bleed my-20 flex h-72 items-center bg-[#FBCFE8] px-4 md:rounded-2xl md:px-6 lg:h-80 lg:pl-12">
<div className="relative left-1/2 right-1/2 -mx-[50vw] my-20 flex h-72 w-screen items-center bg-[#FBCFE8] px-4 md:left-auto md:right-auto md:mx-auto md:w-full md:max-w-[85%] md:rounded-2xl md:px-6 lg:h-80 lg:pl-12">
<div className="z-10 max-w-sm text-[#831843]">
<Heading level="2" size="xlarge" spacing>
Skriv for bloggen
@@ -3,7 +3,7 @@ import { Tooltip } from "@navikt/ds-react";
import { useContext } from "react";
import { IdContext, useCheckAuth } from "./utils";
function EditButton(): JSX.Element {
function EditButton() {
const idCtx = useContext(IdContext);
const validUser = useCheckAuth();
@@ -12,7 +12,7 @@ function EditButton(): JSX.Element {
<>
<div className="overflow-hidden">
<Tooltip
content="Bare tilgjengelig for innloggede redaktører"
content="Vises bare for innloggede redaktører"
placement="left"
delay={500}
>
@@ -10,7 +10,7 @@ export const LevelTwoHeading = ({
children: [React.ReactNode | string];
hidden?: boolean;
id: string;
}): JSX.Element => {
}) => {
return (
<>
{hidden && <div id={id} className="scroll-m-18" />}
@@ -0,0 +1,56 @@
import { logNav } from "components/website-modules/utils/amplitude";
import Link from "next/link";
import cl from "clsx";
export const IntroCards = ({
links,
className,
variant,
}: {
links: {
title: string;
desc: string;
icon: React.FC<any>;
href: string;
}[];
className?: string;
variant?: "forside" | "komponentside";
}) => {
return (
<ul className={cl("grid w-full gap-4 md:gap-6", className)}>
{links.map(({ icon: Icon, title, desc, href }) => (
<li key={title} className="grid">
<Link
href={href}
passHref
className={cl(
"focus-visible:shadow-focus ring-border-subtle text-deepblue-700 bg-surface-default hover:shadow-small hover:ring-border-subtle group z-10 rounded-lg p-4 ring-1 hover:ring-1 focus:outline-none",
{
"shadow-small max-w-md": variant === "forside",
}
)}
onClick={(e) =>
logNav(
"intro-kort",
window.location.pathname,
e.currentTarget.getAttribute("href")
)
}
>
<span className="flex items-center gap-2">
<Icon
aria-hidden
className="text-deepblue-500 shrink-0 text-2xl"
role="img"
/>
<span className="text-xl font-semibold group-hover:underline">
{title}
</span>
</span>
<div className="text-text-default mt-2">{desc}</div>
</Link>
</li>
))}
</ul>
);
};
@@ -1,32 +1,24 @@
import Image from "next/legacy/image";
import NextLink from "next/link";
import { urlFor } from "@/lib";
import { SanityBlockContent } from "@/sanity-block";
import { AkselBloggDocT, ResolveContributorsT, ResolveSlugT } from "@/types";
import { dateStr } from "@/utils";
import { BodyLong, BodyShort, Heading, Link } from "@navikt/ds-react";
import { SanityT, urlFor } from "@/lib";
import cl from "clsx";
import { getImage } from "components/website-modules/utils/get-image";
import { SanityBlockContent } from "@/sanity-block";
import Image from "next/legacy/image";
import NextLink from "next/link";
export type BloggPageT = Partial<
SanityT.Schema.aksel_blogg & {
slug: string;
contributors?: { title?: string }[];
}
>;
export const getAuthors = (blog: BloggPageT) =>
(blog?.contributors as any)?.map((x) => x?.title) ?? [];
export const getAuthors = (
blog: ResolveContributorsT<ResolveSlugT<AkselBloggDocT>>
) => (blog?.contributors as any)?.map((x) => x?.title) ?? [];
export const LatestBloggposts = ({
bloggs,
title,
variant = "blogg",
level = "1",
intro,
}: {
bloggs: BloggPageT[];
bloggs: ResolveContributorsT<ResolveSlugT<AkselBloggDocT>>[];
title: string;
variant?: "blogg" | "forside";
level?: "1" | "2";
intro?: any[];
}) => {
@@ -35,18 +27,11 @@ export const LatestBloggposts = ({
}
return (
<div
className={cl({
"mt-20": variant === "blogg",
})}
>
<div className="mt-20">
<Heading
level={level}
size="xlarge"
className={cl(
"text-deepblue-800 mx-auto w-full md:mx-0 md:max-w-none",
{ "text-5xl": variant === "blogg" }
)}
className="text-deepblue-700 mx-auto w-full text-5xl md:mx-0 md:max-w-none"
>
{title}
</Heading>
@@ -59,18 +44,8 @@ export const LatestBloggposts = ({
/>
)}
{/* Desktop-view */}
<div
className={cl("hidden gap-12", {
"my-10 md:flex": variant === "forside",
"my-20 grid-cols-2 md:grid": variant === "blogg",
})}
>
<div
className={cl({
"flex-auto grow-[4]": variant === "forside",
"col-span-1": variant === "blogg",
})}
>
<div className="my-12 hidden grid-cols-2 gap-12 md:grid">
<div className="col-span-1">
<div className="relative mb-10 block aspect-video">
{bloggs[0]?.seo?.image ? (
<Image
@@ -123,90 +98,67 @@ export const LatestBloggposts = ({
</BodyShort>
)}
</div>
<div
className={cl("gap-12", {
"flex flex-auto grow-[1] place-items-start": variant === "forside",
"col-span-1 grid": variant === "blogg",
})}
>
<div className={cl("grid gap-12")}>
{bloggs.slice(1, 4).map((blog) => (
<div
key={blog._id}
className={cl("flex gap-6", {
"border-b-border-subtle border-b pb-8": variant === "forside",
})}
>
{variant === "blogg" && (
<div className="relative hidden aspect-square h-[11.75rem] lg:block">
{blog?.seo?.image ? (
<Image
src={urlFor(blog.seo.image).auto("format").url()}
layout="fill"
objectFit="cover"
aria-hidden
priority
className="rounded-lg"
/>
) : (
<Image
src={getImage(blog?.heading ?? "", "thumbnail")}
layout="fill"
objectFit="cover"
aria-hidden
priority
className="rounded-lg"
/>
)}
</div>
<div className="col-span-1 grid place-content-start gap-12">
{bloggs.slice(1, 3).map((blog) => (
<div key={blog._id} className="flex gap-6">
<div className="relative hidden aspect-square h-[11.75rem] lg:block">
{blog?.seo?.image ? (
<Image
src={urlFor(blog.seo.image).auto("format").url()}
layout="fill"
objectFit="cover"
aria-hidden
priority
className="rounded-lg"
/>
) : (
<Image
src={getImage(blog?.heading ?? "", "thumbnail")}
layout="fill"
objectFit="cover"
aria-hidden
priority
className="rounded-lg"
/>
)}
<div>
<NextLink href={`/${blog.slug}`} passHref legacyBehavior>
<Link className="text-deepblue-500 no-underline hover:underline">
<Heading
size="small"
level={(Number(level) + 1).toString() as any}
>
{blog.heading}
</Heading>
</Link>
</NextLink>
<BodyLong className="mt-4" size="small">
{blog?.ingress}
</BodyLong>
{getAuthors(blog).length > 0 ? (
<BodyShort
size="small"
className="text-text-subtle mt-4 flex gap-2"
>
<span className="font-semibold">
{getAuthors(blog)[0]}
</span>
<span>
{dateStr(blog?.publishedAt ?? blog._createdAt)}
</span>
</BodyShort>
) : (
<BodyShort size="small" className="text-text-subtle mt-4">
<span>
{dateStr(blog?.publishedAt ?? blog._createdAt)}
</span>
</BodyShort>
)}
</div>
</div>
))}
</div>
<div>
<NextLink href={`/${blog.slug}`} passHref legacyBehavior>
<Link className="text-deepblue-500 no-underline hover:underline">
<Heading
size="small"
level={(Number(level) + 1).toString() as any}
>
{blog.heading}
</Heading>
</Link>
</NextLink>
<BodyLong className="mt-4" size="small">
{blog?.ingress}
</BodyLong>
{getAuthors(blog).length > 0 ? (
<BodyShort
size="small"
className="text-text-subtle mt-4 flex gap-2"
>
<span className="font-semibold">{getAuthors(blog)[0]}</span>
<span>{dateStr(blog?.publishedAt ?? blog._createdAt)}</span>
</BodyShort>
) : (
<BodyShort size="small" className="text-text-subtle mt-4">
<span>{dateStr(blog?.publishedAt ?? blog._createdAt)}</span>
</BodyShort>
)}
</div>
</div>
))}
</div>
</div>
{/* Mobile view */}
<div className="my-10 mx-auto grid gap-12 md:hidden">
<div
className={cl("w-full", {
"border-b-border-subtle border-b pb-8": variant === "forside",
})}
>
<div className="w-full">
<div className="relative mb-10 block aspect-video">
{bloggs[0]?.seo?.image ? (
<Image
@@ -258,36 +210,29 @@ export const LatestBloggposts = ({
)}
</div>
<div className="grid w-full gap-12">
{bloggs.slice(1, 4).map((blog) => (
<div
key={blog._id}
className={cl({
"border-b-border-subtle border-b pb-8": variant === "forside",
})}
>
{variant === "blogg" && (
<div className="relative mb-6 block aspect-video">
{blog?.seo?.image ? (
<Image
src={urlFor(blog.seo.image).auto("format").url()}
layout="fill"
objectFit="cover"
aria-hidden
priority
className="rounded-lg"
/>
) : (
<Image
src={getImage(blog?.heading ?? "", "thumbnail")}
layout="fill"
objectFit="cover"
aria-hidden
priority
className="rounded-lg"
/>
)}
</div>
)}
{bloggs.slice(1, 3).map((blog) => (
<div key={blog._id}>
<div className="relative mb-6 block aspect-video">
{blog?.seo?.image ? (
<Image
src={urlFor(blog.seo.image).auto("format").url()}
layout="fill"
objectFit="cover"
aria-hidden
priority
className="rounded-lg"
/>
) : (
<Image
src={getImage(blog?.heading ?? "", "thumbnail")}
layout="fill"
objectFit="cover"
aria-hidden
priority
className="rounded-lg"
/>
)}
</div>
<div>
<NextLink href={`/${blog.slug}`} passHref legacyBehavior>
<Link className="text-deepblue-500 no-underline hover:underline">
@@ -6,7 +6,7 @@ import { BodyShort, Button } from "@navikt/ds-react";
import Link from "next/link";
import { useRouter } from "next/router";
function PreviewBanner(): JSX.Element {
function PreviewBanner() {
const { asPath } = useRouter();
const validUser = useCheckAuth();
@@ -13,7 +13,7 @@ export function TableOfContents({
changedState: any;
hideToc?: boolean;
aksel?: boolean;
}): JSX.Element {
}) {
const [toc, setToc] = useState<
{ heading: string; id: string; lvl3: { heading: string; id: string }[] }[]
>([]);
Loaded 100 of 189 files, more files were not shown because too many files have changed in this diff. Show more