Compare commits

...
Author SHA1 Message Date
github-actions[bot] 27d89d7a41 Lerna versionbump [ci skip]
- @navikt/ds-react@0.9.1
2021-09-23 07:26:09 +00:00
Andreas Nordahl 3a56f34a62 [FIX] Allow text fields to be of any type that looks like a text input (#1264) 2021-09-23 09:11:14 +02:00
github-actions[bot] e7660412bc Lerna versionbump [ci skip]
- @navikt/ds-react@0.9.0
2021-09-21 13:07:25 +00:00
Andreas Nordahl 956afbb91a [FEATURE] remove Bubble from speech-bubble/index exports, and import it directly in SpeechBubble (#1262) 2021-09-21 14:55:56 +02:00
github-actions[bot] 5fd28b0131 Lerna versionbump [ci skip]
- @navikt/ds-css@0.8.3
 - @navikt/ds-icons@0.5.3
 - @navikt/ds-react@0.8.3
 - @navikt/ds-tokens@0.5.1
 - nav-frontend-ekspanderbartpanel@4.0.2
 - nav-frontend-hjelpetekst@3.1.2
 - nav-frontend-ikonknapper@2.1.2
 - nav-frontend-js-utils@1.0.20
 - nav-frontend-knapper@3.1.2
 - nav-frontend-lesmerpanel@2.0.2
 - nav-frontend-popover@2.0.3
 - nav-frontend-skjema-style@3.0.2
 - nav-frontend-skjema@4.0.4
 - nav-frontend-stegindikator@2.0.2
 - nav-frontend-tabs@2.0.2
 - nav-frontend-toggle@2.1.2
 - nav-frontend-veileder@3.0.2
 - nav-frontend-veilederpanel@2.0.2
2021-09-20 12:53:58 +00:00
Ken 646f6b858e [FIX] Fikset type-error 2021-09-20 14:36:44 +02:00
Ken c5add547bc fikset build 2021-09-20 14:07:00 +02:00
Andreas Nordahl cac3a433c4 [FIX] Remove flex-shrink: 0 from button (#1259) 2021-09-20 14:05:03 +02:00
Ken 5eb5b6b617 Update CONTRIBUTING.md 2021-09-20 14:03:47 +02:00
Ken 19afca1ed6 Update CONTRIBUTING.md 2021-09-20 14:03:30 +02:00
Ken 7c341f7cd2 [FIX] Chore: oppdatert pakkeversjoner og scripts (#1254) 2021-09-20 14:02:28 +02:00
github-actions[bot] 9a1a48d319 Lerna versionbump [ci skip]
- @navikt/ds-css@0.8.2
 - @navikt/ds-react@0.8.2
 - nav-frontend-skjema@4.0.3
2021-09-20 11:48:54 +00:00
Ken ce4afb17a8 [FIX] Refactor speechbubble til dot-notasjon (#1256) 2021-09-20 13:35:33 +02:00
Ken 146111e859 [FIX] Justert alignment av tekst i SpeechBubble (#1255) 2021-09-20 13:35:25 +02:00
Ken 40a8965cec [FIX] Setter aria-live til polite bare når 20 tegn gjenstår... (#1258)
... i Textarea
2021-09-20 13:34:23 +02:00
github-actions[bot] 8f4e6a5e89 Lerna versionbump [ci skip]
- @navikt/ds-react@0.8.1
2021-09-17 15:03:05 +00:00
Ken e73c9d2f3e [FIX] short-uuid -> uuid (short-uuid brekker sanity) (#1257) 2021-09-17 16:47:51 +02:00
Ken 0849fffe40 oppdatert changelog 2021-09-16 15:07:24 +02:00
TuvaSverdstad 7a261e86a3 Update produktsider.mdx (#1253) 2021-09-16 15:03:17 +02:00
TuvaSverdstad a2c48a9246 Update livssituasjonssider.mdx (#1252) 2021-09-16 15:03:03 +02:00
github-actions[bot] 7c845ac464 Lerna versionbump [ci skip]
- @navikt/ds-css@0.8.1
2021-09-16 08:24:28 +00:00
Ken 6edd03a9c1 [FIX] hotfix searchfield clearbutton 2021-09-16 10:09:35 +02:00
Andreas NordahlandKen 724a90eb28 [FIX] Button padding fix (#1248)
Co-authored-by: Ken <ken.aleksander@gmail.com>
2021-09-16 10:00:54 +02:00
TuvaSverdstad 43b686e769 Update produktsider.mdx (#1249) 2021-09-16 09:09:16 +02:00
github-actions[bot] c485e1bfc7 Lerna versionbump [ci skip]
- @navikt/ds-css@0.8.0
 - @navikt/ds-react@0.8.0
 - @navikt/ds-tokens@0.5.0
2021-09-15 14:04:17 +00:00
KenandAndreas Nordahl 9533504b16 [FEATURE] Samling av oppdaterte vnext komponenter (#1194)
Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
2021-09-15 15:46:55 +02:00
T. GulbrandsenandKen bca56d1c48 God praksis om man bruker disabled state (#1246)
* God praksis for når man bruker disabled state

* Update disabled.mdx

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2021-09-15 14:28:34 +02:00
TuvaSverdstad a656a19df5 Update livssituasjonssider.mdx (#1245) 2021-09-15 09:14:57 +02:00
Ken a2ac8fedb1 Update build-publish.yml 2021-09-14 15:58:56 +02:00
TuvaSverdstadandKen bf0a71f1d4 Update produktsider.mdx (#1243)
* Update produktsider.mdx

* Update produktsider.mdx

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2021-09-14 13:25:02 +02:00
TuvaSverdstadandKen e4b51f49fb Update livssituasjonssider.mdx (#1244)
* Update livssituasjonssider.mdx

* Update livssituasjonssider.mdx

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2021-09-14 13:24:52 +02:00
Ken ea49e12e23 Update .specifyrc.json 2021-09-13 16:24:21 +02:00
Ken 4a29f5b449 Update .specifyrc.json 2021-09-13 16:21:11 +02:00
Ken 7b7950dab1 Update .specifyrc.json 2021-09-13 16:19:40 +02:00
Snyk bot bcb8d46c72 [Snyk] Security upgrade chalk from 1.1.3 to 2.0.0 (#1240) 2021-09-13 09:28:08 +02:00
TuvaSverdstad 60dbbaedd9 Update produktsider.mdx (#1236)
innholdsoppdatering
2021-09-10 11:09:49 +02:00
Ken 8991704a09 endret base branch for token sync 2021-09-10 08:52:26 +02:00
Ken 4a22f10763 [Tokens] Config for farge-sync (#1234) 2021-09-10 08:48:52 +02:00
github-actions[bot] 7335fb6c8d Lerna versionbump [ci skip]
- @navikt/ds-react@0.7.7
2021-09-08 10:25:17 +00:00
Ken 9b95eff894 [fix] Versjonering i commit MSG (#1220)
* started oppdatering av versionering

* oppdatert workflow

* oppdatert workflows

* oppdatert workflows2

* oppdatert workflow3

* tester pakke-endring

* la til chromatic i workflow comment

* testendring

* fikset workflow settings

* oppdatert yarn lock
2021-09-08 12:08:46 +02:00
github-actions[bot] 08ce808f21 Lerna versionbump [ci skip]
- @navikt/ds-react@0.7.6
2021-09-08 09:27:16 +00:00
Andreas Nordahl 64b2f2bfb5 Make href optional in link (#1230) 2021-09-08 11:09:15 +02:00
Ken df38a410a5 midlertidig fjernet specify fra master 2021-09-08 07:31:50 +00:00
github-actions[bot] 0e426ee905 Lerna versionbump [ci skip]
- @navikt/ds-css@0.7.4
2021-09-07 11:23:35 +00:00
Ken 7f0278429b flex-shrink 0 på chevron (#1224) 2021-09-07 13:08:25 +02:00
github-actions[bot] 041c662737 Lerna versionbump [ci skip]
- @navikt/ds-css@0.7.3
2021-09-07 06:16:58 +00:00
Andreas Nordahl f8c59d7bc1 Alert + confirmation-panel link color (#1223)
* use text color for links when contrast to background is below 4.5

* fix confirmation error background color

* fix confirmation panel link color
2021-09-07 08:04:35 +02:00
Snyk bot f0dccb0a83 [Snyk] Security upgrade axios from 0.21.1 to 0.21.3 (#1221) 2021-09-06 11:03:43 +02:00
github-actions[bot] 11f23ef579 Lerna versionbump [ci skip]
- nav-frontend-ikonknapper@2.1.1
 - nav-frontend-knapper-style@2.1.1
 - nav-frontend-knapper@3.1.1
 - nav-frontend-tabell-style@2.1.1
 - nav-frontend-toggle-style@2.1.1
 - nav-frontend-toggle@2.1.1
2021-08-31 13:33:47 +00:00
Ken ebb7be678f Oppdatert text-transform for Knapper (#1201) 2021-08-31 15:19:02 +02:00
github-actions[bot] 588d485841 Lerna versionbump [ci skip]
- nav-frontend-skjema@4.0.2
2021-08-30 14:29:05 +00:00
Ken f4ec864c5d oppdatert proptypes for input 2021-08-30 16:14:53 +02:00
Karl O c91131c29c update Input to support modern refs (#1216)
- Merger da build-feilen antas til å være på grunn av fork av repo.
2021-08-30 15:53:04 +02:00
TuvaSverdstad d8e18812ff Update produktsider.mdx (#1210) 2021-08-30 09:41:41 +02:00
TuvaSverdstad d40f624edb Update livssituasjonssider.mdx (#1211) 2021-08-30 09:41:28 +02:00
Ken 1cfd79fdb8 fikset feil i env for workflow 2021-08-26 08:48:58 +02:00
Ken 9dabc6386d oppdatert workflow for auth 2021-08-26 08:26:26 +02:00
github-actions[bot] ac6215408d Lerna versionbump [ci skip]
- @navikt/ds-css@0.7.2
2021-08-25 14:28:40 +00:00
Ken 6e4e0bde93 version fix modal 2021-08-25 16:12:48 +02:00
Ken dcf0ecc9a6 modal hotfix 2021-08-25 16:12:37 +02:00
Ken 2b1cc85517 Oppdatert modal-styling for å unngå fullskjerm (#1200) 2021-08-25 16:05:05 +02:00
github-actions[bot] 1053ca7dca Lerna versionbump [ci skip]
- @navikt/ds-css@0.6.21
 - @navikt/ds-react@0.7.5
2021-08-25 08:41:50 +00:00
Ken 25c186473b Fjernet docs fra repo (#1187)
* fjernet docs

* update yarn lock

* fikset packages.json
2021-08-25 10:24:36 +02:00
Ken 7ea6c9c0f1 fjernet utdaterte komponenter (#1186) 2021-08-25 10:24:03 +02:00
Ken a6014bb409 Fikser code-styling for eksempler i God-praksis (#1188)
* forsøk på code fix for god-praksis målinger

* fjernet console-log
2021-08-24 16:34:29 +02:00
Ken f60ff3a8c9 oppdatert maler (#1185) 2021-08-23 16:58:08 +02:00
Ken 8d8425acfb commiter endring i lerna.json lokalt for publisering 2021-08-22 20:03:56 +02:00
Ken ce086d890f fikset needs i workflow 2021-08-22 19:50:04 +02:00
Ken 5e9ef5fbd3 oppdater navn workflow 2021-08-22 19:48:41 +02:00
Ken 21958012a2 fikset workflow 2021-08-22 19:43:54 +02:00
Ken fa0307ec15 oppdatet workflow 2021-08-22 19:39:22 +02:00
Ken 69c32e4036 tmp fix for workflow 2021-08-20 17:06:45 +02:00
Ken 9a9e265831 forsøk på wokflow fix 2021-08-20 16:47:44 +02:00
Ken fb37c6135f fikset workflow 2021-08-20 15:51:51 +02:00
Ken 09259ef960 oppdatert workflow 2021-08-20 15:36:09 +02:00
Ken 2b0753e4a6 oppdatert gitignore 2021-08-20 15:30:17 +02:00
Ken 471e9b19ee Update lerna.json 2021-08-20 15:14:32 +02:00
Ken 86b7b8e406 Oppdaterte lerna config (#1183) 2021-08-20 15:06:55 +02:00
Ken 563942947d Lar oss publisere pakker til github package registry (#1182)
* oppdaterte lern aconfig

* fikset registry

* fjernet gammle pakker fra publish
2021-08-20 14:45:16 +02:00
github-actions[bot] c9adb83158 Lerna versionbump [ci skip]
- @navikt/ds-css@0.6.20
 - @navikt/ds-react@0.7.4
2021-08-20 10:00:01 +00:00
KenAndreas NordahlMagnusRom MagnusRom@users.noreply.github.com
bf079796f3 SearchField komponent (#1178)
Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
Co-authored-by: MagnusRom MagnusRom@users.noreply.github.com
2021-08-20 11:42:42 +02:00
Andreas Nordahl a1f4f0fe28 only allow string for checkbox value (#1181) 2021-08-20 11:40:13 +02:00
Ken f146c0c57c Update useCheckbox.ts 2021-08-20 11:36:40 +02:00
Ken fd397b03e5 La til storybook på repo forside 2021-08-20 08:10:56 +02:00
Michael Johansen 2a66f1ec6e Glemmer alltid denne lenka (#1180) 2021-08-19 16:38:19 +02:00
375 changed files with 7368 additions and 21282 deletions

No files matched your search

+46 -16
View File
@@ -11,7 +11,7 @@ on:
workflow_dispatch:
jobs:
build:
test-build:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
runs-on: ubuntu-latest
steps:
@@ -27,10 +27,10 @@ jobs:
with:
path: "**/node_modules"
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- name: Install deps
- name: install
if: steps.node-cache.outputs.cache-hit != 'true'
run: yarn install
- name: Gulp-build
- name: Boot
run: yarn boot
- name: Eslint and Stylelint
run: yarn lint
@@ -38,7 +38,7 @@ jobs:
run: echo "ACCESS_TOKEN=${{ secrets.VERKTOYKASSE_INNHOLD_TOKEN }}" >> website/.env
- name: add branch token to .env
run: echo "BRANCH=HEAD" >> website/.env
- name: Test gatsby-build
- name: Test gatsby-build (design.nav.no)
run: yarn build:gatsby
- name: Test chromatic
uses: chromaui/action@v1
@@ -48,9 +48,9 @@ jobs:
exitZeroOnChanges: true
publish-npm:
needs: build
needs: test-build
runs-on: ubuntu-latest
if: github.event_name == 'push'
if: github.event_name == 'push' && contains(github.event.head_commit.message, '[fix]') || contains(github.event.head_commit.message, '[feature]') || contains(github.event.head_commit.message, '[breaking]')
steps:
- uses: actions/checkout@v2
with:
@@ -66,23 +66,53 @@ jobs:
with:
path: "**/node_modules"
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- name: Install deps
- name: install
if: steps.node-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile
- name: Gulp-build
- name: Boot
run: yarn boot
- run: git config --global user.email "github-actions[bot]@users.noreply.github.com"
- run: git config --global user.name "github-actions[bot]"
- run: git remote set-url origin https://github-actions[bot]:$NAV_DS_TOKEN@github.com/$GITHUB_REPOSITORY.git
- name: Setup github connection for auth
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git remote set-url origin https://github-actions[bot]:$NAV_DS_TOKEN@github.com/$GITHUB_REPOSITORY.git
env:
NAV_DS_TOKEN: ${{secrets.GIT_REPO}}
- run: yarn lerna version patch --include-merged-tags --yes
- run: yarn lerna publish from-package --yes
- name: Update changed packages with PATCH
if: "contains(github.event.head_commit.message, '[fix]')"
run: yarn lerna version patch --include-merged-tags --yes
- name: Update changed packages with MINOR
if: "contains(github.event.head_commit.message, '[feature]')"
run: yarn lerna version minor --include-merged-tags --yes
- name: Update changed packages with MAJOR
if: "contains(github.event.head_commit.message, '[breaking]')"
run: yarn lerna version major --include-merged-tags --yes
- name: Create a .npmrc file for NPM
run: |
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
npm whoami
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_AUTOMATION}}
NPM_TOKEN: ${{secrets.NPM_AUTOMATION}}
- name: Publish to NPM registry
run: |
yarn lerna publish from-package --yes
rm .npmrc
- name: Create a .npmrc file for the github package repository
uses: FerLuisxd/create-npmrc@3
with:
org_name: navikt
env:
AUTH_TOKEN: ${{secrets.GIT_REPO}}
- name: Publish to Github registry
run: |
rm lerna.json && cp utilities/lerna.json lerna.json
git add . && git commit -m "tmp"
yarn lerna publish --registry https://npm.pkg.github.com from-package --yes
publish-pages:
needs: publish-npm
needs: test-build
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
@@ -122,7 +152,7 @@ jobs:
env:
NAV_DS_TOKEN: ${{secrets.GIT_REPO}}
- name: Deploy storybook
- name: Deploy storybook to designsystem-repo
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{secrets.GIT_REPO}}
+1
View File
@@ -41,6 +41,7 @@ typings/
# Optional npm cache directory
.npm
.npmrc
# Optional eslint cache
.eslintcache
+21 -32
View File
@@ -1,54 +1,43 @@
{
"repository": "@nav/designsystem",
"head": "updated-specify-tokens",
"base": "master",
"head": "specify-sync",
"base": "specify-token-parsing",
"rules": [
{
"name": "Specify / Icons",
"path": "@navikt/ds-icons/svg",
"name": "Color sync",
"path": "@navikt/ds-tokens/src/colors.js",
"filter": {
"types": ["vector"]
"types": ["color"]
},
"parsers": [
{
"name": "pascalcasify",
"name": "to-theme-ui",
"options": {
"keys": ["name"]
}
},
{
"name": "name-assets-files-by-pattern",
"options": {
"pattern": "{{name}}.{{format}}"
"formatConfig": {
"module": "commonjs"
},
"formatTokens": {
"colorFormat": {
"format": "rgb"
}
}
}
}
]
},
{
"name": "Specify / Icons - metadata",
"path": "@navikt/ds-icons/figma-api/metadata-specify.json",
"name": "Spacing sync",
"path": "@navikt/ds-tokens/src/spacing.js",
"filter": {
"types": ["vector"]
"types": ["measurement"]
},
"parsers": [
{
"name": "pascalcasify",
"name": "to-theme-ui",
"options": {
"keys": ["name"]
}
},
{
"name": "pick",
"options": {
"keys": [
"name",
"createdAt",
"updatedAt",
"meta.description",
"meta.parentFrame",
"meta.frame",
"page"
]
"formatConfig": {
"module": "commonjs"
}
}
}
]
+229
View File
@@ -0,0 +1,229 @@
import { Meta } from "@storybook/addon-docs";
<Meta title="ds-react/Migration" />
# Migrering til ds-react, ds-css v0.8.0
Denne guiden vil være til hjelp for de som allerede har begynt å ta i bruk de nye pakkene våre tidligere enn v0.8.0.
For de som ikke har begynt å ta i bruk pakkene kan man se bort fra denne.
Fra versjon v0.7 til v0.8 er det komment flere store endringer både i ds-react og ds-css. For å lettere
oppdatere til v0.8 har vi da laget en liten guide som forklarer de største endringene.
## Styling
De fleste komponenter har fått diverse justering på styling. Anbefales da å ta en rask sjekk om alt fortsatt stemmer
etter oppdateringen.
## Sizing
Alle komponenter som tidligere var implementert med `size`-prop har fått oppdatert
props fra "xs", "s", "m", "l", "xl", "2xl" -> "xsmall", "small", "medium", "large", "xlarge", "2xlarge".
Dette betyr også at css-stylingen er eks endret fra `.navds-body-short--s` -> `.navds-body-short--small`
## Overridable component
Komponenter som tidligere implementerte ovveridable component med bruk av `component`-prop bruker nå `as`.
Implementasjonen av OverridableComponent er WIP så kan hende typene ender opp med å krangle i enkelte tilfeller. Om så ta gjerne kontakt med oss
slik at vi får sett på det tilfellet!
```jsx
/* Før */
<BodyShort component="span" />
/* Etter */
<BodyShort as="span" />
```
## Navneendringer
### Buttons
- `Primary` -> `Secondary` (Normal)
- `Action` -> `Primary` (Hoved)
- `Secondary` -> `Tertiary` (Flat)
For alle som har brukt `<Button />` så må man fikse slik at riktige knapper blir brukt der de skal!
## Nytt
- GuidePanel (veilederpanel)
- HelpText (Hjeleptext)
### Typography
Vi har valgt å endre fra `<Title/>` -> `<Heading/>` i typografien vår da dette ga mer mening i bruk.
APIet til komponenten er ikke endret borsett fra "Sizing" endringene nevt lengre opp, så skal bare være en rask search/replace.
For de som har brukt css-en direkte, eks `navds-title` så må man endre til `navds-heading`
Endret `Header` -> `PageHeader`, samme som er nevnt ang endringen over gjelder her også: sjekk css hvis brukt direkte.
## Fjernet komponenter
Fjernet da den var utdaterte/må ses mer på
- ProductPageLayout
## Typography
Linjehøyder for alle typo-komponentene er oppdatert til å matche figma.
Lagt til en Heading lvl 6 og size="xsmall"
## AccordionMenu
Implementert med dot-notation
- Trenger bare importere AccordionMenu
- AccordionMenuCollapsable -> AccordionMenu.Collapsable
- AccordionMenuItem -> AccordionMenu.Item
## Accordion
Implementert med dot-notation
- Trenger bare importere Accordion nå
Fragmenterte komponenten:
- Accordion -> Accordion.Item
- Header -> Accordion.Header
- children -> Accordion.Content
La til prop: `defaultOpen` på `Accordion.Item`
```jsx
/* Før */
<Accordion heading="tittel" open={open} onClick={(open) => setOpen(!open)}>
Eu magna fugiat officia
</Accordion>
<Accordion heading="tittel2" open={open2} onClick={(open2) => setOpen(!open2)}>
Eu magna fugiat officia
</Accordion>
/* Etter */
<Accordion>
<Accordion.Item open={open}>
<Accordion.Header onClick={(open) => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam officia
laboris voluptate officia pariatur.Lorem est ex anim velit
</Accordion.Content>
</Accordion.Item>
<Accordion.Item open={open2}>
<Accordion.Header onClick={(open2) => setOpen(!open2)}>
Accordion header text
</Accordion.Header>
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam officia
laboris voluptate officia pariatur.Lorem est ex anim velit
</Accordion.Content>
</Accordion.Item>
</Accordion>
```
## Alert
- La til `fullWidth`-prop for alert uten border-radius og width 100%
- La til `inline`-prop for alert med transparent border/background og 0 padding.
## Button
Oppdatert med Overridablecomponent.
Håndtering av sentrering, margins er oppdatert. Trenger ikke wrappe tekst med `span` når man skal bruke ikoner lengre.
Hvis man skal manuelt justere på alignment av innhold, eks bruke `flex-direction: column` må man sette
det på css-klassen `.navds-button__inner` da children er wrappet i den.
## CopyToClipboard
Ekstender nå ButtonProps, slik at man eks kan ta i bruk `size`-proppen
`text`-prop -> `copyText`
`label`-prop -> `popoverText`
Fjernet `icon`-prop, la til `popoverPlacement`
## Modal
Implementert med dot-notasjon
Innholds-padding er flyttet fra Modal -> Modal.Content
```
/* Før */
<Modal>Modal innhold</Modal>
/* Etter */
<Modal><Modal.Content>Modal innhold</Modal.Content></Modal>
```
## LinkPanel
Implementert med dot-notasjon
```jsx
/* Før */
<LinkPanel href="#">Consectetur eu duis aliqua eu irure fugiat fugiat eu.</LinkPanel>
/* Etter */
<LinkPanel href="#">
<LinkPanel.Title>
Consectetur eu duis aliqua eu irure fugiat fugiat eu.
</LinkPanel.Title>
</LinkPanel>
```
Kan nå legge til en beskrivelse med `Linkpanel.Description`
```jsx
<LinkPanel href="#">
<LinkPanel.Title>
Consectetur eu duis aliqua eu irure fugiat fugiat eu.
</LinkPanel.Title>
<LinkPanel.Description>Aliqua id aliquip Lorem esse</LinkPanel.Description>
</LinkPanel>
```
## Popover
Implementert med dot-notasjon
Får nå padding rundt innhold med Popover.Content
```jsx
/* Før */
<Popover>Popover innhold</Popover>
/* Etter */
<Popover>
<Popover.Content>Modal innhold</Popover.Content>
</Popover>
```
## Header -> PageHeader
Props må fikses for de som har brukt denne komponenten, i tilleg til å endre navn.
- `variant`-prop -> `align`
- `theme`-prop -> `variant`
## MicroCard
- Oppdatert med OverridableComponent
## SpeechBubble
Implementert med Dot-notasjon
- `<Bubble/>` -> `<SpeechBubble.Bubble/>`
Bubble er fortsatt eksportert så vil ikke brekke noe for de som har begynt å ta denne i bruk.
+1 -7
View File
@@ -20,7 +20,7 @@ Dette vil gjøre styling og overriding av komponenter enklere da man kan bruke c
## Intern / Ekstern sizing
Komponenter tilpasses og standariseres bedre for skillet mellom interne/eksterne flater.
Løsning er ikke fast bestemt, men eksempel på dette er `size="s" -> 32px, size="m"-> 48px`.
Løsning er ikke fast bestemt, men eksempel på dette er `size="small" -> 32px, size="medium"-> 48px`.
Dette vil da eksempelvis kunne være en standard som er gjennomgående for de fleste komponentene.
## Ny dokumentasjon-side
@@ -44,12 +44,6 @@ eks darkmode.
Dette er noe vi ikke har på planene for tiden, men etterhvert som ting faller på plass så vil dette være
noe vi kunne ta en titt på hvis vi ser at det trengs.
## Feature-flagging
Ideen om å ta i bruk feature-flagging er noe som virker veldig interessant og vil da se på muligheten for å kunne levere
større endringe i feature-flags for testing, og da publisere under eks major-bump i faste intervaller. Dette vil da kunne
gjøre det enklere for deg som consumer av pakkene å ha oversikt over endringer og hva som må migreres.
## Versjonering
To av de nye pakkene under `@navikt`, da `ds-css` og `ds-react` er nå versjonert under to store pakker med alle komponentene. I fremtiden vil vi se på å
+3
View File
@@ -0,0 +1,3 @@
# Designsystem v2
Storybook: https://navikt.github.io/Designsystemet/
-8
View File
@@ -1,8 +0,0 @@
.navds-accordion-anchor-menu {
padding: var(--navds-spacing-4) 0;
}
.navds-accordion-anchor-menu__title {
margin-left: var(--navds-spacing-4);
margin-right: var(--navds-spacing-4);
}
+19 -6
View File
@@ -1,3 +1,11 @@
:root {
--navds-accordion-menu-color-text: var(--navds-color-text-link);
--navds-accordion-menu-color-text-focus: var(--navds-color-darkgray);
--navds-accordion-menu-color-background-hover: var(--navds-color-blue-10);
--navds-accordion-menu-color-text-active: var(--navds-color-text);
--navds-accordion-menu-outline-focus: var(--navds-text-focus);
}
.navds-accordion-menu__list {
list-style: none;
margin: 0;
@@ -18,7 +26,7 @@
justify-content: space-between;
align-items: center;
font-weight: var(--navds-font-weight-bold);
color: var(--navds-color-text-link);
color: var(--navds-accordion-menu-color-text);
text-decoration: underline;
}
@@ -31,7 +39,7 @@
.navds-accordion-menu-collapsable__expand-icon {
font-size: 1.5rem;
color: var(--navds-color-text-link);
color: var(--navds-accordion-menu-color);
flex-shrink: 0;
margin-left: var(--navds-spacing-2);
}
@@ -73,18 +81,23 @@
.navds-accordion-menu-item:focus,
.navds-accordion-menu-collapsable__button:focus {
outline: 3px solid var(--navds-text-focus);
outline: 3px solid var(--navds-accordion-menu-outline-focus);
outline-offset: -3px;
color: var(--navds-color-darkgray);
color: var(--navds-accordion-menu-color-text-focus);
}
.navds-accordion-menu-collapsable__button:focus
> .navds-accordion-menu-collapsable__expand-icon {
color: var(--navds-accordion-menu-color-focus);
}
.navds-accordion-menu-item:hover,
.navds-accordion-menu-collapsable__button:hover {
background-color: var(--navds-color-blue-10);
background-color: var(--navds-accordion-menu-color-background-hover);
}
.navds-accordion-menu-item--active {
box-shadow: inset 0.5rem 0 var(--navds-color-text-link);
color: var(--navds-color-text);
color: var(--navds-accordion-menu-color-text-active);
text-decoration: none;
}
+36 -48
View File
@@ -1,82 +1,70 @@
.ReactCollapse--collapse {
transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1);
:root {
--navds-accordion-color-text: var(--navds-color-darkgray);
--navds-accordion-color-background: var(--navds-color-background);
--navds-accordion-color-text-hover: var(--navds-color-blue-50);
--navds-accordion-color-border-hover: var(--navds-color-blue-50);
--navds-accordion-color-border-focus: var(--navds-color-background);
}
.navds-accordion .ReactCollapse--collapse {
transition: height 250ms cubic-bezier(0.4, 0, 0.2, 1);
}
.navds-accordion {
position: relative;
background: var(--navds-color-background);
border-bottom: 2px solid #c9c9c9;
background: var(--navds-accordion-color-background);
}
.navds-accordion:hover {
/* color: black; */
border-bottom: 2px solid var(--navds-color-blue-50);
}
.navds-accordion:focus,
.navds-accordion__button:focus {
box-shadow: var(--navds-shadow-focus);
.navds-accordion__header:focus {
outline: none;
box-shadow: var(--navds-shadow-focus);
border-color: var(--navds-accordion-color-border-focus);
}
.navds-accordion__chevron {
width: 1.25em;
height: 1.25em;
transform: rotateZ(0deg);
.navds-accordion__header:hover {
color: var(--navds-accordion-color-text-hover);
border-color: var(--navds-accordion-color-border-hover);
text-decoration: underline;
}
.navds-accordion__expand-icon {
width: 1.5rem;
height: 1.5rem;
flex-shrink: 0;
margin-left: var(--navds-spacing-4);
}
.navds-accordion__chevron--up {
transform: rotateZ(-180deg);
.navds-accordion__expand-icon--flip {
transform: rotateZ(180deg);
}
.navds-accordion__chevron--down {
transform: rotateZ(0deg);
}
.navds-accordion__button {
padding: var(--navds-spacing-4);
.navds-accordion__header {
padding: var(--navds-spacing-4) var(--navds-spacing-3);
background: transparent;
text-align: left;
border: none;
width: 100%;
margin-bottom: 0;
margin: 0;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
color: var(--navds-color-text-link);
}
.navds-accordion__button:hover .navds-accordion__heading {
text-decoration: underline;
color: var(--navds-color-text-link);
border-bottom: 2px solid #a0a0a0;
gap: var(--navds-spacing-4);
}
.navds-accordion__content {
padding: var(--navds-spacing-2) var(--navds-spacing-4) var(--navds-spacing-4);
color: var(--navds-accordion-color-text);
padding: var(--navds-spacing-5) var(--navds-spacing-3) var(--navds-spacing-10);
}
.navds-accordion--open .navds-accordion__content {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.navds-accordion--open > .navds-accordion__button {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.navds-accordion__chevron--filled {
.navds-accordion__expand-icon--filled {
display: none;
}
.navds-accordion__button:hover
> .navds-accordion__chevron.navds-accordion__chevron--filled {
.navds-accordion__header:hover
> .navds-accordion__expand-icon.navds-accordion__expand-icon--filled {
display: inherit;
}
.navds-accordion__button:hover > .navds-accordion__chevron {
.navds-accordion__header:hover > .navds-accordion__expand-icon {
display: none;
}
+86 -51
View File
@@ -1,84 +1,119 @@
:root {
--navds-alert-color-border: var(--navds-color-gray-40);
--navds-alert-color-error-border: var(--navds-color-error-border);
--navds-alert-color-error-background: var(--navds-color-error-background);
--navds-alert-color-warning-border: var(--navds-color-warning-border);
--navds-alert-color-warning-background: var(--navds-color-warning-background);
--navds-alert-color-info-border: var(--navds-color-info-border);
--navds-alert-color-info-background: var(--navds-color-info-background);
--navds-alert-color-success-border: var(--navds-color-success-border);
--navds-alert-color-success-background: var(--navds-color-success-background);
--navds-alert-color-error-icon: var(--navds-color-red-60);
--navds-alert-color-error-icon-background: var(--navds-color-white);
--navds-alert-color-warning-icon: var(--navds-color-orange-40);
--navds-alert-color-warning-icon-background: var(--navds-color-darkgray);
--navds-alert-color-info-icon: var(--navds-color-lightblue-70);
--navds-alert-color-info-icon-background: var(--navds-color-white);
--navds-alert-color-success-icon: var(--navds-color-green-70);
--navds-alert-color-success-icon-background: var(--navds-color-white);
}
.navds-alert {
border-radius: 4px;
border: var(--navds-border-default);
/* Padding calculated based on 18px font for 64px tall alert */
padding: var(--navds-spacing-4) var(--navds-spacing-4);
display: grid;
grid-auto-flow: column;
justify-content: start;
min-height: 64px;
box-sizing: border-box;
border: 1px solid;
border-color: var(--navds-alert-color-border);
padding: calc(var(--navds-spacing-4) + 1px) calc(var(--navds-spacing-4) + 1px);
display: flex;
gap: var(--navds-spacing-3);
align-items: center;
}
.navds-alert--s {
padding: var(--navds-spacing-1) var(--navds-spacing-4);
min-height: 32px;
.navds-alert__wrapper {
max-width: 43.5rem;
}
.navds-alert > span > svg {
margin-right: var(--navds-spacing-3);
font-size: 1.5rem;
.navds-alert--small {
padding: calc(var(--navds-spacing-1) - 1px) var(--navds-spacing-4);
}
.navds-alert--full-width {
border-radius: 0;
}
.navds-alert > .navds-alert__icon {
flex-shrink: 0;
font-size: 1.5rem;
align-self: flex-start;
height: var(--navds-font-line-height-xl);
}
.navds-alert--small > .navds-alert__icon {
font-size: 1.25rem;
height: var(--navds-font-line-height-l);
}
.navds-alert--error {
border-color: var(--navds-alert-color-error-border);
background-color: var(--navds-alert-color-error-background);
}
.navds-alert--error > .navds-alert__icon {
color: var(--navds-alert-color-error-icon);
background: radial-gradient(
circle,
var(--navds-color-background) 50%,
var(--navds-alert-color-error-icon-background) 50%,
0,
transparent
);
}
.navds-alert > div {
display: block;
margin: auto 0;
max-width: 43.5rem;
flex: 1;
}
.navds-alert > span {
display: flex;
align-items: center;
max-height: calc(var(--navds-spacing-8) - 2px);
}
.navds-alert--error {
border-color: var(--navds-color-error-border);
background-color: var(--navds-color-error-background);
}
.navds-alert--error > span > svg {
color: var(--navds-color-red-60);
}
.navds-alert--warning {
border-color: var(--navds-color-warning-border);
background-color: var(--navds-color-warning-background);
border-color: var(--navds-alert-color-warning-border);
background-color: var(--navds-alert-color-warning-background);
}
.navds-alert--warning > span > svg {
color: var(--navds-color-orange-40);
.navds-alert--warning > .navds-alert__icon {
color: var(--navds-alert-color-warning-icon);
background: radial-gradient(
circle,
var(--navds-color-darkgray) 50%,
var(--navds-alert-color-warning-icon-background) 50%,
0,
transparent
);
}
.navds-alert--info {
border-color: var(--navds-color-info-border);
background-color: var(--navds-color-info-background);
border-color: var(--navds-alert-color-info-border);
background-color: var(--navds-alert-color-info-background);
}
.navds-alert--info > span > svg {
color: var(--navds-color-lightblue-70);
.navds-alert--info > .navds-alert__icon {
color: var(--navds-alert-color-info-icon);
background: radial-gradient(
circle,
var(--navds-alert-color-info-icon-background) 50%,
0,
transparent
);
}
.navds-alert--success {
border-color: var(--navds-color-success-border);
background-color: var(--navds-color-success-background);
border-color: var(--navds-alert-color-success-border);
background-color: var(--navds-alert-color-success-background);
}
.navds-alert--success > span > svg {
color: var(--navds-color-green-70);
.navds-alert--success > .navds-alert__icon {
color: var(--navds-alert-color-success-icon);
background: radial-gradient(
circle,
var(--navds-alert-color-success-icon-background) 50%,
0,
transparent
);
}
.navds-alert--inline {
background-color: transparent;
border-color: transparent;
padding: 0;
}
+5 -2
View File
@@ -9,7 +9,8 @@
* https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
*/
.sr-only {
.sr-only,
.navds-sr-only {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
@@ -32,7 +33,9 @@
*/
.sr-only.focusable:active,
.sr-only.focusable:focus {
.sr-only.focusable:focus,
.navds-sr-only.focusable:active,
.navds-sr-only.focusable:focus {
clip: auto;
height: auto;
margin: 0;
+153 -87
View File
@@ -1,47 +1,72 @@
:root {
/* Primary */
--navds-button-color-primary-text: var(--navds-color-white);
--navds-button-color-primary-border-focus: var(--navds-color-white);
--navds-button-color-primary-background: var(--navds-color-action-default);
--navds-button-color-primary-background-hover: var(
--navds-color-action-hover
);
--navds-button-color-primary-background-active: var(
--navds-color-action-active
);
/* Secondary */
--navds-button-color-secondary-text: var(--navds-color-action-default);
--navds-button-color-secondary-text-hover: var(--navds-color-text-inverse);
--navds-button-color-secondary-text-active: var(--navds-color-text-inverse);
--navds-button-color-secondary-border: var(--navds-color-action-default);
--navds-button-color-secondary-border-focus-active-hover: var(
--navds-color-white
);
--navds-button-color-secondary-background: var(--navds-color-background);
--navds-button-color-secondary-background-hover: var(
--navds-color-action-hover
);
--navds-button-color-secondary-background-active: var(
--navds-color-action-active
);
/* Tertiary */
--navds-button-color-tertiary-text: var(--navds-color-action-default);
--navds-button-color-tertiary-text-active: var(--navds-color-text-inverse);
--navds-button-color-tertiary-border-hover: var(--navds-color-action-default);
--navds-button-color-tertiary-border-focus: var(--navds-color-action-default);
--navds-button-color-tertiary-border-active: var(--navds-color-white);
--navds-button-color-tertiary-background-active: var(
--navds-color-action-active
);
/* Danger */
--navds-button-color-danger-text: var(--navds-color-white);
--navds-button-color-danger-background: var(--navds-color-danger-default);
--navds-button-color-danger-background-hover: var(--navds-color-danger-hover);
--navds-button-color-danger-background-active: var(
--navds-color-danger-active
);
--navds-button-color-danger-border-focus: var(--navds-color-white);
/* Disabled */
--navds-button-color-text-disabled: var(--navds-color-text-inverse);
--navds-button-color-background-disabled: var(--navds-color-disabled);
}
.navds-button {
display: inline-flex;
cursor: pointer;
background-color: var(--navds-color-background);
color: var(--navds-color-action-default);
margin: 0;
text-align: center;
text-decoration: none;
border-color: var(--navds-color-action-default);
border: none;
background: none;
border-radius: 2px;
border-style: solid;
border-width: 2px;
min-height: 48px;
align-items: center;
/* Padding calculated based on 18px font for 44px tall button */
padding: calc(var(--navds-spacing-3) - 2px) var(--navds-spacing-3);
min-width: 48px;
padding: var(--navds-spacing-3);
}
.navds-button > svg {
font-size: 1.5rem;
width: 1.5rem;
height: 1.5rem;
}
.navds-button--s > svg {
font-size: 1.25rem;
width: 1.25rem;
height: 1.25rem;
}
.navds-button > svg + *:not(.sr-only),
.navds-button > *:not(.sr-only) + svg {
margin-left: 0.5rem;
}
/* .navds-button:last-child {
margin-left: 0.5rem;
} */
.navds-button--s {
/* Padding calculated based on 16px font for 32px tall button */
padding: 0.25rem calc(var(--navds-spacing-4) - 2px);
min-height: 32px;
.navds-button--small {
padding-top: 0.375rem;
padding-bottom: 0.375rem;
min-width: 32px;
}
.navds-button:focus {
@@ -49,94 +74,135 @@
box-shadow: var(--navds-shadow-focus);
}
/**************************
* .navds-button--primary *
**************************/
.navds-button--primary:hover,
.navds-button--primary:active {
color: var(--navds-color-text-inverse);
background-color: var(--navds-color-action-hover);
border-color: transparent;
.navds-button__inner {
margin: auto;
display: flex;
align-items: center;
gap: var(--navds-spacing-2);
}
.navds-button--primary:active {
background-color: var(--navds-color-action-active);
.navds-button svg {
font-size: 1.5rem;
}
/****************************
.navds-button--small svg {
font-size: 1.25rem;
}
/*************************
* .navds-button--primary *
*************************/
.navds-button--primary {
background-color: var(--navds-button-color-primary-background);
color: var(--navds-button-color-primary-text);
}
.navds-button--primary:hover {
background-color: var(--navds-button-color-primary-background-hover);
}
.navds-button--primary:active {
background-color: var(--navds-button-color-primary-background-active);
}
.navds-button--primary:focus {
box-shadow: inset 0 0 0 1px var(--navds-button-color-primary-border-focus),
var(--navds-shadow-focus);
}
/**************************
* .navds-button--secondary *
****************************/
**************************/
.navds-button--secondary {
border-color: transparent;
background-color: transparent;
color: var(--navds-button-color-secondary-text);
background-color: var(--navds-button-color-secondary-background);
box-shadow: inset 0 0 0 2px var(--navds-button-color-secondary-border);
}
.navds-button--secondary:hover {
color: var(--navds-button-color-secondary-text-hover);
background-color: var(--navds-button-color-secondary-background-hover);
box-shadow: none;
}
.navds-button--secondary:hover,
.navds-button--secondary:focus {
border-color: var(--navds-color-action-default);
box-shadow: inset 0 0 0 2px var(--navds-button-color-secondary-border),
var(--navds-shadow-focus);
}
.navds-button--secondary:active {
color: var(--navds-color-text-inverse);
border-color: var(--navds-color-action-active);
background-color: var(--navds-color-action-active);
color: var(--navds-button-color-secondary-text-active);
background-color: var(--navds-button-color-secondary-background-active);
box-shadow: none;
}
.navds-button--secondary:focus:hover,
.navds-button--secondary:focus:active {
box-shadow: inset 0 0 0 1px
var(--navds-button-color-secondary-border-focus-active-hover),
var(--navds-shadow-focus);
}
/****************************
* .navds-button--tertiary *
****************************/
.navds-button--tertiary {
color: var(--navds-button-color-tertiary-text);
}
.navds-button--tertiary:hover {
box-shadow: inset 0 0 0 2px var(--navds-button-color-tertiary-border-hover);
}
.navds-button--tertiary:focus {
box-shadow: inset 0 0 0 2px var(--navds-button-color-tertiary-border-focus),
var(--navds-shadow-focus);
}
.navds-button--tertiary:active {
color: var(--navds-button-color-tertiary-text-active);
background-color: var(--navds-button-color-tertiary-background-active);
box-shadow: inset 0 0 0 1px var(--navds-button-color-tertiary-border-active);
}
.navds-button--tertiary:active:focus {
box-shadow: inset 0 0 0 1px var(--navds-button-color-tertiary-border-active),
var(--navds-shadow-focus);
}
/*************************
* .navds-button--action *
* .navds-button--danger *
*************************/
.navds-button--action {
background-color: var(--navds-color-action-default);
border-color: var(--navds-color-action-default);
}
.navds-button--danger {
background-color: var(--navds-color-danger-default);
border-color: var(--navds-color-danger-default);
}
.navds-button--action,
.navds-button--danger {
color: white;
border-width: 1px;
}
.navds-button--action:hover {
background-color: var(--navds-color-action-hover);
border-color: var(--navds-color-action-hover);
background-color: var(--navds-button-color-danger-background);
color: var(--navds-button-color-danger-text);
}
.navds-button--danger:hover {
background-color: var(--navds-color-danger-hover);
border-color: var(--navds-color-danger-hover);
}
.navds-button--action:active {
background-color: var(--navds-color-action-active);
background-color: var(--navds-button-color-danger-background-hover);
}
.navds-button--danger:active {
background-color: var(--navds-color-danger-active);
background-color: var(--navds-button-color-danger-background-active);
}
.navds-button--action:focus,
.navds-button--danger:focus {
border-color: white;
box-shadow: inset 0 0 0 1px var(--navds-button-color-danger-border-focus),
var(--navds-shadow-focus);
}
/**************************
* .navds-button:disabled *
**************************/
.navds-button:disabled:disabled {
background-color: var(--navds-color-disabled);
color: var(--navds-color-text-inverse);
.navds-button:disabled {
color: var(--navds-button-color-text-disabled);
background-color: var(--navds-button-color-background-disabled);
cursor: not-allowed;
border-width: 0;
box-shadow: none;
transform: none;
}
+25 -11
View File
@@ -1,31 +1,45 @@
:root {
--navds-card-micro-color-text: var(--navds-color-text-primary);
--navds-card-micro-color-background: var(--navds-color-orange-20);
--navds-card-micro-color-border: transparent;
--navds-card-micro-color-text-hover: var(--navds-color-blue-50);
--navds-card-micro-color-background-hover: var(--navds-color-white);
--navds-card-micro-color-border-hover: var(--navds-color-blue-50);
--navds-card-micro-color-text-focus: var(--navds-color-blue-50);
--navds-card-micro-color-background-focus: var(--navds-color-white);
--navds-card-micro-color-shadow-focus: var(--navds-color-blue-80);
--navds-card-micro-color-background-active: var(--navds-color-blue-70);
--navds-card-micro-color-text-active: var(--navds-color-white);
}
/*
MicroCard
*/
.navds-card__micro {
border-radius: 1rem;
color: var(--navds-color-text-primary);
color: var(--navds-card-micro-color-text);
display: inline-flex;
padding: var(--navds-spacing-1) var(--navds-spacing-2);
text-decoration: none;
background-color: var(--navds-color-orange-20);
border: 1px solid transparent;
background-color: var(--navds-card-micro-color-background);
border: 1px solid var(--navds-card-micro-color-border);
}
.navds-card__micro:hover {
background-color: var(--navds-color-white);
border-color: var(--navds-color-blue-50);
color: var(--navds-color-blue-50);
background-color: var(--navds-card-micro-color-background-hover);
border-color: var(--navds-card-micro-color-border-hover);
color: var(--navds-card-micro-color-text-hover);
}
.navds-card__micro:focus {
background-color: var(--navds-color-white);
color: var(--navds-color-blue-50);
background-color: var(--navds-card-micro-color-background-focus);
color: var(--navds-card-micro-color-text-focus);
outline: none;
box-shadow: var(--navds-shadow-focus);
box-shadow: 0 0 0 3px var(--navds-card-micro-color-shadow-focus);
}
.navds-card__micro:active {
background-color: var(--navds-color-blue-70);
color: var(--navds-color-white);
background-color: var(--navds-card-micro-color-background-active);
color: var(--navds-card-micro-color-text-active);
}
-8
View File
@@ -1,11 +1,3 @@
.navds-copy-to-clipboard {
display: inline-flex;
align-items: center;
column-gap: 0.5em;
padding: var(--navds-spacing-1);
min-height: 32px;
}
.navds-copy-to-clipboard__popover {
padding: var(--navds-spacing-1);
}
+3 -3
View File
@@ -1,13 +1,13 @@
.navds-checkbox-group--s > .navds-checkboxes {
.navds-checkbox-group--small > .navds-checkboxes {
display: flex;
flex-direction: column;
gap: 4px;
}
.navds-fieldset.navds-checkbox-group--m > .navds-checkboxes {
.navds-fieldset.navds-checkbox-group--medium > .navds-checkboxes {
margin-top: 0;
}
.navds-fieldset.navds-checkbox-group--m > .navds-fieldset__error {
.navds-fieldset.navds-checkbox-group--medium > .navds-fieldset__error {
margin-top: 0;
}
+41 -19
View File
@@ -1,3 +1,25 @@
:root {
--navds-checkbox-color-background: var(--navds-color-white);
--navds-checkbox-color-border: var(--navds-color-gray-60);
--navds-checkbox-color-label-hover: var(--navds-color-blue-50);
--navds-checkbox-color-border-hover: var(--navds-color-blue-50);
--navds-checkbox-color-background-hover: var(--navds-color-blue-10);
--navds-checkbox-color-description: var(--navds-color-gray-80);
--navds-checkbox-color-border-checked: var(--navds-color-blue-50);
--navds-checkbox-color-background-checked: var(--navds-color-blue-50);
--navds-checkbox-color-shadow-error: var(--navds-color-red-50);
--navds-checkbox-color-border-error: var(--navds-color-red-50);
/* Disabled */
--navds-checkbox-color-label-disabled: var(--navds-color-gray-40);
--navds-checkbox-color-border-disabled: var(--navds-color-gray-60);
--navds-checkbox-color-background-disabled: var(--navds-color-gray-10);
--navds-checkbox-color-border-checked-disabled: var(--navds-color-gray-40);
--navds-checkbox-color-background-checked-disabled: var(
--navds-color-gray-40
);
}
.navds-checkbox {
position: relative;
padding: var(--navds-spacing-3) 0;
@@ -24,7 +46,7 @@
.navds-checkbox__description {
padding-left: calc(48px - 12px);
color: var(--navds-color-gray-80);
color: var(--navds-checkbox-color-description);
}
.navds-checkbox--with-description {
@@ -45,37 +67,37 @@
.navds-checkbox__label::before {
content: "";
background-color: white;
border: 1px solid var(--navds-color-border);
background-color: var(--navds-checkbox-color-background);
border: 1px solid var(--navds-checkbox-color-border);
width: 1.5rem;
height: 1.5rem;
border-radius: 4px;
flex-shrink: 0;
}
.navds-checkbox--s {
.navds-checkbox--small {
padding: var(--navds-spacing-1) 0;
}
.navds-checkbox--s > .navds-checkbox__input {
.navds-checkbox--small > .navds-checkbox__input {
width: 24px;
height: 24px;
top: 2px;
left: 0;
}
.navds-checkbox--s > .navds-checkbox__label::before {
.navds-checkbox--small > .navds-checkbox__label::before {
margin-top: -2px;
margin-bottom: -2px;
}
.navds-checkbox__input:hover + .navds-checkbox__label {
color: var(--navds-color-blue-50);
color: var(--navds-checkbox-color-label-hover);
}
.navds-checkbox__input:hover + .navds-checkbox__label::before {
border-color: var(--navds-color-blue-50);
background-color: var(--navds-color-blue-10);
border-color: var(--navds-checkbox-color-border-hover);
background-color: var(--navds-checkbox-color-background-hover);
}
.navds-checkbox__input:focus + .navds-checkbox__label::before {
@@ -87,8 +109,8 @@
background-position: center center;
background-repeat: no-repeat;
background-size: 75%;
border: 2px solid var(--navds-color-blue-50);
background-color: var(--navds-color-blue-50);
border: 2px solid var(--navds-checkbox-color-border-checked);
background-color: var(--navds-checkbox-color-background-checked);
}
.navds-checkbox__input:checked:focus + .navds-checkbox__label::before {
@@ -99,26 +121,26 @@
.navds-checkbox--error
> .navds-checkbox__input:not(:hover):not(:focus):not(:disabled):not(:checked)
+ .navds-checkbox__label::before {
box-shadow: 0 0 0 1px var(--navds-color-red-50);
border-color: var(--navds-color-red-50);
box-shadow: 0 0 0 1px var(--navds-checkbox-color-shadow-error);
border-color: var(--navds-checkbox-color-border-error);
}
.navds-checkbox--s .navds-error-message {
.navds-checkbox--small .navds-error-message {
margin-top: 4px;
}
.navds-checkbox__input:disabled,
.navds-checkbox__input:disabled + .navds-checkbox__label {
color: var(--navds-color-gray-40);
color: var(--navds-checkbox-color-label-disabled);
cursor: not-allowed;
}
.navds-checkbox__input:disabled + .navds-checkbox__label::before {
background-color: var(--navds-color-gray-10);
border-color: var(--navds-color-gray-60);
background-color: var(--navds-checkbox-color-background-disabled);
border-color: var(--navds-checkbox-color-border-disabled);
}
.navds-checkbox__input:disabled:checked + .navds-checkbox__label::before {
background-color: var(--navds-color-gray-40);
border-color: var(--navds-color-gray-40);
background-color: var(--navds-checkbox-color-background-checked-disabled);
border-color: var(--navds-checkbox-color-border-checked-disabled);
}
+46 -16
View File
@@ -1,10 +1,40 @@
:root {
--navds-confirmation-panel-color-background: var(
--navds-color-warning-background
);
--navds-confirmation-panel-color-background-checked: var(
--navds-color-success-background
);
--navds-confirmation-panel-color-border-checked: var(
--navds-color-success-background
);
--navds-confirmation-panel-color-background-error: var(
--navds-color-error-background
);
--navds-confirmation-panel-color-checkbox-background-checked-hover: var(
--navds-color-green-70
);
--navds-confirmation-panel-color-checkbox-border-checked-hover: var(
--navds-color-green-70
);
--navds-confirmation-panel-color-checkbox-background-checked: var(
--navds-color-green-50
);
--navds-confirmation-panel-color-checkbox-border-checked: var(
--navds-color-green-50
);
--navds-confirmation-panel-color-checkbox-label-checked: var(
--navds-color-darkgray
);
}
.navds-confirmation-panel {
display: flex;
flex-direction: column;
gap: var(--navds-spacing-4);
padding: var(--navds-spacing-4);
border-radius: 4px;
background-color: #ffeccc;
background-color: var(--navds-confirmation-panel-color-background);
transition: background-color linear 100ms;
}
@@ -12,27 +42,21 @@
max-width: 80ch;
}
.navds-confirmation-panel--s {
.navds-confirmation-panel--small {
padding: var(--navds-spacing-3);
gap: var(--navds-spacing-2);
}
.navds-confirmation-panel--checked {
background-color: #ccf1d6;
border-color: #ccf1d6;
background-color: var(--navds-confirmation-panel-color-background-checked);
border-color: var(--navds-confirmation-panel-color-border-checked);
}
.navds-confirmation-panel--error {
background-color: #f3e3e3;
background-color: var(--navds-confirmation-panel-color-background-error);
border: 1px solid transparent;
}
.navds-confirmation-panel--checked
> .navds-confirmation-panel__content
.navds-link:not(:focus) {
color: var(--navds-color-darkgray);
}
.navds-confirmation-panel
.navds-checkbox__input:hover
+ .navds-checkbox__label {
@@ -42,23 +66,29 @@
.navds-confirmation-panel--checked
.navds-checkbox__input:hover
+ .navds-checkbox__label {
color: var(--navds-color-darkgray);
color: var(--navds-confirmation-panel-color-checkbox-label-checked);
}
.navds-confirmation-panel--checked
.navds-checkbox__input
+ .navds-checkbox__label::before {
transition: none;
background-color: var(--navds-color-green-50);
border-color: var(--navds-color-green-50);
background-color: var(
--navds-confirmation-panel-color-checkbox-background-checked
);
border-color: var(--navds-confirmation-panel-color-checkbox-border-checked);
background-image: var(--navds-checkmark-image-white);
}
.navds-confirmation-panel--checked
.navds-checkbox__input:hover
+ .navds-checkbox__label::before {
background-color: var(--navds-color-green-70);
border-color: var(--navds-color-green-70);
background-color: var(
--navds-confirmation-panel-color-checkbox-background-checked-hover
);
border-color: var(
--navds-confirmation-panel-color-checkbox-border-checked-hover
);
}
.navds-confirmation-panel--checked
+5 -1
View File
@@ -1,4 +1,8 @@
:root {
--navds-error-message-color-text: var(--navds-color-text-error);
}
.navds-error-message {
display: block;
color: var(--navds-color-red-50);
color: var(--navds-error-message-color-text);
}
+11 -6
View File
@@ -1,10 +1,15 @@
.navds-error-summary {
background-color: #fff;
padding: var(--navds-spacing-4);
border: 4px solid #ba3a26;
:root {
--navds-error-summary-color-background: var(--navds-color-white);
--navds-error-summary-color-border: var(--navds-color-error-border);
}
.navds-error-summary--s {
.navds-error-summary {
background-color: var(--navds-error-summary-color-background);
padding: var(--navds-spacing-4);
border: 4px solid var(--navds-error-summary-color-border);
}
.navds-error-summary--small {
padding: var(--navds-spacing-2);
}
@@ -20,6 +25,6 @@
gap: 0.25rem;
}
.navds-error-summary--s > .navds-error-summary__list {
.navds-error-summary--small > .navds-error-summary__list {
margin: 0.5rem 0;
}
+1 -1
View File
@@ -9,7 +9,7 @@
margin-top: 8px;
}
.navds-fieldset--s > :not(:first-child):not(:empty) {
.navds-fieldset--small > :not(:first-child):not(:empty) {
margin-top: 4px;
}
+2 -2
View File
@@ -3,8 +3,8 @@
margin-top: 8px;
}
.navds-form-field--s > :not(:first-child):not(:empty),
.navds-form-field--s > input:not(:first-child) {
.navds-form-field--small > :not(:first-child):not(:empty),
.navds-form-field--small > input:not(:first-child) {
margin-top: 4px;
}
+1
View File
@@ -13,3 +13,4 @@
@import "select.css";
@import "text-field.css";
@import "textarea.css";
@import "search-field.css";
+3 -3
View File
@@ -1,13 +1,13 @@
.navds-radio-group--s > .navds-radio-buttons {
.navds-radio-group--small > .navds-radio-buttons {
display: flex;
flex-direction: column;
gap: 4px;
}
.navds-fieldset.navds-radio-group--m > .navds-radio-buttons {
.navds-fieldset.navds-radio-group--medium > .navds-radio-buttons {
margin-top: 0;
}
.navds-fieldset.navds-radio-group--m > .navds-fieldset__error {
.navds-fieldset.navds-radio-group--medium > .navds-fieldset__error {
margin-top: 0;
}
+49 -22
View File
@@ -1,3 +1,27 @@
:root {
--navds-radio-color-description: var(--navds-color-gray-80);
--navds-radio-color-background: var(--navds-color-white);
--navds-radio-color-border: var(--navds-color-gray-60);
--navds-radio-color-label-hover: var(--navds-color-blue-50);
--navds-radio-color-border-hover: var(--navds-color-blue-50);
--navds-radio-color-background-hover: var(--navds-color-blue-10);
--navds-radio-color-border-checked: var(--navds-color-blue-50);
--navds-radio-color-shadow-checked: var(--navds-color-blue-50);
--navds-radio-color-shadow-checked-focus: var(--navds-color-blue-80);
--navds-radio-color-shadow-background-checked-focus: var(--navds-color-white);
--navds-radio-color-shadow-dot-checked-focus: var(--navds-color-blue-50);
--navds-radio-color-shadow-error: var(--navds-color-red-50);
--navds-radio-color-border-error: var(--navds-color-red-50);
/* Disabled */
--navds-radio-color-background-disabled: var(--navds-color-gray-10);
--navds-radio-color-border-disabled: var(--navds-color-gray-60);
--navds-radio-color-label-disabled: var(--navds-color-gray-40);
--navds-radio-color-background-disabled-checked: var(--navds-color-gray-40);
--navds-radio-color-border-disabled-checked: var(--navds-color-gray-40);
--navds-radio-color-shadow-disabled-checked: var(--navds-color-gray-40);
}
.navds-radio {
position: relative;
padding: var(--navds-spacing-3) 0;
@@ -33,7 +57,7 @@
.navds-radio__description {
padding-left: calc(48px - 12px);
color: var(--navds-color-gray-80);
color: var(--navds-radio-color-description);
}
.navds-radio--with-description {
@@ -46,8 +70,8 @@
.navds-radio__label::before {
content: "";
background-color: white;
border: 1px solid var(--navds-color-border);
background-color: var(--navds-radio-color-background);
border: 1px solid var(--navds-radio-color-border);
width: 1.5rem;
height: 1.5rem;
border-radius: 4px;
@@ -55,29 +79,29 @@
border-radius: 50%;
}
.navds-radio--s {
.navds-radio--small {
padding: var(--navds-spacing-1) 0;
}
.navds-radio--s > .navds-radio__input {
.navds-radio--small > .navds-radio__input {
width: 24px;
height: 24px;
top: 2px;
left: 0;
}
.navds-radio--s > .navds-radio__label::before {
.navds-radio--small > .navds-radio__label::before {
margin-top: -2px;
margin-bottom: -2px;
}
.navds-radio__input:hover + .navds-radio__label {
color: var(--navds-color-blue-50);
color: var(--navds-radio-color-label-hover);
}
.navds-radio__input:hover + .navds-radio__label::before {
border-color: var(--navds-color-blue-50);
background-color: var(--navds-color-blue-10);
border-color: var(--navds-radio-color-border-hover);
background-color: var(--navds-radio-color-background-hover);
}
.navds-radio__input:focus + .navds-radio__label::before {
@@ -85,40 +109,43 @@
}
.navds-radio__input:checked + .navds-radio__label::before {
border: 2px solid var(--navds-color-blue-50);
box-shadow: 0 0 0 3px #fff inset, 0 0 0 2rem var(--navds-color-blue-50) inset;
border: 2px solid var(--navds-radio-color-border-checked);
box-shadow: 0 0 0 3px #fff inset,
0 0 0 2rem var(--navds-radio-color-shadow-checked) inset;
}
.navds-radio__input:checked:focus + .navds-radio__label::before {
transition: box-shadow 200ms cubic-bezier(0.465, 0.183, 0.153, 0.946);
box-shadow: 0 0 0 3px var(--navds-color-blue-80), 0 0 0 3px #fff inset,
0 0 0 2rem var(--navds-color-blue-50) inset;
box-shadow: 0 0 0 3px var(--navds-radio-color-shadow-checked-focus),
0 0 0 3px var(--navds-radio-color-shadow-background-checked-focus) inset,
0 0 0 2rem var(--navds-radio-color-shadow-dot-checked-focus) inset;
}
.navds-radio--error
> .navds-radio__input:not(:hover):not(:focus):not(:disabled):not(:checked)
+ .navds-radio__label::before {
box-shadow: 0 0 0 1px var(--navds-color-red-50);
border-color: var(--navds-color-red-50);
box-shadow: 0 0 0 1px var(--navds-radio-color-shadow-error);
border-color: var(--navds-radio-color-border-error);
}
.navds-radio--s .navds-error-message {
.navds-radio--small .navds-error-message {
margin-top: 4px;
}
.navds-radio__input:disabled,
.navds-radio__input:disabled + .navds-radio__label {
color: var(--navds-color-gray-40);
color: var(--navds-radio-color-label-disabled);
cursor: not-allowed;
}
.navds-radio__input:disabled + .navds-radio__label::before {
background-color: var(--navds-color-gray-10);
border-color: var(--navds-color-gray-60);
background-color: var(--navds-radio-color-background-disabled);
border-color: var(--navds-radio-color-border-disabled);
}
.navds-radio__input:disabled:checked + .navds-radio__label::before {
background-color: var(--navds-color-gray-40);
border-color: var(--navds-color-gray-40);
box-shadow: 0 0 0 3px #fff inset, 0 0 0 2rem var(--navds-color-gray-40) inset;
background-color: var(--navds-radio-color-background-disabled-checked);
border-color: var(--navds-radio-color-border-disabled-checked);
box-shadow: 0 0 0 3px #fff inset,
0 0 0 2rem var(--navds-radio-color-shadow-disabled-checked) inset;
}
+45
View File
@@ -0,0 +1,45 @@
:root {
--navds-search-field-color-shadow-error: var(--navds-color-red-50);
--navds-search-field-color-border-error: var(--navds-color-red-50);
--navds-search-field-color-clearbutton-border: var(--navds-color-gray-60);
}
.navds-search-field__input-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
.navds-form-field--small .navds-search-field__input {
padding: 0.15rem;
min-height: 32px;
}
.navds-search-field__input-wrapper > *:not(:first-child):not(:last-child) {
border-radius: 0;
}
.navds-search-field__input-wrapper > :first-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.navds-search-field__input-wrapper > :last-child {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.navds-search-field__input-wrapper :focus {
z-index: var(--navds-z-index-focus);
}
.navds-search-field__button,
.navds-search-field__clear-button {
flex-shrink: 0;
}
.navds-search-field--error
.navds-search-field__input:not(:hover):not(:focus):not(:disabled) {
box-shadow: 0 0 0 1px var(--navds-search-field-color-shadow-error) inset;
border-color: var(--navds-search-field-color-border-error);
}
+21 -13
View File
@@ -1,9 +1,20 @@
:root {
--navds-select-color-background: var(--navds-color-white);
--navds-select-color-border: var(--navds-color-gray-60);
--navds-select-color-border-hover: var(--navds-color-blue-50);
--navds-select-color-border-error: var(--navds-color-red-50);
--navds-select-color-shadow-error: var(--navds-color-red-50);
--navds-select-color-border-disabled: var(--navds-color-gray-40);
--navds-select-color-background-disabled: var(--navds-color-gray-10);
--navds-select-color-text-disabled: var(--navds-color-darkgray);
}
.navds-select__input {
appearance: none;
padding: 0.5rem;
background-color: white;
background-color: var(--navds-select-color-background);
border-radius: 4px;
border: 1px solid var(--navds-color-gray-40);
border: 1px solid var(--navds-select-color-border);
width: 100%;
box-sizing: border-box;
min-height: 48px;
@@ -13,7 +24,7 @@
}
.navds-select__input:hover {
border-color: var(--navds-color-blue-50);
border-color: var(--navds-select-color-border-hover);
}
.navds-select__input:focus {
@@ -35,7 +46,7 @@
pointer-events: none;
}
.navds-form-field--s .navds-select__input {
.navds-form-field--small .navds-select__input {
min-height: 32px;
padding: 0.25rem;
}
@@ -44,19 +55,16 @@
Error handling
*/
.navds-select--error > * select:not(:hover):not(:focus):not(:disabled) {
box-shadow: 0 0 0 1px var(--navds-color-red-50);
border-color: var(--navds-color-red-50);
box-shadow: 0 0 0 1px var(--navds-select-color-shadow-error);
border-color: var(--navds-select-color-border-error);
}
/*
Disabled handling
TODO: Oppdatere farger her
*/
/* Disabled handling */
.navds-select__input:disabled,
.navds-select__input[read-only] {
background-color: var(--navds-color-gray-10);
border-color: var(--navds-color-gray-40);
background-color: var(--navds-select-color-background-disabled);
border-color: var(--navds-select-color-border-disabled);
box-shadow: none;
color: var(--navds-color-darkgray);
color: var(--navds-select-color-text-disabled);
cursor: not-allowed;
}
+32 -14
View File
@@ -1,20 +1,31 @@
:root {
--navds-text-field-color-background: var(--navds-color-white);
--navds-text-field-color-border: var(--navds-color-gray-60);
--navds-text-field-color-border-hover: var(--navds-color-blue-50);
--navds-text-field-color-border-error: var(--navds-color-red-50);
--navds-text-field-color-shadow-error: var(--navds-color-red-50);
--navds-text-field-color-border-disabled: var(--navds-color-gray-40);
--navds-text-field-color-background-disabled: var(--navds-color-gray-10);
--navds-text-field-color-text-disabled: var(--navds-color-darkgray);
}
.navds-text-field__input {
appearance: none;
padding: 0.5rem;
background-color: white;
background-color: var(--navds-text-field-color-background);
border-radius: 4px;
border: 1px solid var(--navds-color-border);
border: 1px solid var(--navds-text-field-color-border);
min-height: 48px;
width: 100%;
}
.navds-form-field--s > .navds-text-field__input {
padding: 0.25rem;
.navds-form-field--small > .navds-text-field__input {
padding: 0.15rem;
min-height: 32px;
}
.navds-text-field__input:hover {
border-color: var(--navds-color-blue-50);
border-color: var(--navds-text-field-color-border-hover);
}
.navds-text-field__input:focus {
@@ -27,19 +38,26 @@
*/
.navds-text-field--error
> .navds-text-field__input:not(:hover):not(:focus):not(:disabled) {
box-shadow: 0 0 0 1px var(--navds-color-red-50);
border-color: var(--navds-color-red-50);
box-shadow: 0 0 0 1px var(--navds-text-field-color-shadow-error);
border-color: var(--navds-text-field-color-border-error);
}
/*
TODO: Oppdater denne til riktige farger
Disabled handling
*/
/* Disabled handling */
.navds-text-field__input:disabled,
.navds-text-field__input[readonly] {
background-color: #f1f1f1;
border-color: #6a6a6a;
background-color: var(--navds-text-field-color-background-disabled);
border-color: var(--navds-text-field-color-border-disabled);
box-shadow: none;
color: #262626;
color: var(--navds-text-field-color-text-disabled);
cursor: not-allowed;
}
/**
* Removes default search icon
*/
.navds-text-field__input[type="search"]::-webkit-search-decoration,
.navds-text-field__input[type="search"]::-webkit-search-cancel-button,
.navds-text-field__input[type="search"]::-webkit-search-results-button,
.navds-text-field__input[type="search"]::-webkit-search-results-decoration {
-webkit-appearance: none;
}
+25 -13
View File
@@ -1,3 +1,16 @@
:root {
--navds-textarea-color-background: var(--navds-color-white);
--navds-textarea-color-border: var(--navds-color-gray-60);
--navds-textarea-color-border-hover: var(--navds-color-blue-50);
--navds-textarea-color-border-error: var(--navds-color-red-50);
--navds-textarea-color-shadow-error: var(--navds-color-red-50);
--navds-textarea-color-counter-text: var(--navds-color-gray-40);
--navds-textarea-color-counter-text-error: var(--navds-color-red-50);
--navds-textarea-color-text-disabled: var(--navds-color-darkgray);
--navds-textarea-color-border-disabled: var(--navds-color-gray-40);
--navds-textarea-color-background-disabled: var(--navds-color-gray-10);
}
.navds-textarea__wrapper {
position: relative;
width: 100%;
@@ -6,9 +19,9 @@
.navds-textarea__input {
appearance: none;
padding: var(--navds-spacing-2);
background-color: white;
background-color: var(--navds-textarea-color-background);
border-radius: 4px;
border: 1px solid var(--navds-color-border);
border: 1px solid var(--navds-textarea-color-border);
resize: none;
width: 100%;
transition: height 0.1s ease-out;
@@ -21,7 +34,7 @@
}
.navds-textarea__input:hover {
border-color: var(--navds-color-blue-50);
border-color: var(--navds-textarea-color-border-hover);
}
.navds-textarea__input:focus {
@@ -29,18 +42,18 @@
box-shadow: var(--navds-shadow-focus);
}
.navds-form-field--s .navds-textarea__input {
.navds-form-field--small .navds-textarea__input {
padding: var(--navds-spacing-1);
min-height: 32px;
}
.navds-form-field--s .navds-textarea--counter.navds-textarea__input {
.navds-form-field--small .navds-textarea--counter.navds-textarea__input {
padding-bottom: var(--navds-spacing-7);
}
.navds-textarea__counter {
pointer-events: none;
color: var(--navds-color-gray-40);
color: var(--navds-textarea-color-counter-text);
font-style: italic;
position: absolute;
text-align: right;
@@ -50,7 +63,7 @@
}
.navds-textarea__counter--error {
color: var(--navds-color-red-50);
color: var(--navds-textarea-color-counter-text-error);
}
/**
@@ -58,19 +71,18 @@
*/
.navds-textarea--error
.navds-textarea__input:not(:hover):not(:focus):not(:disabled) {
box-shadow: 0 0 0 1px var(--navds-color-red-50);
border-color: var(--navds-color-red-50);
box-shadow: 0 0 0 1px var(--navds-textarea-color-shadow-error);
border-color: var(--navds-textarea-color-border-error);
}
/*
TODO: Oppdater denne til riktige farger
Disabled handling
*/
.navds-textarea__input:disabled,
.navds-textarea__input[readonly] {
background-color: #f1f1f1;
border-color: #6a6a6a;
background-color: var(--navds-textarea-color-background-disabled);
border-color: var(--navds-textarea-color-border-disabled);
box-shadow: none;
color: #262626;
color: var(--navds-textarea-color-text-disabled);
cursor: not-allowed;
}
+76
View File
@@ -0,0 +1,76 @@
:root {
--navds-guide-panel-color-background: var(--navds-color-background);
--navds-guide-panel-color-border: var(--navds-color-blue-40);
--navds-guide-panel-color-illustration-background: var(--navds-color-blue-20);
}
/**
* GuidePanel component
*/
.navds-guide-panel {
position: relative;
padding-left: 2.5rem;
}
.navds-guide-panel__content {
background-color: var(--navds-guide-panel-color-background);
border-radius: 4px;
border: 2px solid var(--navds-guide-panel-color-border);
min-height: 7.25rem;
padding: 1.5rem;
padding-left: 3.5rem;
}
.navds-guide-panel--poster {
padding-left: 0;
padding-top: 3.125rem;
}
.navds-guide-panel--poster .navds-guide-panel__content {
padding: 2rem;
padding-top: 4.25rem;
}
.navds-guide-panel .navds-guide {
position: absolute;
top: 1rem;
transform: translateX(-50%);
}
.navds-guide-panel--poster .navds-guide {
left: 50%;
top: 0;
}
/**
* Guide component
*/
.navds-guide {
display: flex;
align-items: center;
justify-content: center;
}
/* Guide illustration frame */
.navds-guide__illustration {
background: var(--navds-guide-panel-color-illustration-background);
border-radius: 50%;
overflow: hidden;
}
.navds-guide__illustration svg,
.navds-guide__illustration img {
height: 100%;
width: 100%;
}
/* Illustration sizes */
.navds-guide__illustration--small {
height: 5rem;
width: 5rem;
}
.navds-guide__illustration--medium {
height: 6.25rem;
width: 6.25rem;
}
-63
View File
@@ -1,63 +0,0 @@
.navds-header {
display: flex;
justify-content: center;
background-color: var(--navds-color-background);
padding-top: 1.5rem;
padding-bottom: 1.5rem;
padding-left: calc((100vw - 100%) / 2);
padding-right: calc((100vw - 100%) / 2);
margin-left: calc((100vw - 100%) / -2);
margin-right: calc((100vw - 100%) / -2);
}
.navds-header__wrapper {
width: 100%;
max-width: 56.5rem;
text-align: start;
}
.navds-header__title {
display: flex;
margin: 0 auto;
width: 100%;
position: relative;
flex-direction: column;
}
.navds-header--left > .navds-header__wrapper {
text-align: start;
}
.navds-header--center > .navds-header__wrapper {
text-align: center;
}
.navds-header__illustration {
margin-right: 1.5rem;
pointer-events: none;
}
.navds-header__illustration > svg {
width: 5rem;
height: 5rem;
}
.navds-header--situation {
box-shadow: 0 -4px 0 var(--navds-color-orange-40) inset;
}
.navds-header--product {
box-shadow: 0 -4px 0 var(--navds-color-green-40) inset;
}
.navds-header--guide {
box-shadow: 0 -4px 0 var(--navds-color-deepblue-40) inset;
}
@media (max-width: 649px) {
.navds-header__illustration > svg {
width: 3rem;
height: 3rem;
}
.navds-header__title {
font-size: var(--navds-font-size-title-xl);
}
}
+54
View File
@@ -0,0 +1,54 @@
:root {
--navds-help-text-color-button-background: transparent;
--navds-help-text-color-icon: var(--navds-color-blue-50);
--navds-help-text-color-icon-hover: var(--navds-color-white);
--navds-help-text-color-icon-background-hover: var(--navds-color-blue-50);
--navds-help-text-color-icon-shadow-hover: var(--navds-color-blue-50);
--navds-help-text-color-icon-focus: var(--navds-color-white);
--navds-help-text-color-icon-background-focus: var(--navds-color-blue-50);
--navds-help-text-color-icon-shadow-focus: var(--navds-color-blue-80);
--navds-help-text-color-popover-background: var(--navds-color-lightblue-10);
}
.navds-help-text__button {
margin: 0;
padding: 0;
border: 0;
cursor: pointer;
background-color: var(--navds-help-text-color-button-background);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.navds-help-text__button:focus {
outline: none;
}
.navds-help-text__icon {
border-radius: 50%;
font-size: 1.5rem;
color: var(--navds-help-text-color-icon);
}
.navds-help-text__button:hover > .navds-help-text__icon {
color: var(--navds-help-text-color-icon-hover);
background: var(--navds-help-text-color-icon-background-hover);
box-shadow: 0 0 0 2px var(--navds-help-text-color-icon-shadow-hover);
}
.navds-help-text__button:focus > .navds-help-text__icon {
outline: none;
color: var(--navds-help-text-color-icon-focus);
background: var(--navds-help-text-color-icon-background-focus);
box-shadow: 0 0 0 3px var(--navds-help-text-color-icon-shadow-focus);
}
.navds-help-text__popover > .navds-popover__arrow::before {
background-color: var(--navds-help-text-color-popover-background);
}
.navds-help-text__popover.navds-popover {
background-color: var(--navds-help-text-color-popover-background);
}
+6 -4
View File
@@ -1,19 +1,17 @@
@import "baseline/baseline.css";
@import "typography.css";
@import "grid.css";
@import "layouts.css";
@import "accordion.css";
@import "accordion-anchor-menu.css";
@import "accordion-menu.css";
@import "alert.css";
@import "button.css";
@import "card.css";
@import "content-container.css";
@import "copy-to-clipboard.css";
@import "header.css";
@import "internal-header.css";
@import "guide-panel.css";
@import "form/index.css";
@import "help-text.css";
@import "link.css";
@import "loader.css";
@import "modal.css";
@@ -22,3 +20,7 @@
@import "panel.css";
@import "link-panel.css";
@import "speech-bubble.css";
/* Navno spesific packages */
@import "page-header.css";
@import "card.css";
+12 -6
View File
@@ -1,3 +1,9 @@
:root {
--navds-internal-header-color-background: var(--navds-color-darkgray);
--navds-internal-header-color-border: var(--navds-color-gray-40);
--navds-internal-header-color-text: var(--navds-color-text-inverse);
}
/**************************
* .navds-header *
**************************/
@@ -5,8 +11,8 @@
.navds-interal-header {
display: flex;
align-items: center;
background: var(--navds-color-darkgray);
color: white;
background: var(--navds-internal-header-color-background);
color: var(--navds-internal-header-color-text);
max-width: 100vw;
min-height: 50px;
}
@@ -22,13 +28,13 @@
.navds-interal-header__title {
padding: 0 var(--navds-spacing-6);
border-right: 1px solid var(--navds-color-gray-40);
border-right: 1px solid var(--navds-internal-header-color-border);
display: flex;
align-self: stretch;
align-items: center;
text-decoration: none;
margin: 0;
color: var(--navds-color-text-inverse);
color: var(--navds-internal-header-color-text);
}
.navds-interal-header__title > span > a {
@@ -46,10 +52,10 @@
**************************/
.navds-interal-header__user {
color: var(--navds-color-text-inverse);
color: var(--navds-internal-header-color-text);
padding: 0 var(--navds-spacing-6);
margin-left: auto;
border-left: 1px solid var(--navds-color-gray-40);
border-left: 1px solid var(--navds-internal-header-color-border);
display: flex;
align-self: stretch;
align-items: center;
-357
View File
@@ -1,357 +0,0 @@
/*****************
* .navds-layout *
*****************/
.navds-layout__container {
display: grid;
grid-gap: var(--navds-grid-gutter-small);
grid-template-columns: repeat(12, minmax(0, 1fr));
margin-right: auto;
margin-left: auto;
}
.navds-layout__container--1-columns,
.navds-layout__container--2-columns {
max-width: 60rem;
}
.navds-layout__container--3-columns {
max-width: 79.5rem;
}
.navds-layout__section--white > * {
background: white;
}
.navds-layout__section--padding > * {
padding: var(--navds-layout-padding-small);
}
.navds-layout__section > *:not(:last-child) {
margin-bottom: var(--navds-layout-padding-small);
}
.navds-layout__section--left,
.navds-layout__section--main,
.navds-layout__section--right {
grid-column: span 12;
}
@media (min-width: 448px) {
.navds-layout__container {
grid-gap: var(--navds-grid-gutter-medium-and-larger);
}
.navds-layout__section > *:not(:last-child) {
margin-bottom: var(--navds-grid-gutter-medium-and-larger);
}
.navds-layout__section--padding.navds-layout__section--left > *,
.navds-layout__section--padding.navds-layout__section--main > *,
.navds-layout__section--padding.navds-layout__section--right > * {
padding: var(--navds-layout-padding-medium-and-larger);
}
}
@media (min-width: 648px) {
/* prettier-ignore */
.navds-layout__container--2-columns > .navds-layout__section--left.navds-layout__section--sticky {
/* TEMP Solution until dekratøren has updated */
--navds-sidebar-sticky-offset: var(--decorator-sticky-offset);
top: calc(
var(--navds-grid-gutter-small) + var(--navds-sidebar-sticky-offset)
);
position: sticky;
max-height: calc(
100vh - var(--navds-grid-gutter-small) * 2 -
var(--navds-sidebar-sticky-offset)
);
overflow-y: auto;
}
.navds-layout__container {
grid-gap: var(--navds-grid-gutter-medium-and-larger);
}
.navds-layout__section--padding.navds-layout__section--right > * {
padding: var(--navds-layout-padding-small);
}
/* prettier-ignore */
.navds-layout__container--2-columns > .navds-layout__section--padding.navds-layout__section--left > * {
padding: var(--navds-layout-padding-small);
}
.navds-layout__container--1-columns > .navds-layout__section--main {
grid-column: span 10;
}
.navds-layout__container--2-columns > .navds-layout__section--left,
.navds-layout__container--2-columns > .navds-layout__section--right {
grid-row: 1;
grid-column: span 4;
}
.navds-layout__container--2-columns > .navds-layout__section--main {
grid-row: 1;
grid-column: span 8;
}
.navds-layout__container--3-columns > .navds-layout__section--left {
grid-row: 1;
grid-column: span 8;
}
.navds-layout__container--3-columns > .navds-layout__section--main {
grid-row: 2;
grid-column: span 8;
}
.navds-layout__container--3-columns > .navds-layout__section--right {
grid-column: span 4;
grid-row: 1 / span 2;
}
}
@media (min-width: 960px) {
/* prettier-ignore */
.navds-layout__container--3-columns > .navds-layout__section--left.navds-layout__section--sticky {
/* TEMP Solution until dekratøren has updated */
--navds-sidebar-sticky-offset: var(--decorator-sticky-offset);
top: calc(
var(--navds-grid-gutter-small) + var(--navds-sidebar-sticky-offset)
);
position: sticky;
max-height: calc(
100vh - var(--navds-grid-gutter-small) * 2 -
var(--navds-sidebar-sticky-offset)
);
overflow-y: auto;
}
.navds-layout__section--padding.navds-layout__section--left > * {
padding: var(--navds-layout-padding-small);
}
.navds-layout__container--1-columns > .navds-layout__section--main {
grid-column: span 8;
}
.navds-layout__container--3-columns > .navds-layout__section--left {
grid-row: 1;
grid-column: span 3;
}
.navds-layout__container--3-columns > .navds-layout__section--main {
grid-row: 1;
grid-column: span 6;
}
.navds-layout__container--3-columns > .navds-layout__section--right {
grid-row: 1;
grid-column: span 3;
}
}
/*************************
* .navds-layout__header *
************************/
.navds-layout__header {
background: var(--navds-layout-background-white);
}
.navds-layout__header-content {
grid-column: span 12;
}
.navds-layout__header-title {
margin: var(--navds-spacing-1) var(--navds-spacing-3);
}
@media (min-width: 448px) {
.navds-layout__header-title {
margin: var(--navds-spacing-1) 0;
}
}
/*************************
* .navds-layout__body *
************************/
.navds-layout__body {
background: var(--navds-layout-background-gray);
scroll-margin-block: 2rem;
}
.navds-layout__body--white {
background: var(--navds-layout-background-white);
}
@media (min-width: 648px) {
.navds-layout__body--2-columns.navds-layout__body--padding {
padding-top: 3rem;
}
}
@media (min-width: 960px) {
.navds-layout__body--3-columns.navds-layout__body--padding {
padding-top: 3rem;
}
}
/*************************
* .navds-layout__panel *
************************/
.navds-layout__panel {
width: 100%;
max-width: 100%;
position: relative;
display: inline-block;
padding: var(--navds-layout-padding-small);
background: white;
padding-top: 2.5rem;
}
.navds-layout__panel--icon-margin {
margin-top: 2rem;
}
.navds-layout__panel:not(:last-child) {
margin-bottom: var(--navds-grid-gutter-small);
}
.navds-layout__panel--highlight {
box-shadow: rgb(102, 164, 220) 0 0 0 0.15rem;
}
.navds-layout__panel-content {
margin-top: 1.25rem;
}
.navds-layout__panel-icon {
position: absolute;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
top: -2rem;
left: 0;
}
.navds-layout__panel-icon svg,
.navds-layout__panel-icon img {
background: #c7dbed;
border-radius: 2rem;
padding: 1rem;
height: 4rem;
width: 4rem;
}
.navds-layout__panel-title {
margin: 0.5rem 0;
}
.navds-layout__panel-copy {
display: flex;
align-items: center;
font-weight: 600;
font-size: 14px;
}
.navds-layout__panel-copy + .navds-copy-to-clipboard__popover {
background-color: var(--navds-color-gray-90);
color: var(--navds-color-white);
font-size: 14px;
}
.navds-layout__panel-popover-content {
margin: 0.5rem;
}
.navds-layout__panel-copy-anchor:hover {
text-decoration: underline;
}
.navds-layout__panel-anchor {
position: relative;
top: -2.5rem;
}
.navds-layout__panel-anchor--child {
position: absolute;
}
.navds-layout__panel-anchor--child--icon {
position: absolute;
margin-top: -2rem;
}
@media (min-width: 448px) {
.navds-layout__panel {
padding: var(--navds-layout-padding-medium-and-larger);
}
.navds-layout__panel:not(:last-child) {
margin-bottom: var(--navds-grid-gutter-medium-and-larger);
}
}
@media (min-width: 448px) and (max-width: 959px) {
.navds-layout__section .navds-accordion-anchor-menu__title {
margin-left: 2.5rem;
margin-right: 2.5rem;
}
.navds-layout__section .navds-accordion-menu-item,
.navds-layout__section
.navds-accordion-menu-collapsable
.navds-accordion-menu-collapsable__button {
padding-left: 2.5rem;
padding-right: 2.5rem;
}
.navds-layout__section
.navds-accordion-menu-collapsable
.navds-accordion-menu-item,
.navds-layout__section
.navds-accordion-menu-collapsable
.navds-accordion-menu-collapsable
.navds-accordion-menu-collapsable__button {
padding-left: 3.5rem;
padding-right: 3.5rem;
}
.navds-layout__section
.navds-accordion-menu-collapsable
.navds-accordion-menu-collapsable
.navds-accordion-menu-item,
.navds-layout__section
.navds-accordion-menu-collapsable
.navds-accordion-menu-collapsable
.navds-accordion-menu-collapsable
.navds-accordion-menu-collapsable__button {
padding-left: 4.5rem;
padding-right: 4.5rem;
}
}
@media (min-width: 648px) {
/* prettier-ignore */
.navds-layout__container--2-columns .navds-layout__panel--icon-margin:first-child {
margin-top: 0;
}
}
@media (min-width: 960px) {
/* prettier-ignore */
.navds-layout__container--3-columns .navds-layout__panel--icon-margin:first-child {
margin-top: 0;
}
.navds-layout__panel--icon-margin:not(:first-child) {
margin-top: 2rem;
}
}
+21 -9
View File
@@ -1,19 +1,26 @@
.navds-link-panel {
display: flex;
justify-content: space-between;
align-items: center;
text-decoration: none;
color: var(--navds-color-gray-90);
:root {
--navds-link-panel-color-text: var(--navds-color-gray-90);
--navds-link-panel-color-border-hover: var(--navds-color-blue-50);
--navds-link-panel-color-title-hover: var(--navds-color-text-link);
}
.navds-link-panel:hover .navds-link-panel-title {
.navds-link-panel {
text-decoration: none;
color: var(--navds-link-panel-color-text);
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--navds-spacing-2);
}
.navds-link-panel:hover .navds-link-panel__title {
text-decoration: underline;
color: var(--navds-color-text-link);
color: var(--navds-link-panel-color-title-hover);
}
.navds-link-panel:hover {
box-shadow: var(--navds-shadow-hover);
border-color: var(--navds-color-blue-50);
border-color: var(--navds-link-panel-color-border-hover);
}
.navds-link-panel:focus {
@@ -22,6 +29,7 @@
}
.navds-link-panel__chevron {
flex-shrink: 0;
font-size: 1.5rem;
transition: transform 200ms;
}
@@ -30,3 +38,7 @@
.navds-link-panel:focus-within > .navds-link-panel__chevron {
transform: translateX(4px);
}
.navds-link-panel__description {
margin-top: var(--navds-spacing-2);
}
+30 -10
View File
@@ -1,10 +1,30 @@
:root {
--navds-link-color-text: var(--navds-color-text-link);
--navds-link-color-text-focus: var(--navds-color-text-inverse);
--navds-link-color-text-active: var(--navds-color-text-inverse);
--navds-link-color-background-focus: var(--navds-text-focus);
--navds-link-color-background-active: var(--navds-text-focus);
--navds-link-color-icon: var(--navds-color-text-link);
--navds-link-color-icon-focus: var(--navds-color-text-inverse);
--navds-link-color-on-info-background: var(--navds-color-text-primary);
--navds-link-color-on-error-background: var(--navds-color-text-primary);
}
.navds-link {
color: var(--navds-color-text-link);
color: var(--navds-link-color-text);
text-decoration: underline;
display: inline-grid;
grid-auto-flow: column;
display: inline-flex;
align-items: center;
gap: 0.25rem;
gap: var(--navds-spacing-1);
}
.navds-alert--info .navds-link {
color: var(--navds-link-color-on-info-background);
}
.navds-alert--error .navds-link,
.navds-confirmation-panel--error .navds-link {
color: var(--navds-link-color-on-error-background);
}
.navds-link:hover {
@@ -13,24 +33,24 @@
.navds-link:focus {
outline: none;
color: var(--navds-color-text-inverse);
color: var(--navds-link-color-text-focus);
text-decoration: none;
background-color: var(--navds-text-focus);
background-color: var(--navds-link-color-background-focus);
box-shadow: var(--navds-text-shadow);
}
.navds-link:active {
outline: none;
color: var(--navds-color-text-inverse);
color: var(--navds-link-color-text-active);
text-decoration: none;
background-color: var(--navds-text-focus);
background-color: var(--navds-link-color-background-active);
box-shadow: var(--navds-text-shadow);
}
.navds-link svg {
color: var(--navds-color-text-link);
color: var(--navds-link-color-icon);
}
.navds-link:focus svg {
color: var(--navds-color-text-inverse);
color: var(--navds-link-color-icon-focus);
}
+30 -18
View File
@@ -1,3 +1,15 @@
:root {
--navds-loader-color-foreground: var(--navds-color-gray-40);
--navds-loader-color-background: var(--navds-color-gray-10);
--navds-loader-color-neutral-foreground: var(--navds-color-gray-40);
--navds-loader-color-interaction-foreground: var(--navds-color-blue-50);
--navds-loader-color-inverted-foreground: var(--navds-color-white);
--navds-loader-color-inverted-background: rgba(255, 255, 255, 0.3);
--navds-loader-color-transparent-background: transparent;
--navds-loader-color-on-button-background: rgba(255, 255, 255, 0.3);
--navds-loader-color-on-button-foreground: currentColor;
}
.navds-loader {
width: 1.5rem;
display: inline-block;
@@ -9,54 +21,54 @@
animation: loader-dasharray 1.4s ease-in-out infinite;
stroke-dasharray: 80px, 200px;
stroke-dashoffset: 0;
stroke: var(--navds-color-gray-40);
stroke: var(--navds-loader-color-foreground);
}
.navds-loader__background {
stroke: var(--navds-color-gray-10);
stroke: var(--navds-loader-color-background);
}
.navds-loader--neutral .navds-loader__foreground {
stroke: var(--navds-color-gray-40);
stroke: var(--navds-loader-color-neutral-foreground);
}
.navds-loader--interaction .navds-loader__foreground {
stroke: var(--navds-color-blue-50);
stroke: var(--navds-loader-color-interaction-foreground);
}
.navds-loader--inverted .navds-loader__foreground {
stroke: white;
stroke: var(--navds-loader-color-inverted-foreground);
}
.navds-loader--inverted .navds-loader__background {
stroke: rgba(255, 255, 255, 0.3);
stroke: var(--navds-loader-color-inverted-background);
}
.navds-loader--transparent .navds-loader__background {
stroke: transparent;
stroke: var(--navds-loader-color-transparent-background);
}
.navds-loader--2xl {
.navds-loader--2xlarge {
width: 4rem;
}
.navds-loader--xl {
.navds-loader--xlarge {
width: 2.5rem;
}
.navds-loader--l {
.navds-loader--large {
width: 2rem;
}
.navds-loader--m {
.navds-loader--medium {
width: 1.5rem;
}
.navds-loader--s {
.navds-loader--small {
width: 1.25rem;
}
.navds-loader--xs {
.navds-loader--xsmall {
width: 1rem;
}
@@ -65,20 +77,20 @@
*/
.navds-button .navds-loader .navds-loader__foreground {
stroke: currentColor;
stroke: var(--navds-loader-color-on-button-foreground);
}
.navds-button:hover .navds-loader .navds-loader__background {
stroke: rgba(255, 255, 255, 0.3);
stroke: var(--navds-loader-color-on-button-background);
}
.navds-button:active .navds-loader .navds-loader__background {
stroke: rgba(255, 255, 255, 0.3);
stroke: var(--navds-loader-color-on-button-background);
}
.navds-button--action .navds-loader .navds-loader__background,
.navds-button--primary .navds-loader .navds-loader__background,
.navds-button--danger .navds-loader .navds-loader__background {
stroke: rgba(255, 255, 255, 0.3);
stroke: var(--navds-loader-color-on-button-background);
}
@keyframes loader-rotate {
+17 -9
View File
@@ -1,18 +1,23 @@
:root {
--navds-modal-color-background: var(--navds-color-background);
--navds-modal-color-overlay: var(--navds-color-modal-overlay);
}
.ReactModal__Body--open {
overflow: hidden;
}
.navds-modal {
background-color: var(--navds-color-background);
background-color: var(--navds-modal-color-background);
border-radius: 4px;
display: block;
position: relative;
padding: var(--navds-spacing-4);
border-radius: 4px;
overflow: auto;
max-height: 100%;
z-index: var(--navds-z-index-modal-content);
top: 50%;
transform: translateY(-50%);
}
.navds-modal__content {
padding: var(--navds-spacing-4);
}
.navds-modal:focus,
@@ -23,13 +28,16 @@
.navds-modal__overlay {
position: fixed;
z-index: var(--navds-z-index-modal-overlay);
z-index: var(--navds-z-index-modal);
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: var(--navds-color-modal-overlay);
background-color: var(--navds-modal-color-overlay);
padding: var(--navds-spacing-4);
display: flex;
align-items: center;
justify-content: center;
}
.navds-modal__button--shake {
@@ -44,7 +52,7 @@
}
.navds-modal__button {
position: fixed;
position: absolute;
top: var(--navds-spacing-4);
right: var(--navds-spacing-4);
display: flex;
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "0.6.19",
"version": "0.8.3",
"private": false,
"description": "Css for NAV Designsystem components",
"author": "NAV Designsystem team",
@@ -18,13 +18,13 @@
"main": "./dist/index.css",
"scripts": {
"build": "postcss --use postcss-import -o dist/index.css index.css",
"watch-css": "postcss -w --use postcss-import -o dist/index.css index.css"
"watch": "postcss --watch --use postcss-import -o dist/index.css index.css"
},
"devDependencies": {
"@navikt/ds-tokens": "^0.4.4",
"@navikt/ds-tokens": "^0.5.1",
"normalize.css": "^8.0.1",
"postcss": "^8.2.7",
"postcss": "^8.3.6",
"postcss-cli": "^8.3.1",
"postcss-import": "^14.0.0"
"postcss-import": "^14.0.2"
}
}
+70
View File
@@ -0,0 +1,70 @@
:root {
--navds-page-header-color-background: var(--navds-color-background);
--navds-page-header-color-shadow-situation: var(--navds-color-orange-40);
--navds-page-header-color-shadow-product: var(--navds-color-green-40);
--navds-page-header-color-shadow-guide: var(--navds-color-deepblue-40);
}
.navds-page-header {
display: flex;
justify-content: center;
background-color: var(--navds-page-header-color-background);
padding-top: 1.5rem;
padding-bottom: 1.5rem;
padding-left: calc((100vw - 100%) / 2);
padding-right: calc((100vw - 100%) / 2);
margin-left: calc((100vw - 100%) / -2);
margin-right: calc((100vw - 100%) / -2);
}
.navds-page-header__wrapper {
width: 100%;
max-width: 56.5rem;
text-align: start;
}
.navds-page-header__title {
display: flex;
margin: 0 auto;
width: 100%;
position: relative;
flex-direction: column;
}
.navds-page-header--left > .navds-page-header__wrapper {
text-align: start;
}
.navds-page-header--center > .navds-page-header__wrapper {
text-align: center;
}
.navds-page-header__illustration {
margin-right: 1.5rem;
pointer-events: none;
}
.navds-page-header__illustration > svg {
width: 5rem;
height: 5rem;
}
.navds-page-header--situation {
box-shadow: 0 -4px 0 var(--navds-page-header-color-shadow-situation) inset;
}
.navds-page-header--product {
box-shadow: 0 -4px 0 var(--navds-page-header-color-shadow-product) inset;
}
.navds-page-header--guide {
box-shadow: 0 -4px 0 var(--navds-page-header-color-shadow-guide) inset;
}
@media (max-width: 649px) {
.navds-page-header__illustration > svg {
width: 3rem;
height: 3rem;
}
.navds-page-header__title {
font-size: var(--navds-font-size-title-xl);
}
}
+7 -3
View File
@@ -1,11 +1,15 @@
:root {
--navds-panel-color-background: var(--navds-color-white);
--navds-panel-color-border: var(--navds-color-border);
}
.navds-panel {
background-color: var(--navds-color-white);
display: block;
background-color: var(--navds-panel-color-background);
padding: var(--navds-spacing-4);
border-radius: var(--navds-border-radius);
border: 1px solid transparent;
}
.navds-panel--border {
border-color: var(--navds-color-border);
border-color: var(--navds-panel-color-border);
}
+24 -15
View File
@@ -1,9 +1,20 @@
:root {
--navds-popover-color-background: var(--navds-color-background);
--navds-popover-color-border: var(--navds-color-gray-40);
--navds-popover-color-shadow: var(--navds-color-gray-20);
}
.navds-popover {
z-index: var(--navds-z-index-popover-default);
background-color: var(--navds-color-background);
box-shadow: 0 0.05rem 0.25rem 0.125rem rgba(0, 0, 0, 0.08);
border: var(--navds-border-default);
border-radius: 2px;
z-index: var(--navds-z-index-popover);
background-color: var(--navds-popover-color-background);
box-shadow: 0 2px 4px 0 var(--navds-popover-color-shadow);
border: 1px solid;
border-color: var(--navds-popover-color-border);
border-radius: 4px;
}
.navds-popover__content {
padding: var(--navds-spacing-4);
}
.navds-popover--hidden {
@@ -16,22 +27,20 @@
}
.navds-popover__arrow {
z-index: var(--navds-z-index-popover-arrow);
z-index: -1;
}
.navds-popover__arrow::before {
content: "";
display: block;
content: "";
transform: rotate(45deg);
background-color: var(--navds-popover-color-background);
border: 1px solid;
border-color: var(--navds-popover-color-border);
width: 1rem;
height: 1rem;
transform: rotate(45deg);
background-color: var(--navds-color-background);
border: var(--navds-border-default);
}
.navds-popover__arrow::before .navds-popover--small {
width: 0.67rem;
height: 0.67rem;
top: 0;
left: 0;
}
.navds-popover[data-popper-placement^="top"] > .navds-popover__arrow {
+19 -6
View File
@@ -1,3 +1,13 @@
:root {
--navds-speechbubble-color-background: var(--navds-color-gray-10);
--navds-speechbubble-color-shadow: var(--navds-color-gray-20);
--navds-speechbubble-color-illustration: var(--navds-color-darkgray);
--navds-speechbubble-color-illustration-background: var(
--navds-color-gray-20
);
--navds-speechbubble-color-detail-text: var(--navds-color-gray-60);
}
.navds-speechbubble {
display: flex;
align-items: flex-end;
@@ -23,8 +33,8 @@
.navds-speechbubble__illustration {
align-items: center;
background: var(--navds-color-gray-20);
color: var(--navds-color-darkgray);
background: var(--navds-speechbubble-color-illustration-background);
color: var(--navds-speechbubble-color-illustration);
border-radius: 50%;
display: flex;
flex-shrink: 0;
@@ -42,10 +52,10 @@
.navds-speechbubble__bubble {
padding: 1rem;
box-shadow: 0 2px 4px 0 var(--navds-color-gray-20);
box-shadow: 0 2px 4px 0 var(--navds-speechbubble-color-shadow);
width: fit-content;
max-width: 37.5rem;
background-color: var(--navds-color-gray-10);
background-color: var(--navds-speechbubble-color-background);
border-radius: 12px;
border-bottom-left-radius: 2px;
display: flex;
@@ -61,9 +71,12 @@
.navds-speechbubble--right .navds-speechbubble__bubble {
border-radius: 12px;
border-bottom-right-radius: 2px;
align-items: flex-end;
}
.navds-speechbubble__top-text {
color: var(--navds-color-gray-60);
color: var(--navds-speechbubble-color-detail-text);
}
.navds-speechbubble--right .navds-speechbubble__top-text {
align-self: flex-end;
}
+40 -16
View File
@@ -1,30 +1,54 @@
.navds-tag {
border-radius: 4px;
border: var(--navds-border-default);
background-color: var(--navds-color-tag-info-background);
border-color: var(--navds-color-tag-info-border);
display: inline-block;
:root {
--navds-tag-color-border: var(--navds-color-gray-40);
--navds-tag-color-background: var(--navds-color-gray-10);
--navds-tag-color-info-background: var(--navds-color-tag-info-background);
--navds-tag-color-info-border: var(--navds-color-tag-info-border);
--navds-tag-color-warning-background: var(
--navds-color-tag-warning-background
);
--navds-tag-color-warning-border: var(--navds-color-tag-warning-border);
--navds-tag-color-success-background: var(
--navds-color-tag-success-background
);
--navds-tag-color-success-border: var(--navds-color-tag-success-border);
--navds-tag-color-error-background: var(--navds-color-tag-error-background);
--navds-tag-color-error-border: var(--navds-color-tag-error-border);
}
/* Padding calculated based on 16px font for 24px tall tag */
padding: 0.0625rem var(--navds-spacing-2);
.navds-tag {
border: 1px solid;
border-color: var(--navds-tag-color-border);
border-radius: 4px;
background-color: var(--navds-tag-color-background);
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.125rem var(--navds-spacing-3);
min-height: 32px;
}
.navds-tag--small {
min-height: 24px;
padding-right: var(--navds-spacing-1);
padding-left: var(--navds-spacing-1);
}
.navds-tag--error {
background-color: var(--navds-color-tag-error-background);
border-color: var(--navds-color-tag-error-border);
background-color: var(--navds-tag-color-error-background);
border-color: var(--navds-tag-color-error-border);
}
.navds-tag--success {
background-color: var(--navds-color-tag-success-background);
border-color: var(--navds-color-tag-success-border);
background-color: var(--navds-tag-color-success-background);
border-color: var(--navds-tag-color-success-border);
}
.navds-tag--warning {
background-color: var(--navds-color-tag-warning-background);
border-color: var(--navds-color-tag-warning-border);
background-color: var(--navds-tag-color-warning-background);
border-color: var(--navds-tag-color-warning-border);
}
.navds-tag--info {
background-color: var(--navds-color-tag-info-background);
border-color: var(--navds-color-tag-info-border);
background-color: var(--navds-tag-color-info-background);
border-color: var(--navds-tag-color-info-border);
}
+66 -47
View File
@@ -1,64 +1,75 @@
/* Title */
.navds-title {
/* Heading */
.navds-heading {
font-weight: var(--navds-font-weight-bold);
margin: 0;
}
.navds-title--2xl {
font-size: var(--navds-font-size-title-2xl);
.navds-heading--2xlarge {
font-size: var(--navds-font-size-heading-2xl);
letter-spacing: -0.01em;
line-height: var(--navds-font-line-height-s);
line-height: var(--navds-font-line-height-heading-2xl);
}
.navds-title--2xl.navds-typo--spacing {
.navds-heading--2xlarge.navds-typo--spacing {
margin-bottom: var(--navds-spacing-5);
}
.navds-title--xl {
font-size: var(--navds-font-size-title-xl);
.navds-heading--xlarge {
font-size: var(--navds-font-size-heading-xl);
letter-spacing: -0.008em;
line-height: var(--navds-font-line-height-s);
line-height: var(--navds-font-line-height-heading-xl);
}
.navds-title--xl.navds-typo--spacing {
.navds-heading--xlarge.navds-typo--spacing {
margin-bottom: var(--navds-spacing-4);
}
.navds-title--l {
font-size: var(--navds-font-size-title-l);
.navds-heading--large {
font-size: var(--navds-font-size-heading-l);
letter-spacing: -0.004em;
line-height: var(--navds-font-line-height-s);
line-height: var(--navds-font-line-height-heading-l);
}
.navds-title--l.navds-typo--spacing {
.navds-heading--large.navds-typo--spacing {
margin-bottom: var(--navds-spacing-3);
}
.navds-title--m {
font-size: var(--navds-font-size-title-m);
.navds-heading--medium {
font-size: var(--navds-font-size-heading-m);
letter-spacing: -0.002em;
line-height: var(--navds-font-line-height-s);
line-height: var(--navds-font-line-height-heading-m);
}
.navds-title--m.navds-typo--spacing {
.navds-heading--medium.navds-typo--spacing {
margin-bottom: var(--navds-spacing-3);
}
.navds-title--s {
font-size: var(--navds-font-size-title-s);
.navds-heading--small {
font-size: var(--navds-font-size-heading-s);
letter-spacing: -0.001em;
line-height: var(--navds-font-line-height-s);
line-height: var(--navds-font-line-height-heading-s);
}
.navds-title--s.navds-typo--spacing {
.navds-heading--small.navds-typo--spacing {
margin-bottom: var(--navds-spacing-3);
}
.navds-heading--xsmall {
font-size: var(--navds-font-size-heading-xs);
letter-spacing: -0.001em;
line-height: var(--navds-font-line-height-heading-xs);
}
.navds-heading--xsmall.navds-typo--spacing {
margin-bottom: var(--navds-spacing-3);
}
/* Ingress */
.navds-ingress {
font-size: var(--navds-font-size-xl);
font-weight: var(--navds-font-weight-regular);
letter-spacing: -0.001em;
line-height: var(--navds-font-line-height-m);
line-height: var(--navds-font-line-height-xl);
margin: 0;
}
@@ -69,15 +80,9 @@
/* Body */
.navds-body-long {
font-size: var(--navds-font-size-l);
font-weight: var(--navds-font-weight-regular);
letter-spacing: 0;
line-height: var(--navds-font-line-height-m);
margin: 0;
}
.navds-body-short {
font-size: var(--navds-font-size-l);
letter-spacing: 0;
line-height: var(--navds-font-line-height-s);
line-height: var(--navds-font-line-height-xl);
margin: 0;
}
@@ -85,30 +90,44 @@
margin-bottom: var(--navds-spacing-7);
}
.navds-body-long--small {
font-size: var(--navds-font-size-m);
letter-spacing: 0.002em;
line-height: var(--navds-font-line-height-l);
}
.navds-body-long--small.navds-typo--spacing {
margin-bottom: var(--navds-spacing-6);
}
.navds-body-short {
font-size: var(--navds-font-size-l);
font-weight: var(--navds-font-weight-regular);
letter-spacing: 0;
line-height: var(--navds-font-line-height-l);
margin: 0;
}
.navds-body-short.navds-typo--spacing {
margin-bottom: var(--navds-spacing-3);
}
.navds-body--s {
.navds-body-short--small {
font-size: var(--navds-font-size-m);
letter-spacing: 0.002em;
line-height: var(--navds-font-line-height-s);
line-height: var(--navds-font-line-height-m);
}
.navds-body-long.navds-body--s.navds-typo--spacing {
margin-bottom: var(--navds-spacing-6);
}
.navds-body-short.navds-body--s.navds-typo--spacing {
.navds-body-short--small.navds-typo--spacing {
margin-bottom: var(--navds-spacing-2);
}
/* Label */
.navds-label {
font-size: var(--navds-font-size-l);
letter-spacing: 0;
line-height: var(--navds-font-line-height-s);
font-weight: var(--navds-font-weight-bold);
letter-spacing: 0;
line-height: var(--navds-font-line-height-l);
margin: 0;
}
@@ -116,22 +135,22 @@
margin-bottom: var(--navds-spacing-3);
}
.navds-label--s {
.navds-label--small {
font-size: var(--navds-font-size-m);
letter-spacing: 0.002em;
line-height: var(--navds-font-line-height-s);
line-height: var(--navds-font-line-height-m);
}
.navds-label--s.navds-typo--spacing {
.navds-label--small.navds-typo--spacing {
margin-bottom: var(--navds-spacing-2);
}
/* Small text */
.navds-detail {
font-size: var(--navds-font-size-s);
letter-spacing: 0.004em;
line-height: var(--navds-font-line-height-s);
font-weight: var(--navds-font-weight-bold);
letter-spacing: 0.004em;
line-height: var(--navds-font-line-height-m);
margin: 0;
}
@@ -139,10 +158,10 @@
margin-bottom: var(--navds-spacing-2);
}
.navds-detail--s {
.navds-detail--small {
font-weight: var(--navds-font-weight-regular);
}
.navds-detail--s.navds-typo--spacing {
.navds-detail--small.navds-typo--spacing {
margin-bottom: var(--navds-spacing-2);
}
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-icons",
"version": "0.5.2",
"version": "0.5.3",
"private": false,
"description": "NAVs egne ikoner i SVG og React format",
"repository": {
@@ -29,22 +29,22 @@
"dl-icons": "FILE_KEY=UmEVH3pZ71uJPsSz9ilP3Y node --experimental-modules --es-module-specifier-resolution=node -r dotenv/config figma-api/index.mjs dotenv_config_path=figma-api/.env",
"create-icons": "svgr --silent --typescript --ref --icon --title-prop --replace-attr-values \"#262626=currentColor\" -d src svg",
"convert-icons": "node figma-api/pngConverter.mjs",
"clean": "rimraf src esm cjs png NAV-ikonpakke-png.zip NAV-ikonpakke-svg.zip",
"clean": "rimraf src png NAV-ikonpakke-png.zip NAV-ikonpakke-svg.zip",
"zip-icons": "node figma-api/zipIcons.mjs",
"build": "npm run clean && npm run create-icons && tsc && tsc -p tsconfig-esm.json && yarn create-package-json-pointers-to-esm && npm run convert-icons && yarn zip-icons"
"build": "yarn clean && yarn create-icons && tsc && tsc -p tsconfig-esm.json && yarn create-package-json-pointers-to-esm && yarn run convert-icons && yarn zip-icons"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
},
"devDependencies": {
"@svgr/cli": "^5.4.0",
"@svgr/cli": "^5.5.0",
"copyfiles": "^2.4.1",
"dotenv": "^8.2.0",
"dotenv": "^10.0.0",
"lodash.kebabcase": "^4.1.1",
"lodash.startcase": "4.4.0",
"react": "^16.8.0 || ^17.0.0",
"rimraf": "3.0.2",
"sharp": "0.27.1",
"sharp": "0.29.1",
"zip-dir": "^2.0.0"
}
}
+12 -9
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "0.7.3",
"version": "0.9.1",
"private": false,
"description": "NAV designsystem react components",
"author": "NAV Designsystem team",
@@ -33,21 +33,24 @@
"watch": "tsc --watch -p tsconfig-esm.json"
},
"dependencies": {
"@material-ui/core": "^4.12.2",
"@navikt/ds-icons": "^0.5.2",
"@popperjs/core": "^2.5.4",
"@material-ui/core": "^4.12.3",
"@navikt/ds-icons": "^0.5.3",
"@popperjs/core": "^2.10.1",
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.3.1",
"react-collapse": "^5.1.0",
"react-merge-refs": "^1.1.0",
"react-modal": "3.12.1",
"react-popper": "^2.2.4",
"short-uuid": "^4.2.0"
"react-modal": "3.14.3",
"react-popper": "^2.2.5",
"uuid": "^8.3.2"
},
"devDependencies": {
"@types/react-router-dom": "^5.1.9",
"@types/styled-components": "^5.1.14",
"copyfiles": "^2.4.1",
"react-router-dom": "^5.2.0",
"rimraf": "3.0.2"
"react-router-dom": "^5.3.0",
"rimraf": "3.0.2",
"styled-components": "^5.3.1"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
@@ -1,35 +0,0 @@
import React, { forwardRef, HTMLAttributes } from "react";
import { AccordionMenu as BaseAccordionMenu } from "../accordion-menu";
import { Title } from "..";
import { ActiveAnchorProvider } from "./ActiveAnchorStore";
import cl from "classnames";
export interface AccordionAnchorMenuProps
extends HTMLAttributes<HTMLDivElement> {
title?: string;
children: React.ReactNode;
}
const AccordionAnchorMenu = forwardRef<
HTMLDivElement,
AccordionAnchorMenuProps
>(({ children, title, className, ...rest }, ref) => (
<div
className={cl("navds-accordion-anchor-menu", className)}
ref={ref}
{...rest}
>
{title && (
<Title level={2} size="m" className="navds-accordion-anchor-menu__title">
{title}
</Title>
)}
<ActiveAnchorProvider>
<BaseAccordionMenu aria-label={title || "Meny"}>
{children}
</BaseAccordionMenu>
</ActiveAnchorProvider>
</div>
));
export default AccordionAnchorMenu;
@@ -1 +0,0 @@
export { AccordionMenuCollapsable as AccordionAnchorMenuCollapsable } from "../accordion-menu";
@@ -1,39 +0,0 @@
import React, { forwardRef, useEffect } from "react";
import { AccordionMenuItem, AccordionMenuItemType } from "../accordion-menu";
import { useStore } from "./ActiveAnchorStore";
const AccordionAnchorMenuItem: AccordionMenuItemType = forwardRef(
(props, ref) => {
const isAnchorActive = useIsAnchorActive(
props.href && props.href.split("#")[1]
);
return (
<AccordionMenuItem
{...props}
ref={ref}
active={props.active || isAnchorActive}
/>
);
}
);
const useIsAnchorActive = (anchor: string | undefined) => {
const { activeAnchor, registerAnchor, unregisterAnchor } = useStore();
useEffect(() => {
if (anchor) {
const target = document.getElementById(anchor);
if (target) {
registerAnchor(anchor);
return () => {
unregisterAnchor(anchor);
};
}
}
}, [anchor, registerAnchor, unregisterAnchor]);
return (anchor && activeAnchor === anchor) || false;
};
export default AccordionAnchorMenuItem;
@@ -1,73 +0,0 @@
import React, {
createContext,
useCallback,
useContext,
useState,
useEffect,
} from "react";
export interface ActiveAnchorStore {
activeAnchor?: string;
registerAnchor: (anchor: string) => void;
unregisterAnchor: (anchor: string) => void;
}
export const ActiveAnchorContext = createContext({} as ActiveAnchorStore);
export const ActiveAnchorProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const [anchors, setAnchors] = useState<string[]>([]);
const [activeAnchor, setActiveAnchor] = useState<string>();
useEffect(() => {
const scrollListener = () => {
const offset = 100;
const lastPassedAnchor = anchors
.map((anchor) => document.getElementById(anchor) as HTMLElement)
.map((element: HTMLElement) => ({
id: element.id,
top: element.getBoundingClientRect().top - offset,
scrolledToBottom:
window.innerHeight + window.pageYOffset >=
document.body.offsetHeight,
}))
.filter((element) => element.scrolledToBottom || element.top <= 0)
.sort((a, b) => (a.top < b.top ? -1 : 1))
.map((anchor) => anchor.id)
.pop();
// Set active anchor and related url hash
if (lastPassedAnchor && activeAnchor !== lastPassedAnchor) {
const { href, hash } = window.location;
const urlWithoutHash = href.replace(hash, "");
const urlWithAnchor = `${urlWithoutHash}#${lastPassedAnchor}`;
const title = document.title;
window.history.replaceState(window.history.state, title, urlWithAnchor);
setActiveAnchor(lastPassedAnchor);
}
};
window.addEventListener("scroll", scrollListener);
return () => {
window.removeEventListener("scroll", scrollListener);
};
}, [anchors, activeAnchor]);
return (
<ActiveAnchorContext.Provider
value={{
activeAnchor,
registerAnchor: useCallback((anchor) => {
setAnchors((anchors) => [...anchors, anchor]);
}, []),
unregisterAnchor: useCallback((anchor) => {
setAnchors((anchors) => anchors.filter((a) => a !== anchor));
}, []),
}}
>
{children}
</ActiveAnchorContext.Provider>
);
};
export const useStore = () => useContext(ActiveAnchorContext);
@@ -1,3 +0,0 @@
export { default as AccordionAnchorMenu } from "./AccordionAnchorMenu";
export { AccordionAnchorMenuCollapsable } from "./AccordionAnchorMenuCollapsable";
export { default as AccordionAnchorMenuItem } from "./AccordionAnchorMenuItem";
@@ -1,14 +0,0 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import { AccordionAnchorMenu } from "../../index";
import { Success } from "@navikt/ds-react";
<Meta title="ds-react/accordion-anchor-menu/intro" />
# AccordionAnchorMenu
NOTE: Komponenten er ikke oppdatert og er veldig buggy. Ville ungått bruk av denne om mulig og bare brukt
vanlig `AccordionMenu`. Hvorvidt vi kommer til å oppdatere denne og ta den med i 1.0 er usikkert.
`AccordionAnchorMenu` er en meny-komponent som implementerer `AccordionMenu` med context
for lytting på aktiv anchor/heading. Dette vil si at active-state settes automatisk.
når man scroller forbi den relevante linken på siden.
@@ -1,125 +0,0 @@
import * as React from "react";
import {
AccordionAnchorMenu as Menu,
AccordionAnchorMenuCollapsable as Collapsable,
AccordionAnchorMenuItem as Item,
} from "../index";
import {
ProductPageLayout as Layout,
ProductPageSection as Section,
ProductPagePanel as Panel,
} from "../../index";
import { Right } from "../../layouts/stories/components/sections/Right";
import { LightBulb, Telephone } from "@navikt/ds-icons";
import { MainOne } from "../../layouts/stories/components/sections/Main";
import { MainTwo } from "../../layouts/stories/components/sections/Main";
import { MainThree } from "../../layouts/stories/components/sections/Main";
import { Link, HashRouter as Router } from "react-router-dom";
export default {
title: "ds-react/accordion-anchor-menu",
component: { Menu },
parameters: {
layout: "fullscreen",
},
};
export const All = () => (
<Layout title={"Nunc et lorem"}>
<Section left sticky withPadding={false}>
<Menu title={"Minima"}>
<Item href={"#leo-quis"}>Leo quis</Item>
<Collapsable title={"Proin accumsan"}>
<Item href={"#nulla-pariatur"}>Nulla pariatur</Item>
<Item href={"#luctus-justo"}>Luctus justo</Item>
</Collapsable>
<Item href={"#maecenas-in-pretium"}>Maecenas in pretium</Item>
</Menu>
</Section>
<Section whiteBackground={false} withPadding={false}>
<Panel
title={"Leo quis"}
anchor={"leo-quis"}
highlight={true}
icon={<LightBulb />}
>
<MainOne title={false} />
</Panel>
<Panel title={"Proin accumsan"} anchor={"proin-accumsan"}>
<MainTwo title={false} />
</Panel>
<Panel
title={"Maecenas in pretium"}
anchor={"maecenas-in-pretium"}
icon={<Telephone />}
>
<MainThree title={false} />
</Panel>
</Section>
<Section right sticky>
<Right />
</Section>
</Layout>
);
export const ReactRouter = () => (
<Layout title={"Nunc et lorem"}>
<Section left sticky withPadding={false}>
<Menu>
<Item component={Link} to="/link1">
Leo quis
</Item>
<Collapsable title={"Proin accumsan"}>
<Item component={Link} to="/link2">
Nulla pariatur
</Item>
<Item component={Link} to="/link3">
Luctus justo
</Item>
</Collapsable>
<Collapsable title={"Sint cupidatat"}>
<Item component={Link} to="/link4">
Nulla pariatur
</Item>
<Item component={Link} to="/link5">
Luctus justo
</Item>
</Collapsable>
<Item component={Link} to="/link6">
Maecenas in pretium
</Item>
</Menu>
</Section>
<Section whiteBackground={false} withPadding={false}>
<Panel
title={"Leo quis"}
anchor={"leo-quis"}
highlight={true}
icon={<LightBulb />}
>
<MainOne title={false} />
</Panel>
<Panel title={"Proin accumsan"} anchor={"proin-accumsan"}>
<MainTwo title={false} />
</Panel>
<Panel
title={"Maecenas in pretium"}
anchor={"maecenas-in-pretium"}
icon={<Telephone />}
>
<MainThree title={false} />
</Panel>
</Section>
<Section right sticky>
<Right />
</Section>
</Layout>
);
ReactRouter.decorators = [
(Story) => (
<Router>
<Story />
</Router>
),
];
@@ -1,11 +1,23 @@
import React, { forwardRef, HTMLAttributes } from "react";
import React, { forwardRef } from "react";
import cl from "classnames";
import MenuItems from "./MenuItems";
import Collapsable, {
AccordionMenuCollapsableType,
} from "./AccordionMenuCollapsable";
import Item, { AccordionMenuItemType } from "./AccordionMenuItem";
export interface AccordionMenuProps extends HTMLAttributes<HTMLElement> {
export interface AccordionMenuProps extends React.HTMLAttributes<HTMLElement> {
children: React.ReactNode;
}
interface AccordionMenuComponent
extends React.ForwardRefExoticComponent<
AccordionMenuProps & React.RefAttributes<HTMLElement>
> {
Collapsable: AccordionMenuCollapsableType;
Item: AccordionMenuItemType;
}
const AccordionMenu = forwardRef<HTMLElement, AccordionMenuProps>(
({ children, className, ...rest }, ref) => {
return (
@@ -19,6 +31,9 @@ const AccordionMenu = forwardRef<HTMLElement, AccordionMenuProps>(
</nav>
);
}
);
) as AccordionMenuComponent;
AccordionMenu.Collapsable = Collapsable;
AccordionMenu.Item = Item;
export default AccordionMenu;
@@ -10,35 +10,38 @@ export interface AccordionMenuCollapsableProps
children: React.ReactNode;
}
const AccordionMenuCollapsable = forwardRef<
HTMLDivElement,
AccordionMenuCollapsableProps
>(({ children, defaultOpen = false, title, className, ...rest }, ref) => {
const [isOpen, setIsOpen] = useState(defaultOpen);
export type AccordionMenuCollapsableType = React.ForwardRefExoticComponent<
AccordionMenuCollapsableProps & React.RefAttributes<HTMLDivElement>
>;
return (
<div
ref={ref}
className={cl("navds-accordion-menu-collapsable", className, {
"navds-accordion-menu-collapsable--open": isOpen,
})}
{...rest}
>
<button
onClick={() => setIsOpen(!isOpen)}
className="navds-accordion-menu-collapsable__button"
const Collapsable: AccordionMenuCollapsableType = forwardRef(
({ children, defaultOpen = false, title, className, ...rest }, ref) => {
const [isOpen, setIsOpen] = useState(defaultOpen);
return (
<div
ref={ref}
className={cl("navds-accordion-menu-collapsable", className, {
"navds-accordion-menu-collapsable--open": isOpen,
})}
{...rest}
>
{title}
<Expand
role="img"
focusable="false"
aria-label={isOpen ? "Pil peker opp" : "Pil peker ned"}
className="navds-accordion-menu-collapsable__expand-icon"
/>
</button>
{isOpen && <MenuItems>{children}</MenuItems>}
</div>
);
});
<button
onClick={() => setIsOpen(!isOpen)}
className="navds-accordion-menu-collapsable__button"
>
{title}
<Expand
role="img"
focusable="false"
aria-label={isOpen ? "Pil peker opp" : "Pil peker ned"}
className="navds-accordion-menu-collapsable__expand-icon"
/>
</button>
{isOpen && <MenuItems>{children}</MenuItems>}
</div>
);
}
);
export default AccordionMenuCollapsable;
export default Collapsable;
@@ -1,26 +1,25 @@
import React, { forwardRef } from "react";
import { OverridableComponent } from "../util";
import { OverridableComponent } from "..";
import cl from "classnames";
export type AccordionMenuItemType = OverridableComponent<AccordionMenuItemProps>;
export interface AccordionMenuItemProps {
props: {
children: React.ReactNode;
active?: boolean;
} & React.HTMLAttributes<HTMLAnchorElement>;
defaultComponent: "a";
export interface AccordionMenuItemProps
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
children: React.ReactNode;
/**
* Sets active styling if true
* @default false
*/
active?: boolean;
}
const AccordionMenuItem: AccordionMenuItemType = forwardRef(
export type AccordionMenuItemType = OverridableComponent<
AccordionMenuItemProps,
HTMLAnchorElement
>;
const Item: AccordionMenuItemType = forwardRef(
(
{
children,
component: Component = "a",
active = false,
className,
...rest
},
{ children, as: Component = "a", active = false, className, ...rest },
ref
) => {
return (
@@ -37,4 +36,4 @@ const AccordionMenuItem: AccordionMenuItemType = forwardRef(
}
);
export default AccordionMenuItem;
export default Item;
+3 -6
View File
@@ -1,6 +1,3 @@
export { default as AccordionMenu } from "./AccordionMenu";
export { default as AccordionMenuCollapsable } from "./AccordionMenuCollapsable";
export {
default as AccordionMenuItem,
AccordionMenuItemType,
} from "./AccordionMenuItem";
export { default as AccordionMenu, AccordionMenuProps } from "./AccordionMenu";
export { AccordionMenuCollapsableProps } from "./AccordionMenuCollapsable";
export { AccordionMenuItemProps } from "./AccordionMenuItem";
@@ -1,9 +1,5 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import {
AccordionMenu,
AccordionMenuItem,
AccordionMenuCollapsable,
} from "../../index";
import { AccordionMenu } from "../../index";
<Meta title="ds-react/accordion-menu/intro" />
@@ -11,59 +7,59 @@ import {
```jsx
<AccordionMenu>
<AccordionMenuItem href="#leo">Leo</AccordionMenuItem>
<AccordionMenuCollapsable title="Proin">
<AccordionMenuItem href="#nulla" active>
<AccordionMenu.item href="#leo">Leo</AccordionMenu.item>
<AccordionMenu.Collapsable title="Proin">
<AccordionMenu.item href="#nulla" active>
Nulla
</AccordionMenuItem>
<AccordionMenuItem href="#luctus">Luctus</AccordionMenuItem>
</AccordionMenuCollapsable>
<AccordionMenuCollapsable title="Accumsan">
<AccordionMenuItem href="#justo" aria-current="page">
</AccordionMenu.item>
<AccordionMenu.item href="#luctus">Luctus</AccordionMenu.item>
</AccordionMenu.Collapsable>
<AccordionMenu.Collapsable title="Accumsan">
<AccordionMenu.item href="#justo" aria-current="page">
Justo
</AccordionMenuItem>
<AccordionMenuCollapsable title="Proin">
<AccordionMenuItem href="#nulla">Nulla</AccordionMenuItem>
<AccordionMenuItem href="#luctus">Luctus</AccordionMenuItem>
</AccordionMenuCollapsable>
</AccordionMenuCollapsable>
</AccordionMenu.item>
<AccordionMenu.Collapsable title="Proin">
<AccordionMenu.item href="#nulla">Nulla</AccordionMenu.item>
<AccordionMenu.item href="#luctus">Luctus</AccordionMenu.item>
</AccordionMenu.Collapsable>
</AccordionMenu.Collapsable>
</AccordionMenu>
```
<Canvas>
<AccordionMenu>
<AccordionMenuItem href="#leo">Leo</AccordionMenuItem>
<AccordionMenuCollapsable title="Proin">
<AccordionMenuItem href="#nulla" active>
<AccordionMenu.Item href="#leo">Leo</AccordionMenu.Item>
<AccordionMenu.Collapsable title="Proin">
<AccordionMenu.Item href="#nulla" active>
Nulla
</AccordionMenuItem>
<AccordionMenuItem href="#luctus">Luctus</AccordionMenuItem>
</AccordionMenuCollapsable>
<AccordionMenuCollapsable title="Accumsan">
<AccordionMenuItem href="#justo" aria-current="page">
</AccordionMenu.Item>
<AccordionMenu.Item href="#luctus">Luctus</AccordionMenu.Item>
</AccordionMenu.Collapsable>
<AccordionMenu.Collapsable title="Accumsan">
<AccordionMenu.Item href="#justo" aria-current="page">
Justo
</AccordionMenuItem>
<AccordionMenuCollapsable title="Proin">
<AccordionMenuItem href="#nulla">Nulla</AccordionMenuItem>
<AccordionMenuItem href="#luctus">Luctus</AccordionMenuItem>
</AccordionMenuCollapsable>
</AccordionMenuCollapsable>
</AccordionMenu.Item>
<AccordionMenu.Collapsable title="Proin">
<AccordionMenu.Item href="#nulla">Nulla</AccordionMenu.Item>
<AccordionMenu.Item href="#luctus">Luctus</AccordionMenu.Item>
</AccordionMenu.Collapsable>
</AccordionMenu.Collapsable>
</AccordionMenu>
</Canvas>
Accordion-menu støtter opp til maks to-nivårer av `AccordionMenuCollapsable` akkurat nå.
Accordion-menu støtter opp til maks to-nivårer av `AccordionMenu.Collapsable` akkurat nå.
`AccordionMenuItem` er implementert med `OverridableComponent`, noe som
`AccordionMenu.Item` er implementert med `OverridableComponent`, noe som
gjør at man kan ta i bruk eks react-router slik:
```jsx
<Item
component={NavLink}
<AccordionMenu.item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/1"
>
Lenketekst
</Item>
</AccordionMenu.item>
```
Her er `NavLink` fra `react-router-dom` brukt, og man får da
@@ -1,29 +1,10 @@
import * as React from "react";
import {
AccordionMenu,
AccordionMenuItem as Item,
AccordionMenuCollapsable as Collapsable,
} from "../index";
import { AccordionMenu } from "../index";
import { NavLink, HashRouter as Router } from "react-router-dom";
export default {
title: "ds-react/accordion-menu",
component: { AccordionMenu },
parameters: {
backgrounds: {
default: "light",
values: [
{
name: "light",
value: "#F1F1F1",
},
{
name: "white",
value: "#fff",
},
],
},
},
};
export const All = () => (
@@ -34,113 +15,113 @@ export const All = () => (
}}
>
<AccordionMenu>
<Item href="#leo">Leo</Item>
<Collapsable title="Proin">
<Item href="#nulla" active>
<AccordionMenu.Item href="#leo">Leo</AccordionMenu.Item>
<AccordionMenu.Collapsable title="Proin">
<AccordionMenu.Item href="#nulla" active>
Nulla
</Item>
<Item href="#luctus">Luctus</Item>
</Collapsable>
<Collapsable title="Accumsan">
<Item href="#justo" aria-current="page">
</AccordionMenu.Item>
<AccordionMenu.Item href="#luctus">Luctus</AccordionMenu.Item>
</AccordionMenu.Collapsable>
<AccordionMenu.Collapsable title="Accumsan">
<AccordionMenu.Item href="#justo" aria-current="page">
Justo
</Item>
<Item href="#pariatur" active aria-current="page">
</AccordionMenu.Item>
<AccordionMenu.Item href="#pariatur" active aria-current="page">
Pariatur
</Item>
<Collapsable title="Proin">
<Item href="#nulla" active>
</AccordionMenu.Item>
<AccordionMenu.Collapsable title="Proin">
<AccordionMenu.Item href="#nulla" active>
Nulla
</Item>
<Item href="#luctus">Luctus</Item>
</Collapsable>
</Collapsable>
<Item href="#justo" active>
</AccordionMenu.Item>
<AccordionMenu.Item href="#luctus">Luctus</AccordionMenu.Item>
</AccordionMenu.Collapsable>
</AccordionMenu.Collapsable>
<AccordionMenu.Item href="#justo" active>
Justo
</Item>
<Item href="#pariatur">Pariatur</Item>
</AccordionMenu.Item>
<AccordionMenu.Item href="#pariatur">Pariatur</AccordionMenu.Item>
</AccordionMenu>
</div>
);
export const ReactRouter = () => (
<AccordionMenu>
<Collapsable title="Nivå 1 – 3 rems høy">
<Item
component={NavLink}
<AccordionMenu.Collapsable title="Nivå 1 – 3 rems høy">
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/1"
>
Nivå 2 innrykk 2 rems
</Item>
<Item
component={NavLink}
</AccordionMenu.Item>
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/2"
>
Subtitle 3
</Item>
</Collapsable>
<Collapsable title="Skjema og søknad">
<Collapsable title="Satser">
<Item
component={NavLink}
</AccordionMenu.Item>
</AccordionMenu.Collapsable>
<AccordionMenu.Collapsable title="Skjema og søknad">
<AccordionMenu.Collapsable title="Satser">
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/3"
>
Nivå 3 – 3 rems innrykk Har du rett til dagpenger når du mottar annen
økonomisk støtte fra NAV?
</Item>
</Collapsable>
<Item
component={NavLink}
</AccordionMenu.Item>
</AccordionMenu.Collapsable>
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/4"
>
Subtitle 2
</Item>
<Item
component={NavLink}
</AccordionMenu.Item>
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/5"
>
Subtitle 3
</Item>
</Collapsable>
<Collapsable title="Sakbehandlingstider">
<Collapsable title="Subtitle 4 Lang tittel på andre nivå lorem ipsum">
<Item
component={NavLink}
</AccordionMenu.Item>
</AccordionMenu.Collapsable>
<AccordionMenu.Collapsable title="Sakbehandlingstider">
<AccordionMenu.Collapsable title="Subtitle 4 Lang tittel på andre nivå lorem ipsum">
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/6"
>
Subtitle 5
</Item>
</Collapsable>
</Collapsable>
<Item
component={NavLink}
</AccordionMenu.Item>
</AccordionMenu.Collapsable>
</AccordionMenu.Collapsable>
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/7"
>
Internasjonalt
</Item>
<Collapsable title="Meld fra om endringer lang tittel på første nivå">
<Item
component={NavLink}
</AccordionMenu.Item>
<AccordionMenu.Collapsable title="Meld fra om endringer lang tittel på første nivå">
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/8"
>
Subtitle 6
</Item>
</Collapsable>
<Item
component={NavLink}
</AccordionMenu.Item>
</AccordionMenu.Collapsable>
<AccordionMenu.Item
as={NavLink}
activeClassName="navds-accordion-menu-item--active"
to="/9"
>
Nivå 1
</Item>
</AccordionMenu.Item>
</AccordionMenu>
);
+25 -100
View File
@@ -1,108 +1,33 @@
import React, { forwardRef, useEffect, useState } from "react";
import cl from "classnames";
import { UnmountClosed, Collapse } from "react-collapse";
import { Expand, ExpandFilled } from "@navikt/ds-icons";
import { useId } from "..";
import React, { forwardRef } from "react";
import AccordionItem, { AccordionItemType } from "./AccordionItem";
import AccordionContent, { AccordionContentType } from "./AccordionContent";
import AccordionHeader, { AccordionHeaderType } from "./AccordionHeader";
export interface AccordionProps
extends React.HTMLAttributes<HTMLButtonElement> {
/**
* Component content
*/
children: React.ReactNode;
/**
* Content on interactive surface of component
*/
heading: React.ReactNode;
/**
* Opens component if 'true', closes if 'false'
* Using this props removes automatic control of open-state
* @default false
*/
open?: boolean;
/**
* Callback for when user interacts with component
*/
onClick?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
/**
* Removes content-element from dom when closed
* @default false
*/
renderContentWhenClosed?: boolean;
interface AccordionComponent
extends React.ForwardRefExoticComponent<
AccordionProps & React.RefAttributes<HTMLDivElement>
> {
Item: AccordionItemType;
Header: AccordionHeaderType;
Content: AccordionContentType;
}
const Accordion = forwardRef<HTMLButtonElement, AccordionProps>(
(
{
children,
heading,
open = false,
className,
renderContentWhenClosed = false,
onClick,
id,
...rest
},
ref
) => {
const [internalOpen, setInternalOpen] = useState<boolean>(open);
export interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* Content inside accordion
*/
children: React.ReactNode;
}
const buttonId = useId(id);
const contentId = useId();
const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
({ className, ...rest }, ref) => (
<div {...rest} className={cl("navds-accordion", className)} ref={ref} />
)
) as AccordionComponent;
useEffect(() => {
setInternalOpen(open);
}, [open]);
const CollapseComponent = renderContentWhenClosed
? Collapse
: UnmountClosed;
return (
<div
className={cl("navds-accordion", className, {
"navds-accordion--open": internalOpen,
"navds-accordion--closed": !internalOpen,
})}
>
<button
ref={ref}
id={buttonId}
className="navds-accordion__button"
aria-expanded={open}
aria-controls={contentId}
onClick={onClick ? onClick : () => setInternalOpen((open) => !open)}
{...rest}
>
<span className="navds-accordion__heading navds-title navds-title--s">
{heading}
</span>
<Expand
focusable="false"
role="img"
className={cl(
"navds-accordion__chevron",
`navds-accordion__chevron--${internalOpen ? "up" : "down"}`
)}
/>
<ExpandFilled
focusable="false"
role="img"
className={cl(
"navds-accordion__chevron",
"navds-accordion__chevron--filled",
`navds-accordion__chevron--${internalOpen ? "up" : "down"}`
)}
/>
</button>
<div id={contentId} role="region" aria-labelledby={buttonId}>
<CollapseComponent isOpened={internalOpen}>
<div className="navds-accordion__content">{children}</div>
</CollapseComponent>
</div>
</div>
);
}
);
Accordion.Header = AccordionHeader;
Accordion.Content = AccordionContent;
Accordion.Item = AccordionItem;
export default Accordion;
@@ -0,0 +1,59 @@
import cl from "classnames";
import React, { forwardRef, useContext } from "react";
import { Collapse, UnmountClosed } from "react-collapse";
import { useClientLayoutEffect, useId } from "../util";
import { AccordionItemContext } from "./AccordionItem";
export interface AccordionContentProps
extends React.HTMLAttributes<HTMLDivElement> {
/**
* Accordion panel content
*/
children: React.ReactNode;
}
export type AccordionContentType = React.ForwardRefExoticComponent<
AccordionContentProps & React.RefAttributes<HTMLDivElement>
>;
const AccordionContent: AccordionContentType = forwardRef(
({ children, className, id, ...rest }, ref) => {
const context = useContext(AccordionItemContext);
const newId = useId(id);
const setContentId = context && context.setContentId;
useClientLayoutEffect(() => {
setContentId && setContentId(id ? newId : `accordionContent-${newId}`);
}, [setContentId, newId]);
if (context === null) {
console.error(
"<Accordion.Content> has to be used within an <Accordion.Item>"
);
return null;
}
const CollapseComponent = context.renderContentWhenClosed
? Collapse
: UnmountClosed;
return (
<div
ref={ref}
id={context.contentId}
role="region"
aria-labelledby={context.buttonId}
{...rest}
>
<CollapseComponent isOpened={context.open}>
<div className={cl("navds-accordion__content", className)}>
{children}
</div>
</CollapseComponent>
</div>
);
}
);
export default AccordionContent;
@@ -0,0 +1,84 @@
import { Expand, ExpandFilled } from "@navikt/ds-icons";
import cl from "classnames";
import React, { forwardRef, useContext } from "react";
import { AccordionItemContext } from "./AccordionItem";
import { useClientLayoutEffect, useId } from "..";
export interface AccordionHeaderProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
/**
* Button content
*/
children: React.ReactNode;
}
export type AccordionHeaderType = React.ForwardRefExoticComponent<
AccordionHeaderProps & React.RefAttributes<HTMLButtonElement>
>;
const AccordionHeader: AccordionHeaderType = forwardRef(
({ children, className, id, onClick, ...rest }, ref) => {
const context = useContext(AccordionItemContext);
const newId = useId(id);
const setButtonId = context && context.setButtonId;
useClientLayoutEffect(() => {
setButtonId && setButtonId(id ? newId : `accordionContent-${newId}`);
}, [setButtonId, newId]);
if (context === null) {
console.error(
"<Accordion.Header> has to be used within an <Accordion.Item>"
);
return null;
}
const handleClick = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
context.toggleOpen();
onClick && onClick(e);
};
return (
<button
ref={ref}
id={context.buttonId}
className={cl(
"navds-accordion__header",
className,
"navds-heading",
"navds-heading--small"
)}
onClick={handleClick}
aria-controls={context.contentId}
{...rest}
>
{children}
<Expand
focusable="false"
role="img"
aria-label={context.open ? "Lukk panel ikon" : "Åpne panel ikon"}
className={cl("navds-accordion__expand-icon", {
"navds-accordion__expand-icon--flip": context.open,
})}
/>
<ExpandFilled
focusable="false"
role="img"
aria-label={context.open ? "Lukk panel ikon" : "Åpne panel ikon"}
className={cl(
"navds-accordion__expand-icon",
"navds-accordion__expand-icon--filled",
{
"navds-accordion__expand-icon--flip": context.open,
}
)}
/>
</button>
);
}
);
export default AccordionHeader;
@@ -0,0 +1,93 @@
import cl from "classnames";
import React, { createContext, forwardRef, useState } from "react";
export interface AccordionItemProps
extends React.HTMLAttributes<HTMLDivElement> {
/**
* Content inside accordion item
*/
children: React.ReactNode;
/**
* Opens component if 'true', closes if 'false'
* Using this props removes automatic control of open-state
*/
open?: boolean;
/**
* Defaults the accordion to opened state
* @default false
*/
defaultOpen?: boolean;
/**
* Removes content-element from dom when closed
* @default false
*/
renderContentWhenClosed?: boolean;
}
export type AccordionItemType = React.ForwardRefExoticComponent<
AccordionItemProps & React.RefAttributes<HTMLDivElement>
>;
export interface AccordionItemContextProps {
open: boolean;
toggleOpen: () => void;
setButtonId: (id: string) => void;
setContentId: (id: string) => void;
buttonId: string;
contentId: string;
renderContentWhenClosed: boolean;
}
export const AccordionItemContext = createContext<AccordionItemContextProps | null>(
null
);
const AccordionItem: AccordionItemType = forwardRef(
(
{
children,
className,
open,
defaultOpen = false,
renderContentWhenClosed = false,
onClick,
id,
...rest
},
ref
) => {
const [internalOpen, setInternalOpen] = useState<boolean>(defaultOpen);
const [buttonId, setButtonId] = useState("");
const [contentId, setContentId] = useState("");
return (
<div
className={cl("navds-accordion__item", className, {
"navds-accordion__item--open": open ?? internalOpen,
})}
ref={ref}
{...rest}
>
<AccordionItemContext.Provider
value={{
open: open ?? internalOpen,
toggleOpen: () => {
if (open === undefined) {
setInternalOpen((iOpen) => !iOpen);
}
},
renderContentWhenClosed,
setButtonId,
buttonId,
setContentId,
contentId,
}}
>
{children}
</AccordionItemContext.Provider>
</div>
);
}
);
export default AccordionItem;
@@ -1,4 +1,4 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import { Meta, Canvas, Props } from "@storybook/addon-docs";
import { Accordion } from "../../index";
<Meta title="ds-react/accordion/intro" />
@@ -6,28 +6,67 @@ import { Accordion } from "../../index";
# Hvordan ta i bruk Accordion
```jsx
<Accordion heading="Qui id id ad cupidatat ullamco.">
Et anim nostrud reprehenderit duis eu tempor et irure proident. Eu ea occaecat
aliqua commodo sunt. Sit cupidatat ad id occaecat exercitation ipsum laboris
duis velit consequat adipisicing do amet aute. Aliquip culpa minim commodo
laborum eiusmod eu magna elit veniam ullamco ullamco minim.
<Accordion>
<Accordion.Item>
<Accordion.Header>Accordion header text</Accordion.Header>
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam officia
laboris voluptate officia pariatur.Lorem est ex anim velit occaecat nisi
qui nostrud sit.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item>
<Accordion.Header>Aliquip amet irure consectetur occaecat</Accordion.Header>
<Accordion.Content>
Cupidatat aliqua eu ea et anim excepteur. Labore aliquip dolore laborum
consequat. Reprehenderit ad velit quis eiusmod ex sint aliquip do deserunt
amet exercitation velit Lorem.
</Accordion.Content>
</Accordion.Item>
</Accordion>
```
<Canvas>
<Accordion heading="Qui id id ad cupidatat ullamco.">
Et anim nostrud reprehenderit duis eu tempor et irure proident. Eu ea
occaecat aliqua commodo sunt. Sit cupidatat ad id occaecat exercitation
ipsum laboris duis velit consequat adipisicing do amet aute. Aliquip culpa
minim commodo laborum eiusmod eu magna elit veniam ullamco ullamco minim.
<Accordion>
<Accordion.Item>
<Accordion.Header>Accordion header text</Accordion.Header>
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam
officia laboris voluptate officia pariatur.Lorem est ex anim velit
occaecat nisi qui nostrud sit.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item>
<Accordion.Header>
Aliquip amet irure consectetur occaecat
</Accordion.Header>
<Accordion.Content>
Cupidatat aliqua eu ea et anim excepteur. Labore aliquip dolore laborum
consequat. Reprehenderit ad velit quis eiusmod ex sint aliquip do
deserunt amet exercitation velit Lorem.
</Accordion.Content>
</Accordion.Item>
</Accordion>
</Canvas>
Accordion-komponeten styrer selv open/closed state, men om man ønsker kan man selv overskrive denne med
`open`-prop + `onClick`-prop.
## Controlled state
Note: Hvis man tar i bruk `onClick`, så tolker komponeten det slik at du ønsker å styre state selv, så
man må da også bruke `open`-prop
Accordion-komponeten styrer selv open-state, men om man ønsker kan man selv overskrive denne med
`open`-prop + `onClick`-prop slik det er gjort på eksemplet.
`renderContentWhenClosed`-prop bestemmer om innholdet (children) skal beholdes i dom-strukturen mens
```jsx
<Accordion>
<Accordion.Item open={open}>
<Accordion.Header onClick={(open) => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam officia
laboris voluptate officia pariatur.Lorem est ex anim velit
</Accordion.Content>
</Accordion.Item>
</Accordion>
```
`renderContentWhenClosed`-prop på `Accordion.Item` bestemmer om innholdet (children) skal beholdes i dom-strukturen mens
Accordion er lukket. Defaulter til `false`.
@@ -1,9 +1,17 @@
import React, { useState } from "react";
import AccordionContent from "../AccordionContent";
import AccordionHeader from "../AccordionHeader";
import AccordionItem from "../AccordionItem";
import { Accordion } from "../index";
export default {
title: "ds-react/accordion",
component: Accordion,
subcomponents: {
AccordionItem,
AccordionContent,
AccordionHeader,
},
};
export const All = () => {
@@ -11,49 +19,74 @@ export const All = () => {
return (
<>
<h1>Accordion</h1>
<Accordion heading="tittel" open={open} onClick={(e) => setOpen(!open)}>
Eu magna fugiat officia sit ullamco reprehenderit reprehenderit officia.
Culpa fugiat irure deserunt irure enim adipisicing qui id. Pariatur
commodo dolore consequat nulla cupidatat commodo nisi sunt. Ad proident
occaecat cillum eu Lorem proident sunt anim officia voluptate. Veniam
ullamco magna elit amet mollit exercitation magna quis ad occaecat in
elit. Labore ad id pariatur consequat consectetur ullamco culpa dolor
dolor. Sunt irure eiusmod velit duis excepteur veniam consectetur eu
occaecat reprehenderit qui anim dolore. Ea voluptate dolore proident
esse aliqua amet magna pariatur incididunt ea excepteur. Aliquip magna
ut ipsum veniam eu laborum id commodo.
</Accordion>
<h1>Open</h1>
<Accordion heading="tittel" open={true} onClick={(e) => null}>
Eu magna fugiat officia sit ullamco reprehenderit reprehenderit officia.
Culpa fugiat irure deserunt irure enim adipisicing qui id. Pariatur
commodo dolore consequat nulla cupidatat commodo nisi sunt. Ad proident
occaecat cillum eu Lorem proident sunt anim officia voluptate. Veniam
ullamco magna elit amet mollit exercitation magna quis ad occaecat in
elit. Labore ad id pariatur consequat consectetur ullamco culpa dolor
dolor. Sunt irure eiusmod velit duis excepteur veniam consectetur eu
occaecat reprehenderit qui anim dolore. Ea voluptate dolore proident
esse aliqua amet magna pariatur incididunt ea excepteur. Aliquip magna
ut ipsum veniam eu laborum id commodo.
</Accordion>
<h1>Long heading</h1>
<Accordion
heading="Consequat incididunt aliquip aliquip fugiat anim cupidatat eu do ipsum pariatur."
open={open}
onClick={(e) => setOpen(!open)}
>
Eu magna fugiat officia sit ullamco reprehenderit reprehenderit officia.
Culpa fugiat irure deserunt irure enim adipisicing qui id. Pariatur
commodo dolore consequat nulla cupidatat commodo nisi sunt. Ad proident
occaecat cillum eu Lorem proident sunt anim officia voluptate. Veniam
ullamco magna elit amet mollit exercitation magna quis ad occaecat in
elit. Labore ad id pariatur consequat consectetur ullamco culpa dolor
dolor. Sunt irure eiusmod velit duis excepteur veniam consectetur eu
occaecat reprehenderit qui anim dolore. Ea voluptate dolore proident
esse aliqua amet magna pariatur incididunt ea excepteur. Aliquip magna
ut ipsum veniam eu laborum id commodo.
</Accordion>
<div>
<h1>Accordion</h1>
<h2>Controlled</h2>
<Accordion>
<Accordion.Item open={open}>
<Accordion.Header onClick={() => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam
officia laboris voluptate officia pariatur.Lorem est ex anim velit
occaecat nisi qui nostrud sit consectetur consectetur officia
nostrud ullamco. Est ex duis proident nostrud elit qui laborum
anim minim eu eiusmod. Veniam in nostrud sunt tempor velit
incididunt sint ex dolor qui velit id eu. Deserunt magna sunt
velit in. Est exercitation id cillum qui do. Minim adipisicing
nostrud commodo proident occaecat aliquip nulla anim proident
reprehenderit. Magna ipsum officia veniam cupidatat duis veniam
dolore reprehenderit mollit velit.Ut consequat commodo minim
occaecat id pariatur. Nisi enim tempor laborum commodo. Tempor sit
quis nostrud eu cupidatat sunt commodo reprehenderit irure
deserunt eiusmod ipsum. Exercitation quis commodo cillum eiusmod
eiusmod. Do laborum qui proident commodo adipisicing eiusmod id.
</Accordion.Content>
</Accordion.Item>
</Accordion>
<h2>Un-controlled</h2>
<Accordion>
<Accordion.Item>
<Accordion.Header>Accordion header text</Accordion.Header>
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam
officia laboris voluptate officia pariatur.Lorem est ex anim velit
occaecat nisi qui nostrud sit consectetur consectetur officia
nostrud ullamco. Est ex duis proident nostrud elit qui laborum
anim minim eu eiusmod. Veniam in nostrud sunt tempor velit
incididunt sint ex dolor qui velit id eu. Deserunt magna sunt
velit in. Est exercitation id cillum qui do. Minim adipisicing
nostrud commodo proident occaecat aliquip nulla anim proident
reprehenderit. Magna ipsum officia veniam cupidatat duis veniam
dolore reprehenderit mollit velit.Ut consequat commodo minim
occaecat id pariatur. Nisi enim tempor laborum commodo. Tempor sit
quis nostrud eu cupidatat sunt commodo reprehenderit irure
deserunt eiusmod ipsum. Exercitation quis commodo cillum eiusmod
eiusmod. Do laborum qui proident commodo adipisicing eiusmod id.
</Accordion.Content>
</Accordion.Item>
<Accordion.Item>
<Accordion.Header>Accordion header text</Accordion.Header>
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam
officia laboris voluptate officia pariatur.Lorem est ex anim velit
occaecat nisi qui nostrud sit consectetur consectetur officia
nostrud ullamco. Est ex duis proident nostrud elit qui laborum
anim minim eu eiusmod. Veniam in nostrud sunt tempor velit
incididunt sint ex dolor qui velit id eu. Deserunt magna sunt
velit in. Est exercitation id cillum qui do. Minim adipisicing
nostrud commodo proident occaecat aliquip nulla anim proident
reprehenderit. Magna ipsum officia veniam cupidatat duis veniam
dolore reprehenderit mollit velit.Ut consequat commodo minim
occaecat id pariatur. Nisi enim tempor laborum commodo. Tempor sit
quis nostrud eu cupidatat sunt commodo reprehenderit irure
deserunt eiusmod ipsum. Exercitation quis commodo cillum eiusmod
eiusmod. Do laborum qui proident commodo adipisicing eiusmod id.
</Accordion.Content>
</Accordion.Item>
</Accordion>
</div>
</>
);
};
+66 -43
View File
@@ -1,4 +1,4 @@
import React, { forwardRef } from "react";
import React, { createContext, forwardRef } from "react";
import cl from "classnames";
import {
ErrorFilled,
@@ -6,80 +6,103 @@ import {
InformationFilled,
SuccessFilled,
} from "@navikt/ds-icons";
import AlertContent, { AlertContentType } from "./AlertContent";
import AlertTitle, { AlertTitleType } from "./AlertTitle";
import { BodyLong } from "..";
export interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* Alert content
*/
children: React.ReactNode;
/**
* Decides what design the alert will have
*/
variant: "error" | "warning" | "info" | "success";
children: React.ReactNode;
/**
* Changes padding and font-sizes
* @default "m"
* @default "medium"
*/
size?: "m" | "s";
size?: "medium" | "small";
/**
* Toggles full-width Alert
* @default false
*/
fullWidth?: boolean;
/**
* Removes background from Alert
*/
inline?: boolean;
}
const Icon = ({ variant }) => {
const Icon = ({ variant, ...props }) => {
switch (variant) {
case "error":
return (
<ErrorFilled
aria-label={`${variant}-ikon`}
focusable="false"
role="img"
/>
);
return <ErrorFilled {...props} />;
case "warning":
return (
<WarningFilled
aria-label={`${variant}-ikon`}
focusable="false"
role="img"
/>
);
return <WarningFilled {...props} />;
case "info":
return (
<InformationFilled
aria-label={`${variant}-ikon`}
focusable="false"
role="img"
/>
);
return <InformationFilled {...props} />;
case "success":
return (
<SuccessFilled
aria-label={`${variant}-ikon`}
focusable="false"
role="img"
/>
);
return <SuccessFilled {...props} />;
default:
return null;
}
};
export interface AlertContextProps {
size: "medium" | "small";
}
export const AlertContext = createContext<AlertContextProps | null>(null);
interface AlertComponent
extends React.ForwardRefExoticComponent<
AlertProps & React.RefAttributes<HTMLDivElement>
> {
Title: AlertTitleType;
Content: AlertContentType;
}
const Alert = forwardRef<HTMLDivElement, AlertProps>(
({ variant, children, className, size = "m", ...rest }, ref) => (
(
{
children,
className,
variant,
size = "medium",
fullWidth = false,
inline = false,
...rest
},
ref
) => (
<div
{...rest}
ref={ref}
className={cl(
className,
"navds-alert",
`navds-alert--${variant}`,
`navds-alert--${size}`,
"navds-body-long",
{ "navds-body--s": size === "s" }
{ "navds-alert--full-width": fullWidth, "navds-alert--inline": inline }
)}
{...rest}
>
<span>
<span className="sr-only">{`${variant}-ikon`}</span>
<Icon variant={variant} />
</span>
<div>{children}</div>
<Icon
aria-label={`${variant}-ikon`}
focusable="false"
role="img"
variant={variant}
alt={`${variant}-ikon`}
className="navds-alert__icon"
/>
<BodyLong as="div" size={size} className="navds-alert__wrapper">
{children}
</BodyLong>
</div>
)
);
) as AlertComponent;
Alert.Title = AlertTitle;
Alert.Content = AlertContent;
export default Alert;
@@ -0,0 +1,41 @@
import React, { forwardRef, useContext } from "react";
import cl from "classnames";
import { BodyLong } from "..";
import { AlertContext } from ".";
export interface AlertContentProps
extends React.HTMLAttributes<HTMLDivElement> {
/**
* Alert content
*/
children: React.ReactNode;
}
export type AlertContentType = React.ForwardRefExoticComponent<
AlertContentProps & React.RefAttributes<HTMLDivElement>
>;
const AlertContent: AlertContentType = forwardRef(
({ children, className, ...rest }, ref) => {
const context = useContext(AlertContext);
if (context === null) {
console.warn("AlertContent has to be wrapped in <Alert />");
return null;
}
return (
<BodyLong
{...rest}
as="div"
className={cl(className, "navds-alert__content")}
ref={ref}
size={context.size ?? "medium"}
>
{children}
</BodyLong>
);
}
);
export default AlertContent;
+41
View File
@@ -0,0 +1,41 @@
import React, { forwardRef, useContext } from "react";
import cl from "classnames";
import { AlertContext, Heading } from "..";
export interface AlertTitleProps extends React.HTMLAttributes<HTMLDivElement> {
/**
* Alert content
*/
children: React.ReactNode;
}
export type AlertTitleType = React.ForwardRefExoticComponent<
AlertTitleProps & React.RefAttributes<HTMLDivElement>
>;
const AlertTitle: AlertTitleType = forwardRef(
({ children, className, ...rest }, ref) => {
const context = useContext(AlertContext);
if (context === null) {
console.warn("AlertTitle has to be wrapped in <Alert />");
return null;
}
const size = context.size === "medium" ? "small" : "xsmall";
return (
<Heading
{...rest}
ref={ref}
className={cl(className, "navds-alert__title")}
as="div"
size={size}
>
{children}
</Heading>
);
}
);
export default AlertTitle;
@@ -1,5 +1,5 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import { Alert } from "../../index";
import { Alert, Heading, BodyLong } from "../../index";
<Meta title="ds-react/alert/intro" />
@@ -26,7 +26,7 @@ import { Alert } from "../../index";
## Varianter
`variants`-prop kan brukes for å endre utseende mellom
`info`, `success`, `warning` og `error`
`info`, `success`, `warning` og `error`.
<Canvas>
<Alert variant="info">Id elit esse enim reprehenderit.</Alert>
@@ -37,19 +37,60 @@ import { Alert } from "../../index";
## Sizing
Alert har to størrelser: Default 64px min-height og small 32px min-height
Alert har to størrelser: Default 64px height og small 32px height default.
<Canvas>
<Alert size="s" variant="info">
<Alert size="small" variant="info">
Id elit esse enim reprehenderit.
</Alert>
<Alert size="s" variant="success">
<Alert size="small" variant="success">
Id elit esse enim reprehenderit.
</Alert>
<Alert size="s" variant="warning">
<Alert size="small" variant="warning">
Id elit esse enim reprehenderit.
</Alert>
<Alert size="s" variant="error">
<Alert size="small" variant="error">
Id elit esse enim reprehenderit.
</Alert>
</Canvas>
## fullWidth
<Canvas>
<div style={{ margin: 32, display: "grid", gap: 16 }}>
<Alert fullWidth variant="info">
Id elit esse enim reprehenderit.
</Alert>
<Alert fullWidth size="small" variant="info">
Id elit esse enim reprehenderit.
</Alert>
</div>
</Canvas>
## Med heading
```jsx
<Alert variant="info">
<Heading spacing size="small" level="2">
Aliquip duis est in commodo pariatur
</Heading>
<BodyLong>
Ullamco ullamco laborum et commodo sint culpa cupidatat culpa qui laboris
ex. Labore ex occaecat proident qui qui fugiat magna. Fugiat sint commodo
consequat eu aute.
</BodyLong>
</Alert>
```
<Canvas>
<Alert variant="info">
<Heading spacing size="small" level="3">
Aliquip duis est in commodo pariatur
</Heading>
<BodyLong>
Ullamco ullamco laborum et commodo sint culpa cupidatat culpa qui laboris
ex. Labore ex occaecat proident qui qui fugiat magna. Fugiat sint commodo
consequat eu aute.
</BodyLong>
</Alert>
</Canvas>
@@ -1,5 +1,6 @@
import React from "react";
import { Alert } from "../index";
import { Alert } from "..";
import { BodyLong, Heading } from "../..";
export default {
title: "ds-react/alert",
@@ -17,21 +18,104 @@ export const All = () => {
return (
<>
<h1>Alert</h1>
{variants.map((variant) => (
{variants.map((variant, i) => (
<Alert key={variant} variant={variant}>
Id elit esse enim reprehenderit.Tempor tempor ex exercitation id aute
eu.Laborum nulla nisi irure voluptate mollit fugiat.Est quis culpa
nostrud et reprehenderit ea sint.Eu veniam labore enim labore qui
eiusmod Lorem amet ad esse.
{new Array(i + 1).fill(
"Id elit esse enim reprehenderit enim nisi veniam nostrud."
)}
</Alert>
))}
<h2>Small</h2>
<div>
{variants.map((variant) => (
<Alert key={variant} variant={variant} size="s">
Exercitation enim nisi veniam nostrud Lorem ipsum ea fugiat. Aute
exercitation voluptate proident sit ex reprehenderit quis ex ut
mollit.
{variants.map((variant, i) => (
<Alert key={variant} variant={variant} size="small">
{new Array(i + 1).fill(
"Id elit esse enim reprehenderit enim nisi veniam nostrud."
)}
</Alert>
))}
</div>
<h2>Alert fullWidth</h2>
{variants.map((variant, i) => (
<Alert fullWidth key={variant} variant={variant}>
{new Array(i + 1).fill(
"Id elit esse enim reprehenderit enim nisi veniam nostrud."
)}
</Alert>
))}
<h2>Small</h2>
<div>
{variants.map((variant, i) => (
<Alert fullWidth key={variant} variant={variant} size="small">
{new Array(i + 1).fill(
"Id elit esse enim reprehenderit enim nisi veniam nostrud."
)}
</Alert>
))}
</div>
<h2>Inline</h2>
<div>
{variants.map((variant, i) => (
<Alert inline key={variant} variant={variant}>
{new Array(i + 1).fill(
"Id elit esse enim reprehenderit enim nisi veniam nostrud."
)}
</Alert>
))}
</div>
<h2>Inline small</h2>
<div>
{variants.map((variant, i) => (
<Alert inline key={variant} variant={variant} size="small">
{new Array(i + 1).fill(
"Id elit esse enim reprehenderit enim nisi veniam nostrud."
)}
</Alert>
))}
</div>
<h2>Med Heading</h2>
<div>
{variants.map((variant, i) => (
<Alert key={variant} variant={variant}>
<Heading spacing size="small" level="3">
Aliquip duis est in commodo pariatur
</Heading>
<BodyLong spacing>
Ullamco ullamco laborum et commodo sint culpa cupidatat culpa qui
laboris ex. Labore ex occaecat proident qui qui fugiat magna.
Fugiat sint commodo consequat eu aute.
</BodyLong>
<Heading level="4" size="xsmall" spacing>
Ullamco eiusmod Lorem eiusmod eu.
</Heading>
<BodyLong>
Ullamco ullamco laborum et commodo sint culpa cupidatat culpa qui
laboris ex. Labore ex occaecat proident qui qui fugiat magna.
Fugiat sint commodo consequat eu aute.
</BodyLong>
</Alert>
))}
</div>
<h2>Med Heading small</h2>
<div>
{variants.map((variant, i) => (
<Alert key={variant} variant={variant} size="small">
<Heading spacing size="small" level="3">
Aliquip duis est in commodo pariatur
</Heading>
<BodyLong spacing>
Ullamco ullamco laborum et commodo sint culpa cupidatat culpa qui
laboris ex. Labore ex occaecat proident qui qui fugiat magna.
Fugiat sint commodo consequat eu aute.
</BodyLong>
<Heading level="4" size="xsmall" spacing>
Ullamco eiusmod Lorem eiusmod eu.
</Heading>
<BodyLong>
Ullamco ullamco laborum et commodo sint culpa cupidatat culpa qui
laboris ex. Labore ex occaecat proident qui qui fugiat magna.
Fugiat sint commodo consequat eu aute.
</BodyLong>
</Alert>
))}
</div>
+26 -12
View File
@@ -1,7 +1,9 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import { BodyShort, OverridableComponent } from "../";
export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
/**
* Component content
*/
@@ -10,12 +12,12 @@ export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
* Changes design and interactions
* @default "primary"
*/
variant?: "primary" | "secondary" | "action" | "danger";
variant?: "primary" | "secondary" | "tertiary" | "danger";
/**
* Changes padding, height and font-size
* @default "m"
* @default "medium"
*/
size?: "m" | "s";
size?: "medium" | "small";
/**
* Prevent the user from interacting with the button: it cannot be pressed or focused.
* @note Avoid using if possible for accessibility purposes
@@ -24,20 +26,32 @@ export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
disabled?: boolean;
}
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ variant = "primary", className, size = "m", ...rest }, ref) => (
<button
const Button: OverridableComponent<ButtonProps, HTMLButtonElement> = forwardRef(
(
{
as: Component = "button",
variant = "primary",
className,
children,
size = "medium",
...rest
},
ref
) => (
<Component
{...rest}
ref={ref}
className={cl(
className,
"navds-button",
`navds-button--${variant}`,
`navds-button--${size}`,
"navds-body-short",
{ "navds-body--s": size === "s" }
`navds-button--${size}`
)}
{...rest}
/>
>
<BodyShort as="span" className="navds-button__inner" size={size}>
{children}
</BodyShort>
</Component>
)
);
@@ -1,29 +1,29 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import { Button, Loader } from "../../index";
import { Success } from "@navikt/ds-react";
import { Success } from "@navikt/ds-icons";
<Meta title="ds-react/button/intro" />
# Hvordan ta i bruk Button
```jsx
<Button>Buttontekst</Button>
<Button>Button</Button>
```
<Canvas>
<Button>Buttontekst</Button>
<Button>Button</Button>
</Canvas>
## Varianter
`variants`-prop kan brukes for å endre utseende mellom
`primary`, `secondary`, `action` og `danger`
`primary`, `secondary`, `tertiary` og `danger`
<Canvas>
<Button variant="primary">Buttontekst</Button>
<Button variant="secondary">Buttontekst</Button>
<Button variant="action">Buttontekst</Button>
<Button variant="danger">Buttontekst</Button>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="tertiary">Tertiary</Button>
<Button variant="danger">Danger</Button>
</Canvas>
## Sizing
@@ -31,35 +31,40 @@ import { Success } from "@navikt/ds-react";
Button har to størrelser: Default 48px min-height og small 32px min-height
<Canvas>
<Button size="s" variant="primary">
Buttontekst
<Button size="small" variant="primary">
Primary
</Button>
<Button size="s" variant="secondary">
Buttontekst
<Button size="small" variant="secondary">
Secondary
</Button>
<Button size="s" variant="action">
Buttontekst
<Button size="small" variant="tertiary">
Tertiary
</Button>
<Button size="s" variant="danger">
Buttontekst
<Button size="small" variant="danger">
Danger
</Button>
</Canvas>
## Med ikon eller `<Loader />`
Hvis man setter ikoner (svg) eller `<Loader />` rett på button vil størrelsen
bli justert automatisk. For å få riktige marginer rundt ikonet må man da wrappe innholdet
i et element
bli justert automatisk og sentrert.
<Canvas>
<Button>
<span>Buttontekst</span> <Loader />
<Loader /> Laster... <Loader />
</Button>
<Button size="s">
<span>Buttontekst</span>
<Button size="small">
<Loader />
Laster...
<Loader />
</Button>
<Button>
<Loader /> <span>Buttontekst</span>
<Success /> Laster... <Success />
</Button>
<Button size="small">
<Success />
Laster...
<Success />
</Button>
</Canvas>
@@ -10,33 +10,40 @@ export default {
const Section = ({ children }) => (
<div
style={{
display: "grid",
display: "flex",
gap: 16,
gridAutoFlow: "column",
justifyContent: "start",
padding: 24,
background: "lightgray",
paddingLeft: 0,
}}
>
{children}
</div>
);
const variants: Array<"primary" | "secondary" | "action" | "danger"> = [
const variants: Array<"primary" | "secondary" | "tertiary" | "danger"> = [
"primary",
"secondary",
"action",
"tertiary",
"danger",
];
const varSwitch = {
primary: "Primary",
secondary: "Secondary",
tertiary: "Tertiary",
danger: "Danger",
};
export const All = () => {
return (
<>
<div style={{ paddingLeft: "1rem" }}>
<h1>Button</h1>
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant}>
{variant}
{varSwitch[variant]}
</Button>
))}
</Section>
@@ -44,27 +51,23 @@ export const All = () => {
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant} disabled>
{variant}
{varSwitch[variant]}
</Button>
))}
</Section>
<h2>As link</h2>
<Section>
{variants.map((variant) => (
<a
key={variant}
className={`navds-button navds-button--${variant} navds-body-short`}
href="the-link"
>
{variant}
</a>
<Button as="a" key={variant} variant={variant} href="the-link">
{varSwitch[variant]}
</Button>
))}
</Section>
<h2>Small</h2>
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant} size="s">
{variant}
<Button key={variant} variant={variant} size="small">
{varSwitch[variant]}
</Button>
))}
</Section>
@@ -72,26 +75,34 @@ export const All = () => {
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant}>
<span>{variant}</span> <Success />
{variant} <Success />
</Button>
))}
</Section>
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant}>
<span className="sr-only">Success ikon</span>
<Success />
</Button>
))}
</Section>
<h2>Small w/icon</h2>
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant} size="s">
<Success /> <span>{variant}</span>
<Button key={variant} variant={variant} size="small">
<Success /> {variant}
</Button>
))}
</Section>
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant} size="s">
<Button key={variant} variant={variant} size="small">
<span className="sr-only">Success ikon</span>
<Success />
</Button>
))}
</Section>
</>
</div>
);
};
+25 -23
View File
@@ -1,30 +1,32 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import { OverridableComponent } from "../util";
import { OverridableComponent } from "..";
export interface MicroCardProps {
props: {
children: string;
} & React.HTMLAttributes<HTMLAnchorElement>;
defaultComponent: "a";
export interface MicroCardProps
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
/**
* Link text
*/
children: React.ReactNode;
}
export const MicroCard: OverridableComponent<MicroCardProps> = forwardRef(
({ className, component: Component = "a", children, ...rest }, ref) => (
<Component
ref={ref}
className={cl(
"navds-card__micro",
"navds-detail",
"navds-detail--s",
className
)}
title={children}
{...rest}
>
{children}
</Component>
)
);
export const MicroCard: OverridableComponent<
MicroCardProps,
HTMLAnchorElement
> = forwardRef(({ className, as: Component = "a", children, ...rest }, ref) => (
<Component
ref={ref}
className={cl(
"navds-card__micro",
"navds-detail",
"navds-detail--small",
className
)}
title={children}
{...rest}
>
{children}
</Component>
));
export default MicroCard;
@@ -1,2 +0,0 @@
export { default as ContentContainer } from "./ContentContainer";
export * from "./ContentContainer";
@@ -1,31 +0,0 @@
import { Meta, Canvas } from "@storybook/addon-docs";
<Meta title="ds-react/content-container/intro" />
# Hvordan ta i bruk ContentContainer
```jsx
<ContentContainer>
<div>innhold...</div>
</ContentContainer>
```
## Bruk
Komponenten fungerer som en wrapper rundt innholdet ditt på siden for å
justere padding og max-width. Dette er all stylingen som blir applied
```css
.navds-content-container {
margin-left: auto;
margin-right: auto;
max-width: var(--navds-content-container-max-width);
padding: var(--navds-content-container-padding-small);
}
@media (min-width: 448px) {
.navds-content-container {
padding: var(--navds-content-container-padding-medium-and-larger);
}
}
```
@@ -1,33 +0,0 @@
import * as React from "react";
import { ContentContainer } from "../index";
import { BodyLong } from "../../index";
import "./style.css";
export default {
title: "ds-react/content-container",
component: ContentContainer,
parameters: {
layout: "fullscreen",
backgrounds: {
default: "NAV gray",
values: [
{
name: "NAV gray",
value: "#f1f1f1",
},
{
name: "white",
value: "#ffffff",
},
],
},
},
};
export const All = () => {
return (
<ContentContainer className={"navds-story-content-container"}>
<BodyLong size="m">-- Innhold --</BodyLong>
</ContentContainer>
);
};
@@ -1,15 +0,0 @@
.navds-story-content-container {
display: flex;
border-radius: 0.25rem;
justify-content: center;
align-items: center;
margin-bottom: 1.5rem;
min-height: 10rem;
background: repeating-linear-gradient(
45deg,
#d6d6d6,
#d6d6d6 10px,
transparent 10px,
transparent 20px
);
}
@@ -1,18 +1,12 @@
import { Copy } from "@navikt/ds-icons";
import copy from "copy-to-clipboard";
import { Placement } from "@popperjs/core";
import cl from "classnames";
import React, {
forwardRef,
HTMLAttributes,
useEffect,
useRef,
useState,
} from "react";
import copy from "copy-to-clipboard";
import React, { forwardRef, useEffect, useRef, useState } from "react";
import mergeRefs from "react-merge-refs";
import { Popover, Button } from "..";
import { BodyShort, Button, ButtonProps, Popover } from "..";
export interface CopyToClipboardProps
extends HTMLAttributes<HTMLButtonElement> {
export interface CopyToClipboardProps extends Omit<ButtonProps, "children"> {
/**
* Button text
*/
@@ -20,20 +14,31 @@ export interface CopyToClipboardProps
/**
* Text to be copied to clipboard
*/
text: string;
copyText: string;
/**
* Description of text, examples: "personnummer", "navn", "epost" etc.
*/
label: string;
popoverText: string;
/**
* Use a differnet icon to display
* @default "Files" from @navikt/ds-icons
* Allows extending popover properties like "placement"
* @default "right"
*/
icon?: React.ReactElement;
popoverPlacement?: Placement;
}
const CopyToClipboard = forwardRef<HTMLButtonElement, CopyToClipboardProps>(
({ children, text, label, icon, className, ...rest }, ref) => {
(
{
children,
copyText,
popoverText,
className,
size = "medium",
popoverPlacement = "right",
...rest
},
ref
) => {
const buttonRef = useRef<HTMLButtonElement>(null);
const mergedRef = mergeRefs([buttonRef, ref]);
const timeoutRef = useRef<number | null>();
@@ -48,10 +53,10 @@ const CopyToClipboard = forwardRef<HTMLButtonElement, CopyToClipboardProps>(
};
}, [openPopover]);
const title = `Kopier ${label} (${text})`;
const title = `Kopier ${copyText}`;
const handleClick = () => {
copy(text);
copy(copyText);
setOpenPopover(true);
};
@@ -63,17 +68,14 @@ const CopyToClipboard = forwardRef<HTMLButtonElement, CopyToClipboardProps>(
title={title}
className={cl("navds-copy-to-clipboard", className)}
onClick={handleClick}
size={size}
{...rest}
>
{icon ? (
<>{icon}</>
) : (
<Copy
focusable="false"
role="img"
aria-label="Fil ikon for kopiering"
/>
)}
<Copy
focusable="false"
role="img"
aria-label="Fil ikon for kopiering"
/>
{children ? children : <span className="sr-only">{title}</span>}
</Button>
<Popover
@@ -81,11 +83,13 @@ const CopyToClipboard = forwardRef<HTMLButtonElement, CopyToClipboardProps>(
anchorEl={buttonRef.current}
open={openPopover}
onClose={() => setOpenPopover(false)}
placement="right"
placement={popoverPlacement}
arrow={false}
className="navds-copy-to-clipboard__popover"
>
{label}
<BodyShort size={size} as="span">
{popoverText}
</BodyShort>
</Popover>
</div>
);
@@ -1,7 +1,6 @@
import * as React from "react";
import { CopyToClipboard } from "../index";
import { Link } from "@navikt/ds-icons";
export default {
title: "@ds-react/copy-to-clipboard",
@@ -15,24 +14,24 @@ export const All = () => {
return (
<div>
<h2>Fritstående knapp</h2>
<CopyToClipboard label={label} text={text} />
<CopyToClipboard popoverText={label} copyText={text} />
<h2>Sammen med tekst</h2>
<CopyToClipboard label={label} text={text}>
<CopyToClipboard popoverText={label} copyText={text}>
Kopier tekst
</CopyToClipboard>
<h2>Tilpasser seg fontstørrelse</h2>
<CopyToClipboard label={label} text={text} style={{ fontSize: "0.8rem" }}>
<h2>Small size</h2>
<CopyToClipboard popoverText={label} copyText={text} size="small">
Kopier tekst
</CopyToClipboard>
<CopyToClipboard popoverText={label} copyText={text} size="small" />
<h2>Custom icon</h2>
<h2>Endrer placement av popover</h2>
<CopyToClipboard
icon={<Link />}
label={label}
text={text}
style={{ fontSize: "0.8rem" }}
popoverText={label}
copyText={text}
popoverPlacement="bottom-end"
>
Kopier tekst
</CopyToClipboard>
@@ -6,30 +6,40 @@ import { Success } from "@navikt/ds-react";
# Hvordan ta i bruk CopyToClipboard
Innholdet i `text` vil da bli kopiert til clipboard, mens innholdet i `label`
brukes i popovertekst og `sr-only` span som rendres hvis knappen ikke har noe tekstinnhold
`sr-only` tekst blir da `Kopier ${label} (${text})`
Innholdet i `copyText` vil bli kopiert til clipboard, mens innholdet i `popoverText`
brukes i popover. Hvis komponenten ikke har noen children (tekst i button) vil da en "sr-only" tekst blie
lagt på knappen med tekst "Kopier copyText"
```jsx
<CopyToClipboard label={"Kopierte PI til clipboard"} text={"3.14"}>
Kopier Pi{" "}
<CopyToClipboard popoverText={"Kopierte adresse"} copyText={"0660 OSLO"}>
Kopier adresse
</CopyToClipboard>
```
<Canvas>
<CopyToClipboard label={"Kopierte PI til clipboard"} text={"3.14"}>
Kopier Pi{" "}
<CopyToClipboard popoverText={"Kopiert adresse"} copyText={"0660 OSLO"}>
Kopier adresse
</CopyToClipboard>
</Canvas>
## Custom ikon
Man kan sette andre ikoner en `Copy` ved `icon`-proppen
## Sizing
```jsx
<CopyToClipboard
icon={<Link />}
label={"Kopierte PI til clipboard"}
text={"3.14"}
/>
popoverText={"Kopierte adressen"}
copyText={"0660 OSLO"}
size="small"
>
Kopier adresse
</CopyToClipboard>
```
<Canvas>
<CopyToClipboard
popoverText={"Kopierte adressen"}
copyText={"0660 OSLO"}
size="small"
>
Kopier adresse
</CopyToClipboard>
</Canvas>
@@ -23,7 +23,7 @@ const ConfirmationPanel = forwardRef<HTMLDivElement, ConfirmationPanelProps>(
<div
ref={ref}
className={cl("navds-confirmation-panel", className, {
"navds-confirmation-panel--s": props.size === "s",
"navds-confirmation-panel--s": props.size === "small",
"navds-confirmation-panel--error": !!props.error,
"navds-confirmation-panel--checked": !!props.checked,
})}
+2 -2
View File
@@ -5,11 +5,11 @@ import { Label } from "..";
const ErrorMessage = (props) => (
<Label
{...props}
component="div"
as="div"
className={cl(
"navds-error-message",
props.className,
`navds-error-message--${props.size ?? "m"}`
`navds-error-message--${props.size ?? "medium"}`
)}
/>
);
@@ -17,7 +17,7 @@ export type FieldsetContextProps = {
/**
* Changes paddings, margins and font-sizes
*/
size: "m" | "s";
size: "medium" | "small";
disabled: boolean;
};
@@ -94,7 +94,7 @@ const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
>
<Label
size={size}
component="legend"
as="legend"
className={cl("navds-fieldset__legend", {
"sr-only": !!hideLegend,
})}
+2 -2
View File
@@ -58,7 +58,7 @@ const Select = forwardRef<HTMLSelectElement, SelectProps>((props, ref) => {
<Label
htmlFor={inputProps.id}
size={size}
component="label"
as="label"
className={cl("navds-select__label", {
"sr-only": hideLabel,
})}
@@ -85,7 +85,7 @@ const Select = forwardRef<HTMLSelectElement, SelectProps>((props, ref) => {
className,
"navds-select__input",
"navds-body-short",
`navds-body--${size ?? "m"}`
`navds-body--${size ?? "medium"}`
)}
size={props.htmlSize}
>
+8 -2
View File
@@ -19,6 +19,11 @@ export interface TextFieldProps
* TextField label
*/
label: React.ReactNode;
/**
* Type of form control
* @default "text"
*/
type?: "email" | "number" | "password" | "tel" | "text" | "url";
}
const TextField = forwardRef<HTMLInputElement, TextFieldProps>((props, ref) => {
@@ -37,6 +42,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>((props, ref) => {
description,
htmlSize,
hideLabel = false,
type = "text",
...rest
} = props;
@@ -52,7 +58,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>((props, ref) => {
<Label
htmlFor={inputProps.id}
size={size}
component="label"
as="label"
className={cl("navds-text-field__label", { "sr-only": hideLabel })}
>
{label}
@@ -73,7 +79,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>((props, ref) => {
{...omit(rest, ["error", "errorId", "size"])}
{...inputProps}
ref={ref}
type="text"
type={type}
className={cl(
className,
"navds-text-field__input",
+3 -3
View File
@@ -72,7 +72,7 @@ const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
<Label
htmlFor={inputProps.id}
size={size}
component="label"
as="label"
className={cl("navds-textarea__label", {
"sr-only": hideLabel,
})}
@@ -99,7 +99,7 @@ const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
className,
"navds-textarea__input",
"navds-body-short",
`navds-body-${size ?? "m"}`,
`navds-body-${size ?? "medium"}`,
{
"navds-textarea--counter": hasMaxLength,
}
@@ -140,7 +140,7 @@ export const Counter = ({ maxLength, currentLength, size }) => {
className={cl("navds-textarea__counter", {
"navds-textarea__counter--error": difference < 0,
})}
aria-live="polite"
aria-live={difference < 20 ? "polite" : "off"}
size={size}
>
{difference < 0
@@ -16,6 +16,10 @@ export interface CheckboxProps
* Hides label and makes it viewable for screen-readers only.
*/
hideLabel?: boolean;
/**
* The value of the HTML element.
*/
value?: string;
}
const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
@@ -55,7 +59,7 @@ const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
ref={ref}
/>
<BodyShort
component="label"
as="label"
htmlFor={inputProps.id}
size={size}
className="navds-checkbox__label"
@@ -54,7 +54,7 @@ const CheckboxGroup = forwardRef<HTMLFieldSetElement, CheckboxGroupProps>(
className={cl(
className,
"navds-checkbox-group",
`navds-checkbox-group--${rest.size ?? fieldset?.size ?? "m"}`
`navds-checkbox-group--${rest.size ?? fieldset?.size ?? "medium"}`
)}
>
<CheckboxGroupContext.Provider
@@ -95,10 +95,14 @@ Man kan både sette en description på CheckboxGroup og selve checkbox
## Sizing
Checkboxer har default 44px høy klikkflate. Med size="s" blir denne til 24px slik som før
Checkboxer har default 44px høy klikkflate. Med size="small" blir denne til 24px slik som før
```jsx
<CheckboxGroup legend="Mollit eiusmod" error="Boks nr 2 må være valgt" size="s">
<CheckboxGroup
legend="Mollit eiusmod"
error="Boks nr 2 må være valgt"
size="small"
>
<Checkbox value="Apple">Apple</Checkbox>
<Checkbox value="Orange">Orange</Checkbox>
<Checkbox value="Melon">Melon</Checkbox>
@@ -109,7 +113,7 @@ Checkboxer har default 44px høy klikkflate. Med size="s" blir denne til 24px sl
<CheckboxGroup
legend="Mollit eiusmod"
error="Boks nr 2 må være valgt"
size="s"
size="small"
>
<Checkbox value="Apple">Apple</Checkbox>
<Checkbox value="Orange" error="Boksen må være valgt">
@@ -48,7 +48,7 @@ export const All = () => {
<CheckboxGroup
legend="Mollit eiusmod"
error="Boks nr 2 må være valgt"
size="s"
size="small"
>
<Checkbox value="Apple">Apple</Checkbox>
<Checkbox value="Orange">Orange</Checkbox>
@@ -17,7 +17,7 @@ const useCheckbox = ({ children, ...props }: CheckboxProps) => {
"`checked` is unsupported on <Checkbox> elements within a <CheckboxGroup>. Please set a `value` or `defaultValue` on <CheckboxGroup> instead."
);
}
if (props.value === null) {
if (props.value === undefined) {
console.warn(
"A <Checkbox> element within a <CheckboxGroup> requires a `value` property."
);
@@ -1,6 +1,6 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import { Title } from "../..";
import { Heading, BodyShort } from "../..";
export interface ErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {
/**
@@ -9,9 +9,9 @@ export interface ErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
/**
* Changes padding and font-sizes
* @default "m"
* @default "medium"
*/
size?: "m" | "s";
size?: "medium" | "small";
/**
* Heading above links
*/
@@ -25,7 +25,14 @@ export interface ErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {
const ErrorSummary = forwardRef<HTMLDivElement, ErrorSummaryProps>(
(
{ children, className, size = "m", headingTag = "h2", heading, ...rest },
{
children,
className,
size = "medium",
headingTag = "h2",
heading,
...rest
},
ref
) => {
return (
@@ -40,24 +47,18 @@ const ErrorSummary = forwardRef<HTMLDivElement, ErrorSummaryProps>(
tabIndex={-1}
role="region"
>
<Title
className="navds-error-summary__title"
component={headingTag}
size="s"
<Heading
className="navds-error-summary__heading"
as={headingTag}
size="small"
>
{heading}
</Title>
<ul
className={cl(
"navds-error-summary__list",
"navds-body-short",
`navds-body--${size}`
)}
>
</Heading>
<BodyShort as="ul" size={size} className="navds-error-summary__list">
{React.Children.map(children, (child) => {
return <li key={child?.toString()}>{child}</li>;
})}
</ul>
</BodyShort>
</div>
);
}
@@ -2,20 +2,20 @@ import React, { forwardRef } from "react";
import cl from "classnames";
import { OverridableComponent } from "../..";
export type ErrorType = OverridableComponent<ErrorSummaryItemProps>;
export interface ErrorSummaryItemProps {
props: {
/**
* Link text
*/
children: React.ReactNode;
} & React.HTMLAttributes<HTMLAnchorElement>;
defaultComponent: "a";
export interface ErrorSummaryItemProps
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
/**
* Link text
*/
children: React.ReactNode;
}
export type ErrorType = OverridableComponent<
ErrorSummaryItemProps,
HTMLAnchorElement
>;
const ErrorSummaryItem: ErrorType = forwardRef(
({ children, component: Component = "a", className, ...rest }, ref) => {
({ children, as: Component = "a", className, ...rest }, ref) => {
return (
<Component
{...rest}
@@ -16,8 +16,8 @@ export const All = () => {
Tekstfeltet må ha en godkjent e-mail
</ErrorSummaryItem>
</ErrorSummary>
<h2>size s</h2>
<ErrorSummary size="s" heading="Feiloppsummering komponent">
<h2>size small</h2>
<ErrorSummary size="small" heading="Feiloppsummering komponent">
<ErrorSummaryItem href="#1">Checkbox må fylles ut</ErrorSummaryItem>
<ErrorSummaryItem href="#2">
Tekstfeltet må ha en godkjent e-mail
+6
View File
@@ -10,6 +10,12 @@ export {
FieldsetProps,
} from "./Fieldset";
export { Radio, RadioGroup, RadioGroupProps, RadioProps } from "./radio";
export {
SearchField,
SearchFieldProps,
SearchFieldInput,
SearchFieldInputProps,
} from "./search-field";
export { default as Select, SelectProps } from "./Select";
export {
ErrorSummary,
+1 -1
View File
@@ -46,7 +46,7 @@ const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
ref={ref}
/>
<BodyShort
component="label"
as="label"
htmlFor={inputProps.id}
size={size}
className="navds-radio__label"
@@ -67,7 +67,7 @@ const RadioGroup = forwardRef<HTMLFieldSetElement, RadioGroupProps>(
className={cl(
className,
"navds-radio-group",
`navds-radio-group--${rest.size ?? fieldset?.size ?? "m"}`
`navds-radio-group--${rest.size ?? fieldset?.size ?? "medium"}`
)}
>
<RadioGroupContext.Provider
@@ -95,10 +95,14 @@ Man kan både sette en description på RadioGroup og selve Radio
## Sizing
Radioer har default 44px høy klikkflate. Med size="s" blir denne til 24px slik som før
Radioer har default 44px høy klikkflate. Med size="small" blir denne til 24px slik som før
```jsx
<RadioGroup legend="Mollit eiusmod" error="Boks nr 2 må være valgt" size="s">
<RadioGroup
legend="Mollit eiusmod"
error="Boks nr 2 må være valgt"
size="small"
>
<Radio value="Apple">Apple</Radio>
<Radio value="Orange">Orange</Radio>
<Radio value="Melon">Melon</Radio>
@@ -106,7 +110,11 @@ Radioer har default 44px høy klikkflate. Med size="s" blir denne til 24px slik
```
<Canvas>
<RadioGroup legend="Mollit eiusmod" error="Boks nr 2 må være valgt" size="s">
<RadioGroup
legend="Mollit eiusmod"
error="Boks nr 2 må være valgt"
size="small"
>
<Radio value="Apple">Apple</Radio>
<Radio value="Orange" error="Boksen må være valgt">
Orange
Loaded 100 of 375 files, more files were not shown because too many files have changed in this diff. Show more