mirror of
https://github.com/navikt/aksel.git
synced 2026-10-13 01:02:02 +00:00
Compare commits
105
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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,23 @@
|
||||
# @navikt/aksel-icons
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel-icons",
|
||||
"version": "2.7.8",
|
||||
"version": "2.8.6",
|
||||
"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
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,19 @@
|
||||
# @navikt/ds-codemod
|
||||
|
||||
## 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.6",
|
||||
"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.6",
|
||||
"@navikt/ds-react": "^2.8.6",
|
||||
"clsx": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 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;
|
||||
|
||||
@@ -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.6",
|
||||
"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.6",
|
||||
"normalize.css": "^8.0.1",
|
||||
"postcss": "^8.4.0",
|
||||
"postcss-cli": "^9.0.0",
|
||||
|
||||
@@ -2,18 +2,26 @@
|
||||
"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"
|
||||
@@ -76,6 +84,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 +115,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 +301,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 +322,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,73 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 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.6",
|
||||
"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.6",
|
||||
"@navikt/ds-icons": "^2.8.6",
|
||||
"@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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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,19 @@
|
||||
# @navikt/ds-tailwind
|
||||
|
||||
## 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.6",
|
||||
"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.6",
|
||||
"@types/jest": "^29.0.0",
|
||||
"color": "4.2.3",
|
||||
"jest": "^29.0.0",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @navikt/ds-tokens
|
||||
|
||||
## 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.6",
|
||||
"description": "Design-tokens for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @navikt/ds-icons
|
||||
|
||||
## 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.6",
|
||||
"description": "Aksel icons for NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"repository": {
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @navikt/ds-css-internal
|
||||
|
||||
## 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.6",
|
||||
"description": "CSS for NAV internal Designsystem-components",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,61 @@
|
||||
# @navikt/ds-react-internal
|
||||
|
||||
## 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.6",
|
||||
"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.6",
|
||||
"@navikt/ds-react": "^2.8.6",
|
||||
"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.6",
|
||||
"@navikt/ds-codemod": "^2.8.6",
|
||||
"@navikt/ds-css": "^2.8.6",
|
||||
"@navikt/ds-css-internal": "^2.8.6",
|
||||
"@navikt/ds-icons": "^2.8.6",
|
||||
"@navikt/ds-react": "^2.8.6",
|
||||
"@navikt/ds-react-internal": "^2.8.6",
|
||||
"@navikt/ds-tailwind": "^2.8.6",
|
||||
"@navikt/ds-tokens": "^2.8.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier-plugin-tailwindcss": "^0.2.3"
|
||||
|
||||
@@ -3,6 +3,7 @@ import { BodyLong, Detail, Heading, Ingress, Link } from "@navikt/ds-react";
|
||||
import BlockContent from "@sanity/block-content-to-react";
|
||||
import cl from "clsx";
|
||||
import InnholdsKort from "components/sanity-modules/cards/InnholdsKort";
|
||||
import ExpansionCard from "components/sanity-modules/ExpansionCard";
|
||||
import NextLink from "next/link";
|
||||
import React, { createContext, useContext } from "react";
|
||||
import {
|
||||
@@ -49,6 +50,7 @@ const serializers = {
|
||||
do_dont: ({ node }) => <DoDont node={node} />,
|
||||
bilde: ({ node }) => <Bilde node={node} />,
|
||||
alert: ({ node }) => <Alert node={node} />,
|
||||
expansioncard: ({ node }) => <ExpansionCard node={node} />,
|
||||
kode: ({ node }) => <Kode node={node} />,
|
||||
tabell_v2: ({ node }) => <Tabell node={node} />,
|
||||
accordion: ({ node }) => <Accordion node={node} />,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
const Logo = (props): JSX.Element => (
|
||||
const Logo = (props) => (
|
||||
<svg
|
||||
width="119"
|
||||
height="26"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
const NAVLogoDark = (props): JSX.Element => (
|
||||
const NAVLogoDark = (props) => (
|
||||
<svg
|
||||
width="3.25em"
|
||||
height="3.25em"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
const NAVLogoWhite = (props): JSX.Element => (
|
||||
const NAVLogoWhite = (props) => (
|
||||
<svg
|
||||
width="3.25em"
|
||||
height="3.25em"
|
||||
|
||||
@@ -1,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,5 +1,5 @@
|
||||
import { Label } from "@navikt/ds-react";
|
||||
import { GroupedHits, SearchHit, options } from "lib/types/search";
|
||||
import { GroupedHitsT, SearchHitT, searchOptions } from "@/types";
|
||||
import { Hit, IconHit, IconPageHit } from "./Hit";
|
||||
import React from "react";
|
||||
|
||||
@@ -9,7 +9,7 @@ export function Group({
|
||||
startIndex,
|
||||
logSuccess,
|
||||
}: {
|
||||
groups: GroupedHits;
|
||||
groups: GroupedHitsT;
|
||||
query: string;
|
||||
startIndex: number;
|
||||
logSuccess: (index: number, url: string) => void;
|
||||
@@ -21,7 +21,7 @@ export function Group({
|
||||
return (
|
||||
<>
|
||||
{Object.entries(groups)
|
||||
.sort((a, b) => options[a[0]].index - options[b[0]].index)
|
||||
.sort((a, b) => searchOptions[a[0]].index - searchOptions[b[0]].index)
|
||||
.map(([key, val], index, arr) => {
|
||||
const prev = arr.slice(0, index);
|
||||
const total =
|
||||
@@ -32,7 +32,7 @@ export function Group({
|
||||
logSuccess={logSuccess}
|
||||
startIndex={total}
|
||||
key={key}
|
||||
heading={`${options[key].display} (${val.length})`}
|
||||
heading={`${searchOptions[key].display} (${val.length})`}
|
||||
hits={val}
|
||||
query={query}
|
||||
/>
|
||||
@@ -50,7 +50,7 @@ export function GroupComponent({
|
||||
logSuccess,
|
||||
}: {
|
||||
heading: React.ReactNode;
|
||||
hits: SearchHit[];
|
||||
hits: SearchHitT[];
|
||||
query: string;
|
||||
startIndex: number;
|
||||
logSuccess: (index: number, url: string) => void;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Tag } from "@navikt/ds-react";
|
||||
import cl from "classnames";
|
||||
import Image from "next/legacy/image";
|
||||
import { StatusTag } from "components/website-modules/StatusTag";
|
||||
import { SearchHit } from "lib/types/search";
|
||||
import { SearchHitT } from "@/types";
|
||||
import NextLink from "next/link";
|
||||
|
||||
export function Hit({
|
||||
@@ -13,7 +13,7 @@ export function Hit({
|
||||
index,
|
||||
logSuccess,
|
||||
}: {
|
||||
hit: SearchHit;
|
||||
hit: SearchHitT;
|
||||
query: string;
|
||||
index: number;
|
||||
logSuccess: (index: number, url: string) => void;
|
||||
@@ -81,7 +81,7 @@ export function IconHit({
|
||||
index,
|
||||
logSuccess,
|
||||
}: {
|
||||
hit: SearchHit;
|
||||
hit: SearchHitT;
|
||||
query: string;
|
||||
index: number;
|
||||
logSuccess: (index: number, url: string) => void;
|
||||
@@ -139,7 +139,7 @@ export function IconPageHit({
|
||||
index,
|
||||
logSuccess,
|
||||
}: {
|
||||
hit: SearchHit;
|
||||
hit: SearchHitT;
|
||||
query: string;
|
||||
index: number;
|
||||
logSuccess: (index: number, url: string) => void;
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
Search,
|
||||
} from "@navikt/ds-react";
|
||||
import { ChangeLogIconOutline } from "components/assets";
|
||||
import { options, SearchResults } from "lib/types/search";
|
||||
import { searchOptions, SearchResultsT } from "@/types";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import ReactModal from "react-modal";
|
||||
@@ -24,10 +24,10 @@ import styles from "../header.module.css";
|
||||
|
||||
*/
|
||||
export const GlobalSearch = () => {
|
||||
const [results, setResults] = useState<SearchResults>(null);
|
||||
const [results, setResults] = useState<SearchResultsT>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [activeTags, setTags] = useState<Array<keyof typeof options>>([]);
|
||||
const [activeTags, setTags] = useState<Array<keyof typeof searchOptions>>([]);
|
||||
const [os, setOs] = useState<"mac" | "windows">("windows");
|
||||
const inputRef = useRef(null);
|
||||
|
||||
@@ -223,7 +223,7 @@ export const GlobalSearch = () => {
|
||||
</button>
|
||||
<div className="search-grid-filter mt-8">
|
||||
<CheckboxGroup legend="Filter" onChange={setTags}>
|
||||
{Object.entries(options)
|
||||
{Object.entries(searchOptions)
|
||||
.filter((x) => !x[1].hidden)
|
||||
.map(([key, val]) => (
|
||||
<Checkbox
|
||||
@@ -284,7 +284,7 @@ export const GlobalSearch = () => {
|
||||
{`${results?.totalHits} treff på "${query}"${
|
||||
activeTags.length > 0
|
||||
? ` i ${activeTags
|
||||
.map((x) => options[x].display.toLowerCase())
|
||||
.map((x) => searchOptions[x].display.toLowerCase())
|
||||
.join(", ")}`
|
||||
: ""
|
||||
}`}
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
import { SanityT, urlFor } from "@/lib";
|
||||
import { SanityBlockContent } from "@/sanity-block";
|
||||
import { Next } from "@navikt/ds-icons";
|
||||
import { BodyShort, Detail, Heading, Ingress, Label } from "@navikt/ds-react";
|
||||
import ArtikkelCard from "components/sanity-modules/cards/ArtikkelCard";
|
||||
import Head from "next/head";
|
||||
import NextLink from "next/link";
|
||||
|
||||
import {
|
||||
abbrName,
|
||||
BreadCrumbs,
|
||||
dateStr,
|
||||
Feedback,
|
||||
TableOfContents,
|
||||
} from "../..";
|
||||
import { NoSidebarLayout } from "./wrappers/NoSidebar";
|
||||
|
||||
const AkselArtikkelTemplate = ({
|
||||
data,
|
||||
title,
|
||||
}: {
|
||||
data: SanityT.Schema.aksel_artikkel;
|
||||
title: string;
|
||||
}): JSX.Element => {
|
||||
if (!data.content || !data.heading) {
|
||||
console.warn(
|
||||
`Artikkelen har ikke ${
|
||||
!data.content ? "innhold" : "overskrift"
|
||||
}, så den kan ikke vises.`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const date = data?.updateInfo?.lastVerified
|
||||
? data?.updateInfo?.lastVerified
|
||||
: data?.publishedAt
|
||||
? data.publishedAt
|
||||
: data._updatedAt;
|
||||
|
||||
const authors = (data?.contributors as any)?.map((x) => x?.title) ?? [];
|
||||
|
||||
const hasTema = "tema" in data && data.tema && data?.tema.length > 0;
|
||||
|
||||
const aside = data?.relevante_artikler?.length > 0 && (
|
||||
<aside
|
||||
className="overflow-x-clip py-8"
|
||||
aria-labelledby="relevante-artikler-aside"
|
||||
>
|
||||
<div className="relativept-12 pb-16">
|
||||
<div className="dynamic-wrapper">
|
||||
<Heading
|
||||
level="2"
|
||||
size="medium"
|
||||
className="text-deepblue-700 px-4"
|
||||
id="relevante-artikler-aside"
|
||||
>
|
||||
{data?.relevante_artikler?.length === 1
|
||||
? `Les også`
|
||||
: `Relevante artikler`}
|
||||
</Heading>
|
||||
<div className="card-grid-3-1 mt-6 px-4">
|
||||
{data.relevante_artikler.map((x: any) =>
|
||||
x && x?._id ? <ArtikkelCard level="3" {...x} key={x._id} /> : null
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
|
||||
const filteredTema =
|
||||
hasTema && data?.tema?.filter((x: any) => x?.title && x?.slug);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{`${data?.heading} - ${title}`}</title>
|
||||
<meta
|
||||
property="og:title"
|
||||
content={`${data?.heading} - ${title}`}
|
||||
key="ogtitle"
|
||||
/>
|
||||
<meta
|
||||
name="description"
|
||||
content={data?.seo?.meta ?? data?.ingress}
|
||||
key="desc"
|
||||
/>
|
||||
<meta
|
||||
property="og:description"
|
||||
content={data?.seo?.meta ?? data?.ingress}
|
||||
key="ogdesc"
|
||||
/>
|
||||
<meta property="og:type" content="article" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content={
|
||||
data?.seo?.image
|
||||
? urlFor(data?.seo?.image)
|
||||
.width(1200)
|
||||
.height(630)
|
||||
.fit("crop")
|
||||
.quality(100)
|
||||
.url()
|
||||
: hasTema && (data.tema[0] as any)?.seo?.image
|
||||
? urlFor((data.tema[0] as any)?.seo?.image)
|
||||
.width(1200)
|
||||
.height(630)
|
||||
.fit("crop")
|
||||
.quality(100)
|
||||
.url()
|
||||
: ""
|
||||
}
|
||||
key="ogimage"
|
||||
/>
|
||||
</Head>
|
||||
<NoSidebarLayout aside={aside}>
|
||||
<div className="mx-auto mb-16 max-w-prose lg:ml-0">
|
||||
<BreadCrumbs auto />
|
||||
<Heading
|
||||
level="1"
|
||||
size="large"
|
||||
className="text-deepblue-800 mt-4 md:text-5xl"
|
||||
>
|
||||
{data.heading}
|
||||
</Heading>
|
||||
{data?.ingress && (
|
||||
<Ingress className="override-text-700 mt-4 text-2xl">
|
||||
{data?.ingress}
|
||||
</Ingress>
|
||||
)}
|
||||
|
||||
<div className="mt-6 inline-flex flex-wrap items-center gap-2 text-base">
|
||||
<Detail uppercase as="span">
|
||||
{dateStr(date)}
|
||||
</Detail>
|
||||
{authors?.length > 0 && (
|
||||
<>
|
||||
<span className="bg-deepblue-700 h-2 w-2 rotate-45 rounded-[1px] opacity-25" />
|
||||
<BodyShort
|
||||
size="small"
|
||||
as="div"
|
||||
className="flex flex-wrap gap-1"
|
||||
>
|
||||
<address className="not-italic">{authors?.[0]}</address>
|
||||
</BodyShort>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{hasTema && (
|
||||
<div className="mt-8 flex flex-wrap gap-2">
|
||||
{filteredTema.map(({ title, slug }: any) => (
|
||||
<span key={title}>
|
||||
<NextLink
|
||||
key={title}
|
||||
href={`/god-praksis/${slug.current}`}
|
||||
passHref
|
||||
legacyBehavior
|
||||
>
|
||||
<BodyShort
|
||||
size="small"
|
||||
as="a"
|
||||
className="min-h-8 text-deepblue-800 focus-visible:shadow-focus flex items-center justify-center gap-[2px] rounded-full bg-gray-200 pl-4 pr-1 capitalize no-underline hover:underline focus:outline-none"
|
||||
>
|
||||
{title}
|
||||
<Next aria-hidden />
|
||||
</BodyShort>
|
||||
</NextLink>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="relative mx-auto mt-4 max-w-prose lg:ml-0 lg:grid lg:max-w-none lg:grid-flow-row-dense lg:grid-cols-3 lg:items-start lg:gap-x-12">
|
||||
<TableOfContents
|
||||
changedState={data?.content ?? []}
|
||||
hideToc={false}
|
||||
aksel
|
||||
/>
|
||||
<div className="max-w-prose lg:col-span-2 lg:col-start-1">
|
||||
<SanityBlockContent blocks={data?.content ?? []} variant="aksel" />
|
||||
<div className="mt-12">
|
||||
{authors?.length > 0 && (
|
||||
<Label className="text-deepblue-700 mb-2" as="p">
|
||||
Bidragsytere
|
||||
</Label>
|
||||
)}
|
||||
{authors?.length > 0 && (
|
||||
<BodyShort
|
||||
as="div"
|
||||
className="text-text-subtle mb-1 flex flex-wrap gap-1"
|
||||
>
|
||||
{authors.map(abbrName).map((x, y) => (
|
||||
<address className="not-italic" key={x}>
|
||||
{x}
|
||||
{y !== authors.length - 1 && ", "}
|
||||
</address>
|
||||
))}
|
||||
</BodyShort>
|
||||
)}
|
||||
<BodyShort as="span" className="text-text-subtle">
|
||||
Publisert: {dateStr(data?.publishedAt ?? data?._updatedAt)}
|
||||
</BodyShort>
|
||||
</div>
|
||||
<div className="mt-12 md:mt-16">
|
||||
<Feedback akselFeedback docId={data?._id} docType={data?._type} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</NoSidebarLayout>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AkselArtikkelTemplate;
|
||||
@@ -1,189 +0,0 @@
|
||||
import { SanityT, urlFor } from "@/lib";
|
||||
import { SanityBlockContent } from "@/sanity-block";
|
||||
import { BodyShort, Heading, Ingress, Label } from "@navikt/ds-react";
|
||||
import cl from "clsx";
|
||||
import { Header } from "components/layout/header/Header";
|
||||
import Head from "next/head";
|
||||
import { Footer } from "..";
|
||||
import {
|
||||
abbrName,
|
||||
Bilde,
|
||||
BreadCrumbs,
|
||||
dateStr,
|
||||
Feedback,
|
||||
TableOfContents,
|
||||
} from "../..";
|
||||
|
||||
const AkselPrinsippTemplate = ({
|
||||
data,
|
||||
title,
|
||||
}: {
|
||||
data: SanityT.Schema.aksel_prinsipp;
|
||||
title: string;
|
||||
}): JSX.Element => {
|
||||
if (!data.content || !data.heading) {
|
||||
console.warn(
|
||||
`Artikkelen har ikke ${
|
||||
!data.content ? "innhold" : "overskrift"
|
||||
}, så den kan ikke vises.`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const authors = (data?.contributors as any)?.map((x) => x?.title) ?? [];
|
||||
const mainPage = data?.prinsipp?.hovedside;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{`${data?.heading} - Prinsipp - ${title}`}</title>
|
||||
<meta
|
||||
property="og:title"
|
||||
content={`${data?.heading} - ${title}`}
|
||||
key="ogtitle"
|
||||
/>
|
||||
<meta
|
||||
property="og:description"
|
||||
content={data?.seo?.meta ?? data?.ingress}
|
||||
key="ogdesc"
|
||||
/>
|
||||
<meta property="og:type" content="article" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content={
|
||||
data?.seo?.image
|
||||
? urlFor(data?.seo?.image)
|
||||
.width(1200)
|
||||
.height(630)
|
||||
.fit("crop")
|
||||
.quality(100)
|
||||
.url()
|
||||
: ""
|
||||
}
|
||||
key="ogimage"
|
||||
/>
|
||||
</Head>
|
||||
<Header variant={mainPage ? "default" : "subtle"} />
|
||||
<main
|
||||
tabIndex={-1}
|
||||
id="hovedinnhold"
|
||||
className={cl("aksel-artikkel pt-4 focus:outline-none", {
|
||||
"bg-white": mainPage,
|
||||
"bg-surface-subtle": !mainPage,
|
||||
})}
|
||||
>
|
||||
<article className="overflow-x-clip">
|
||||
<div
|
||||
className={cl("max-w-aksel mx-auto px-4 sm:w-[90%]", {
|
||||
"pb-32": mainPage,
|
||||
})}
|
||||
>
|
||||
<div className="pt-12">
|
||||
<div className="mx-auto mb-16 max-w-prose lg:ml-0 ">
|
||||
{!mainPage && (
|
||||
<BreadCrumbs
|
||||
text={`Prinsipper for ${data?.prinsipp?.prinsippvalg}`}
|
||||
href={`/prinsipper/${data?.prinsipp?.prinsippvalg}`}
|
||||
/>
|
||||
)}
|
||||
<Heading
|
||||
level="1"
|
||||
size="large"
|
||||
className="text-deepblue-700 mt-4 md:text-5xl"
|
||||
>
|
||||
{data.heading}
|
||||
</Heading>
|
||||
{data?.ingress && (
|
||||
<Ingress className="override-text-700 mt-5 text-2xl">
|
||||
{data?.ingress}
|
||||
</Ingress>
|
||||
)}
|
||||
<div className="mt-6 flex gap-3 text-base">
|
||||
<BodyShort
|
||||
size="small"
|
||||
as="span"
|
||||
className="text-text-subtle "
|
||||
>
|
||||
{dateStr(data?._updatedAt)}
|
||||
</BodyShort>
|
||||
{authors?.length > 0 && (
|
||||
<BodyShort
|
||||
size="small"
|
||||
as="div"
|
||||
className="flex flex-wrap gap-1"
|
||||
>
|
||||
<address className="not-italic">{authors[0]}</address>
|
||||
</BodyShort>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={cl("pt-32", {
|
||||
"bg-gray-100": mainPage,
|
||||
})}
|
||||
>
|
||||
<div className="max-w-aksel mx-auto px-4 sm:w-[90%]">
|
||||
<div className="pb-16 md:pb-32">
|
||||
<div className="relative mx-auto mt-4 max-w-prose lg:ml-0 lg:grid lg:max-w-none lg:grid-flow-row-dense lg:grid-cols-3 lg:items-start lg:gap-x-12">
|
||||
<TableOfContents
|
||||
changedState={data?.content ?? []}
|
||||
hideToc={false}
|
||||
aksel
|
||||
/>
|
||||
<div className="max-w-prose lg:col-span-2 lg:col-start-1">
|
||||
{data?.hero_bilde && (
|
||||
<Bilde
|
||||
node={data.hero_bilde as any}
|
||||
className="-mt-36 mb-10 sm:-mt-72"
|
||||
/>
|
||||
)}
|
||||
<SanityBlockContent
|
||||
blocks={data?.content ?? []}
|
||||
variant="aksel"
|
||||
/>
|
||||
<div className="mt-12">
|
||||
{authors?.length > 0 && (
|
||||
<Label className="text-deepblue-700 mb-2" as="p">
|
||||
Bidragsytere
|
||||
</Label>
|
||||
)}
|
||||
{authors?.length > 0 && (
|
||||
<BodyShort
|
||||
as="div"
|
||||
className="text-text-subtle mb-1 flex flex-wrap gap-1"
|
||||
>
|
||||
{authors.map(abbrName).map((x, y) => (
|
||||
<address className="not-italic" key={x}>
|
||||
{x}
|
||||
{y !== authors.length - 1 && ", "}
|
||||
</address>
|
||||
))}
|
||||
</BodyShort>
|
||||
)}
|
||||
<BodyShort as="span" className="text-text-subtle ">
|
||||
Publisert:{" "}
|
||||
{dateStr(data?.publishedAt ?? data?._updatedAt)}
|
||||
</BodyShort>
|
||||
</div>
|
||||
<div className="mt-12 md:mt-16">
|
||||
<Feedback
|
||||
akselFeedback
|
||||
docId={data?._id}
|
||||
docType={data?._type}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AkselPrinsippTemplate;
|
||||
@@ -1,28 +0,0 @@
|
||||
import { Footer } from "@/layout";
|
||||
import { Header } from "components/layout/header/Header";
|
||||
import React from "react";
|
||||
|
||||
export const NoSidebarLayout = ({
|
||||
children,
|
||||
aside = null,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
aside?: React.ReactNode;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<Header variant="subtle" />
|
||||
<main
|
||||
tabIndex={-1}
|
||||
id="hovedinnhold"
|
||||
className="aksel-artikkel bg-surface-subtle pt-4 focus:outline-none"
|
||||
>
|
||||
<div className="max-w-aksel mx-auto px-4 sm:w-[90%]">
|
||||
<article className="pt-12 pb-16 md:pb-32">{children}</article>
|
||||
</div>
|
||||
{aside}
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,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">
|
||||
|
||||
@@ -38,7 +38,7 @@ const Element = ({
|
||||
block,
|
||||
}: {
|
||||
block: Sanity.Keyed<SanityT.Schema.do_dont_block>;
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
if (!block.picture) return null;
|
||||
return (
|
||||
<figure
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { SanityBlockContent } from "@/sanity-block";
|
||||
import { ExpansionCard as DsExpansionCard } from "@navikt/ds-react";
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
|
||||
const ExpansionCard = ({
|
||||
node,
|
||||
}: {
|
||||
node: {
|
||||
heading: string;
|
||||
heading_level: "h3" | "h4";
|
||||
description?: string;
|
||||
body: any[];
|
||||
};
|
||||
}) => {
|
||||
if (!node.heading || !node.body || !node.heading_level) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<DsExpansionCard className="mb-7 max-w-2xl" aria-label={node.heading}>
|
||||
<DsExpansionCard.Header>
|
||||
<DsExpansionCard.Title
|
||||
as={node.heading_level}
|
||||
size={node.heading_level === "h3" ? "medium" : "small"}
|
||||
>
|
||||
{node.heading}
|
||||
</DsExpansionCard.Title>
|
||||
{node?.description && (
|
||||
<DsExpansionCard.Description>
|
||||
{node.description}
|
||||
</DsExpansionCard.Description>
|
||||
)}
|
||||
</DsExpansionCard.Header>
|
||||
<DsExpansionCard.Content>
|
||||
<SanityBlockContent blocks={node.body} noLastMargin />
|
||||
</DsExpansionCard.Content>
|
||||
</DsExpansionCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default withErrorBoundary(ExpansionCard, "ExpansionCard");
|
||||
@@ -1,15 +1,15 @@
|
||||
import { LevelTwoHeading } from "@/components";
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT } from "@/lib";
|
||||
import { SanityBlockContent } from "@/sanity-block";
|
||||
import { AkselGrunnleggendeDocT, AkselKomponentDocT } from "@/types";
|
||||
import { Label } from "@navikt/ds-react";
|
||||
import React from "react";
|
||||
|
||||
const Intro = ({
|
||||
node,
|
||||
}: {
|
||||
node: SanityT.Schema.intro_komponent;
|
||||
}): JSX.Element => {
|
||||
node: AkselKomponentDocT["intro"] | AkselGrunnleggendeDocT["intro"];
|
||||
}) => {
|
||||
if (!node || !node.body || !node.brukes_til) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Snippet } from "@/components";
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT } from "@/lib";
|
||||
|
||||
const Kode = ({ node }: { node: SanityT.Schema.kode }): JSX.Element => {
|
||||
const Kode = ({ node }: { node: SanityT.Schema.kode }) => {
|
||||
if (!node || !node.code) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ type SpesialT = {
|
||||
token?: { title: string; kategori: string };
|
||||
};
|
||||
|
||||
const SideModul = ({ node }: { node: SpesialT }): JSX.Element => {
|
||||
const SideModul = ({ node }: { node: SpesialT }) => {
|
||||
if (!node || !node.modul) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@ import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT } from "@/lib";
|
||||
import { Table } from "@navikt/ds-react";
|
||||
|
||||
const TableComponent = ({
|
||||
node,
|
||||
}: {
|
||||
node: SanityT.Schema.tabell_v2;
|
||||
}): JSX.Element => {
|
||||
const TableComponent = ({ node }: { node: SanityT.Schema.tabell_v2 }) => {
|
||||
if (!node || !node.rows || node.rows.length < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,7 @@ const KBD = (props: React.HTMLAttributes<HTMLElement>) => (
|
||||
/>
|
||||
);
|
||||
|
||||
const UuSeksjon = ({
|
||||
node,
|
||||
}: {
|
||||
node: SanityT.Schema.tastatur_modul;
|
||||
}): JSX.Element => {
|
||||
const UuSeksjon = ({ node }: { node: SanityT.Schema.tastatur_modul }) => {
|
||||
if (!node || !node?.tastatur) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,39 +1,16 @@
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT } from "@/lib";
|
||||
import { ClipboardIcon } 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 { Expand } 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>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FeedbackT } from "@/lib";
|
||||
import { FeedbackT } from "@/types";
|
||||
import { IdContext } from "@/utils";
|
||||
import { Button, Heading, Textarea } from "@navikt/ds-react";
|
||||
import cl from "classnames";
|
||||
|
||||
@@ -16,7 +16,7 @@ const Video = ({
|
||||
transkripsjon?: string;
|
||||
caption?: string;
|
||||
};
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
if (
|
||||
|
||||
@@ -19,7 +19,7 @@ const Bilde = ({
|
||||
dekorativt?: boolean;
|
||||
};
|
||||
className?: string;
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
if (!node || !node.asset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT } from "@/lib";
|
||||
|
||||
import {
|
||||
ResolveContributorsSingleT,
|
||||
ResolveTemaT,
|
||||
ResolveSlugT,
|
||||
AkselGodPraksisDocT,
|
||||
} from "@/types";
|
||||
import { BodyShort, Detail, Heading } from "@navikt/ds-react";
|
||||
import NextLink from "next/link";
|
||||
import { abbrName, dateStr, logNav } from "../..";
|
||||
@@ -16,16 +22,9 @@ const ArtikkelCard = ({
|
||||
tema,
|
||||
level = "2",
|
||||
...rest
|
||||
}: Partial<
|
||||
(SanityT.Schema.aksel_artikkel | SanityT.Schema.aksel_blogg) & {
|
||||
slug: string;
|
||||
tema: string[];
|
||||
source?: string;
|
||||
contributor: { title: string } | null;
|
||||
variant?: "god-praksis" | "tema";
|
||||
level?: "2" | "3" | "4";
|
||||
}
|
||||
>) => {
|
||||
}: ResolveContributorsSingleT<
|
||||
ResolveTemaT<ResolveSlugT<AkselGodPraksisDocT>>
|
||||
> & { source: string; variant: string; level?: "2" | "3" }) => {
|
||||
const date = (rest as any)?.updateInfo?.lastVerified
|
||||
? (rest as any)?.updateInfo?.lastVerified
|
||||
: publishedAt
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT } from "@/lib";
|
||||
import { AkselBloggDocT, ResolveContributorsT, ResolveSlugT } from "@/types";
|
||||
import { BodyLong, BodyShort, Heading, Link } from "@navikt/ds-react";
|
||||
import { getAuthors } from "components/website-modules/LatestBloggs";
|
||||
import NextLink from "next/link";
|
||||
@@ -8,14 +8,7 @@ import { dateStr, logNav } from "../..";
|
||||
const BloggCard = ({
|
||||
blog,
|
||||
}: {
|
||||
blog: Partial<
|
||||
SanityT.Schema.aksel_blogg & {
|
||||
slug: string;
|
||||
contributors?: {
|
||||
title?: string;
|
||||
}[];
|
||||
}
|
||||
>;
|
||||
blog: ResolveContributorsT<ResolveSlugT<AkselBloggDocT>>;
|
||||
}) => {
|
||||
return (
|
||||
<li
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import { urlFor } from "@/lib";
|
||||
import { AkselTemaT } from "@/types";
|
||||
import { logNav } from "@/utils";
|
||||
import { BodyShort } from "@navikt/ds-react";
|
||||
import cl from "clsx";
|
||||
import NextLink from "next/link";
|
||||
import Image from "next/legacy/image";
|
||||
import { logNav } from "@/utils";
|
||||
import { SanityT, urlFor } from "@/lib";
|
||||
|
||||
interface AkselTemaT extends SanityT.Schema.aksel_tema {
|
||||
refCount: number;
|
||||
}
|
||||
import NextLink from "next/link";
|
||||
|
||||
const GodPraksisCard = ({ node }: { node: AkselTemaT }) => {
|
||||
if (
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import NextLink from "next/link";
|
||||
import Image from "next/legacy/image";
|
||||
import { urlFor } from "@/lib";
|
||||
import { AkselTemaT } from "@/types";
|
||||
import { logNav } from "@/utils";
|
||||
import { SanityT, urlFor } from "@/lib";
|
||||
|
||||
interface AkselTemaT extends SanityT.Schema.aksel_tema {
|
||||
refCount: number;
|
||||
}
|
||||
import Image from "next/legacy/image";
|
||||
import NextLink from "next/link";
|
||||
|
||||
const GodPraksisCardSimple = ({ node }: { node: Partial<AkselTemaT> }) => {
|
||||
if (!node?.pictogram || !node?.slug?.current || !node?.title) {
|
||||
@@ -14,7 +11,7 @@ const GodPraksisCardSimple = ({ node }: { node: Partial<AkselTemaT> }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<li className="flex items-center gap-2 px-2 py-4 sm:gap-4 sm:px-6">
|
||||
<li className="flex items-center gap-2 px-2 py-4 sm:gap-4 sm:px-6">
|
||||
<div className="relative h-8 w-8 shrink-0 sm:h-12 sm:w-12">
|
||||
<Image
|
||||
src={urlFor(node?.pictogram).auto("format").url()}
|
||||
|
||||
@@ -10,7 +10,7 @@ const RelatertInnhold = ({
|
||||
node,
|
||||
}: {
|
||||
node: SanityT.Schema.relatert_innhold;
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
if (!node || node?.lenker?.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ const ComponentExamples = ({
|
||||
dir?: SanityT.Schema.kode_eksempler_fil;
|
||||
filnavn?: SanityT.Schema.kode_eksempler_fil;
|
||||
};
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
const [activeExample, setActiveExample] = useState(null);
|
||||
const [frameState, setFrameState] = useState(300);
|
||||
const [unloaded, setUnloaded] = useState(true);
|
||||
|
||||
@@ -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");
|
||||
@@ -0,0 +1,60 @@
|
||||
import { Heading, Label, Tag as DsTag } from "@navikt/ds-react";
|
||||
import cl from "clsx";
|
||||
|
||||
export const Tag = ({
|
||||
type,
|
||||
text,
|
||||
size = "medium",
|
||||
beta = false,
|
||||
}: {
|
||||
type: string;
|
||||
text?: string;
|
||||
size?: "medium" | "small";
|
||||
beta?: boolean;
|
||||
}) => {
|
||||
const Comp = ({ ...props }: any) =>
|
||||
size === "medium" ? (
|
||||
<Heading {...props} as="div" size="medium" />
|
||||
) : (
|
||||
<Label
|
||||
{...props}
|
||||
as="div"
|
||||
size="small"
|
||||
className={cl(props?.className, "mb-2")}
|
||||
/>
|
||||
);
|
||||
|
||||
switch (type) {
|
||||
case "aksel_artikkel":
|
||||
return (
|
||||
<Comp className="text-teal-600">{text ? text : "God praksis"}</Comp>
|
||||
);
|
||||
case "aksel_blogg":
|
||||
return <Comp className="text-pink-600">Blogg</Comp>;
|
||||
case "komponent_artikkel":
|
||||
return (
|
||||
<Comp className="text-deepblue-600 flex items-center gap-3">
|
||||
Komponent
|
||||
{beta && (
|
||||
<DsTag variant="alt1" size="small">
|
||||
Beta
|
||||
</DsTag>
|
||||
)}
|
||||
</Comp>
|
||||
);
|
||||
case "ds_artikkel":
|
||||
return (
|
||||
<Comp className="text-deepblue-600 flex items-center gap-3">
|
||||
Grunnleggende
|
||||
{beta && (
|
||||
<DsTag variant="alt1" size="small">
|
||||
Beta
|
||||
</DsTag>
|
||||
)}
|
||||
</Comp>
|
||||
);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -4,7 +4,7 @@ export const Highlighter = ({
|
||||
}: {
|
||||
type: string;
|
||||
prev?: string;
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
const isString = type === "string" || type.match(/^["][^"]+"$/) !== null;
|
||||
|
||||
const isType =
|
||||
|
||||
@@ -27,7 +27,11 @@ const List = ({ prop, parent }: { prop: any; parent: string }) => {
|
||||
prop?.required ? "" : "?"
|
||||
} `}</span>
|
||||
) : (
|
||||
<Tooltip content={`${prop.defaultValue}`} arrow={false} delay={0}>
|
||||
<Tooltip
|
||||
content={`default: ${prop.defaultValue}`}
|
||||
arrow={false}
|
||||
delay={0}
|
||||
>
|
||||
<span className="mr-2 cursor-pointer border-b border-dashed border-gray-600 font-semibold">{`${
|
||||
prop.name
|
||||
}${prop?.required ? "" : "?"}`}</span>
|
||||
@@ -51,7 +55,7 @@ const List = ({ prop, parent }: { prop: any; parent: string }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const PropTable = ({ komponent }: { komponent: PropT }): JSX.Element => {
|
||||
const PropTable = ({ komponent }: { komponent: PropT }) => {
|
||||
return (
|
||||
<div>
|
||||
<Heading
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from "react";
|
||||
import { withErrorBoundary } from "@/error-boundary";
|
||||
import PropTableV2, { PropT } from "./PropTabell";
|
||||
|
||||
const PropsSeksjon = ({ node }: { node: any }): JSX.Element => {
|
||||
const PropsSeksjon = ({ node }: { node: any }) => {
|
||||
if (
|
||||
!node ||
|
||||
(node?.elementer?.length === 0 && node?.komponenter?.length === 0)
|
||||
|
||||
@@ -7,7 +7,7 @@ import cl from "clsx";
|
||||
import React from "react";
|
||||
import style from "./tips.module.css";
|
||||
|
||||
const Tips = ({ node }: { node: SanityT.Schema.tips }): JSX.Element => {
|
||||
const Tips = ({ node }: { node: SanityT.Schema.tips }) => {
|
||||
if (!node || !node.body) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export const Frame = ({
|
||||
{hasDescription && <th>Beskrivelse</th>}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="component-token-grid">
|
||||
<tbody className="component-token-grid grid grid-cols-[repeat(auto-fill,_minmax(min(20rem,_100%),_1fr))] gap-4">
|
||||
{tokens.map((c) => (
|
||||
<tr
|
||||
key={c.name}
|
||||
|
||||
@@ -57,7 +57,7 @@ const CubeSmall = () => (
|
||||
|
||||
export const BloggAd = () => {
|
||||
return (
|
||||
<div className="full-bleed my-20 flex h-72 items-center bg-[#FBCFE8] px-4 md:rounded-2xl md:px-6 lg:h-80 lg:pl-12">
|
||||
<div className="relative left-1/2 right-1/2 -mx-[50vw] my-20 flex h-72 w-screen items-center bg-[#FBCFE8] px-4 md:left-auto md:right-auto md:mx-auto md:w-full md:max-w-[85%] md:rounded-2xl md:px-6 lg:h-80 lg:pl-12">
|
||||
<div className="z-10 max-w-sm text-[#831843]">
|
||||
<Heading level="2" size="xlarge" spacing>
|
||||
Skriv for bloggen
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Tooltip } from "@navikt/ds-react";
|
||||
import { useContext } from "react";
|
||||
import { IdContext, useCheckAuth } from "./utils";
|
||||
|
||||
function EditButton(): JSX.Element {
|
||||
function EditButton() {
|
||||
const idCtx = useContext(IdContext);
|
||||
|
||||
const validUser = useCheckAuth();
|
||||
|
||||
@@ -10,7 +10,7 @@ export const LevelTwoHeading = ({
|
||||
children: [React.ReactNode | string];
|
||||
hidden?: boolean;
|
||||
id: string;
|
||||
}): JSX.Element => {
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{hidden && <div id={id} className="scroll-m-18" />}
|
||||
|
||||
@@ -1,33 +1,24 @@
|
||||
import Image from "next/legacy/image";
|
||||
import NextLink from "next/link";
|
||||
import { urlFor } from "@/lib";
|
||||
import { SanityBlockContent } from "@/sanity-block";
|
||||
import { AkselBloggDocT, ResolveContributorsT, ResolveSlugT } from "@/types";
|
||||
import { dateStr } from "@/utils";
|
||||
import { BodyLong, BodyShort, Heading, Link } from "@navikt/ds-react";
|
||||
import { SanityT, urlFor } from "@/lib";
|
||||
import cl from "clsx";
|
||||
import { getImage } from "components/website-modules/utils/get-image";
|
||||
import { SanityBlockContent } from "@/sanity-block";
|
||||
import AkselLink from "components/website-modules/AkselLink";
|
||||
import Image from "next/legacy/image";
|
||||
import NextLink from "next/link";
|
||||
|
||||
export type BloggPageT = Partial<
|
||||
SanityT.Schema.aksel_blogg & {
|
||||
slug: string;
|
||||
contributors?: { title?: string }[];
|
||||
}
|
||||
>;
|
||||
|
||||
export const getAuthors = (blog: BloggPageT) =>
|
||||
(blog?.contributors as any)?.map((x) => x?.title) ?? [];
|
||||
export const getAuthors = (
|
||||
blog: ResolveContributorsT<ResolveSlugT<AkselBloggDocT>>
|
||||
) => (blog?.contributors as any)?.map((x) => x?.title) ?? [];
|
||||
|
||||
export const LatestBloggposts = ({
|
||||
bloggs,
|
||||
title,
|
||||
variant = "blogg",
|
||||
level = "1",
|
||||
intro,
|
||||
}: {
|
||||
bloggs: BloggPageT[];
|
||||
bloggs: ResolveContributorsT<ResolveSlugT<AkselBloggDocT>>[];
|
||||
title: string;
|
||||
variant?: "blogg" | "forside";
|
||||
level?: "1" | "2";
|
||||
intro?: any[];
|
||||
}) => {
|
||||
@@ -36,18 +27,11 @@ export const LatestBloggposts = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cl({
|
||||
"mt-20": variant === "blogg",
|
||||
})}
|
||||
>
|
||||
<div className="mt-20">
|
||||
<Heading
|
||||
level={level}
|
||||
size="xlarge"
|
||||
className={cl(
|
||||
"text-deepblue-700 mx-auto w-full md:mx-0 md:max-w-none",
|
||||
{ "text-5xl": variant === "blogg" }
|
||||
)}
|
||||
className="text-deepblue-700 mx-auto w-full text-5xl md:mx-0 md:max-w-none"
|
||||
>
|
||||
{title}
|
||||
</Heading>
|
||||
@@ -169,11 +153,6 @@ export const LatestBloggposts = ({
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{variant === "forside" && (
|
||||
<AkselLink href="/produktbloggen" className="h-fit self-end">
|
||||
Les flere blogginnlegg
|
||||
</AkselLink>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -284,11 +263,6 @@ export const LatestBloggposts = ({
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{variant === "forside" && (
|
||||
<AkselLink href="/produktbloggen" className="self-end">
|
||||
Les flere blogginnlegg
|
||||
</AkselLink>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { BodyShort, Button } from "@navikt/ds-react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
function PreviewBanner(): JSX.Element {
|
||||
function PreviewBanner() {
|
||||
const { asPath } = useRouter();
|
||||
const validUser = useCheckAuth();
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export function TableOfContents({
|
||||
changedState: any;
|
||||
hideToc?: boolean;
|
||||
aksel?: boolean;
|
||||
}): JSX.Element {
|
||||
}) {
|
||||
const [toc, setToc] = useState<
|
||||
{ heading: string; id: string; lvl3: { heading: string; id: string }[] }[]
|
||||
>([]);
|
||||
|
||||
@@ -13,7 +13,7 @@ export function TableOfContentsv2({
|
||||
changedState: any;
|
||||
hideToc?: boolean;
|
||||
aksel?: boolean;
|
||||
}): JSX.Element {
|
||||
}) {
|
||||
const [toc, setToc] = useState<
|
||||
{ heading: string; id: string; lvl3: { heading: string; id: string }[] }[]
|
||||
>([]);
|
||||
@@ -157,7 +157,7 @@ export function TableOfContentsv2({
|
||||
<BodyShort
|
||||
as="li"
|
||||
size="small"
|
||||
className={cl("py-1", {
|
||||
className={cl("relative py-1", {
|
||||
"font-semibold": link.id === activeId,
|
||||
"": link.id !== activeId,
|
||||
})}
|
||||
@@ -166,7 +166,7 @@ export function TableOfContentsv2({
|
||||
href={`#${link.id}`}
|
||||
onClick={() => handleFocus(`${link.id}`)}
|
||||
className={cl(
|
||||
"block max-w-full no-underline hover:underline",
|
||||
"z-10 block max-w-full no-underline hover:underline",
|
||||
{
|
||||
"text-deepblue-800":
|
||||
link.id === activeId &&
|
||||
@@ -179,7 +179,7 @@ export function TableOfContentsv2({
|
||||
</Link>
|
||||
{link?.lvl3?.length > 0 && (
|
||||
<ul
|
||||
className={cl("animate-fadeIn pt-1", {
|
||||
className={cl("animate-toc z-10 pt-1 ", {
|
||||
hidden: link.id !== activeId,
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -6,3 +6,15 @@
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.containerStatic {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
padding: 1.5rem 1rem;
|
||||
}
|
||||
|
||||
.containerStatic > * {
|
||||
max-width: 30rem;
|
||||
width: 100%;
|
||||
}
|
||||
@@ -4,15 +4,25 @@ import cl from "clsx";
|
||||
|
||||
export const withDsExample = (
|
||||
Component: ComponentType,
|
||||
variant?: "full" | "inverted"
|
||||
/**
|
||||
* Static: Used for dynamic-height examples like ExpansionCard
|
||||
*/
|
||||
variant?: "full" | "inverted" | "static"
|
||||
) => {
|
||||
const DsHOC = (props: any) => (
|
||||
<div
|
||||
className={cl(styles.container, {
|
||||
className={cl({
|
||||
"bg-gray-900": variant === "inverted",
|
||||
[styles.containerStatic]: variant === "static",
|
||||
[styles.container]: variant !== "static",
|
||||
})}
|
||||
>
|
||||
<div id="ds-example" className={cl({ "w-full": variant === "full" })}>
|
||||
<div
|
||||
id="ds-example"
|
||||
className={cl({
|
||||
"w-full": variant === "full",
|
||||
})}
|
||||
>
|
||||
<Component {...props} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loaded 100 of 183 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user