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
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 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
176 changed files with 4626 additions and 2690 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:
+16
View File
@@ -1,5 +1,21 @@
# @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
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-icons",
"version": "2.7.8",
"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
}
}
+12
View File
@@ -1,5 +1,17 @@
# @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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-codemod",
"version": "2.7.8",
"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.8",
"@navikt/ds-react": "^2.7.8",
"@navikt/ds-icons": "^2.8.5",
"@navikt/ds-react": "^2.8.5",
"clsx": "^1.1.1"
},
"devDependencies": {
+26
View File
@@ -1,5 +1,31 @@
# @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
+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.8",
"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.8",
"@navikt/ds-tokens": "^2.8.5",
"normalize.css": "^8.0.1",
"postcss": "^8.4.0",
"postcss-cli": "^9.0.0",
+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"
+58
View File
@@ -1,5 +1,63 @@
# @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
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "2.7.8",
"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.8",
"@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;
}
+12
View File
@@ -1,5 +1,17 @@
# @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 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tailwind",
"version": "2.7.8",
"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.8",
"@navikt/ds-tokens": "^2.8.5",
"@types/jest": "^29.0.0",
"color": "4.2.3",
"jest": "^29.0.0",
+12
View File
@@ -1,5 +1,17 @@
# @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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tokens",
"version": "2.7.8",
"version": "2.8.5",
"description": "Design-tokens for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
+12
View File
@@ -1,5 +1,17 @@
# @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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-icons",
"version": "2.7.8",
"version": "2.8.5",
"description": "Aksel icons for NAV",
"author": "Aksel | NAV designsystem team",
"repository": {
+12
View File
@@ -1,5 +1,17 @@
# @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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css-internal",
"version": "2.7.8",
"version": "2.8.5",
"description": "CSS for NAV internal Designsystem-components",
"author": "Aksel | NAV designsystem team",
"keywords": [
+48
View File
@@ -1,5 +1,53 @@
# @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
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react-internal",
"version": "2.7.8",
"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.8",
"@navikt/ds-react": "^2.7.8",
"@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.8",
"@navikt/ds-codemod": "^2.7.8",
"@navikt/ds-css": "^2.7.8",
"@navikt/ds-css-internal": "^2.7.8",
"@navikt/ds-icons": "^2.7.8",
"@navikt/ds-react": "^2.7.8",
"@navikt/ds-react-internal": "^2.7.8",
"@navikt/ds-tailwind": "^2.7.8",
"@navikt/ds-tokens": "^2.7.8"
"@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} />,
@@ -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"
@@ -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;
@@ -13,7 +13,7 @@ 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-12 px-4 pt-12 pb-16 md:px-6 xl:grid-cols-5 xl:gap-6">
<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 />
@@ -52,6 +52,13 @@ function Snarveier() {
<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>
);
@@ -1,6 +1,6 @@
import { Button, Label, Textarea } from "@navikt/ds-react";
import { IdContext } from "components/website-modules/utils/contexts/id-context";
import { FeedbackT } from "lib/types/types";
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" 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">
@@ -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);
@@ -223,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
@@ -284,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,7 +38,7 @@ const Element = ({
block,
}: {
block: Sanity.Keyed<SanityT.Schema.do_dont_block>;
}): JSX.Element => {
}) => {
if (!block.picture) return null;
return (
<figure
@@ -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
@@ -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,14 +8,7 @@ import { dateStr, logNav } from "../..";
const BloggCard = ({
blog,
}: {
blog: Partial<
SanityT.Schema.aksel_blogg & {
slug: string;
contributors?: {
title?: string;
}[];
}
>;
blog: ResolveContributorsT<ResolveSlugT<AkselBloggDocT>>;
}) => {
return (
<li
@@ -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 (
@@ -1,12 +1,9 @@
import { withErrorBoundary } from "@/error-boundary";
import NextLink from "next/link";
import Image from "next/legacy/image";
import { urlFor } from "@/lib";
import { AkselTemaT } from "@/types";
import { logNav } from "@/utils";
import { SanityT, urlFor } from "@/lib";
interface AkselTemaT extends SanityT.Schema.aksel_tema {
refCount: number;
}
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) {
@@ -14,7 +11,7 @@ const GodPraksisCardSimple = ({ node }: { node: Partial<AkselTemaT> }) => {
}
return (
<li className="flex items-center gap-2 px-2 py-4 sm:gap-4 sm:px-6">
<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()}
@@ -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();
@@ -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" />}
@@ -1,33 +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 AkselLink from "components/website-modules/AkselLink";
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[];
}) => {
@@ -36,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-700 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>
@@ -169,11 +153,6 @@ export const LatestBloggposts = ({
</div>
</div>
))}
{variant === "forside" && (
<AkselLink href="/produktbloggen" className="h-fit self-end">
Les flere blogginnlegg
</AkselLink>
)}
</div>
</div>
@@ -284,11 +263,6 @@ export const LatestBloggposts = ({
</div>
</div>
))}
{variant === "forside" && (
<AkselLink href="/produktbloggen" className="self-end">
Les flere blogginnlegg
</AkselLink>
)}
</div>
</div>
</div>
@@ -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 }[] }[]
>([]);
@@ -13,7 +13,7 @@ export function TableOfContentsv2({
changedState: any;
hideToc?: boolean;
aksel?: boolean;
}): JSX.Element {
}) {
const [toc, setToc] = useState<
{ heading: string; id: string; lvl3: { heading: string; id: string }[] }[]
>([]);
@@ -6,3 +6,15 @@
padding-left: 1rem;
padding-right: 1rem;
}
.containerStatic {
display: flex;
justify-content: center;
height: 100%;
padding: 1.5rem 1rem;
}
.containerStatic > * {
max-width: 30rem;
width: 100%;
}
@@ -4,15 +4,25 @@ import cl from "clsx";
export const withDsExample = (
Component: ComponentType,
variant?: "full" | "inverted"
/**
* Static: Used for dynamic-height examples like ExpansionCard
*/
variant?: "full" | "inverted" | "static"
) => {
const DsHOC = (props: any) => (
<div
className={cl(styles.container, {
className={cl({
"bg-gray-900": variant === "inverted",
[styles.containerStatic]: variant === "static",
[styles.container]: variant !== "static",
})}
>
<div id="ds-example" className={cl({ "w-full": variant === "full" })}>
<div
id="ds-example"
className={cl({
"w-full": variant === "full",
})}
>
<Component {...props} />
</div>
</div>
@@ -1,4 +1,4 @@
import { FeedbackT, HelpfulArticleEnum } from "@/lib";
import { FeedbackT, HelpfulArticleEnum } from "@/types";
import { Button, Heading, Label, Textarea } from "@navikt/ds-react";
import cl from "clsx";
import { useRouter } from "next/router";
@@ -18,7 +18,7 @@ const Feedback = ({
center?: boolean;
akselFeedback?: boolean;
text?: string;
}): JSX.Element => {
}) => {
const idCtx = useContext(IdContext);
const { asPath, basePath } = useRouter();
const [textValue, setTextValue] = useState("");
@@ -105,7 +105,7 @@ export const IconPage = ({ name }: { name: string }) => {
id="hovedinnhold"
className="min-h-[80vh] focus:outline-none"
>
<div className="centered-layout mb-40 grid max-w-screen-2xl pt-20">
<div className="mx-auto mb-40 grid w-full max-w-screen-2xl px-4 pt-20 sm:px-6">
<div>
<div>
<h1 className="text-deepblue-700 my-0 w-fit text-5xl font-bold">
@@ -6,9 +6,11 @@ import { ChangeLogIconOutline } from "components/assets";
const SuggestionBlockComponent = ({
variant,
reference = "",
unsafe = false,
}: {
variant: "komponent-beta" | "komponent-ny";
reference?: string;
unsafe?: boolean;
}) => {
return (
<div
@@ -22,12 +24,18 @@ const SuggestionBlockComponent = ({
<Heading size="small" level="2">
{options[variant]?.heading}
</Heading>
<BodyLong className="mt-2">{options[variant]?.text}</BodyLong>
<BodyLong className="mt-2">
{variant === "komponent-beta" && unsafe
? options["komponent-beta-unsafe"].text
: options[variant]?.text}
</BodyLong>
<Button
variant="secondary-neutral"
as="a"
href={options[variant].link + reference}
className="mt-4 w-fit"
target="_blank"
rel="noreferrer noopener"
>
Send innspill
</Button>
@@ -56,6 +64,8 @@ const SuggestionBlockIcon = ({
as="a"
href={options[variant].link + reference}
className="mt-4 w-fit"
target="_blank"
rel="noreferrer noopener"
>
Send innspill
</Button>
@@ -67,6 +77,7 @@ const SuggestionBlockIcon = ({
export const SuggestionBlock = ({
variant,
reference = "",
unsafe,
}: {
variant:
| "ikoner"
@@ -78,9 +89,16 @@ export const SuggestionBlock = ({
| "ikon-not-found"
| "ikon";
reference?: string;
unsafe?: boolean;
}) => {
if (variant === "komponent-ny" || variant === "komponent-beta") {
return <SuggestionBlockComponent variant={variant} reference={reference} />;
return (
<SuggestionBlockComponent
variant={variant}
unsafe={unsafe}
reference={reference}
/>
);
}
if (variant === "ikon-ny" || variant === "ikon") {
@@ -106,6 +124,8 @@ export const SuggestionBlock = ({
variant="secondary-neutral"
as="a"
href={options[variant]?.link + reference}
target="_blank"
rel="noreferrer noopener"
>
Send forslag
</Button>
@@ -113,8 +133,7 @@ export const SuggestionBlock = ({
);
};
const issueUrl =
"https://github.com/navikt/aksel/issues/new?assignees=olejorgenbakken";
const issueUrl = "https://github.com/navikt/aksel/issues/new?assignees=KenAJoh";
const options: {
[key: string]: {
@@ -165,7 +184,45 @@ const options: {
icon: <ChangeLogIconOutline />,
},
"komponent-beta": {
text: "Komponenten er under utvikling. Dette kan medføre bugs slik at teamet ditt må ta stilling til om dere ønsker å bruke denne i produksjon. Hvis komponenten er prefikset med UNSAFE kan det også medføre breaking-changes i patch/minor versjon av kodepakker og i Figma. Tar du den i bruk ønsker vi gjerne innspill til hvordan den fungerer i tjenesten din!",
text: "Komponenten er under utvikling, men klar for adopsjon. Vi er ønsker gjerne innspill på hvordan den fungerer og hvilken forbedringer vi kan gjøre.",
link: `${issueUrl}&labels=forespørsel+🥰%2Ckomponenter+🧩%2Cbeta+🧪&template=update-component.yml&title=%5BInnspill+til+komponent%5D%3A+`,
heading: "Beta",
icon: (
<svg
width="25"
height="24"
viewBox="0 0 25 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
focusable={false}
aria-hidden
>
<path
d="M14.5471 3.99994H10.4528V9.48408L4.83594 17.1731C3.94768 18.3891 4.92474 19.9999 6.55053 19.9999H18.4495C20.0753 19.9999 21.0523 18.3891 20.1641 17.1731L14.5471 9.48408V3.99994Z"
stroke="#262626"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M9.5 4H15.5"
stroke="#262626"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M8.75 12L16.25 12"
stroke="#262626"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
),
},
"komponent-beta-unsafe": {
text: "Komponenten er under utvikling. Så lenge komponenten er prefikset med UNSAFE kan det også medføre breaking-changes i minor versjon av kodepakker og i Figma. Teamet ditt må ta selv ta stilling til om dere ønsker å bruke denne i produksjon.",
link: `${issueUrl}&labels=forespørsel+🥰%2Ckomponenter+🧩%2Cbeta+🧪&template=update-component.yml&title=%5BInnspill+til+komponent%5D%3A+`,
heading: "Beta",
icon: (
-2
View File
@@ -1,7 +1,5 @@
export * from "./sanity/queries";
export * from "./sanity/santiy";
export * from "./types/types";
export * from "./types/search";
export type { default as SanityT } from "./types/schema";
export function isDevelopment(): boolean {
+17 -266
View File
@@ -113,6 +113,16 @@ const accordionBlock = `_type == "accordion"=>{
${defaultBlock}
}
}
}
`;
const expansionCardBlock = `_type == "expansioncard"=>{
...,
body[]{
...,
${markDef},
${defaultBlock}
}
}`;
const spesialSeksjon = `_type == "spesial_seksjon" =>{
@@ -141,7 +151,7 @@ const propsSeksjon = `_type == "props_seksjon" =>{
const tokenRef = `_type == "token_ref"=>@->`;
const deRefs = `
export const destructureBlocks = `
${alert},
${tips},
${tokenRef},
@@ -154,245 +164,28 @@ ${propsSeksjon},
${installSeksjon},
${spesialSeksjon},
${accordionBlock},
${expansionCardBlock},
${defaultBlock},
`;
export const allDocuments = `*[]{...,'slug': slug.current }`;
export const akselTema = `*[_type == "godpraksis_landingsside"][0]{
"page": {
...,
intro[]{
...,
${deRefs}
}
},
"temaer": *[_type == "aksel_tema" && defined(seksjoner[].sider[])]{
...,
"refCount": count(*[_type == "aksel_artikkel" && !(_id in path("drafts.**")) && references(^._id)])
},
"resent": *[_type == "aksel_artikkel" && defined(publishedAt)] | order(publishedAt desc)[0...9]{
_id,
heading,
_createdAt,
_updatedAt,
publishedAt,
"slug": slug.current,
"tema": tema[]->title,
ingress,
}
}`;
const contributorsAll = `contributors[]->{
export const contributorsAll = `contributors[]->{
anonym == true => {"title":@.anon_navn.current},
anonym != true => {"title":@.title}
}`;
const contributorsSingle = `contributors[0]->{
export const contributorsSingle = `contributors[0]->{
anonym == true => {"title":@.anon_navn.current},
anonym != true => {"title":@.title}
}`;
export const akselBloggPosts = `*[_type == "blogg_landingsside"][0]{
"page": {..., intro[]{...,${deRefs}}},
"bloggposts": *[_type == "aksel_blogg"] | order(_createdAt desc){
seo,
heading,
ingress,
publishedAt,
_createdAt,
_id,
"slug": slug.current,
${contributorsAll}
}
}`;
export const akselForsideQuery = `*[_type == "aksel_forside"][0]{
"page": {
...,
},
"bloggs": *[_type == "aksel_blogg"] | order(_createdAt desc)[0...4]{
...,
"slug": slug.current,
${contributorsAll}
},
"tema": *[_type == "aksel_tema" && defined(seksjoner[].sider[])],
"resent": *[_type == "aksel_artikkel" && defined(publishedAt)] | order(publishedAt desc)[0...3]{
_id,
heading,
_createdAt,
_updatedAt,
publishedAt,
"slug": slug.current,
"tema": tema[]->title,
ingress,
}
}`;
export const akselPrinsippBySlug = `{
"prinsipp": *[slug.current == $slug] | order(_updatedAt desc)[0]
{
...,
"slug": slug.current,
"content": select(
$valid == "true" => content[]{
...,
${deRefs}
},
$valid != "true" => []
),
${contributorsAll}
}
}`;
export const akselDocumentBySlug = `{
"page": *[slug.current == $slug] | order(_updatedAt desc)[0]
{
...,
"slug": slug.current,
content[]{
...,
${deRefs}
},
tema[]->{title, slug, seo},
${contributorsAll},
relevante_artikler[]->{
_id,
heading,
_createdAt,
_updatedAt,
publishedAt,
updateInfo,
"slug": slug.current,
"tema": tema[]->tag,
ingress,
"contributor": ${contributorsSingle},
}
}
}`;
export const akselEditorById = `*[_id == $id][0]
{
${contributorsAll}
}`;
const sidebarQuery = `"sidebar": *[_type == $type && defined(kategori)] {
export const sidebarQuery = `"sidebar": *[_type == $type && defined(kategori)] {
heading,
"slug": slug.current,
kategori,
"tag": status.tag,
}`;
/**
* "refs" må disables i preview da next-sanity sin
* preview-funksjonalitet fører til en infinite loop som låser applikasjonen.
* Dette er på grunn av av hele datasettet blir lastet inn i preview flere ganger som til slutt låser vinduet.
*/
export const komponentQuery = `{
"page": *[_type == "komponent_artikkel" && slug.current == $slug] | order(_updatedAt desc)[0]
{
...,
"slug": slug.current,
linked_package {
"title": @->title,
"github_link": @->github_link,
"status": @->status
},
intro{
...,
body[]{
...,
${deRefs}
}
},
content[]{
...,
${deRefs}
},
},
"refs": select(
$preview == "true" => [],
$preview != "true" => *[_type == "komponent_artikkel" && count(*[references(^._id)][slug.current == $slug]) > 0][0...3]{
_id,
heading,
"slug": slug,
status
}
),
"seo": *[_type == "komponenter_landingsside"][0].seo.image,
${sidebarQuery}
}`;
export const grunnleggendeQuery = `{
"page": *[_type == "ds_artikkel" && slug.current == $slug] | order(_updatedAt desc)[0]
{
...,
"slug": slug.current,
content[]{
...,
${deRefs}
},
},
"seo": *[_type == "komponenter_landingsside"][0].seo.image,
${sidebarQuery}
}`;
export const akselTemaDocs = `{
"tema": *[_type == "aksel_tema" && slug.current == $slug] | order(_updatedAt desc)[0]{
...,
"ansvarlig": ansvarlig->{title, roller},
seksjoner[]{
...,
beskrivelse[]{
...,
${deRefs}
},
sider[]->{
_id,
heading,
_createdAt,
_updatedAt,
publishedAt,
updateInfo,
"slug": slug.current,
"tema": tema[]->title,
ingress,
"contributor": ${contributorsSingle}
}
},
"pictogram": pictogram.asset-> {
url,
altText,
},
}
}`;
export const akselBloggBySlug = `{
"blogg": *[slug.current == $slug && _type == "aksel_blogg"] | order(_updatedAt desc)[0]
{
...,
"slug": slug.current,
"content": select(
$valid == "true" => content[]{
...,
${deRefs}
},
$valid != "true" => []
),
${contributorsAll}
},
"morePosts": *[_type == "aksel_blogg" && slug.current != $slug] | order(publishedAt desc, _updatedAt desc)[0...3] {
"slug": slug.current,
heading,
_createdAt,
_id,
ingress,
${contributorsAll},
}
}`;
const landingsSideQuery = (t) => {
export const landingPageQuery = (t) => {
const kat =
t === "komponenter"
? komponentKategorier
@@ -402,48 +195,6 @@ const landingsSideQuery = (t) => {
return `"page": *[_type == "${t}_landingsside"][0]{
...,
${kat.map((x) => `intro_${x.value}[]{...,${deRefs}}`).join(",")}
}`;
};
export const komponentLandingQuery = `{${sidebarQuery}, ${landingsSideQuery(
"komponenter"
)}, "links": *[_type == "komponent_artikkel" && defined(kategori)]{_id,heading,"slug": slug,status,kategori}}`;
export const grunnleggendeLandingQuery = `{${sidebarQuery}, ${landingsSideQuery(
"grunnleggende"
)}, "links": *[_type == "ds_artikkel" && defined(kategori)]{_id,heading,"slug": slug,status,kategori}}`;
export const akselStandaloneBySlug = `{
"page": *[slug.current == $slug && _type == "aksel_standalone"] | order(_updatedAt desc)[0]
{
...,
"slug": slug.current,
content[]{
...,
${deRefs}
}
}
}`;
export const akselArticleFields = `
_id,
heading,
_createdAt,
_updatedAt,
publishedAt,
updateInfo,
"slug": slug.current,
"tema": tema[]->title,
ingress,
status,
_type,
`;
export const akselArticleAll = (boundry = "") => {
return `{
"articles": *[_type == "aksel_artikkel" && defined(publishedAt)] | order(publishedAt desc)${boundry} {
${akselArticleFields}
}
${kat.map((x) => `intro_${x.value}[]{...,${destructureBlocks}}`).join(",")}
}`;
};
@@ -1,15 +1,3 @@
export type SidebarT = {
heading: string;
slug: string;
kategori: string;
tag?: string;
}[];
export type PageTypeT = {
type: "Komponenter" | "Grunnleggende";
title: string;
};
export enum HelpfulArticleEnum {
"JA" = "ja",
"DELVIS" = "delvis",
Loaded 100 of 176 files, more files were not shown because too many files have changed in this diff. Show more