Compare commits

..
Author SHA1 Message Date
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
github-actions[bot] 2853e5cd94 Lerna versionbump [ci skip]
- @navikt/ds-react@0.7.3
2021-08-18 08:42:44 +00:00
Ken 8a068e787d oppdatert omit props (#1177) 2021-08-18 10:28:24 +02:00
Ken f8fbf6c3a8 oppdatert utdaterte stories 2021-08-18 08:37:49 +02:00
Ken 6da78d13a3 fjernet storybook plugins som ikke ble brukt 2021-08-18 08:32:12 +02:00
github-actions[bot] bc7ff31a29 Lerna versionbump [ci skip]
- @navikt/ds-css@0.6.19
 - @navikt/ds-icons@0.5.2
 - @navikt/ds-react@0.7.2
2021-08-17 08:02:27 +00:00
Ken b82afbe806 Forsøk på margin-top fix for form-elements (#1176) 2021-08-17 09:42:58 +02:00
Ken 92425cdb5b Erstattet rm -rf med rimraf for windows support (#1175) 2021-08-17 09:42:51 +02:00
github-actions[bot] 12cca3e352 Lerna versionbump [ci skip]
- @navikt/ds-icons@0.5.1
 - @navikt/ds-react@0.7.1
2021-08-13 14:21:59 +00:00
Ken 396bcfbb8a Oppdatert package-resolving for ds-react og ds-icons (#1171)
* oppdatet script

* oppdatert icons script

* endret til mjs

* oppdatert icons script

* oppdaterte ds-react script og packagehandler script

* oppdaterte versjoner

* lint fix

* oppdater ds-react imports

* oppdaterte package script
2021-08-13 16:01:11 +02:00
Ken 0a364b989a Oppdatert useId (#1172)
* oppdaterte srrprovider

* fikset useId

* oppdatert yarn lock

* fikset id-bruk i ds-react

* lint fix

* fjernet console log

* fikset story

* fikset error-uu story

* oppdatert til noop når useId kjøres på server
2021-08-13 15:49:09 +02:00
Ken 233cf0cb31 la til subheadings for mobilmeny (#1174) 2021-08-13 15:12:44 +02:00
github-actions[bot] b3d1c8429a Lerna versionbump [ci skip]
- @navikt/ds-icons@0.4.1
 - @navikt/ds-react@0.6.19
2021-08-13 08:04:15 +00:00
Ken 1b66630b08 fikset versjon for ds-icons 2021-08-13 09:47:25 +02:00
Ken a3640b4ad1 Oppdatert ikoner (#1169) 2021-08-13 09:18:32 +02:00
Ken c9092c951e nextjs example app (#1168) 2021-08-12 11:43:04 +02:00
github-actions[bot] 5761ee7213 Lerna versionbump [ci skip]
- @navikt/ds-react@0.6.18
2021-08-12 08:39:45 +00:00
KenandAndreas Nordahl 6239d40d9c Forsøk på form aria-describedby fix (#1166)
* forsøk på fix

* bruker omit2

* Update @navikt/ds-react/src/form/Fieldset/Fieldset.tsx

Co-authored-by: Andreas Nordahl <andnorda@gmail.com>

* Update @navikt/ds-react/src/form/Fieldset/useFieldset.ts

Co-authored-by: Andreas Nordahl <andnorda@gmail.com>

Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
2021-08-12 10:26:03 +02:00
github-actions[bot] 4081131e1a Lerna versionbump [ci skip]
- @navikt/ds-react@0.6.17
2021-08-12 07:44:58 +00:00
Ken a0797cbf70 laget bedre story for hideLabel 2021-08-12 09:29:18 +02:00
Ken 8f0c6948c3 hideLabel-prop for Checkbox (#1167) 2021-08-12 09:25:03 +02:00
github-actions[bot] 9dd22c2201 Lerna versionbump [ci skip]
- @navikt/ds-react@0.6.16
2021-08-11 12:57:49 +00:00
Ken 47f174edee oppdatert props (#1164) 2021-08-11 14:40:53 +02:00
Ken 00ccebf826 Demo for uu-testing av fieldset (#1165) 2021-08-11 13:37:12 +02:00
github-actions[bot] ca3d011b54 Lerna versionbump [ci skip]
- @navikt/ds-react@0.6.15
2021-08-11 10:23:41 +00:00
Ken da11faf790 Endret imports fra ../index -> .. i ds-react (#1161)
* oppdaterte index imports

* Revert "oppdaterte index imports"

This reverts commit a9f766965a.

* fikset storybook crashing

* fikset imports fra merge
2021-08-11 12:09:29 +02:00
github-actions[bot] 41022fb3ab Lerna versionbump [ci skip]
- @navikt/ds-css@0.6.18
 - @navikt/ds-react@0.6.14
 - @navikt/ds-tokens@0.4.4
2021-08-11 10:04:45 +00:00
Ken 81a79de789 vnext ConfirmationPanel (Bekreftcheckboxpanel) (#1160)
* satt opp confirmation-panel

* oppdatert confirmationpanel styling

* oppdatert api

* oppdatert docs

* flyttet checkmark images til tokens
2021-08-11 11:49:15 +02:00
289 changed files with 2414 additions and 17520 deletions

No files matched your search

+36 -14
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,7 +48,7 @@ jobs:
exitZeroOnChanges: true
publish-npm:
needs: build
needs: test-build
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
@@ -66,20 +66,42 @@ 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 all package-versions with patch
run: yarn lerna version patch --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
@@ -122,7 +144,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
-2
View File
@@ -10,7 +10,6 @@ module.exports = {
"../@navikt/**/*.stories.@(js|jsx|ts|tsx|mdx)",
],
addons: [
"@storybook/addon-links",
"@storybook/addon-docs",
{
name: "@storybook/addon-storysource",
@@ -27,6 +26,5 @@ module.exports = {
controls: { hideNoControlsWarning: true },
},
},
"@whitespace/storybook-addon-html",
],
};
+2 -13
View File
@@ -11,7 +11,7 @@ yarn add @navikt/ds-react @navikt/ds-css
```
Siden stilene ikke importeres direkte i komponentene, så må man selv importere ds-css.
Dette gjøres for å la komponetene brukes i Nextjs prosjekter.
For å legge til all stylingen som trengs må man da bare importere `ds-css`.
```bash
import "@navikt/ds-css"
@@ -19,15 +19,4 @@ import "@navikt/ds-css"
Dette vil også legge css-variabler på :root. For å få dette til å fungere med IE11, kan denne pakken tas i bruk: https://jhildenbiddle.github.io/css-vars-ponyfill/#/
## Testing
For å støtte testing med eks Jest som ikke tillater ESM moduler, så kan denne configen legges til
```bash
"moduleNameMapper": {
"@navikt/ds-react(.*)": "@navikt/ds-react/cjs$1",
"@navikt/ds-icons(.*)": "@navikt/ds-icons/cjs$1"
}
```
Dette vil remappe komponentene (og ikonpakken) til å bruke CommonJs versjonen for testing
Note: Disse komponentene kan ikke garanteres at fungerer som forventet i IE11 da vi har valgt og ikke unngå styling-valg basert på IE11 støtte eller ikke.
+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);
}
+2 -2
View File
@@ -83,7 +83,7 @@
}
.navds-checkbox__input:checked + .navds-checkbox__label::before {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMyAxMCI+ICAgIDxnPiAgICA8cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNNCwxMGMtMC40LDAtMC44LTAuMS0xLjEtMC40TDAuNCw3LjFDMC4xLDYuOCwwLDYuNCwwLDZzMC4yLTAuOCwwLjUtMS4xQzEsNC40LDIsNC40LDIuNSw0LjlMNCw2LjRsNi40LTYgICAgQzEwLjgsMC4xLDExLjEsMCwxMS41LDBjMC40LDAsMC44LDAuMiwxLDAuNWMwLjYsMC42LDAuNSwxLjYtMC4xLDIuMXYwTDUsOS42QzQuNyw5LjksNC40LDEwLDQsMTB6IE0xMS44LDEuOUwxMS44LDEuOSAgICBDMTEuOCwxLjksMTEuOCwxLjksMTEuOCwxLjl6IE0xMS4yLDEuMUMxMS4yLDEuMSwxMS4yLDEuMSwxMS4yLDEuMUwxMS4yLDEuMXoiLz4gICAgPC9nPjwvc3ZnPg==);
background-image: var(--navds-checkmark-image-white);
background-position: center center;
background-repeat: no-repeat;
background-size: 75%;
@@ -93,7 +93,7 @@
.navds-checkbox__input:checked:focus + .navds-checkbox__label::before {
background-color: white;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMyAxMCI+ICAgIDxnPiAgICA8cGF0aCBmaWxsPSIjMDA2N0M1IiBkPSJNNCwxMGMtMC40LDAtMC44LTAuMS0xLjEtMC40TDAuNCw3LjFDMC4xLDYuOCwwLDYuNCwwLDZzMC4yLTAuOCwwLjUtMS4xQzEsNC40LDIsNC40LDIuNSw0LjlMNCw2LjRsNi40LTYgICAgQzEwLjgsMC4xLDExLjEsMCwxMS41LDBjMC40LDAsMC44LDAuMiwxLDAuNWMwLjYsMC42LDAuNSwxLjYtMC4xLDIuMXYwTDUsOS42QzQuNyw5LjksNC40LDEwLDQsMTB6IE0xMS44LDEuOUwxMS44LDEuOSAgICBDMTEuOCwxLjksMTEuOCwxLjksMTEuOCwxLjl6IE0xMS4yLDEuMUMxMS4yLDEuMSwxMS4yLDEuMSwxMS4yLDEuMUwxMS4yLDEuMXoiLz4gICAgPC9nPjwvc3ZnPg==);
background-image: var(--navds-checkmark-image-blue);
}
.navds-checkbox--error
@@ -0,0 +1,62 @@
.navds-confirmation-panel {
display: flex;
flex-direction: column;
gap: var(--navds-spacing-4);
padding: var(--navds-spacing-4);
border-radius: 4px;
background-color: #ffeccc;
transition: background-color linear 100ms;
}
.navds-confirmation-panel__content {
max-width: 80ch;
}
.navds-confirmation-panel--s {
padding: var(--navds-spacing-3);
gap: var(--navds-spacing-2);
}
.navds-confirmation-panel--checked {
background-color: #ccf1d6;
border-color: #ccf1d6;
}
.navds-confirmation-panel--error {
background-color: var(--navds-color-error-background);
border: 1px solid transparent;
}
.navds-confirmation-panel
.navds-checkbox__input:hover
+ .navds-checkbox__label {
text-decoration: underline;
}
.navds-confirmation-panel--checked
.navds-checkbox__input:hover
+ .navds-checkbox__label {
color: var(--navds-color-darkgray);
}
.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-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);
}
.navds-confirmation-panel--checked
.navds-checkbox__input:focus:hover
+ .navds-checkbox__label::before {
background-image: var(--navds-checkmark-image-white);
}
+5
View File
@@ -12,3 +12,8 @@
.navds-fieldset--s > :not(:first-child):not(:empty) {
margin-top: 4px;
}
/* Applied when hideLegend is applied to fieldset */
.navds-fieldset > .sr-only + :not(:first-child):not(:empty) {
margin-top: 0;
}
+6
View File
@@ -7,3 +7,9 @@
.navds-form-field--s > input:not(:first-child) {
margin-top: 4px;
}
/* Applied when hideLabel is applied to form-element */
.navds-form-field > .sr-only + :not(:first-child):not(:empty),
.navds-form-field > .sr-only + input:not(:first-child) {
margin-top: 0;
}
+2
View File
@@ -6,9 +6,11 @@
@import "error-summary.css";
@import "checkbox.css";
@import "checkbox-group.css";
@import "confirmation-panel.css";
@import "error-message.css";
@import "radio.css";
@import "radio-group.css";
@import "select.css";
@import "text-field.css";
@import "textarea.css";
@import "search-field.css";
+32
View File
@@ -0,0 +1,32 @@
.navds-search-field__input-wrapper {
display: flex;
}
.navds-form-field--s .navds-search-field__input {
padding: 0.25rem;
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: 1;
}
.navds-search-field--error
.navds-search-field__input:not(:hover):not(:focus):not(:disabled) {
box-shadow: 0 0 0 1px var(--navds-color-red-50) inset;
border-color: var(--navds-color-red-50);
}
-2
View File
@@ -1,10 +1,8 @@
@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";
-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;
}
}
+6
View File
@@ -7,6 +7,12 @@
gap: 0.25rem;
}
.navds-alert--error .navds-link,
.navds-alert--info .navds-link,
.navds-confirmation-panel--error .navds-link {
color: var(--navds-color-text-primary);
}
.navds-link:hover {
text-decoration: none;
}
+6 -5
View File
@@ -4,15 +4,13 @@
.navds-modal {
background-color: var(--navds-color-background);
display: block;
position: relative;
padding: var(--navds-spacing-4);
border-radius: 4px;
display: block;
position: relative;
overflow: auto;
max-height: 100%;
z-index: var(--navds-z-index-modal-content);
top: 50%;
transform: translateY(-50%);
}
.navds-modal:focus,
@@ -30,6 +28,9 @@
right: 0;
background-color: var(--navds-color-modal-overlay);
padding: var(--navds-spacing-4);
display: flex;
align-items: center;
justify-content: center;
}
.navds-modal__button--shake {
@@ -44,7 +45,7 @@
}
.navds-modal__button {
position: fixed;
position: absolute;
top: var(--navds-spacing-4);
right: var(--navds-spacing-4);
display: flex;
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "0.6.17",
"version": "0.7.3",
"private": false,
"description": "Css for NAV Designsystem components",
"author": "NAV Designsystem team",
@@ -21,7 +21,7 @@
"watch-css": "postcss -w --use postcss-import -o dist/index.css index.css"
},
"devDependencies": {
"@navikt/ds-tokens": "^0.4.3",
"@navikt/ds-tokens": "^0.4.4",
"normalize.css": "^8.0.1",
"postcss": "^8.2.7",
"postcss-cli": "^8.3.1",
-6
View File
@@ -1,6 +0,0 @@
{
"type": "commonjs",
"main": "index.js",
"typings": "../esm/index.d.ts",
"sideEffects": false
}
File renamed without changes.
File renamed without changes.
+61 -45
View File
@@ -11,7 +11,7 @@
"name": "AddCircle",
"description": "",
"created_at": "2020-07-01T10:37:42.784Z",
"updated_at": "2021-04-09T13:32:16.308Z",
"updated_at": "2021-08-12T11:15:52.168Z",
"pageName": "Interface",
"visible": true
},
@@ -32,18 +32,18 @@
"visible": true
},
{
"name": "AddPeople",
"name": "AddPerson",
"description": "",
"created_at": "2021-06-15T15:06:55.651Z",
"updated_at": "2021-06-15T15:06:55.651Z",
"updated_at": "2021-08-13T06:33:04.695Z",
"pageName": "People",
"visible": true
},
{
"name": "AddPeopleFilled",
"name": "AddPersonFilled",
"description": "",
"created_at": "2021-06-15T15:06:55.654Z",
"updated_at": "2021-06-15T15:06:55.654Z",
"updated_at": "2021-08-13T06:33:04.683Z",
"pageName": "People",
"visible": true
},
@@ -107,7 +107,7 @@
"name": "Back",
"description": "",
"created_at": "2020-07-01T10:37:42.840Z",
"updated_at": "2021-04-09T13:32:23.607Z",
"updated_at": "2021-08-12T14:51:21.441Z",
"pageName": "Chevron",
"visible": true
},
@@ -123,7 +123,7 @@
"name": "Bag",
"description": "",
"created_at": "2020-07-01T10:37:42.673Z",
"updated_at": "2021-06-14T07:21:59.055Z",
"updated_at": "2021-08-13T09:47:23.613Z",
"pageName": "Jobs",
"visible": true
},
@@ -203,7 +203,7 @@
"name": "Bookmark",
"description": "",
"created_at": "2020-07-01T10:37:42.877Z",
"updated_at": "2021-04-09T13:32:23.611Z",
"updated_at": "2021-08-12T12:32:34.047Z",
"pageName": "File",
"visible": true
},
@@ -251,7 +251,7 @@
"name": "Calculator",
"description": "",
"created_at": "2020-07-01T10:37:42.917Z",
"updated_at": "2021-06-14T07:21:59.043Z",
"updated_at": "2021-08-12T12:31:15.652Z",
"pageName": "Money",
"visible": true
},
@@ -395,7 +395,7 @@
"name": "Clock",
"description": "",
"created_at": "2020-07-01T10:37:42.647Z",
"updated_at": "2021-04-09T13:32:23.334Z",
"updated_at": "2021-08-13T07:30:12.128Z",
"pageName": "Time",
"visible": true
},
@@ -411,7 +411,7 @@
"name": "Close",
"description": "",
"created_at": "2020-07-01T10:37:42.827Z",
"updated_at": "2021-04-09T13:32:16.911Z",
"updated_at": "2021-08-12T13:19:34.922Z",
"pageName": "Interface",
"visible": true
},
@@ -419,7 +419,7 @@
"name": "CloseFilled",
"description": "",
"created_at": "2021-01-11T13:37:55.364Z",
"updated_at": "2021-04-09T13:32:16.624Z",
"updated_at": "2021-08-12T10:54:40.891Z",
"pageName": "Interface",
"visible": true
},
@@ -427,7 +427,7 @@
"name": "CoApplicant",
"description": "",
"created_at": "2021-04-30T10:55:32.823Z",
"updated_at": "2021-04-30T10:55:32.823Z",
"updated_at": "2021-08-13T09:47:48.809Z",
"pageName": "People",
"visible": true
},
@@ -507,7 +507,7 @@
"name": "Copy",
"description": "",
"created_at": "2020-07-01T10:37:42.619Z",
"updated_at": "2021-05-05T12:44:31.388Z",
"updated_at": "2021-08-12T12:36:11.164Z",
"pageName": "File",
"visible": true
},
@@ -567,6 +567,14 @@
"pageName": "File",
"visible": true
},
{
"name": "Decision",
"description": "",
"created_at": "2021-08-13T06:33:04.661Z",
"updated_at": "2021-08-13T06:33:04.661Z",
"pageName": "People",
"visible": true
},
{
"name": "DecisionCheck",
"description": "",
@@ -591,6 +599,14 @@
"pageName": "People",
"visible": true
},
{
"name": "DecisionFilled",
"description": "",
"created_at": "2021-08-13T06:33:04.665Z",
"updated_at": "2021-08-13T06:33:04.665Z",
"pageName": "People",
"visible": true
},
{
"name": "Delete",
"description": "",
@@ -619,7 +635,7 @@
"name": "DialogDots",
"description": "",
"created_at": "2020-07-01T10:37:43.133Z",
"updated_at": "2021-04-09T13:32:23.486Z",
"updated_at": "2021-08-12T11:19:13.127Z",
"pageName": "Communication",
"visible": true
},
@@ -875,7 +891,7 @@
"name": "EmployerFilled",
"description": "",
"created_at": "2021-01-22T13:40:32.293Z",
"updated_at": "2021-04-22T08:46:31.424Z",
"updated_at": "2021-08-13T06:33:04.692Z",
"pageName": "People",
"visible": true
},
@@ -931,7 +947,7 @@
"name": "Eye",
"description": "",
"created_at": "2020-07-01T10:37:42.895Z",
"updated_at": "2021-04-09T13:32:23.514Z",
"updated_at": "2021-08-12T09:55:24.102Z",
"pageName": "Privacy",
"visible": true
},
@@ -939,7 +955,7 @@
"name": "EyeFilled",
"description": "",
"created_at": "2021-01-11T13:37:55.321Z",
"updated_at": "2021-04-09T13:32:16.996Z",
"updated_at": "2021-08-12T09:55:25.386Z",
"pageName": "Privacy",
"visible": true
},
@@ -947,7 +963,7 @@
"name": "EyeScreened",
"description": "",
"created_at": "2020-07-01T10:37:42.956Z",
"updated_at": "2021-04-09T13:32:23.351Z",
"updated_at": "2021-08-12T09:56:29.536Z",
"pageName": "Privacy",
"visible": true
},
@@ -955,7 +971,7 @@
"name": "EyeScreenedFilled",
"description": "",
"created_at": "2021-01-11T13:37:55.578Z",
"updated_at": "2021-04-09T13:32:23.419Z",
"updated_at": "2021-08-12T09:55:47.137Z",
"pageName": "Privacy",
"visible": true
},
@@ -1107,7 +1123,7 @@
"name": "Findout",
"description": "",
"created_at": "2021-05-05T13:04:25.502Z",
"updated_at": "2021-05-05T13:04:25.502Z",
"updated_at": "2021-08-12T12:32:46.082Z",
"pageName": "File",
"visible": true
},
@@ -1139,7 +1155,7 @@
"name": "Folder",
"description": "",
"created_at": "2020-07-01T10:37:42.682Z",
"updated_at": "2021-04-09T13:32:23.439Z",
"updated_at": "2021-08-13T07:30:12.108Z",
"pageName": "File",
"visible": true
},
@@ -1267,7 +1283,7 @@
"name": "HandBandage",
"description": "",
"created_at": "2020-07-01T10:37:42.711Z",
"updated_at": "2021-04-09T13:32:16.442Z",
"updated_at": "2021-08-13T09:48:45.392Z",
"pageName": "Health",
"visible": true
},
@@ -1379,7 +1395,7 @@
"name": "Helmet",
"description": "",
"created_at": "2020-07-01T10:37:42.793Z",
"updated_at": "2021-04-09T13:32:23.412Z",
"updated_at": "2021-08-13T09:49:01.868Z",
"pageName": "Jobs",
"visible": true
},
@@ -1491,7 +1507,7 @@
"name": "Information",
"description": "",
"created_at": "2020-07-01T10:37:43.005Z",
"updated_at": "2021-04-09T13:32:16.578Z",
"updated_at": "2021-08-12T12:35:33.631Z",
"pageName": "Status",
"visible": true
},
@@ -1499,7 +1515,7 @@
"name": "InformationFilled",
"description": "",
"created_at": "2021-01-11T13:37:55.736Z",
"updated_at": "2021-04-09T13:32:16.132Z",
"updated_at": "2021-08-12T11:36:44.756Z",
"pageName": "Status",
"visible": true
},
@@ -1531,7 +1547,7 @@
"name": "LawFilled",
"description": "",
"created_at": "2021-01-11T13:37:55.330Z",
"updated_at": "2021-04-09T13:32:16.725Z",
"updated_at": "2021-08-13T09:50:59.913Z",
"pageName": "Privacy",
"visible": true
},
@@ -1539,7 +1555,7 @@
"name": "Left",
"description": "",
"created_at": "2020-07-01T10:37:42.797Z",
"updated_at": "2021-04-09T13:32:23.354Z",
"updated_at": "2021-08-13T06:33:04.688Z",
"pageName": "Arrow",
"visible": true
},
@@ -1619,7 +1635,7 @@
"name": "Locked",
"description": "",
"created_at": "2020-07-01T10:37:43.027Z",
"updated_at": "2021-04-09T13:32:23.385Z",
"updated_at": "2021-08-12T09:56:54.295Z",
"pageName": "Privacy",
"visible": true
},
@@ -1715,7 +1731,7 @@
"name": "MinusCircleFilled",
"description": "",
"created_at": "2021-01-11T13:37:55.721Z",
"updated_at": "2021-04-09T13:32:16.246Z",
"updated_at": "2021-08-12T10:26:25.789Z",
"pageName": "Interface",
"visible": true
},
@@ -1731,7 +1747,7 @@
"name": "Mobile",
"description": "",
"created_at": "2020-07-01T10:37:43.010Z",
"updated_at": "2021-04-09T13:32:16.508Z",
"updated_at": "2021-08-12T11:19:05.339Z",
"pageName": "Device",
"visible": true
},
@@ -1747,7 +1763,7 @@
"name": "Money",
"description": "",
"created_at": "2020-07-01T10:37:42.741Z",
"updated_at": "2021-04-09T13:32:23.388Z",
"updated_at": "2021-08-12T12:31:01.092Z",
"pageName": "Money",
"visible": true
},
@@ -1891,7 +1907,7 @@
"name": "Office1",
"description": "",
"created_at": "2020-07-01T10:37:42.720Z",
"updated_at": "2021-04-09T13:32:23.456Z",
"updated_at": "2021-08-12T12:56:17.625Z",
"pageName": "Building",
"visible": true
},
@@ -1987,7 +2003,7 @@
"name": "People",
"description": "",
"created_at": "2020-07-01T10:37:42.850Z",
"updated_at": "2021-04-09T13:32:23.661Z",
"updated_at": "2021-08-12T11:17:04.979Z",
"pageName": "People",
"visible": true
},
@@ -2115,7 +2131,7 @@
"name": "Profile",
"description": "",
"created_at": "2021-04-26T09:24:38.029Z",
"updated_at": "2021-04-30T10:55:32.846Z",
"updated_at": "2021-08-12T12:32:56.285Z",
"pageName": "File",
"visible": true
},
@@ -2147,7 +2163,7 @@
"name": "Receipt",
"description": "",
"created_at": "2020-07-01T10:37:42.904Z",
"updated_at": "2021-04-09T13:32:23.649Z",
"updated_at": "2021-08-12T12:29:47.091Z",
"pageName": "Money",
"visible": true
},
@@ -2227,7 +2243,7 @@
"name": "Right",
"description": "",
"created_at": "2020-07-01T10:37:42.642Z",
"updated_at": "2021-04-09T13:32:23.409Z",
"updated_at": "2021-08-12T07:14:26.093Z",
"pageName": "Arrow",
"visible": true
},
@@ -2259,7 +2275,7 @@
"name": "Sandglass",
"description": "",
"created_at": "2020-07-01T10:37:43.117Z",
"updated_at": "2021-04-09T13:32:23.313Z",
"updated_at": "2021-08-12T08:18:12.598Z",
"pageName": "Time",
"visible": true
},
@@ -2323,7 +2339,7 @@
"name": "Search",
"description": "",
"created_at": "2020-07-01T10:37:42.983Z",
"updated_at": "2021-04-09T13:32:16.382Z",
"updated_at": "2021-08-12T12:37:22.919Z",
"pageName": "Interface",
"visible": true
},
@@ -2387,7 +2403,7 @@
"name": "Send",
"description": "",
"created_at": "2020-07-01T10:37:43.101Z",
"updated_at": "2021-04-09T13:32:23.596Z",
"updated_at": "2021-08-13T07:30:12.151Z",
"pageName": "Communication",
"visible": true
},
@@ -2403,7 +2419,7 @@
"name": "Service",
"description": "",
"created_at": "2020-07-01T10:37:42.707Z",
"updated_at": "2021-06-14T07:21:59.047Z",
"updated_at": "2021-08-12T11:15:52.145Z",
"pageName": "People",
"visible": true
},
@@ -2675,7 +2691,7 @@
"name": "SuccessStroke",
"description": "",
"created_at": "2021-04-15T07:12:49.753Z",
"updated_at": "2021-04-15T07:12:49.753Z",
"updated_at": "2021-08-12T11:30:36.177Z",
"pageName": "Status",
"visible": true
},
@@ -2755,7 +2771,7 @@
"name": "ThermometerStroke",
"description": "",
"created_at": "2021-04-07T12:13:28.179Z",
"updated_at": "2021-04-09T13:32:16.814Z",
"updated_at": "2021-08-12T12:34:12.825Z",
"pageName": "Health",
"visible": true
},
@@ -2811,7 +2827,7 @@
"name": "Unlocked",
"description": "",
"created_at": "2020-07-01T10:37:42.823Z",
"updated_at": "2021-04-09T13:32:16.901Z",
"updated_at": "2021-08-12T09:56:56.564Z",
"pageName": "Privacy",
"visible": true
},
@@ -2843,7 +2859,7 @@
"name": "Upload",
"description": "",
"created_at": "2020-07-01T10:37:43.046Z",
"updated_at": "2021-04-09T13:32:23.685Z",
"updated_at": "2021-08-13T07:41:40.719Z",
"pageName": "Attachment",
"visible": true
},
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-icons",
"version": "0.3.3",
"version": "0.5.2",
"private": false,
"description": "NAVs egne ikoner i SVG og React format",
"repository": {
@@ -14,11 +14,10 @@
],
"license": "MIT",
"author": "NAV",
"main": "esm/index.js",
"module": "esm/index.js",
"typings": "esm/index.d.ts",
"sideEffects": false,
"type": "module",
"main": "./cjs/index.js",
"module": "./esm/index.js",
"typings": "./esm/index.d.ts",
"files": [
"/cjs",
"/esm",
@@ -26,12 +25,13 @@
"/svg"
],
"scripts": {
"cjs-package": "copyfiles -f config/package.json cjs",
"dl-icons": "FILE_KEY=UmEVH3pZ71uJPsSz9ilP3Y node --experimental-modules --es-module-specifier-resolution=node -r dotenv/config figma-api/index.js dotenv_config_path=figma-api/.env",
"create-package-json-pointers-to-esm": "node ../../utilities/scripts/createPackageJsonsWithESMPointers.js",
"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.js",
"clean": "rm -rf src && rm -rf esm && rm -rf cjs && rm -rf png && rm -rf NAV-ikonpakke-png.zip && rm -rf NAV-ikonpakke-svg.zip",
"build": "npm run clean && npm run create-icons && tsc && tsc -p tsconfig-esm.json && yarn cjs-package && npm run convert-icons && node figma-api/zipIcons.js"
"convert-icons": "node figma-api/pngConverter.mjs",
"clean": "rimraf src esm cjs 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"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
+3 -14
View File
@@ -4,7 +4,7 @@ import { Meta } from "@storybook/addon-docs";
# Ta i bruk ikonpakken `@navikt/ds-icons`
Alle ikoner kan bli funnet her https://design.nav.no/resources/icons
Alle ikoner kan bli funnet her https://design.nav.no/designsystem/resources/icons
## Oppsett
@@ -12,7 +12,7 @@ Alle ikoner kan bli funnet her https://design.nav.no/resources/icons
yarn add @navikt/ds-icons
```
```bash
```jsx
Import { Expand } from `@navikt/ds-icons`;
<Expand
@@ -22,15 +22,4 @@ Import { Expand } from `@navikt/ds-icons`;
/>
```
## Testing
For å støtte testing med eks Jest som ikke tillater ESM moduler, så kan denne configen legges til
```bash
"moduleNameMapper": {
"@navikt/ds-react(.*)": "@navikt/ds-react/cjs$1",
"@navikt/ds-icons(.*)": "@navikt/ds-icons/cjs$1"
}
```
Dette vil remappe Ikonpakken (og komponentpakken) til å bruke CommonJs versjonen for testing
Note: Det kan være tilfeller der oppsettet ditt ikke har støtte for SVG, og det må da legges til manuelt i eks en webpack config basert på hva som blir brukt.
File renamed without changes.
+5
View File
@@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.9565 8C12.6134 8 13.9565 6.65685 13.9565 5C13.9565 3.34315 12.6134 2 10.9565 2C9.29969 2 7.95654 3.34315 7.95654 5C7.95654 6.65685 9.29969 8 10.9565 8ZM10.9565 10C13.718 10 15.9565 7.76142 15.9565 5C15.9565 2.23858 13.718 0 10.9565 0C8.19512 0 5.95654 2.23858 5.95654 5C5.95654 7.76142 8.19512 10 10.9565 10Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.0569 11.5858C19.2758 10.8047 18.0095 10.8047 17.2285 11.5858L15.8143 13C15.0332 13.781 15.0332 15.0474 15.8143 15.8284L16.6856 16.6997L12.1071 21.2782L11.4 21.9853L12.8142 23.3995L13.5213 22.6924L18.0998 18.114L19.0496 19.0637C19.8306 19.8448 21.0969 19.8448 21.878 19.0637L23.2922 17.6495C24.0733 16.8685 24.0733 15.6021 23.2922 14.8211L20.0569 11.5858ZM18.6427 13L21.878 16.2353L20.4638 17.6495L17.2285 14.4142L18.6427 13Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.1594 11.7521C13.2095 11.2709 12.1352 11 11 11C7.13401 11 4 14.134 4 18H6C6 15.2386 8.23858 13 11 13C11.5609 13 12.0993 13.092 12.6014 13.2617L14.1594 11.7521Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 5C16 7.76142 13.7614 10 11 10C8.23858 10 6 7.76142 6 5C6 2.23858 8.23858 0 11 0C13.7614 0 16 2.23858 16 5ZM4 18C4 14.134 7.13401 11 11 11C12.3956 11 13.6959 11.4084 14.7877 12.1123L8.7108 18H4Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.2782 12.2854C18.8876 11.9049 18.2545 11.9049 17.8639 12.2854L15.3891 14.6973C14.9985 15.0778 14.9985 15.6949 15.3891 16.0754L16.8033 17.4536L11.5 22.6218L12.9142 24L18.2175 18.8318L19.8085 20.3823C20.199 20.7628 20.8322 20.7628 21.2227 20.3823L23.6976 17.9704C24.0881 17.5899 24.0881 16.9728 23.6976 16.5923L19.2782 12.2854Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 764 B

-6
View File
@@ -1,6 +0,0 @@
{
"type": "commonjs",
"main": "index.js",
"typings": "../esm/index.d.ts",
"sideEffects": false
}
+11 -12
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "0.6.13",
"version": "0.7.5",
"private": false,
"description": "NAV designsystem react components",
"author": "NAV Designsystem team",
@@ -14,11 +14,10 @@
"type": "git",
"url": "git+https://github.com/navikt/nav-frontend-moduler/tree/master/%40navikt/ds-react"
},
"main": "esm/index.js",
"module": "esm/index.js",
"typings": "esm/index.d.ts",
"sideEffects": false,
"type": "module",
"main": "./cjs/index.js",
"module": "./esm/index.js",
"typings": "./esm/index.d.ts",
"publishConfig": {
"access": "public"
},
@@ -28,14 +27,14 @@
"/src"
],
"scripts": {
"cjs-package": "copyfiles -f config/package.json cjs",
"clean": "rm -rf cjs esm",
"build": "yarn run clean && tsc && tsc -p tsconfig-esm.json && yarn cjs-package",
"create-package-json-pointers-to-esm": "node ../../utilities/scripts/createPackageJsonsWithESMPointers.js",
"clean": "rimraf cjs esm",
"build": "yarn run clean && tsc && tsc -p tsconfig-esm.json && yarn create-package-json-pointers-to-esm",
"watch": "tsc --watch -p tsconfig-esm.json"
},
"dependencies": {
"@material-ui/core": "^4.12.2",
"@navikt/ds-icons": "^0.3.3",
"@navikt/ds-icons": "^0.5.2",
"@popperjs/core": "^2.5.4",
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.3.1",
@@ -43,12 +42,12 @@
"react-merge-refs": "^1.1.0",
"react-modal": "3.12.1",
"react-popper": "^2.2.4",
"short-uuid": "^4.2.0",
"uuid": "^8.3.2"
"short-uuid": "^4.2.0"
},
"devDependencies": {
"copyfiles": "^2.4.1",
"react-router-dom": "^5.2.0"
"react-router-dom": "^5.2.0",
"rimraf": "3.0.2"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
@@ -1,36 +0,0 @@
import React, { forwardRef, HTMLAttributes } from "react";
import { AccordionMenu as BaseAccordionMenu } from "../accordion-menu";
import { Title } from "../index";
import { ActiveAnchorProvider } from "./ActiveAnchorStore";
import cl from "classnames";
export interface AccordionAnchorMenuProps
extends HTMLAttributes<HTMLDivElement> {
title?: string;
children: React.ReactNode;
className?: string;
}
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>
),
];
@@ -4,7 +4,6 @@ import MenuItems from "./MenuItems";
export interface AccordionMenuProps extends HTMLAttributes<HTMLElement> {
children: React.ReactNode;
className?: string;
}
const AccordionMenu = forwardRef<HTMLElement, AccordionMenuProps>(
@@ -8,7 +8,6 @@ export interface AccordionMenuCollapsableProps
title: string;
defaultOpen?: boolean;
children: React.ReactNode;
className?: string;
}
const AccordionMenuCollapsable = forwardRef<
@@ -1,8 +1,5 @@
import React from "react";
/**
* @ignore
*/
const MenuItems = ({ children }: { children: React.ReactNode }) => (
<ul className="navds-accordion-menu__list">
{React.Children.toArray(children).map((child, i) => (
+4 -14
View File
@@ -2,7 +2,7 @@ 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 { v4 as uuidv4 } from "uuid";
import { useId } from "..";
export interface AccordionProps
extends React.HTMLAttributes<HTMLButtonElement> {
@@ -10,10 +10,6 @@ export interface AccordionProps
* Component content
*/
children: React.ReactNode;
/**
* @ignore
*/
className?: string;
/**
* Content on interactive surface of component
*/
@@ -26,8 +22,6 @@ export interface AccordionProps
open?: boolean;
/**
* Callback for when user interacts with component
*
* @param {object} event
*/
onClick?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
/**
@@ -46,19 +40,15 @@ const Accordion = forwardRef<HTMLButtonElement, AccordionProps>(
className,
renderContentWhenClosed = false,
onClick,
id,
...rest
},
ref
) => {
const [contentId, setContentId] = useState("");
const [buttonId, setButtonId] = useState("");
const [internalOpen, setInternalOpen] = useState<boolean>(open);
// Forsøk på å fikse Nextjs SSR server/client clock problem
useEffect(() => {
setContentId(() => uuidv4());
setButtonId(() => uuidv4());
}, []);
const buttonId = useId(id);
const contentId = useId();
useEffect(() => {
setInternalOpen(open);
+2 -9
View File
@@ -12,17 +12,10 @@ export interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
* Decides what design the alert will have
*/
variant: "error" | "warning" | "info" | "success";
/**
* Component content
*/
children: React.ReactNode;
/**
* @ignore
*/
className?: string;
/**
* Reduces padding on component
* @default "medium"
* Changes padding and font-sizes
* @default "m"
*/
size?: "m" | "s";
}
+6 -8
View File
@@ -1,27 +1,25 @@
import React, { forwardRef } from "react";
import cl from "classnames";
export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
/**
* Component content
*/
children: React.ReactNode;
/**
* @ignore
*/
className?: string;
/**
* Decides component design and interactions
* Changes design and interactions
* @default "primary"
*/
variant?: "primary" | "secondary" | "action" | "danger";
/**
* Reduces internal padding for component
* @default "medium"
* Changes padding, height and font-size
* @default "m"
*/
size?: "m" | "s";
/**
* Prevent the user from interacting with the button: it cannot be pressed or focused.
* @note Avoid using if possible for accessibility purposes
* @default false
*/
disabled?: boolean;
@@ -29,6 +29,13 @@ const variants: Array<"primary" | "secondary" | "action" | "danger"> = [
"danger",
];
const varSwitch = {
primary: "Primary",
secondary: "Secondary",
action: "Action",
danger: "Danger",
};
export const All = () => {
return (
<>
@@ -36,7 +43,7 @@ export const All = () => {
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant}>
{variant}
{varSwitch[variant]}
</Button>
))}
</Section>
@@ -44,7 +51,7 @@ export const All = () => {
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant} disabled>
{variant}
{varSwitch[variant]}
</Button>
))}
</Section>
@@ -56,7 +63,7 @@ export const All = () => {
className={`navds-button navds-button--${variant} navds-body-short`}
href="the-link"
>
{variant}
{varSwitch[variant]}
</a>
))}
</Section>
@@ -64,7 +71,7 @@ export const All = () => {
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant} size="s">
{variant}
{varSwitch[variant]}
</Button>
))}
</Section>
@@ -72,7 +79,7 @@ export const All = () => {
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant}>
<span>{variant}</span> <Success />
<span>{varSwitch[variant]}</span> <Success />
</Button>
))}
</Section>
@@ -80,7 +87,7 @@ export const All = () => {
<Section>
{variants.map((variant) => (
<Button key={variant} variant={variant} size="s">
<Success /> <span>{variant}</span>
<Success /> <span>{varSwitch[variant]}</span>
</Button>
))}
</Section>
-4
View File
@@ -5,10 +5,6 @@ import { OverridableComponent } from "../util";
export interface MicroCardProps {
props: {
children: string;
/**
* @ignore
*/
className?: string;
} & React.HTMLAttributes<HTMLAnchorElement>;
defaultComponent: "a";
}
@@ -2,10 +2,6 @@ import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
export interface ContentContainerProps extends HTMLAttributes<HTMLDivElement> {
/**
* @ignore
*/
classNames?: string;
/**
* Component content
*/
@@ -9,10 +9,14 @@ import React, {
useState,
} from "react";
import mergeRefs from "react-merge-refs";
import { Popover, Button } from "../index";
import { Popover, Button } from "..";
export interface CopyToClipboardProps
extends HTMLAttributes<HTMLButtonElement> {
/**
* Button text
*/
children?: React.ReactNode;
/**
* Text to be copied to clipboard
*/
@@ -0,0 +1,45 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import { BodyLong, Checkbox, CheckboxProps } from "..";
export interface ConfirmationPanelProps extends Partial<CheckboxProps> {
/**
* Additional information on panel
*/
children?: React.ReactNode;
/**
* Checkbox label
*/
label: string;
/**
* Checked state for checkbox
*/
checked: boolean;
}
const ConfirmationPanel = forwardRef<HTMLDivElement, ConfirmationPanelProps>(
({ className, children, label, ...props }, ref) => {
return (
<div
ref={ref}
className={cl("navds-confirmation-panel", className, {
"navds-confirmation-panel--s": props.size === "s",
"navds-confirmation-panel--error": !!props.error,
"navds-confirmation-panel--checked": !!props.checked,
})}
>
{children && (
<BodyLong
size={props.size}
className="navds-confirmation-panel__content"
>
{children}
</BodyLong>
)}
<Checkbox {...props}>{label}</Checkbox>
</div>
);
}
);
export default ConfirmationPanel;
+1 -1
View File
@@ -1,6 +1,6 @@
import React from "react";
import cl from "classnames";
import { Label } from "../index";
import { Label } from "..";
const ErrorMessage = (props) => (
<Label
@@ -1,16 +1,24 @@
import cl from "classnames";
import React, { FieldsetHTMLAttributes, forwardRef, useContext } from "react";
import { BodyShort, Label } from "../../index";
import { BodyShort, Label, omit } from "../..";
import ErrorMessage from "../ErrorMessage";
import { FormFieldProps } from "../useFormField";
import { useFieldset } from "./useFieldset";
export type FieldsetContextProps = {
/**
* Error message applied to element
*/
error?: React.ReactNode;
/**
* Overrides internal errorId
*/
errorId: string;
/**
* Changes paddings, margins and font-sizes
*/
size: "m" | "s";
disabled: boolean;
errorDescribedBy?: string;
};
export const FieldsetContext = React.createContext<FieldsetContextProps | null>(
@@ -23,7 +31,6 @@ export interface FieldsetProps
* FormFields in Fieldset
*/
children: React.ReactNode;
className?: string;
/**
* Fieldset legend
*/
@@ -48,7 +55,6 @@ const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
hasError,
size,
inputDescriptionId,
errorDescribedBy,
} = useFieldset(props);
const fieldset = useContext(FieldsetContext);
@@ -67,14 +73,16 @@ const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
<FieldsetContext.Provider
value={{
error: errorPropagation ? props.error ?? fieldset?.error : undefined,
errorId: props.error ? errorId : fieldset?.errorId ?? errorId,
errorId: cl({
[errorId]: showErrorMsg,
[fieldset?.errorId ?? ""]: !!fieldset?.error,
}),
size,
disabled: props.disabled ?? false,
errorDescribedBy,
}}
>
<fieldset
{...rest}
{...omit(rest, ["errorId", "error", "size"])}
{...inputProps}
ref={ref}
className={cl(
@@ -1,6 +1,3 @@
import cl from "classnames";
import { useContext } from "react";
import { FieldsetContext } from "./index";
import { useFormField } from "../useFormField";
/**
@@ -8,19 +5,13 @@ import { useFormField } from "../useFormField";
*/
export const useFieldset = (props) => {
const formField = useFormField(props, "fieldset");
const { errorId, inputProps, showErrorMsg } = formField;
const fieldset = useContext(FieldsetContext);
const errorDescribedBy: string = cl(fieldset?.errorDescribedBy, {
[errorId]: showErrorMsg,
});
const { inputProps } = formField;
return {
...formField,
errorDescribedBy,
inputProps: {
"aria-invalid": inputProps["aria-invalid"],
"aria-describedby": cl(inputProps["aria-describedby"], errorDescribedBy),
"aria-describedby": inputProps["aria-describedby"],
},
};
};
+6 -2
View File
@@ -1,13 +1,17 @@
import React, { forwardRef, SelectHTMLAttributes } from "react";
import cl from "classnames";
import { Expand } from "@navikt/ds-icons";
import { BodyShort, Label } from "../index";
import { BodyShort, Label, omit } from "..";
import ErrorMessage from "./ErrorMessage";
import { FormFieldProps, useFormField } from "./useFormField";
export interface SelectProps
extends FormFieldProps,
Omit<SelectHTMLAttributes<HTMLSelectElement>, "size"> {
/**
* Collection of <option>-elements
*/
children: React.ReactNode;
/**
* Expose the HTML size attribute
*/
@@ -74,7 +78,7 @@ const Select = forwardRef<HTMLSelectElement, SelectProps>((props, ref) => {
)}
<div className="navds-select__container">
<select
{...rest}
{...omit(rest, ["error", "errorId", "size"])}
{...inputProps}
ref={ref}
className={cl(
+2 -6
View File
@@ -1,16 +1,12 @@
import React, { forwardRef, InputHTMLAttributes } from "react";
import cl from "classnames";
import { BodyShort, Label } from "../index";
import { BodyShort, Label, omit } from "..";
import ErrorMessage from "./ErrorMessage";
import { FormFieldProps, useFormField } from "./useFormField";
export interface TextFieldProps
extends FormFieldProps,
Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
/**
* @ignore
*/
className?: string;
/**
* Expose the HTML size attribute
*/
@@ -74,7 +70,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>((props, ref) => {
</BodyShort>
)}
<input
{...rest}
{...omit(rest, ["error", "errorId", "size"])}
{...inputProps}
ref={ref}
type="text"
+4 -4
View File
@@ -1,10 +1,10 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import TextareaAutosize from "@material-ui/core/TextareaAutosize";
import { BodyShort, Label } from "../index";
import { BodyShort, Label, omit } from "..";
import ErrorMessage from "./ErrorMessage";
import { FormFieldProps, useFormField } from "./useFormField";
import useId from "./useId";
import { useId } from "..";
/**
* TODO: Mulighet for lokalisering av sr-only/counter text
@@ -57,7 +57,7 @@ const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
...rest
} = props;
const maxLengthId = useId({ prefix: "TextareaMaxLength" });
const maxLengthId = `TextareaMaxLength-${useId()}`;
const hasMaxLength = maxLength !== undefined && maxLength > 0;
return (
@@ -92,7 +92,7 @@ const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
)}
<div className="navds-textarea__wrapper">
<TextareaAutosize
{...rest}
{...omit(rest, ["error", "errorId", "size"])}
{...inputProps}
ref={ref}
className={cl(
@@ -3,17 +3,23 @@ import cl from "classnames";
import useCheckbox from "./useCheckbox";
import ErrorMessage from "../ErrorMessage";
import { FormFieldProps } from "../useFormField";
import { BodyShort } from "../../index";
import { omit } from "../../index";
import { BodyShort, omit } from "../..";
export interface CheckboxProps
extends FormFieldProps,
Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
className?: string;
/**
* Label for checkbox
*/
children: React.ReactNode;
/**
* 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) => {
@@ -46,6 +52,7 @@ const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
"error",
"errorId",
"description",
"hideLabel",
])}
{...inputProps}
className="navds-checkbox__input"
@@ -57,7 +64,11 @@ const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
size={size}
className="navds-checkbox__label"
>
{props.children}
{props.hideLabel ? (
<span className="sr-only">{props.children}</span>
) : (
props.children
)}
</BodyShort>
{props.description && (
<BodyShort
@@ -1,6 +1,6 @@
import React, { createContext, forwardRef, useContext } from "react";
import cl from "classnames";
import { Fieldset, FieldsetProps, FieldsetContext } from "../index";
import { Fieldset, FieldsetProps, FieldsetContext } from "..";
export interface CheckboxGroupState {
readonly defaultValue: readonly string[];
@@ -13,6 +13,10 @@ export const CheckboxGroupContext = createContext<CheckboxGroupState | null>(
);
export interface CheckboxGroupProps extends Omit<FieldsetProps, "onChange"> {
/**
* Checkboxes
*/
children: React.ReactNode;
/**
* Controlled state for group
*/
@@ -157,6 +157,38 @@ Ved bruk av `hideLegend` på CheckboxGroup kan man gjøre slik at legend/descrip
</CheckboxGroup>
</Canvas>
## hideLabel
Ved bruk av `hideLabel` kan man lettere ta i bruk checkbox internt i eks tabeller.
```jsx
<CheckboxGroup legend="Mollit eiusmod" hideLegend>
<Checkbox value="Apple" hideLabel>
Apple
</Checkbox>
<Checkbox value="Orange" hideLabel>
Orange
</Checkbox>
<Checkbox value="Melon" hideLabel>
Melon
</Checkbox>
</CheckboxGroup>
```
<Canvas>
<CheckboxGroup legend="Mollit eiusmod" hideLegend>
<Checkbox value="Apple" hideLabel>
Apple
</Checkbox>
<Checkbox value="Orange" hideLabel>
Orange
</Checkbox>
<Checkbox value="Melon" hideLabel>
Melon
</Checkbox>
</CheckboxGroup>
</Canvas>
## Disabled
Ved bruk av `disabled` kan man både disabled enkelte checkboxer eller checkboxgruppen.
@@ -66,6 +66,18 @@ export const All = () => {
<Checkbox value="Orange">Orange</Checkbox>
<Checkbox value="Melon">Melon</Checkbox>
</CheckboxGroup>
<h2>hideLabel</h2>
<CheckboxGroup legend="Mollit eiusmod">
<Checkbox value="Apple" hideLabel>
Apple
</Checkbox>
<Checkbox value="Orange" hideLabel>
Orange
</Checkbox>
<Checkbox value="Melon" hideLabel>
Melon
</Checkbox>
</CheckboxGroup>
<h2>Disabled</h2>
<CheckboxGroup legend="Mollit eiusmod" disabled>
<Checkbox value="Apple">Apple</Checkbox>
@@ -1,5 +1,5 @@
import { useContext } from "react";
import { CheckboxProps } from "../../index";
import { CheckboxProps } from "../..";
import { useFormField } from "../useFormField";
import { CheckboxGroupContext } from "./CheckboxGroup";
@@ -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."
);
@@ -3,13 +3,17 @@ import cl from "classnames";
import { Title } from "../..";
export interface ErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {
/**
* ErrorSummaryItems
*/
children: React.ReactNode;
/**
* Changes padding and font-sizes
* @default "m"
*/
size?: "m" | "s";
/**
* ErrorSummary heading above links
* Heading above links
*/
heading?: React.ReactNode;
/**
@@ -1,11 +1,14 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import { OverridableComponent } from "../../index";
import { OverridableComponent } from "../..";
export type ErrorType = OverridableComponent<ErrorSummaryItemProps>;
export interface ErrorSummaryItemProps {
props: {
/**
* Link text
*/
children: React.ReactNode;
} & React.HTMLAttributes<HTMLAnchorElement>;
defaultComponent: "a";
+10
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,
@@ -19,3 +25,7 @@ export {
} from "./error-summary";
export { Counter, default as Textarea, TextareaProps } from "./Textarea";
export { default as TextField, TextFieldProps } from "./TextField";
export {
default as ConfirmationPanel,
ConfirmationPanelProps,
} from "./ConfirmationPanel";
+1 -2
View File
@@ -1,6 +1,6 @@
import React, { forwardRef, InputHTMLAttributes } from "react";
import cl from "classnames";
import { BodyShort, omit } from "../../index";
import { BodyShort, omit } from "../..";
import ErrorMessage from "../ErrorMessage";
import { FormFieldProps } from "../useFormField";
import { useRadio } from "./useRadio";
@@ -12,7 +12,6 @@ export interface RadioProps
* Label for radio
*/
children: React.ReactNode;
className?: string;
value: string;
}
+12 -3
View File
@@ -1,7 +1,7 @@
import React, { forwardRef, useContext } from "react";
import cl from "classnames";
import { Fieldset, FieldsetContext, FieldsetProps } from "../index";
import useId from "../useId";
import { Fieldset, FieldsetContext, FieldsetProps } from "..";
import { useId } from "../..";
export interface RadioGroupContextProps {
name: string;
@@ -16,6 +16,13 @@ export const RadioGroupContext = React.createContext<RadioGroupContextProps | nu
);
export interface RadioGroupProps extends Omit<FieldsetProps, "onChange"> {
/**
* Collection of <Radio>-elements
*/
children: React.ReactNode;
/**
* Override internal name
*/
name?: string;
/**
* Default checked radiobutton
@@ -51,6 +58,8 @@ const RadioGroup = forwardRef<HTMLFieldSetElement, RadioGroupProps>(
) => {
const fieldset = useContext(FieldsetContext);
const nameId = useId();
return (
<Fieldset
{...rest}
@@ -63,7 +72,7 @@ const RadioGroup = forwardRef<HTMLFieldSetElement, RadioGroupProps>(
>
<RadioGroupContext.Provider
value={{
name: useId({ id: name, prefix: "RadioGroupName" }),
name: name ?? `radioGroupName-${nameId}`,
defaultValue,
value,
onChange,
@@ -0,0 +1,110 @@
import cl from "classnames";
import React, { forwardRef } from "react";
import { BodyShort, Label, omit } from "../..";
import ErrorMessage from "../ErrorMessage";
import { FormFieldProps, useFormField } from "../useFormField";
export interface SearchFieldContextProps {
inputProps: {
id: string;
"aria-invalid": boolean;
"aria-describedby"?: string;
disabled?: boolean;
};
size?: "m" | "s";
}
export const SearchFieldContext = React.createContext<SearchFieldContextProps | null>(
null
);
export interface SearchFieldProps
extends FormFieldProps,
React.HTMLAttributes<HTMLDivElement> {
/**
* SearchFieldInput & SearchFieldButton
*/
children: React.ReactNode;
/**
* If enabled shows the label and description for screenreaders only
*/
hideLabel?: boolean;
/**
* SearchField label
*/
label: React.ReactNode;
}
const SearchField = forwardRef<HTMLDivElement, SearchFieldProps>(
(props, ref) => {
const {
inputProps,
errorId,
showErrorMsg,
hasError,
size,
inputDescriptionId,
} = useFormField(props, "searchfield");
const {
className,
hideLabel,
children,
label,
description,
error,
...rest
} = props;
return (
<div
ref={ref}
{...omit(rest, ["id", "error", "errorId", "size", "disabled"])}
className={cl(
className,
"navds-form-field",
`navds-form-field--${size ?? "m"}`,
"navds-search-field",
{ "navds-search-field--error": hasError }
)}
>
<Label
htmlFor={inputProps.id}
size={size}
component="label"
className={cl("navds-text-field__label", {
"sr-only": hideLabel,
})}
>
{label}
</Label>
{!!description && (
<BodyShort
className={cl("navds-text-field__description", {
"sr-only": hideLabel,
})}
id={inputDescriptionId}
size={size}
>
{description}
</BodyShort>
)}
<div className="navds-search-field__input-wrapper">
<SearchFieldContext.Provider
value={{
inputProps,
size,
}}
>
{children}
</SearchFieldContext.Provider>
</div>
<div id={errorId} aria-relevant="additions removals" aria-live="polite">
{showErrorMsg && <ErrorMessage size={size}>{error}</ErrorMessage>}
</div>
</div>
);
}
);
export default SearchField;
@@ -0,0 +1,43 @@
import React, { forwardRef, useContext } from "react";
import cl from "classnames";
import { SearchFieldContext } from "./SearchField";
import { Button, ButtonProps } from "../..";
export interface SearchFieldButtonProps extends Omit<ButtonProps, "size"> {
/**
* Button text
* @example <Search /> <span>Søk</span>
*/
children: React.ReactNode;
/**
* Changes design and interactions
* @default "action"
*/
variant?: "primary" | "action";
}
const SearchFieldButton = forwardRef<HTMLButtonElement, SearchFieldButtonProps>(
({ className, variant = "action", disabled, ...rest }, ref) => {
const searchField = useContext(SearchFieldContext);
if (searchField === null) {
console.warn("SearchFieldButton has to be wrapped in <SearchField />");
return null;
}
const { size, inputProps } = searchField;
return (
<Button
ref={ref}
className={cl(className, "navds-search-field__button")}
{...rest}
size={size}
variant={variant}
disabled={disabled ?? inputProps?.disabled}
/>
);
}
);
export default SearchFieldButton;
@@ -0,0 +1,44 @@
import React, { forwardRef, useContext } from "react";
import cl from "classnames";
import { SearchFieldContext } from "./SearchField";
import { Button, ButtonProps } from "../..";
export interface SearchFieldClearButtonProps extends Omit<ButtonProps, "size"> {
/**
* Button text
* @example <Close /> <span>Søk</span>
*/
children: React.ReactNode;
/**
* Changes design and interactions
* @default "primary"
*/
variant?: "primary" | "action";
}
const SearchFieldClearButton = forwardRef<
HTMLButtonElement,
SearchFieldClearButtonProps
>(({ className, variant = "primary", disabled, ...rest }, ref) => {
const searchField = useContext(SearchFieldContext);
if (searchField === null) {
console.warn("SearchFieldClearButton has to be wrapped in <SearchField />");
return null;
}
const { size, inputProps } = searchField;
return (
<Button
ref={ref}
className={cl(className, "navds-search-field__button")}
{...rest}
size={size}
variant={variant}
disabled={disabled ?? inputProps?.disabled}
/>
);
});
export default SearchFieldClearButton;
@@ -0,0 +1,37 @@
import React, { forwardRef, InputHTMLAttributes, useContext } from "react";
import cl from "classnames";
import { SearchFieldContext } from "./SearchField";
export interface SearchFieldInputProps
extends InputHTMLAttributes<HTMLInputElement> {}
const SearchFieldInput = forwardRef<HTMLInputElement, SearchFieldInputProps>(
({ className, ...rest }, ref) => {
const searchField = useContext(SearchFieldContext);
if (searchField === null) {
console.warn("SearchFieldInput has to be wrapped in <SearchField />");
return null;
}
const { size, inputProps } = searchField;
return (
<input
{...rest}
{...inputProps}
ref={ref}
type="text"
className={cl(
className,
"navds-search-field__input",
"navds-text-field__input",
"navds-body-short",
`navds-body-${size ?? "m"}`
)}
/>
);
}
);
export default SearchFieldInput;
@@ -0,0 +1,13 @@
export { default as SearchField, SearchFieldProps } from "./SearchField";
export {
default as SearchFieldInput,
SearchFieldInputProps,
} from "./SearchFieldInput";
export {
default as SearchFieldButton,
SearchFieldButtonProps,
} from "./SearchFieldButton";
export {
default as SearchFieldClearButton,
SearchFieldClearButtonProps,
} from "./SearchFieldClearButton";
@@ -0,0 +1,31 @@
import React, { useState } from "react";
import { Close, Search } from "@navikt/ds-icons";
import {
SearchField,
SearchFieldInput,
SearchFieldButton,
SearchFieldClearButton,
} from "../index";
export const Example = () => {
const [value, setValue] = useState("");
return (
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
>
<SearchFieldInput
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<SearchFieldClearButton onClick={() => setValue("")}>
<Close />
<span>Tøm</span>
</SearchFieldClearButton>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
);
};
@@ -0,0 +1,206 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import {
SearchField,
SearchFieldInput,
SearchFieldButton,
SearchFieldClearButton,
} from "../index";
import { Example } from "./search-field-example.tsx";
import { Search } from "@navikt/ds-icons";
<Meta title="ds-react/form/search-field/intro" />
# Hvordan ta i bruk SearchField
## Viktig
Komponenten er ikke testet eller gått gjennom et design-review, så anbefalses og vente med å ta den i bruk.
## Bruk
```jsx
<SearchField label="Mollit eiusmod" description="Ea cupidatat eu sunt commodo">
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
```
<Canvas>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
</Canvas>
## hideLabel
`hideLabel` proppen kan brukes for å vise label + description for bare skjermlesere.
Vi har satt `label` som required siden man vil bruke den i sammenheng med denne proppen for bedre UU.
```jsx
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
```
<Canvas>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
</Canvas>
## Sizing
```jsx
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
size="s"
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
```
<Canvas>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
size="s"
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
</Canvas>
## Errors
```jsx
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
error="Error message"
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
```
<Canvas>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
error="Error message"
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
</Canvas>
## Plassering av knapp
```jsx
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
<SearchFieldInput />
</SearchField>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
```
<Canvas>
<div>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
<SearchFieldInput />
</SearchField>
<br />
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
</div>
</Canvas>
<h2>ClearButton</h2>
Man kan bruke `SearchFieldClearButton` for å håndtere clearing av value i `<input />`. For å bruke denne
kreves det da at `SearchFieldInput` er controlled slik at man styrer state selv slik som eksemplet under.
```jsx
<SearchField label="Mollit eiusmod" description="Ea cupidatat eu sunt commodo">
<SearchFieldInput value={value} onChange={(e) => setValue(e.target.value)} />
<SearchFieldClearButton onClick={() => setValue("")}>
<Close />
<span>Tøm</span>
</SearchFieldClearButton>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
```
<Canvas>
<Example />
</Canvas>
@@ -0,0 +1,147 @@
import React from "react";
import { Meta } from "@storybook/react/types-6-0";
import { Close, Search } from "@navikt/ds-icons";
import {
SearchField,
SearchFieldInput,
SearchFieldButton,
SearchFieldClearButton,
} from "../index";
import { Fieldset } from "../..";
export default {
title: "ds-react/form/search-field",
component: SearchField,
} as Meta;
export const All = () => {
return (
<>
<h1>SearchField</h1>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
<SearchFieldInput />
</SearchField>
<h1>SearchField w clearsearch</h1>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
>
<SearchFieldInput clearSearch />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
<SearchFieldClearButton>
<Close /> <span>Tøm</span>
</SearchFieldClearButton>
<SearchFieldInput />
</SearchField>
<h2>Hidelabel</h2>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
<SearchFieldInput />
</SearchField>
<h2>SearchField small</h2>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
size="s"
>
<SearchFieldButton>
<Search />
<span className="sr-only">Søk</span>
</SearchFieldButton>
<SearchFieldInput />
</SearchField>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
size="s"
>
<SearchFieldInput />
<SearchFieldButton>
<Search />
<span className="sr-only">Søk</span>
</SearchFieldButton>
</SearchField>
<h2>SearchField w error</h2>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
error="Errormsg"
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
error="Errormsg"
>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
<SearchFieldInput />
</SearchField>
<h2>SearchField in Fieldset</h2>
<Fieldset legend="Filter" error="Fieldset-error-msg">
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
error="Errormsg"
hideLabel
>
<SearchFieldInput />
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
</SearchField>
<SearchField
label="Mollit eiusmod"
description="Ea cupidatat eu sunt commodo"
hideLabel
>
<SearchFieldButton>
<Search /> <span>Søk</span>
</SearchFieldButton>
<SearchFieldInput />
</SearchField>
</Fieldset>
</>
);
};
@@ -0,0 +1,59 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import { ConfirmationPanelExample } from "./live-examples";
<Meta title="ds-react/form/confirmation-panel/intro" />
# Hvordan ta i bruk ConfirmationPanel
```jsx
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
>
Ipsum voluptate pariatur <Link href="#123">demolink</Link> anim officia minim
ut mollit voluptate exercitation nulla mollit.
</ConfirmationPanel>
```
<Canvas>
<ConfirmationPanelExample />
</Canvas>
## Størrelser
Kommer i størrelsene "m" og "s".
```jsx
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
size="s"
>
Ipsum voluptate pariatur <Link href="#123">demolink</Link> anim officia minim
ut mollit voluptate exercitation nulla mollit.
</ConfirmationPanel>
```
<Canvas>
<ConfirmationPanelExample size="s" />
</Canvas>
## Errors
```jsx
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
error="Laborum enim esse quis"
>
Ipsum voluptate pariatur <Link href="#123">demolink</Link> anim officia minim
ut mollit voluptate exercitation nulla mollit.
</ConfirmationPanel>
```
<Canvas>
<ConfirmationPanelExample error="Laborum enim esse quis" />
</Canvas>
@@ -0,0 +1,62 @@
import React, { useState } from "react";
import { ConfirmationPanel } from "../index";
import { Meta } from "@storybook/react/types-6-0";
import { Link } from "../..";
export default {
title: "ds-react/form/confirmation-panel",
component: ConfirmationPanel,
} as Meta;
export const All = () => {
const [checked, setChecked] = useState(false);
return (
<div>
<h1>ConfirmationPanel</h1>
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
>
Ipsum voluptate pariatur <Link href="#123">testlink</Link> anim officia
minim ut mollit voluptate exercitation nulla mollit.
</ConfirmationPanel>
<h2>size s</h2>
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
size="s"
>
Ipsum voluptate pariatur <Link href="#123">testlink</Link> anim officia
minim ut mollit voluptate exercitation nulla mollit.
</ConfirmationPanel>
<h3>error</h3>
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
error="Ex cupidatat do do do"
>
Ipsum voluptate pariatur <Link href="#123">testlink</Link> anim officia
minim ut mollit voluptate exercitation nulla mollit.
</ConfirmationPanel>
<h3>error small</h3>
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
error="Ex cupidatat do do do"
size="s"
>
Ipsum voluptate pariatur <Link href="#123">testlink</Link> anim officia
minim ut mollit voluptate exercitation nulla mollit.
</ConfirmationPanel>
<h2>Empty</h2>
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
></ConfirmationPanel>
</div>
);
};
@@ -0,0 +1,75 @@
import React, { useState } from "react";
import { Fieldset } from "../index";
import { Meta } from "@storybook/react/types-6-0";
import { Button, Checkbox, CheckboxGroup } from "../../index";
export default {
title: "ds-react/form/uu-demo",
component: Fieldset,
} as Meta;
export const Demo1 = () => {
const [error, setError] = useState(undefined);
const [fieldsetError, setFieldsetError] = useState(undefined);
const [groupError, setGroupError] = useState(undefined);
const [propagation, setPropagation] = useState(true);
return (
<div>
<h1>Nested-erros + aria-describedby</h1>
<div>
<Button
style={{ marginBottom: "2rem" }}
onClick={() => {
!!fieldsetError
? setFieldsetError(undefined)
: setFieldsetError("Fieldset error message");
}}
>
Toggle fieldset-error
</Button>
<Button
style={{ marginBottom: "2rem" }}
onClick={() => {
!!groupError
? setGroupError(undefined)
: setGroupError("CheckboxGroup error message");
}}
>
Toggle checkboxgroup-error
</Button>
<Button
style={{ marginBottom: "2rem" }}
onClick={() => {
!!error ? setError(undefined) : setError("Textfield error message");
}}
>
Toggle checkbox-error
</Button>
<Button
style={{ marginBottom: "2rem" }}
onClick={() => setPropagation(!propagation)}
>
Toggle errorPropagation
</Button>
</div>
<Fieldset
errorId="FIELDSET-ERROR"
legend="Mollit eiusmod"
error={fieldsetError}
>
<CheckboxGroup
errorId="GROUP-ERROR"
errorPropagation={propagation}
error={groupError}
legend="checkboxgroup"
hideLegend
>
<Checkbox>Checkbox nr 1</Checkbox>
<Checkbox errorId="CHECKBOX-ERROR" error={error}>
Checkbox nr 2
</Checkbox>
<Checkbox>Checkbox nr 3</Checkbox>
</CheckboxGroup>
</Fieldset>
</div>
);
};
@@ -0,0 +1,26 @@
import React, { useState } from "react";
import { ConfirmationPanel } from "..";
import { Link } from "../..";
export const ConfirmationPanelExample = ({
size = "m",
error,
}: {
size: "m" | "s";
error?: string;
}) => {
const [checked, setChecked] = useState(false);
return (
<ConfirmationPanel
checked={checked}
onChange={() => setChecked(!checked)}
label="Checkbox label text"
size={size}
error={error}
>
Ipsum voluptate pariatur <Link href="#123">demolink</Link> anim officia
minim ut mollit voluptate exercitation nulla mollit.
</ConfirmationPanel>
);
};
+27 -5
View File
@@ -1,28 +1,48 @@
import { useContext } from "react";
import cl from "classnames";
import { FieldsetContext } from "./index";
import useId from "./useId";
import { useId } from "../index";
export interface FormFieldProps {
/**
* Error message for element
*/
error?: React.ReactNode;
/**
* Override internal errorId
*/
errorId?: string;
/**
* Changes font-size, padding and gaps
*/
size?: "m" | "s";
/**
* Disables element
*/
disabled?: boolean;
/**
* Adds a description to extend labling of a field
*/
description?: React.ReactNode;
/**
* Override internal id
*/
id?: string;
}
/**
* Handles props and their state for various form-fields in context with Fieldset
*/
export const useFormField = (props: FormFieldProps, prefix?: string) => {
export const useFormField = (props: FormFieldProps, prefix: string) => {
const { size, error, errorId: propErrorId } = props;
const fieldset = useContext(FieldsetContext);
const id = useId({ id: props.id, prefix: prefix ?? "" });
const errorId = useId({ id: propErrorId, prefix: prefix + "Error" ?? "" });
const inputDescriptionId = useId({ prefix: prefix + "Description" });
const genId = useId();
const id = props.id ?? `${prefix}-${genId}`;
const errorId = propErrorId ?? `${prefix}-error-${genId}`;
const inputDescriptionId = `${prefix}-description-${genId}`;
const disabled = fieldset?.disabled || props.disabled;
const hasError: boolean = !disabled && !!(error || fieldset?.error);
@@ -40,6 +60,8 @@ export const useFormField = (props: FormFieldProps, prefix?: string) => {
"aria-describedby":
cl(props["aria-describedby"], {
[inputDescriptionId]: !!props?.description,
[errorId]: showErrorMsg,
[fieldset?.errorId ?? ""]: hasError && !!fieldset?.error,
}) || undefined,
disabled,
},
-15
View File
@@ -1,15 +0,0 @@
import { useEffect, useState } from "react";
import ShortUuid from "short-uuid";
const useId = (props?: { id?: string; prefix?: string }): string => {
const { id = null, prefix = "" } = props ? props : {};
const [localId, setlocalId] = useState<string>("");
useEffect(() => {
setlocalId(`${prefix}-${ShortUuid.generate()}`);
}, [prefix]);
return id ?? localId;
};
export default useId;
+1 -5
View File
@@ -4,11 +4,7 @@ import cl from "classnames";
type Column = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
export interface CellProps extends HTMLAttributes<HTMLDivElement> {
/**
* @ignore
*/
className?: string;
/**
* Component content
* Cell content
*/
children?: React.ReactNode;
/**
+1 -5
View File
@@ -3,13 +3,9 @@ import cl from "classnames";
export interface GridProps extends HTMLAttributes<HTMLDivElement> {
/**
* Component content
* Collection of <Cell>-elements
*/
children: React.ReactNode;
/**
* @ignore
*/
className?: string;
}
const Grid = forwardRef<HTMLDivElement, GridProps>(
({ children, className, ...rest }, ref) => (
-4
View File
@@ -6,10 +6,6 @@ export interface HeaderProps extends HTMLAttributes<HTMLDivElement> {
* Header title
*/
children: string;
/**
* @ignore
*/
className?: string;
/**
* Pictogram placed in header
*/
-2
View File
@@ -1,5 +1,4 @@
export * from "./accordion";
export * from "./accordion-anchor-menu";
export * from "./accordion-menu";
export * from "./alert";
export * from "./button";
@@ -10,7 +9,6 @@ export * from "./form";
export * from "./grid";
export * from "./header";
export * from "./internal-header";
export * from "./layouts";
export * from "./link";
export * from "./link-panel";
export * from "./loader";
@@ -6,10 +6,6 @@ export interface InternalHeaderProps extends HTMLAttributes<HTMLElement> {
* Component content
*/
children?: React.ReactNode;
/**
* @ignore
*/
className?: string;
}
const InternalHeader = forwardRef<HTMLElement, InternalHeaderProps>(
@@ -6,10 +6,6 @@ export interface InternalHeaderTitleProps extends HTMLAttributes<HTMLElement> {
* Component content
*/
children?: React.ReactNode;
/**
* @ignore
*/
className?: string;
/**
* Tag this component will use. Usefull for defining a button/link
* @default "h1"
@@ -3,10 +3,6 @@ import cl from "classnames";
export interface InternalHeaderUserProps
extends HTMLAttributes<HTMLDivElement> {
/**
* @ignore
*/
className?: string;
/**
* user name
*/
-3
View File
@@ -1,3 +0,0 @@
export { default as ProductPageLayout } from "./product-page/ProductPageLayout";
export { default as ProductPagePanel } from "./product-page/ProductPagePanel";
export { default as ProductPageSection } from "./product-page/ProductPageSection";
@@ -1,61 +0,0 @@
import cl from "classnames";
import React, { Children, forwardRef, HTMLAttributes, useEffect } from "react";
import { ContentContainer, Title } from "../../index";
const cls = (className, columns) =>
cl(
"navds-layout__container",
`navds-layout__container--${columns}-columns`,
className
);
export interface ProductPageLayoutProps extends HTMLAttributes<HTMLElement> {
title: string;
children?: React.ReactNode;
className?: string;
}
const ProductPageLayout = forwardRef<HTMLDivElement, ProductPageLayoutProps>(
({ children, title, className, ...rest }, ref) => {
const columns = Children.toArray(children).length;
useEffect(() => {
const layoutBody = document.getElementById("navds-layout-body");
layoutBody?.classList.add(`navds-layout__body--${columns}-columns`);
document.body.classList.add("navds-layout__body--white");
return () => {
layoutBody?.classList.remove(`navds-layout__body--${columns}-columns`);
document.body.classList.remove("navds-layout__body--white");
};
}, [columns]);
return (
<div ref={ref}>
<div id={"navds-layout-header"} className={"navds-layout__header"}>
<ContentContainer>
<div className={cls(className, columns)} {...rest}>
<div className={cl("navds-layout__header-content")}>
<Title
size="2xl"
className={cl("navds-layout__header-title")}
level={1}
>
{title}
</Title>
</div>
</div>
</ContentContainer>
</div>
<div id={"navds-layout-body"} className={"navds-layout__body"}>
<ContentContainer>
<div className={cls(className, columns)} {...rest}>
{children}
</div>
</ContentContainer>
</div>
</div>
);
}
);
export default ProductPageLayout;
@@ -1,73 +0,0 @@
import React, { useEffect, useRef } from "react";
import { forwardRef, ReactNode } from "react";
import cl from "classnames";
import { Title, CopyToClipboard } from "../../";
import { Attachment } from "@navikt/ds-icons";
export interface ProductPagePanelProps
extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
anchor: string;
className?: string;
title: string;
icon?: ReactNode;
highlight?: boolean;
whiteBackground?: boolean;
}
const ProductPagePanel = forwardRef<HTMLDivElement, ProductPagePanelProps>(
({ children, className, title, highlight, icon, anchor, ...rest }, ref) => {
const copyRef = useRef(null);
useEffect(() => {
const header = document.getElementById("navds-layout-body");
header?.classList.add("navds-layout__body--padding");
}, []);
const getLink = () => {
const { href, hash } = window.location;
const urlWithoutHash = href.replace(hash, "");
return `${urlWithoutHash}#${anchor}`;
};
return (
<div
ref={ref}
className={cl(
"navds-layout__panel",
icon && "navds-layout__panel--icon-margin",
highlight && "navds-layout__panel--highlight",
className
)}
{...rest}
>
<div className="navds-layout__panel-anchor">
<div
id={anchor}
className={cl("navds-layout__panel-anchor--child", {
"navds-layout__panel-anchor--child--icon": !!icon,
})}
/>
</div>
{icon && <div className={"navds-layout__panel-icon"}>{icon}</div>}
<Title size={"xl"} className={"navds-layout__panel-title"} level={2}>
{title}
</Title>
<CopyToClipboard
className="navds-layout__panel-copy"
ref={copyRef}
text={getLink()}
label="Kopierte lenke til panel"
icon={<Attachment />}
>
Kopier lenke
</CopyToClipboard>
<div className={"navds-layout__panel-content"}>{children}</div>
</div>
);
}
);
export default ProductPagePanel;
@@ -1,46 +0,0 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
export interface ProductPageSectionProps
extends HTMLAttributes<HTMLDivElement> {
left?: boolean;
right?: boolean;
whiteBackground?: boolean;
withPadding?: boolean;
sticky?: boolean;
}
const ProductPageSection = forwardRef<HTMLDivElement, ProductPageSectionProps>(
(
{
left,
right,
children,
whiteBackground = true,
withPadding = true,
sticky,
className,
...rest
},
ref
) => (
<div
ref={ref}
className={cl(
"navds-layout__section",
left && "navds-layout__section--left",
right && "navds-layout__section--right",
!left && !right && "navds-layout__section--main",
whiteBackground && "navds-layout__section--white",
withPadding && "navds-layout__section--padding",
sticky && "navds-layout__section--sticky",
className
)}
{...rest}
>
{children}
</div>
)
);
export default ProductPageSection;
@@ -1,22 +0,0 @@
import * as React from "react";
import { Button, Link } from "../../../../index";
export const Left = () => (
<ul className={"navds-story-menu"}>
<li>
<Link href={"#leo-quis"}>Leo quis</Link>
</li>
<li>
<Link href={"#proin-accumsan"}>Proin accumsan</Link>
</li>
<li>
<Link href={"#nulla-pariatur"}>Nulla pariatur?</Link>
</li>
<li>
<Link href={"#maecenas-in-pretium"}>Maecenas in pretium</Link>
</li>
<li>
<Button>Søk ...</Button>
</li>
</ul>
);
@@ -1,133 +0,0 @@
import * as React from "react";
import { Button, Cell, Grid, Title, Link, BodyLong } from "../../../../index";
export const Main = ({ title = true }) => (
<>
<MainOne title={title} />
<MainTwo title={title} />
<MainThree title={title} />
</>
);
export const MainOne = ({ title = true }) => (
<div>
{title && (
<Title level={1} size={"xl"} id={"leo-quis"}>
Leo quis
</Title>
)}
<BodyLong>
Sed ullamcorper quam eget lorem volutpat, quis cursus risus fermentum.
Quisque varius ornare nulla, ut condimentum sapien dapibus non. Nullam
eget interdum nibh
</BodyLong>
</div>
);
export const MainTwo = ({ title = true }) => (
<div>
{title && (
<Title level={1} size={"xl"} id={"proin-accumsan"}>
Proin accumsan
</Title>
)}
<BodyLong className={"section"}>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo
inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
</BodyLong>
<Grid className={"section"}>
<Cell xs={6}>
<Link href={"#"}>Ea voluptate</Link>
</Cell>
<Cell xs={6}>
<Link href={"#"}>Quis autem</Link>
</Cell>
</Grid>
<BodyLong className={"section"}>
Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet,
consectetur, adipisci velit, sed quia non numquam eius modi tempora.
</BodyLong>
<Title level={2} size={"l"} id={"nulla-pariatur"}>
Nulla pariatur?
</Title>
<BodyLong className={"section"}>
Etiam viverra neque sit amet libero dapibus tincidunt. Pellentesque quis
imperdiet erat. Morbi sodales bibendum volutpat.
</BodyLong>
<table className={"section tabell tabell--stripet"}>
<thead>
<tr>
<th>ID</th>
<th>Fornavn</th>
<th>Etternavn</th>
<th>Rolle</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Jean-Luc</td>
<td>Picard</td>
<td>Kaptein</td>
</tr>
<tr>
<td>2</td>
<td>William</td>
<td>Riker</td>
<td>Kommandør</td>
</tr>
<tr>
<td>3</td>
<td>Geordi</td>
<td>La Forge</td>
<td>Sjefsingeniør</td>
</tr>
</tbody>
</table>
<BodyLong className={"section"}>
Curabitur a purus pretium, condimentum magna ac, pellentesque diam. Nulla
facilisi. Nullam consequat, dui sed bibendum faucibus, metus mauris
commodo tortor.
</BodyLong>
<Title level={2} size={"l"} id={"luctus-justo"}>
Luctus justo
</Title>
<BodyLong className={"section"}>
Nunc eget consectetur felis, id scelerisque sapien. Ut id feugiat nulla,
ut cursus sem. In viverra felis vitae aliquet finibus.
</BodyLong>
<Button>Søk ...</Button>
</div>
);
export const MainThree = ({ title = true }) => (
<div>
{title && (
<Title level={1} size={"xl"} id={"maecenas-in-pretium"}>
Maecenas in pretium
</Title>
)}
<BodyLong>
Sed ullamcorper quam eget lorem volutpat, quis cursus risus fermentum.
Quisque varius ornare nulla, ut condimentum sapien dapibus non. Nullam
eget interdum nibh
</BodyLong>
<BodyLong>
Cras tempor eros sed dapibus egestas. Curabitur bibendum quam quis lectus
pretium lacinia. Nunc consequat ac augue quis laoreet. Donec porta, erat
vitae blandit egestas, arcu metus pharetra nulla, et laoreet risus purus
convallis turpis.
</BodyLong>
<BodyLong>
Suspendisse potenti. Praesent at elit interdum, porttitor sem eget,
blandit dolor. Nunc eget consectetur felis, id scelerisque sapien. Ut id
feugiat nulla, ut cursus sem. In viverra felis vitae aliquet finibus.
</BodyLong>
<BodyLong>
Vivamus id mi lectus. Duis ac augue magna. Aliquam ut euismod dui. Duis
consectetur, magna a malesuada tempus, elit urna fermentum arcu, at
porttitor magna sapien id enim.
</BodyLong>
</div>
);
@@ -1,8 +0,0 @@
import * as React from "react";
import { Accordion } from "../../../../index";
export const Right = () => (
<div>
<Accordion heading={"Snareveier"}>Test</Accordion>
</div>
);
@@ -1,12 +0,0 @@
.navds-story-menu {
margin: 0;
list-style-type: none;
}
.navds-story-menu li:not(:last-child) {
margin-bottom: 1rem;
}
.navds-story-section {
margin-bottom: 1rem;
}
@@ -1,8 +0,0 @@
import { Meta, Canvas } from "@storybook/addon-docs";
<Meta title="ds-react/layouts/intro" />
# Layouts
Komponenten og storybook-stories her er utdaterte og anbefales ikke å bruke, før
react-pakken er publisert så kommer disse til å forgå store endringer og evt fjernes fra pakken.
@@ -1,90 +0,0 @@
import * as React from "react";
import {
ProductPageLayout as Layout,
ProductPageSection as Section,
ProductPagePanel as Panel,
} from "../../index";
import { Left } from "./components/sections/Left";
import { Main, MainOne, MainTwo, MainThree } from "./components/sections/Main";
import { Right } from "./components/sections/Right";
import { LightBulb, Telephone } from "@navikt/ds-icons";
import "./components/styles.css";
export default {
title: "ds-react/layouts/ProductPage",
component: Layout,
parameters: {
layout: "fullscreen",
},
};
const title = "Nunc et lorem";
export const ThreeColumns = () => (
<Layout title={title}>
<Section left sticky>
<Left />
</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 TwoColumnsLeft = () => (
<Layout title={title}>
<Section left sticky>
<Left />
<Left />
</Section>
<Section>
<Panel
title={"Leo quis"}
anchor={"leo-quis"}
highlight={true}
icon={<LightBulb />}
>
<MainOne title={false} />
</Panel>
<Main />
</Section>
</Layout>
);
export const TwoColumnsRight = () => (
<Layout title={title}>
<Section>
<Main />
</Section>
<Section right sticky>
<Right />
</Section>
</Layout>
);
export const OneColumn = () => (
<Layout title={title}>
<Section>
<Main />
</Section>
</Layout>
);
@@ -1,6 +1,6 @@
import React, { forwardRef } from "react";
import { OverridableComponent } from "../util";
import { Panel } from "../index";
import { Panel } from "..";
import { Next } from "@navikt/ds-icons";
import cl from "classnames";
@@ -8,9 +8,13 @@ export type LinkPanelType = OverridableComponent<LinkPanelProps>;
export interface LinkPanelProps {
props: {
/**
* Panel content
*/
children?: React.ReactNode;
className?: string;
noHeading?: boolean;
/**
* Toggles border on panel
*/
border?: boolean;
} & React.HTMLAttributes<HTMLAnchorElement>;
defaultComponent: "a";
+1 -5
View File
@@ -4,13 +4,9 @@ import cl from "classnames";
export interface LinkProps
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
/**
* Component content
* Link text
*/
children: React.ReactNode;
/**
* @ignore
*/
className?: string;
/**
* Link anchor should direct to
*/
@@ -1,6 +1,8 @@
import React from "react";
import { Link } from "../index";
import { Alert } from "../..";
import { Link } from "..";
import { Add } from "@navikt/ds-icons";
import { ConfirmationPanel } from "../../form";
export default {
title: "ds-react/link",
component: Link,
@@ -11,16 +13,41 @@ export const All = () => {
<>
<h1>Link</h1>
<Link href="#">Dette er en tekstlenke</Link>
<h1>Icon after</h1>
<h2>Icon after</h2>
<Link href="#">
<span>Dette er en tekstlenke</span>
<Add />
</Link>
<h1>Icon before</h1>
<h2>Icon before</h2>
<Link href="#">
<Add />
<span>Dette er en tekstlenke </span>
</Link>
<h2>På farget bakgrunn</h2>
<Alert variant="error">
Her er en <Link href="#about">lenke</Link> på farget bakgrunn
</Alert>
<Alert variant="info">
Her er en <Link href="#about">lenke</Link> på farget bakgrunn
</Alert>
<Alert variant="success">
Her er en <Link href="#about">lenke</Link> på farget bakgrunn
</Alert>
<Alert variant="warning">
Her er en <Link href="#about">lenke</Link> på farget bakgrunn
</Alert>
<ConfirmationPanel label="Samtykke?" checked={false} error="feilmelding">
Her er en <Link href="#about">lenke</Link> på farget bakgrunn
</ConfirmationPanel>
<ConfirmationPanel label="Samtykke?" checked error="feilmelding">
Her er en <Link href="#about">lenke</Link> på farget bakgrunn
</ConfirmationPanel>
<ConfirmationPanel label="Samtykke?" checked={false}>
Her er en <Link href="#about">lenke</Link> på farget bakgrunn
</ConfirmationPanel>
<ConfirmationPanel label="Samtykke?" checked>
Her er en <Link href="#about">lenke</Link> på farget bakgrunn
</ConfirmationPanel>
</>
);
};
+5 -9
View File
@@ -1,12 +1,8 @@
import React, { forwardRef, SVGProps, useRef } from "react";
import React, { forwardRef, SVGProps } from "react";
import cl from "classnames";
import { v4 as uuidv4 } from "uuid";
import { useId } from "..";
export interface LoaderProps extends SVGProps<SVGSVGElement> {
/**
* @ignore
*/
className?: string;
/**
* Changes sizing
* 64px | 40px | 32px | 24px | 20px | 16px
@@ -43,11 +39,11 @@ const Loader = forwardRef<SVGSVGElement, LoaderProps>(
},
ref
) => {
const internalId = useRef(uuidv4());
const internalId = useId(id);
return (
<svg
aria-labelledby={id ?? internalId.current}
aria-labelledby={internalId}
ref={ref}
className={cl("navds-loader", className, `navds-loader--${size}`, {
"navds-loader--transparent": transparent,
@@ -60,7 +56,7 @@ const Loader = forwardRef<SVGSVGElement, LoaderProps>(
preserveAspectRatio="xMidYMid"
{...rest}
>
<title id={id ?? internalId.current}>{title}</title>
<title id={internalId}>{title}</title>
<circle
className="navds-loader__background"
xmlns="http://www.w3.org/2000/svg"
Loaded 100 of 289 files, more files were not shown because too many files have changed in this diff. Show more