mirror of
https://github.com/navikt/aksel.git
synced 2026-10-13 01:02:02 +00:00
Compare commits
117
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5c8a94378 | ||
|
|
212194964c | ||
|
|
d151cf4c07 | ||
|
|
44ba7a3a79 | ||
|
|
d94a636dc4 | ||
|
|
36ae2e5005 | ||
|
|
ed8e284540 | ||
|
|
262d59cf98 | ||
|
|
57705de77c | ||
|
|
4ec35a01ca | ||
|
|
6113e6e59f | ||
|
|
7f3f025db2 | ||
|
|
44671abb5f | ||
|
|
2eb358ad88 | ||
|
|
6bdc02761b | ||
|
|
f52ef19be2 | ||
|
|
989a97a8bc | ||
|
|
8de6ba22c3 | ||
|
|
f664370826 | ||
|
|
55b5856183 | ||
|
|
5a72a62190 | ||
|
|
d89eaccd44 | ||
|
|
7cffc0bf12 | ||
|
|
8d4966c83f | ||
|
|
edcc4e5071 | ||
|
|
a5821578a0 | ||
|
|
7ff8ce7e3b | ||
|
|
fa0c07e04a | ||
|
|
e97b31ea94 | ||
|
|
d1549cb5ff | ||
|
|
01bcbbf1ff | ||
|
|
41fd9e7b25 | ||
|
|
e468f9d93e | ||
|
|
ccd9e73446 | ||
|
|
eb2c7ab777 | ||
|
|
0ccee41b7c | ||
|
|
865a19c681 | ||
|
|
eabad5af35 | ||
|
|
7ab07f3f46 | ||
|
|
5ead5f9cde | ||
|
|
1fb56a32d0 | ||
|
|
1609604073 | ||
|
|
f862aa9c2e | ||
|
|
c88632d92c | ||
|
|
70bf09a4d6 | ||
|
|
0cce29182b | ||
|
|
a7b619dd18 | ||
|
|
945ea68414 | ||
|
|
9e5b5a461f | ||
|
|
66dc7e41ed | ||
|
|
8fce648c79 | ||
|
|
f85a2bd834 | ||
|
|
6812a18a34 | ||
|
|
34f421835c | ||
|
|
9c495cf503 | ||
|
|
721a315f67 | ||
|
|
d508423406 | ||
|
|
c9c8bf72e8 | ||
|
|
d9bb32ace0 | ||
|
|
6082485287 | ||
|
|
2b2b3aa819 | ||
|
|
5628f1c4dd | ||
|
|
b5666ed040 | ||
|
|
72aa6325ed | ||
|
|
e1f2a46ae0 | ||
|
|
489c6678d2 | ||
|
|
be4a951962 | ||
|
|
1276b4d7ef | ||
|
|
8880b0dfb5 | ||
|
|
bfe60a9a62 | ||
|
|
9c70200962 | ||
|
|
33aef230b0 | ||
|
|
88243f76de | ||
|
|
c00112e3e6 | ||
|
|
3c66b00c24 | ||
|
|
db8303af42 | ||
|
|
5fbd2e1814 | ||
|
|
c1360da7d7 | ||
|
|
de2a3990dc | ||
|
|
46433118b2 | ||
|
|
de861e469c | ||
|
|
85697be305 | ||
|
|
ae64920a34 | ||
|
|
36fb35533d | ||
|
|
3709e432bb | ||
|
|
c6077a03fa | ||
|
|
c6d51a0190 | ||
|
|
2221b2e01d | ||
|
|
b31b1b3533 | ||
|
|
ff8bcb870e | ||
|
|
0a7e6311de | ||
|
|
961d97ef0d | ||
|
|
f2477e772d | ||
|
|
bad960be56 | ||
|
|
c53e3a050b | ||
|
|
d9e40b71b1 | ||
|
|
c1828f992f | ||
|
|
522bb95ddb | ||
|
|
7ab690d210 | ||
|
|
de741ce8a8 | ||
|
|
918d21c3ba | ||
|
|
121a678fa0 | ||
|
|
576790a2ff | ||
|
|
6609631f46 | ||
|
|
7c37e3af56 | ||
|
|
9703f082f1 | ||
|
|
18005f89a2 | ||
|
|
8a4321ebd3 | ||
|
|
28938dd4a6 | ||
|
|
bb3a431e2a | ||
|
|
00e787a400 | ||
|
|
04215daf7e | ||
|
|
2c722e3a7d | ||
|
|
8d511c90f1 | ||
|
|
8be270c8c5 | ||
|
|
426f4d54a1 | ||
|
|
8ff68266c8 |
No files matched your search
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# @navikt/aksel-icons
|
||||
|
||||
## 2.8.9
|
||||
|
||||
## 2.8.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`ed8e28454`](https://github.com/navikt/aksel/commit/ed8e284540a9e3a5be7d1d5e393f31db86962613) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Nye ikoner
|
||||
|
||||
- :tada: VideoSlash
|
||||
- :tada: VideoSlashFill
|
||||
|
||||
## 2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
## 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
|
||||
|
||||
@@ -33,8 +33,8 @@ fs.writeFileSync(
|
||||
sub_category: "Time",
|
||||
keywords: string[];
|
||||
variant: "stroke" | "fill";
|
||||
date_added: Date;
|
||||
date_modified: Date;
|
||||
updated_at: Date;
|
||||
created_at: Date;
|
||||
}
|
||||
|
||||
declare const metadata: {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6248 2.35048C11.8568 2.21651 12.1427 2.21651 12.3748 2.35048L20.1578 6.84397C20.273 6.90772 20.3729 7.00264 20.4435 7.125C20.5142 7.24739 20.5465 7.38143 20.544 7.51313V16.5C20.544 16.7679 20.4011 17.0155 20.169 17.1495L12.3903 21.6405C12.2766 21.71 12.143 21.75 12 21.75H12C11.9837 21.75 11.9675 21.7495 11.9513 21.7484C11.8311 21.7407 11.7186 21.7047 11.6205 21.647L3.83057 17.1495C3.59852 17.0155 3.45557 16.7679 3.45557 16.5V7.513C3.45316 7.38134 3.48541 7.24735 3.55605 7.125C3.62669 7.00265 3.7266 6.90773 3.84183 6.84398L11.6248 2.35048ZM4.95557 8.79904V16.067L11.25 19.7011L11.25 12.4331L4.95557 8.79904ZM12.75 12.4329V19.7008L19.044 16.067V8.79904L12.75 12.4329ZM18.294 7.5L11.9998 11.134L5.70557 7.5L11.9998 3.86603L18.294 7.5Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.438 7.11571C20.3678 6.99792 20.2701 6.90625 20.1578 6.84415L12.3872 2.35776C12.3621 2.34263 12.3361 2.32904 12.3095 2.31701C12.2098 2.27163 12.1042 2.24991 11.9999 2.25C11.8955 2.24989 11.7899 2.27161 11.6901 2.31701C11.6635 2.32904 11.6375 2.34263 11.6124 2.35775L3.84183 6.84411C3.7266 6.90785 3.62669 7.00277 3.55605 7.12513C3.48541 7.24748 3.45316 7.38146 3.45557 7.51312V16.5001C3.45557 16.7681 3.59852 17.0157 3.83057 17.1496L11.6124 21.6425C11.6307 21.6535 11.6494 21.6637 11.6685 21.6731C11.6958 21.6866 11.7242 21.6985 11.7533 21.7086C11.8339 21.7368 11.9172 21.7503 11.9998 21.7503C12.0536 21.7503 12.1078 21.7445 12.1613 21.7327C12.2435 21.7147 12.3206 21.6832 12.3903 21.6407L20.169 17.1496C20.4011 17.0157 20.544 16.7681 20.544 16.5001V7.51305C20.5464 7.38481 20.5158 7.25437 20.4489 7.13462C20.4454 7.12826 20.4418 7.12196 20.438 7.11571ZM18.294 7.50013L11.9998 3.86615L5.70557 7.50012L11.9998 11.1341L18.294 7.50013ZM4.95557 8.79916V16.0671L11.25 19.7012L11.25 12.4332L4.95557 8.79916ZM12.75 12.433L19.044 8.79917V16.0671L12.75 19.701V12.433Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 912 B After Width: | Height: | Size: 1.2 KiB |
@@ -14,5 +14,5 @@ keywords:
|
||||
- programmering
|
||||
- distribusjon
|
||||
variant: Stroke
|
||||
updated_at: 08.03.2023
|
||||
updated_at: 23.03.2023
|
||||
created_at: 07.03.2023
|
||||
@@ -14,5 +14,5 @@ keywords:
|
||||
- programmering
|
||||
- distribusjon
|
||||
variant: Fill
|
||||
updated_at: 08.03.2023
|
||||
updated_at: 23.03.2023
|
||||
created_at: 07.03.2023
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.875 6H9.5H15C15.5523 6 16 6.44772 16 7V12V14.4M3 10.5V12V17C3 17.5523 3.44772 18 4 18H9.5H11.125" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16 9.6L21 8V16L16 14.4V9.6Z" stroke="#262626" stroke-width="1.5" stroke-linejoin="round"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.96967 5.46967C3.26256 5.17678 3.73744 5.17678 4.03033 5.46967L16.0303 17.4697C16.3232 17.7626 16.3232 18.2374 16.0303 18.5303C15.7374 18.8232 15.2626 18.8232 14.9697 18.5303L2.96967 6.53033C2.67678 6.23744 2.67678 5.76256 2.96967 5.46967Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 708 B |
@@ -0,0 +1,17 @@
|
||||
name: VideoSlash
|
||||
category: Media
|
||||
sub_category: Media
|
||||
keywords:
|
||||
- record
|
||||
- capture
|
||||
- film
|
||||
- video
|
||||
- camera
|
||||
- opptak
|
||||
- ta opp
|
||||
- filme
|
||||
- video
|
||||
- kamera
|
||||
variant: Stroke
|
||||
updated_at: 30.03.2023
|
||||
created_at: 30.03.2023
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.6749 5.85688C2.41013 6.16353 2.25 6.56307 2.25 7V17C2.25 17.9665 3.0335 18.75 4 18.75H15C15.1725 18.75 15.3391 18.725 15.4966 18.6785L2.6749 5.85688ZM19.4845 16.3025L20.7714 16.7143C20.9995 16.7873 21.2488 16.747 21.4422 16.6058C21.6356 16.4646 21.75 16.2395 21.75 16V8.00001C21.75 7.76052 21.6356 7.53543 21.4422 7.39423C21.2488 7.25303 20.9995 7.2127 20.7714 7.28569L16.75 8.57254V7C16.75 6.0335 15.9665 5.25 15 5.25H8.43198L19.4845 16.3025Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.46967 3.46967C3.76256 3.17678 4.23744 3.17678 4.53033 3.46967L19.5303 18.4697C19.8232 18.7626 19.8232 19.2374 19.5303 19.5303C19.2374 19.8232 18.7626 19.8232 18.4697 19.5303L3.46967 4.53033C3.17678 4.23744 3.17678 3.76256 3.46967 3.46967Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 926 B |
@@ -0,0 +1,17 @@
|
||||
name: VideoSlashFill
|
||||
category: Media
|
||||
sub_category: Media
|
||||
keywords:
|
||||
- record
|
||||
- capture
|
||||
- film
|
||||
- video
|
||||
- camera
|
||||
- opptak
|
||||
- ta opp
|
||||
- filme
|
||||
- video
|
||||
- kamera
|
||||
variant: Fill
|
||||
updated_at: 30.03.2023
|
||||
created_at: 30.03.2023
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel-icons",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"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"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/react/esm",
|
||||
"module": "esnext",
|
||||
"sourceMap": true,
|
||||
"sourceMap": false,
|
||||
"declaration": true
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,8 @@
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/react/cjs",
|
||||
"module": "commonjs"
|
||||
"module": "commonjs",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"exclude": ["./util", "./__tests__", "**/*.stories.*"],
|
||||
"include": ["./src"]
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @navikt/ds-codemod
|
||||
|
||||
## 2.8.9
|
||||
|
||||
## 2.8.8
|
||||
|
||||
## 2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
## 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,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-codemod",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"description": "Aksel codemods for NAVs designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -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.9",
|
||||
"@navikt/ds-react": "^2.8.9",
|
||||
"clsx": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,51 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 2.8.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1905](https://github.com/navikt/aksel/pull/1905) [`212194964`](https://github.com/navikt/aksel/commit/212194964c4dd576e1ffc031316dff8cbe5016a2) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Padding/border-radius tokens for button.css
|
||||
|
||||
## 2.8.8
|
||||
|
||||
## 2.8.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`7f3f025db`](https://github.com/navikt/aksel/commit/7f3f025db2ad605df4240605a733d10d08db753a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset typografi for radio, checkbox. Button token for tertiary
|
||||
|
||||
## 2.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`2eb358ad8`](https://github.com/navikt/aksel/commit/2eb358ad888979d21c385b3900973946f3f466be) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Alert, Chips og ErrorSummary har nå bedre utvalg av tokens
|
||||
|
||||
## 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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
background-color: var(--ac-alert-error-bg, var(--a-surface-danger-subtle));
|
||||
}
|
||||
|
||||
.navds-alert--error > .navds-alert__icon {
|
||||
color: var(--ac-alert-icon-error-color, var(--a-icon-danger));
|
||||
}
|
||||
|
||||
.navds-alert--warning {
|
||||
border-color: var(--ac-alert-warning-border, var(--a-border-warning));
|
||||
background-color: var(--ac-alert-warning-bg, var(--a-surface-warning-subtle));
|
||||
@@ -44,6 +48,7 @@
|
||||
|
||||
.navds-alert--warning > .navds-alert__icon {
|
||||
background: radial-gradient(circle at 50% 57%, var(--a-surface-default) 32%, 0, transparent);
|
||||
color: var(--ac-alert-icon-warning-color, var(--a-icon-warning));
|
||||
}
|
||||
|
||||
.navds-alert--info {
|
||||
@@ -51,11 +56,19 @@
|
||||
background-color: var(--ac-alert-info-bg, var(--a-surface-info-subtle));
|
||||
}
|
||||
|
||||
.navds-alert--info > .navds-alert__icon {
|
||||
color: var(--ac-alert-icon-info-color, var(--a-icon-info));
|
||||
}
|
||||
|
||||
.navds-alert--success {
|
||||
border-color: var(--ac-alert-success-border, var(--a-border-success));
|
||||
background-color: var(--ac-alert-success-bg, var(--a-surface-success-subtle));
|
||||
}
|
||||
|
||||
.navds-alert--success > .navds-alert__icon {
|
||||
color: var(--ac-alert-icon-success-color, var(--a-icon-success));
|
||||
}
|
||||
|
||||
.navds-alert--inline {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
|
||||
@@ -16,38 +16,50 @@
|
||||
}
|
||||
|
||||
.navds-button {
|
||||
--__ac-button-padding: var(--a-spacing-3) var(--a-spacing-5);
|
||||
|
||||
display: inline-flex;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
background: none;
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
padding: var(--a-spacing-3) var(--a-spacing-5);
|
||||
border-radius: var(--ac-button-border-radius, var(--a-border-radius-medium));
|
||||
padding: var(--ac-button-padding, var(--__ac-button-padding));
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-button--small {
|
||||
padding: 0.375rem var(--a-spacing-3);
|
||||
--__ac-button-padding: 0.375rem var(--a-spacing-3);
|
||||
|
||||
padding: var(--ac-button-padding-small, var(--__ac-button-padding));
|
||||
}
|
||||
|
||||
.navds-button--xsmall {
|
||||
padding: var(--a-spacing-05) var(--a-spacing-2);
|
||||
--__ac-button-padding: var(--a-spacing-05) var(--a-spacing-2);
|
||||
|
||||
padding: var(--ac-button-padding-xsmall, var(--__ac-button-padding));
|
||||
gap: var(--a-spacing-1);
|
||||
}
|
||||
|
||||
.navds-button--icon-only {
|
||||
padding: var(--a-spacing-3);
|
||||
--__ac-button-padding: var(--a-spacing-3);
|
||||
|
||||
padding: var(--ac-button-padding-icon-only, var(--__ac-button-padding));
|
||||
}
|
||||
|
||||
.navds-button--small.navds-button--icon-only {
|
||||
padding: 0.375rem;
|
||||
--__ac-button-padding: 0.375rem;
|
||||
|
||||
padding: var(--ac-button-padding-icon-only-small, var(--__ac-button-padding));
|
||||
}
|
||||
|
||||
.navds-button--xsmall.navds-button--icon-only {
|
||||
padding: var(--a-spacing-1);
|
||||
--__ac-button-padding: var(--a-spacing-1);
|
||||
|
||||
padding: var(--ac-button-padding-icon-only-xsmall, var(--__ac-button-padding));
|
||||
}
|
||||
|
||||
.navds-button:focus {
|
||||
@@ -217,6 +229,7 @@
|
||||
|
||||
.navds-button--tertiary {
|
||||
color: var(--ac-button-tertiary-text, var(--a-text-action));
|
||||
background-color: var(--ac-button-tertiary-bg, var(--a-surface-transparent));
|
||||
}
|
||||
|
||||
.navds-button--tertiary:hover {
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
.navds-chips__toggle {
|
||||
box-shadow: inset 0 0 0 1px var(--ac-chip-toggle-border, var(--a-border-default));
|
||||
background-color: var(--ac-chip-toggle-bg, var(--a-surface-neutral-subtle));
|
||||
color: var(--ac-chip-toggle-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-chips__toggle:hover {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
|
||||
.navds-error-summary__list > * {
|
||||
color: var(--a-blue-500);
|
||||
color: var(--ac-error-summary-list-dot, var(--a-text-action));
|
||||
}
|
||||
|
||||
.navds-error-summary--small > .navds-error-summary__list {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"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.9",
|
||||
"normalize.css": "^8.0.1",
|
||||
"postcss": "^8.4.0",
|
||||
"postcss-cli": "^9.0.0",
|
||||
|
||||
@@ -2,23 +2,38 @@
|
||||
"alert": {
|
||||
"--ac-alert-error-border": "--a-border-danger",
|
||||
"--ac-alert-error-bg": "--a-surface-danger-subtle",
|
||||
"--ac-alert-icon-error-color": "--a-icon-danger",
|
||||
"--ac-alert-warning-border": "--a-border-warning",
|
||||
"--ac-alert-warning-bg": "--a-surface-warning-subtle",
|
||||
"--ac-alert-icon-warning-color": "--a-icon-warning",
|
||||
"--ac-alert-info-border": "--a-border-info",
|
||||
"--ac-alert-info-bg": "--a-surface-info-subtle",
|
||||
"--ac-alert-icon-info-color": "--a-icon-info",
|
||||
"--ac-alert-success-border": "--a-border-success",
|
||||
"--ac-alert-success-bg": "--a-surface-success-subtle"
|
||||
"--ac-alert-success-bg": "--a-surface-success-subtle",
|
||||
"--ac-alert-icon-success-color": "--a-icon-success"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"button": {
|
||||
"--ac-button-border-radius": "--a-border-radius-medium",
|
||||
"--ac-button-padding": "var(--a-spacing-3) var(--a-spacing-5)",
|
||||
"--ac-button-padding-small": "0.375rem var(--a-spacing-3)",
|
||||
"--ac-button-padding-xsmall": "var(--a-spacing-05) var(--a-spacing-2)",
|
||||
"--ac-button-padding-icon-only": "var(--a-spacing-3)",
|
||||
"--ac-button-padding-icon-only-small": "0.375rem",
|
||||
"--ac-button-padding-icon-only-xsmall": "var(--a-spacing-1)",
|
||||
"--ac-button-primary-bg": "--a-surface-action",
|
||||
"--ac-button-primary-text": "--a-text-on-action",
|
||||
"--ac-button-primary-hover-bg": "--a-surface-action-hover",
|
||||
@@ -34,6 +49,7 @@
|
||||
"--ac-button-secondary-active-bg": "--a-surface-action-active",
|
||||
"--ac-button-secondary-active-focus-border": "--a-surface-default",
|
||||
"--ac-button-tertiary-text": "--a-text-action",
|
||||
"--ac-button-tertiary-bg": "--a-surface-transparent",
|
||||
"--ac-button-tertiary-hover-text": "--a-text-action-on-action-subtle",
|
||||
"--ac-button-tertiary-hover-bg": "--a-surface-action-subtle-hover",
|
||||
"--ac-button-tertiary-focus-border": "--a-border-action",
|
||||
@@ -76,6 +92,7 @@
|
||||
"chips": {
|
||||
"--ac-chip-toggle-border": "--a-border-default",
|
||||
"--ac-chip-toggle-bg": "--a-surface-neutral-subtle",
|
||||
"--ac-chip-toggle-text": "--a-text-default",
|
||||
"--ac-chip-toggle-hover-border": "--a-border-strong",
|
||||
"--ac-chip-toggle-hover-bg": "--a-surface-neutral-subtle-hover",
|
||||
"--ac-chip-toggle-pressed-bg": "--a-surface-action-selected",
|
||||
@@ -106,6 +123,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",
|
||||
@@ -281,7 +309,8 @@
|
||||
},
|
||||
"errorsummary": {
|
||||
"--ac-error-summary-bg": "--a-surface-default",
|
||||
"--ac-error-summary-border": "--a-border-danger"
|
||||
"--ac-error-summary-border": "--a-border-danger",
|
||||
"--ac-error-summary-list-dot": "--a-text-action"
|
||||
},
|
||||
"checkbox-radio": {
|
||||
"--ac-radio-checkbox-bg": "--a-surface-default",
|
||||
@@ -301,6 +330,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"
|
||||
|
||||
@@ -1,5 +1,99 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 2.8.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@2.8.9
|
||||
- @navikt/ds-icons@2.8.9
|
||||
|
||||
## 2.8.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ed8e28454`](https://github.com/navikt/aksel/commit/ed8e284540a9e3a5be7d1d5e393f31db86962613)]:
|
||||
- @navikt/aksel-icons@2.8.8
|
||||
- @navikt/ds-icons@2.8.8
|
||||
|
||||
## 2.8.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`7f3f025db`](https://github.com/navikt/aksel/commit/7f3f025db2ad605df4240605a733d10d08db753a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset typografi for radio, checkbox. Button token for tertiary
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@2.8.7
|
||||
- @navikt/ds-icons@2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`2eb358ad8`](https://github.com/navikt/aksel/commit/2eb358ad888979d21c385b3900973946f3f466be) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Alert, Chips og ErrorSummary har nå bedre utvalg av tokens
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@2.8.6
|
||||
- @navikt/ds-icons@2.8.6
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"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.9",
|
||||
"@navikt/ds-icons": "^2.8.9",
|
||||
"@radix-ui/react-tabs": "1.0.0",
|
||||
"@radix-ui/react-toggle-group": "1.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
ErrorColored,
|
||||
InformationColored,
|
||||
SuccessColored,
|
||||
WarningColored,
|
||||
ErrorFilled,
|
||||
InformationFilled,
|
||||
SuccessFilled,
|
||||
WarningFilled,
|
||||
} from "@navikt/ds-icons";
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
@@ -37,13 +37,13 @@ export interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
const Icon = ({ variant, ...props }) => {
|
||||
switch (variant) {
|
||||
case "error":
|
||||
return <ErrorColored title="Feil" {...props} />;
|
||||
return <ErrorFilled title="Feil" {...props} />;
|
||||
case "warning":
|
||||
return <WarningColored title="Advarsel" {...props} />;
|
||||
return <WarningFilled title="Advarsel" {...props} />;
|
||||
case "info":
|
||||
return <InformationColored title="Informasjon" {...props} />;
|
||||
return <InformationFilled title="Informasjon" {...props} />;
|
||||
case "success":
|
||||
return <SuccessColored title="Suksess" {...props} />;
|
||||
return <SuccessFilled title="Suksess" {...props} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
@@ -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,8 +1,9 @@
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import cl from "clsx";
|
||||
import useCheckbox from "./useCheckbox";
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import { BodyLong, BodyShort, Detail } from "../../typography";
|
||||
import { omit } from "../../util";
|
||||
import { FormFieldProps } from "../useFormField";
|
||||
import { BodyShort, Detail, omit } from "../..";
|
||||
import useCheckbox from "./useCheckbox";
|
||||
|
||||
export interface CheckboxProps
|
||||
extends FormFieldProps,
|
||||
@@ -43,7 +44,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
(props, ref) => {
|
||||
const { inputProps, hasError, size } = useCheckbox(props);
|
||||
|
||||
const Description = size === "medium" ? BodyShort : Detail;
|
||||
const Description = size === "medium" ? BodyLong : Detail;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -93,11 +94,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
{props.children}
|
||||
</BodyShort>
|
||||
{props.description && (
|
||||
<Description
|
||||
as="span"
|
||||
size="small"
|
||||
className="navds-checkbox__description"
|
||||
>
|
||||
<Description as="span" className="navds-checkbox__description">
|
||||
{props.description}
|
||||
</Description>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import { BodyShort, Detail, omit } from "../..";
|
||||
import { BodyLong, BodyShort, Detail } from "../../typography";
|
||||
import { omit } from "../../util";
|
||||
import { FormFieldProps } from "../useFormField";
|
||||
import { useRadio } from "./useRadio";
|
||||
|
||||
@@ -24,7 +25,7 @@ export interface RadioProps
|
||||
export const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
|
||||
const { inputProps, size, hasError } = useRadio(props);
|
||||
|
||||
const Description = size === "medium" ? BodyShort : Detail;
|
||||
const Description = size === "medium" ? BodyLong : Detail;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -45,11 +46,7 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
|
||||
{props.children}
|
||||
</BodyShort>
|
||||
{props.description && (
|
||||
<Description
|
||||
as="span"
|
||||
size="small"
|
||||
className="navds-radio__description"
|
||||
>
|
||||
<Description as="span" className="navds-radio__description">
|
||||
{props.description}
|
||||
</Description>
|
||||
)}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @navikt/ds-tailwind
|
||||
|
||||
## 2.8.9
|
||||
|
||||
## 2.8.8
|
||||
|
||||
## 2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
## 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,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tailwind",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"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.9",
|
||||
"@types/jest": "^29.0.0",
|
||||
"color": "4.2.3",
|
||||
"jest": "^29.0.0",
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @navikt/ds-tokens
|
||||
|
||||
## 2.8.9
|
||||
|
||||
## 2.8.8
|
||||
|
||||
## 2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
## 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,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tokens",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"description": "Design-tokens for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @navikt/ds-icons
|
||||
|
||||
## 2.8.9
|
||||
|
||||
## 2.8.8
|
||||
|
||||
## 2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
## 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,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-icons",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"description": "Aksel icons for NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"repository": {
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./cjs",
|
||||
"module": "commonjs"
|
||||
"module": "commonjs",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"exclude": ["./figma", "./util", "./tests", "./scripts", "**/*.stories.*"],
|
||||
"include": ["./src"]
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @navikt/ds-css-internal
|
||||
|
||||
## 2.8.9
|
||||
|
||||
## 2.8.8
|
||||
|
||||
## 2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
## 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,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css-internal",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"description": "CSS for NAV internal Designsystem-components",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,85 @@
|
||||
# @navikt/ds-react-internal
|
||||
|
||||
## 2.8.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.8.9
|
||||
- @navikt/ds-icons@2.8.9
|
||||
|
||||
## 2.8.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.8.8
|
||||
- @navikt/ds-icons@2.8.8
|
||||
|
||||
## 2.8.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7f3f025db`](https://github.com/navikt/aksel/commit/7f3f025db2ad605df4240605a733d10d08db753a)]:
|
||||
- @navikt/ds-react@2.8.7
|
||||
- @navikt/ds-icons@2.8.7
|
||||
|
||||
## 2.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2eb358ad8`](https://github.com/navikt/aksel/commit/2eb358ad888979d21c385b3900973946f3f466be)]:
|
||||
- @navikt/ds-react@2.8.6
|
||||
- @navikt/ds-icons@2.8.6
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react-internal",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.9",
|
||||
"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.9",
|
||||
"@navikt/ds-react": "^2.8.9",
|
||||
"clsx": "^1.1.1",
|
||||
"copy-to-clipboard": "^3.3.1"
|
||||
},
|
||||
|
||||
@@ -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.9",
|
||||
"@navikt/ds-codemod": "^2.8.9",
|
||||
"@navikt/ds-css": "^2.8.9",
|
||||
"@navikt/ds-css-internal": "^2.8.9",
|
||||
"@navikt/ds-icons": "^2.8.9",
|
||||
"@navikt/ds-react": "^2.8.9",
|
||||
"@navikt/ds-react-internal": "^2.8.9",
|
||||
"@navikt/ds-tailwind": "^2.8.9",
|
||||
"@navikt/ds-tokens": "^2.8.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier-plugin-tailwindcss": "^0.2.3"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ExternalLink } from "@navikt/ds-icons";
|
||||
import { ExternalLinkIcon } from "@navikt/aksel-icons";
|
||||
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} />,
|
||||
@@ -218,7 +220,7 @@ const serializers = {
|
||||
)
|
||||
}
|
||||
>
|
||||
{children} <ExternalLink title="åpner lenken i ny fane" />
|
||||
{children} <ExternalLinkIcon title="åpner lenken i ny fane" />
|
||||
</Link>
|
||||
) : (
|
||||
<NextLink href={href} passHref legacyBehavior>
|
||||
|
||||
@@ -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,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;
|
||||
+7
-3
@@ -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,4 +1,5 @@
|
||||
import { Close, Hamburger as HamburgerIcon } from "@navikt/ds-icons";
|
||||
import { MenuHamburgerIcon, XMarkIcon } from "@navikt/aksel-icons";
|
||||
|
||||
import { Button } from "@navikt/ds-react";
|
||||
import cl from "clsx";
|
||||
import Link from "next/link";
|
||||
@@ -53,8 +54,9 @@ export const Hamburger = () => {
|
||||
aria-expanded={open}
|
||||
className="focus-visible:shadow-focus hover:bg-surface-neutral-subtle-hover ml-2 flex aspect-square items-center justify-center rounded px-3 py-3 focus:outline-none"
|
||||
>
|
||||
<HamburgerIcon
|
||||
className="pointer-events-none text-2xl"
|
||||
<MenuHamburgerIcon
|
||||
fontSize="2rem"
|
||||
className="pointer-events-none"
|
||||
aria-label="Åpne meny"
|
||||
/>
|
||||
</button>
|
||||
@@ -75,7 +77,7 @@ export const Hamburger = () => {
|
||||
styles.akselTertiaryButton,
|
||||
"absolute top-2 right-2"
|
||||
)}
|
||||
icon={<Close title="lukk meny" className="h-5 w-5" />}
|
||||
icon={<XMarkIcon title="lukk meny" fontSize="1.5rem" />}
|
||||
/>
|
||||
<LinkElement
|
||||
onClick={() => setOpen(false)}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { SearchLogT, useDebounce, logSearch } from "@/utils";
|
||||
import { Search as SearchIcon } from "@navikt/ds-icons";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
@@ -9,12 +8,13 @@ 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";
|
||||
import { Group, GroupComponent } from "./Group";
|
||||
import styles from "../header.module.css";
|
||||
import { MagnifyingGlassIcon } from "@navikt/aksel-icons";
|
||||
|
||||
/**
|
||||
* https://www.figma.com/file/71Sm1h6VV23lbBbQ3CJJ9t/Aksel-v2?node-id=1861%3A186079&t=ARKgZcA6B7ysmG3V-0
|
||||
@@ -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);
|
||||
|
||||
@@ -195,8 +195,8 @@ export const GlobalSearch = () => {
|
||||
className="hover:bg-deepblue-700 bg-deepblue-600 focus-visible:shadow-focus-gap h-11 focus:shadow-none"
|
||||
aria-keyshortcuts="Control+b"
|
||||
icon={
|
||||
<SearchIcon
|
||||
className="pointer-events-none -mt-[1px] shrink-0 text-xl"
|
||||
<MagnifyingGlassIcon
|
||||
className="pointer-events-none -mt-[1px] shrink-0 text-2xl"
|
||||
aria-label="Åpne meny"
|
||||
aria-hidden
|
||||
/>
|
||||
@@ -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,6 +1,6 @@
|
||||
import { SidebarT } from "@/lib";
|
||||
import { AkselSidebarT } from "@/types";
|
||||
import { logNav } from "@/utils";
|
||||
import { Expand } from "@navikt/ds-icons";
|
||||
import { ChevronDownIcon } from "@navikt/aksel-icons";
|
||||
import { BodyShort, Detail, Tag } from "@navikt/ds-react";
|
||||
import cl from "clsx";
|
||||
import Link from "next/link";
|
||||
@@ -26,7 +26,7 @@ const NavItem = ({
|
||||
{
|
||||
"before:border-l-border-action-selected before:top-1/2 before:h-6 before:-translate-y-1/2 before:rounded-full before:border-l-[4px]":
|
||||
isActive,
|
||||
"before:h-full before:rounded-full before:border-l before:border-l-gray-200 hover:before:top-1/2 hover:before:h-6 hover:before:-translate-y-1/2 hover:before:border-l-2 hover:before:border-l-gray-400":
|
||||
"before:h-full before:rounded-full before:border-l before:border-l-gray-200 hover:before:top-1/2 hover:before:h-6 hover:before:-translate-y-1/2 hover:before:border-l-2 hover:before:border-l-gray-400":
|
||||
!isActive,
|
||||
}
|
||||
)}
|
||||
@@ -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();
|
||||
|
||||
@@ -93,11 +99,11 @@ const Dropdown = ({ title, links }: { title: string; links: SidebarT }) => {
|
||||
>
|
||||
<Detail
|
||||
as="span"
|
||||
className="group-focus-visible:shadow-focus group-hover:bg-surface-neutral-subtle group-active:bg-bg-surface-neutral-subtle-hover mt-6 flex w-full items-center justify-between rounded-sm pl-2 font-semibold first:mt-0"
|
||||
className="group-focus-visible:shadow-focus group-hover:bg-surface-neutral-subtle group-active:bg-bg-surface-neutral-subtle-hover mt-6 flex w-full items-center justify-between rounded-sm pl-2 font-semibold transition first:mt-0"
|
||||
>
|
||||
{title}
|
||||
<span className="flex h-6 w-6 items-center justify-center rounded">
|
||||
<Expand
|
||||
<span className="flex h-6 w-6 items-center justify-center rounded">
|
||||
<ChevronDownIcon
|
||||
className={cl("text-base", { "rotate-180": open })}
|
||||
aria-hidden
|
||||
title={!open ? `åpne ${title}` : `lukk ${title}`}
|
||||
@@ -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">
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT, urlFor } from "@/lib";
|
||||
import { ErrorFilled, SuccessFilled, WarningFilled } from "@navikt/ds-icons";
|
||||
import {
|
||||
CheckmarkCircleFillIcon,
|
||||
ExclamationmarkTriangleFillIcon,
|
||||
XMarkOctagonFillIcon,
|
||||
} from "@navikt/aksel-icons";
|
||||
import { BodyShort } from "@navikt/ds-react";
|
||||
import cl from "clsx";
|
||||
import React from "react";
|
||||
@@ -10,23 +14,26 @@ const GetIcon = (s: string) => {
|
||||
switch (s) {
|
||||
case "do":
|
||||
return (
|
||||
<SuccessFilled
|
||||
<CheckmarkCircleFillIcon
|
||||
aria-hidden
|
||||
className="text-large mt-[1px] flex-shrink-0 text-green-500"
|
||||
fontSize="1.5rem"
|
||||
className="flex-shrink-0 text-green-500"
|
||||
/>
|
||||
);
|
||||
case "dont":
|
||||
return (
|
||||
<ErrorFilled
|
||||
<XMarkOctagonFillIcon
|
||||
aria-hidden
|
||||
className="text-large mt-[1px] flex-shrink-0 text-red-500"
|
||||
fontSize="1.5rem"
|
||||
className="flex-shrink-0 text-red-500"
|
||||
/>
|
||||
);
|
||||
case "warning":
|
||||
return (
|
||||
<WarningFilled
|
||||
<ExclamationmarkTriangleFillIcon
|
||||
aria-hidden
|
||||
className="text-large mt-[1px] flex-shrink-0 text-orange-500"
|
||||
fontSize="1.5rem"
|
||||
className="flex-shrink-0 text-orange-500"
|
||||
/>
|
||||
);
|
||||
default:
|
||||
@@ -38,7 +45,7 @@ const Element = ({
|
||||
block,
|
||||
}: {
|
||||
block: Sanity.Keyed<SanityT.Schema.do_dont_block>;
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
if (!block.picture) return null;
|
||||
return (
|
||||
<figure
|
||||
@@ -60,14 +67,18 @@ const Element = ({
|
||||
{
|
||||
"border-t-border-success": block.variant === "do",
|
||||
"border-t-border-danger": block.variant === "dont",
|
||||
"border-t-border-warning": block.variant === "warning",
|
||||
"border-t-surface-warning": block.variant === "warning",
|
||||
}
|
||||
)}
|
||||
/>
|
||||
<figcaption data-variant={block.variant}>
|
||||
<div className="mt-3">
|
||||
{block.description && (
|
||||
<BodyShort size="small" as="span" className="inline-flex gap-2">
|
||||
<BodyShort
|
||||
size="small"
|
||||
as="span"
|
||||
className="inline-flex items-center gap-2"
|
||||
>
|
||||
{GetIcon(block.variant)}
|
||||
{block.description}
|
||||
</BodyShort>
|
||||
|
||||
@@ -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,39 +1,16 @@
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT } from "@/lib";
|
||||
import { ClipboardIcon } from "@navikt/aksel-icons";
|
||||
import { ChevronDownCircleIcon } from "@navikt/aksel-icons";
|
||||
import internal from "@navikt/ds-css-internal/tokens.json";
|
||||
import core from "@navikt/ds-css/tokens.json";
|
||||
import { Expand, SuccessStroke } from "@navikt/ds-icons";
|
||||
import { BodyLong, Label, Link } from "@navikt/ds-react";
|
||||
import cl from "classnames";
|
||||
import copy from "copy-to-clipboard";
|
||||
import CopyButton from "components/sanity-modules/code/CopyButton";
|
||||
import NextLink from "next/link";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
const TokenTable = ({ node }: { node: SanityT.Schema.token_kategori }) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [active, setActive] = useState(false);
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
|
||||
const handleCopy = () => {
|
||||
setActive(true);
|
||||
timeoutRef.current && clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = setTimeout(() => setActive(false), 2000);
|
||||
const str = Object.entries(tokens).reduce(
|
||||
(prev, cur) =>
|
||||
prev +
|
||||
`${cur[0]}: ${
|
||||
cur[1].startsWith("--") ? `var(${cur[1]})` : `${cur[1]}`
|
||||
};\n`,
|
||||
""
|
||||
);
|
||||
copy(str);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => timeoutRef.current && clearTimeout(timeoutRef.current);
|
||||
}, []);
|
||||
|
||||
const tokens: { [key: string]: string } | null =
|
||||
node.title in core
|
||||
@@ -77,22 +54,17 @@ const TokenTable = ({ node }: { node: SanityT.Schema.token_kategori }) => {
|
||||
</table>
|
||||
{(open || !showMore) && (
|
||||
<div className="border-border-divider bg-surface-neutral-subtle relative w-full rounded-b border border-t-0 p-2">
|
||||
<button
|
||||
onClick={handleCopy}
|
||||
className="text-text-default hover:bg-surface-neutral-subtle-hover focus-visible:shadow-focus absolute top-2 right-2 rounded px-1 py-1 text-2xl focus:outline-none"
|
||||
>
|
||||
{active ? (
|
||||
<>
|
||||
<SuccessStroke className="text-[1.5rem]" aria-hidden />
|
||||
<span className="sr-only">Kopier formarterte tokens</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ClipboardIcon aria-hidden />
|
||||
<span className="sr-only">Kopier formarterte tokens</span>
|
||||
</>
|
||||
<CopyButton
|
||||
variant="tokentable"
|
||||
content={Object.entries(tokens).reduce(
|
||||
(prev, cur) =>
|
||||
prev +
|
||||
`${cur[0]}: ${
|
||||
cur[1].startsWith("--") ? `var(${cur[1]})` : `${cur[1]}`
|
||||
};\n`,
|
||||
""
|
||||
)}
|
||||
</button>
|
||||
/>
|
||||
<Label size="small" as="span" spacing>
|
||||
Hva er dette?
|
||||
</Label>
|
||||
@@ -122,14 +94,15 @@ const TokenTable = ({ node }: { node: SanityT.Schema.token_kategori }) => {
|
||||
{!open && showMore && (
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="text-medium group mx-auto flex shrink-0 -translate-y-3/4 flex-col items-center focus:outline-none"
|
||||
className="text-medium group mx-auto flex shrink-0 -translate-y-3/4 flex-col items-center gap-1 focus:outline-none"
|
||||
>
|
||||
<span className="group-focus-visible:bg-border-focus group-focus-visible:text-text-on-action group-focus-visible:shadow-focus">
|
||||
Se alle tokens
|
||||
</span>
|
||||
<Expand
|
||||
className="h-4 w-4 transition-all group-hover:translate-y-1"
|
||||
<ChevronDownCircleIcon
|
||||
className="transition-all group-hover:translate-y-1"
|
||||
aria-hidden
|
||||
fontSize="1.5rem"
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Edit } from "@navikt/ds-icons";
|
||||
import { PencilIcon } from "@navikt/aksel-icons";
|
||||
import { getParameters } from "codesandbox/lib/api/define";
|
||||
|
||||
const indexTsx = `import React from 'react';
|
||||
@@ -29,6 +29,7 @@ export const CodeSandbox = ({ code }: { code: string }) => {
|
||||
"@navikt/ds-react-internal": "latest",
|
||||
"@navikt/ds-css-internal": "latest",
|
||||
"@navikt/ds-icons": "latest",
|
||||
"@navikt/aksel-icons": "latest",
|
||||
},
|
||||
} as any,
|
||||
isBinary: false,
|
||||
@@ -58,9 +59,9 @@ export const CodeSandbox = ({ code }: { code: string }) => {
|
||||
<input type="hidden" name="query" value="module=App.js" />
|
||||
<button
|
||||
type="submit"
|
||||
className="flex items-center justify-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100 focus:outline-none focus-visible:shadow-focus-inset active:bg-gray-200"
|
||||
className="focus-visible:shadow-focus-inset flex items-center justify-center gap-1 rounded-sm px-3 py-2 hover:bg-gray-100 focus:outline-none active:bg-gray-200"
|
||||
>
|
||||
<Edit aria-hidden />
|
||||
<PencilIcon aria-hidden fontSize="1.5rem" />
|
||||
CodeSandbox
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { SuccessStroke } from "@navikt/ds-icons";
|
||||
import { useRef, useState, useEffect } from "react";
|
||||
import copy from "copy-to-clipboard";
|
||||
import React from "react";
|
||||
import cl from "clsx";
|
||||
import style from "./index.module.css";
|
||||
import { ClipboardIcon } from "@navikt/aksel-icons";
|
||||
import { CheckmarkIcon, ClipboardIcon } from "@navikt/aksel-icons";
|
||||
|
||||
const copyCode = (content: string) =>
|
||||
copy(content, {
|
||||
@@ -13,12 +12,11 @@ const copyCode = (content: string) =>
|
||||
|
||||
interface CopyButtonProps {
|
||||
content: string;
|
||||
inTabs?: boolean;
|
||||
inverted?: boolean;
|
||||
variant?: "tokentable" | "codeblock";
|
||||
}
|
||||
|
||||
const CopyButton = React.forwardRef<HTMLButtonElement, CopyButtonProps>(
|
||||
({ content, inTabs, inverted = false }, ref) => {
|
||||
({ content, variant = "codeblock" }, ref) => {
|
||||
const [active, setActive] = useState(false);
|
||||
|
||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
@@ -31,7 +29,7 @@ const CopyButton = React.forwardRef<HTMLButtonElement, CopyButtonProps>(
|
||||
copyCode(content);
|
||||
setActive(true);
|
||||
timeoutRef.current && clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = setTimeout(() => setActive(false), 3000);
|
||||
timeoutRef.current = setTimeout(() => setActive(false), 1000);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -39,25 +37,39 @@ const CopyButton = React.forwardRef<HTMLButtonElement, CopyButtonProps>(
|
||||
ref={ref}
|
||||
aria-live={active ? "polite" : "off"}
|
||||
role={active ? "alert" : undefined}
|
||||
className={cl(style.copybutton, "navds-body-short group z-10", {
|
||||
"flex w-16 items-center justify-center hover:bg-blue-50 focus:outline-none focus-visible:shadow-[inset_0_0_0_2px_var(--a-border-focus)]":
|
||||
inTabs,
|
||||
"text-text-default focus-visible:outline-focus absolute top-2 right-2 rounded bg-gray-100 px-2 py-1 hover:bg-gray-900/10 hover:underline focus-visible:outline-2":
|
||||
!inTabs && inverted,
|
||||
"text-text-on-inverted focus-visible:shadow-focus-inverted absolute top-2 right-2 flex h-10 w-10 items-center justify-center rounded bg-gray-900 hover:bg-gray-800 focus:outline-none":
|
||||
!inTabs && !inverted,
|
||||
})}
|
||||
className={cl(
|
||||
style.copybutton,
|
||||
"navds-body-short group/button absolute top-2 right-2 z-10 flex h-10 w-10 items-center justify-center overflow-hidden rounded backdrop-blur transition duration-75 focus:outline-none",
|
||||
{
|
||||
"hover:text-text-on-inverted focus-visible:shadow-focus-inverted text-3xl text-gray-100 hover:bg-white/20 ":
|
||||
variant === "codeblock",
|
||||
"hover:text-deepblue-800 focus-visible:shadow-focus text-text-subtle hover:bg-surface-hover text-2xl":
|
||||
variant === "tokentable",
|
||||
}
|
||||
)}
|
||||
onClick={handleCopy}
|
||||
>
|
||||
{active ? (
|
||||
<SuccessStroke className="text-[1.5rem]" title="Kopierte kodesnutt" />
|
||||
) : (
|
||||
<ClipboardIcon
|
||||
fontSize="2rem"
|
||||
className="opacity-90 group-hover:opacity-100"
|
||||
title="Kopier kodesnutt"
|
||||
/>
|
||||
)}
|
||||
<span
|
||||
aria-hidden={!active}
|
||||
className={cl(
|
||||
"absolute inset-0 grid place-content-center transition duration-300",
|
||||
{
|
||||
"pointer-events-none translate-y-1.5 opacity-0": !active,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<CheckmarkIcon title="Kopierte kodesnutt" />
|
||||
</span>
|
||||
|
||||
<span
|
||||
aria-hidden={active}
|
||||
className={cl("flex items-center transition duration-300", {
|
||||
"pointer-events-none -translate-y-1.5 opacity-0": active,
|
||||
"group-hover/button:opacity-100": !active,
|
||||
})}
|
||||
>
|
||||
<ClipboardIcon title="Kopier kodesnutt" />
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ const CodeSnippet = ({
|
||||
node: SanityT.Schema.kode;
|
||||
className?: string;
|
||||
style?: any;
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
if (!code || !code.code) {
|
||||
return null;
|
||||
}
|
||||
@@ -27,7 +27,7 @@ const CodeSnippet = ({
|
||||
<div
|
||||
className={cl(
|
||||
className,
|
||||
"relative mb-8 grid max-h-96 overflow-x-auto rounded bg-gray-900"
|
||||
"relative mb-8 grid max-h-96 overflow-x-auto rounded bg-[#0f172a]"
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
@@ -39,7 +39,7 @@ const CodeSnippet = ({
|
||||
theme={undefined}
|
||||
>
|
||||
{({ tokens, getLineProps, getTokenProps }) => (
|
||||
<pre className="text-text-on-inverted relative m-0 overflow-x-auto overflow-y-auto rounded-lg bg-gray-900 p-4 pr-16 font-mono">
|
||||
<pre className="text-text-on-inverted relative m-0 overflow-x-auto overflow-y-auto rounded-lg bg-[#0f172a] p-4 pr-16 font-mono">
|
||||
{tokens.map((line, i) => (
|
||||
<div
|
||||
key={i}
|
||||
|
||||
@@ -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");
|
||||
Loaded 100 of 208 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user