mirror of
https://github.com/navikt/aksel.git
synced 2026-10-13 01:02:02 +00:00
Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1053ca7dca | ||
|
|
25c186473b | ||
|
|
7ea6c9c0f1 | ||
|
|
a6014bb409 | ||
|
|
f60ff3a8c9 | ||
|
|
8d8425acfb | ||
|
|
ce086d890f | ||
|
|
5e9ef5fbd3 | ||
|
|
21958012a2 | ||
|
|
fa0307ec15 | ||
|
|
69c32e4036 | ||
|
|
9a9e265831 | ||
|
|
fb37c6135f | ||
|
|
09259ef960 | ||
|
|
2b0753e4a6 | ||
|
|
471e9b19ee | ||
|
|
86b7b8e406 | ||
|
|
563942947d | ||
|
|
c9adb83158 | ||
|
|
bf079796f3 | ||
|
|
a1f4f0fe28 | ||
|
|
f146c0c57c | ||
|
|
fd397b03e5 | ||
|
|
2a66f1ec6e | ||
|
|
2853e5cd94 | ||
|
|
8a068e787d | ||
|
|
f8fbf6c3a8 | ||
|
|
6da78d13a3 |
No files matched your search
@@ -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,10 +66,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 --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]"
|
||||
@@ -78,8 +78,15 @@ jobs:
|
||||
NAV_DS_TOKEN: ${{secrets.GIT_REPO}}
|
||||
- run: yarn lerna version patch --include-merged-tags --yes
|
||||
- run: yarn lerna publish from-package --yes
|
||||
- name: Create a .npmrc file for the github package repository
|
||||
uses: FerLuisxd/create-npmrc@3
|
||||
with:
|
||||
org_name: navikt
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_AUTOMATION}}
|
||||
AUTH_TOKEN: ${{secrets.GIT_REPO}}
|
||||
- run: rm lerna.json && cp utilities/lerna.json lerna.json
|
||||
- run: git add . && git commit -m "tmp"
|
||||
- run: yarn lerna publish --registry https://npm.pkg.github.com from-package --yes
|
||||
|
||||
publish-pages:
|
||||
needs: publish-npm
|
||||
@@ -122,7 +129,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}}
|
||||
|
||||
@@ -41,6 +41,7 @@ typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
.npmrc
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
};
|
||||
@@ -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.
|
||||
@@ -0,0 +1,3 @@
|
||||
# Designsystem v2
|
||||
|
||||
Storybook: https://navikt.github.io/Designsystemet/
|
||||
@@ -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);
|
||||
}
|
||||
@@ -13,3 +13,4 @@
|
||||
@import "select.css";
|
||||
@import "text-field.css";
|
||||
@import "textarea.css";
|
||||
@import "search-field.css";
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "0.6.19",
|
||||
"version": "0.6.21",
|
||||
"private": false,
|
||||
"description": "Css for NAV Designsystem components",
|
||||
"author": "NAV Designsystem team",
|
||||
|
||||
@@ -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.
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.5",
|
||||
"private": false,
|
||||
"description": "NAV designsystem react components",
|
||||
"author": "NAV Designsystem team",
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import { AccordionMenu as BaseAccordionMenu } from "../accordion-menu";
|
||||
import { Title } from "..";
|
||||
import { ActiveAnchorProvider } from "./ActiveAnchorStore";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface AccordionAnchorMenuProps
|
||||
extends HTMLAttributes<HTMLDivElement> {
|
||||
title?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const AccordionAnchorMenu = forwardRef<
|
||||
HTMLDivElement,
|
||||
AccordionAnchorMenuProps
|
||||
>(({ children, title, className, ...rest }, ref) => (
|
||||
<div
|
||||
className={cl("navds-accordion-anchor-menu", className)}
|
||||
ref={ref}
|
||||
{...rest}
|
||||
>
|
||||
{title && (
|
||||
<Title level={2} size="m" className="navds-accordion-anchor-menu__title">
|
||||
{title}
|
||||
</Title>
|
||||
)}
|
||||
<ActiveAnchorProvider>
|
||||
<BaseAccordionMenu aria-label={title || "Meny"}>
|
||||
{children}
|
||||
</BaseAccordionMenu>
|
||||
</ActiveAnchorProvider>
|
||||
</div>
|
||||
));
|
||||
|
||||
export default AccordionAnchorMenu;
|
||||
@@ -1 +0,0 @@
|
||||
export { AccordionMenuCollapsable as AccordionAnchorMenuCollapsable } from "../accordion-menu";
|
||||
@@ -1,39 +0,0 @@
|
||||
import React, { forwardRef, useEffect } from "react";
|
||||
import { AccordionMenuItem, AccordionMenuItemType } from "../accordion-menu";
|
||||
import { useStore } from "./ActiveAnchorStore";
|
||||
|
||||
const AccordionAnchorMenuItem: AccordionMenuItemType = forwardRef(
|
||||
(props, ref) => {
|
||||
const isAnchorActive = useIsAnchorActive(
|
||||
props.href && props.href.split("#")[1]
|
||||
);
|
||||
|
||||
return (
|
||||
<AccordionMenuItem
|
||||
{...props}
|
||||
ref={ref}
|
||||
active={props.active || isAnchorActive}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const useIsAnchorActive = (anchor: string | undefined) => {
|
||||
const { activeAnchor, registerAnchor, unregisterAnchor } = useStore();
|
||||
|
||||
useEffect(() => {
|
||||
if (anchor) {
|
||||
const target = document.getElementById(anchor);
|
||||
if (target) {
|
||||
registerAnchor(anchor);
|
||||
return () => {
|
||||
unregisterAnchor(anchor);
|
||||
};
|
||||
}
|
||||
}
|
||||
}, [anchor, registerAnchor, unregisterAnchor]);
|
||||
|
||||
return (anchor && activeAnchor === anchor) || false;
|
||||
};
|
||||
|
||||
export default AccordionAnchorMenuItem;
|
||||
@@ -1,73 +0,0 @@
|
||||
import React, {
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
} from "react";
|
||||
|
||||
export interface ActiveAnchorStore {
|
||||
activeAnchor?: string;
|
||||
registerAnchor: (anchor: string) => void;
|
||||
unregisterAnchor: (anchor: string) => void;
|
||||
}
|
||||
|
||||
export const ActiveAnchorContext = createContext({} as ActiveAnchorStore);
|
||||
export const ActiveAnchorProvider = ({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
const [anchors, setAnchors] = useState<string[]>([]);
|
||||
const [activeAnchor, setActiveAnchor] = useState<string>();
|
||||
|
||||
useEffect(() => {
|
||||
const scrollListener = () => {
|
||||
const offset = 100;
|
||||
const lastPassedAnchor = anchors
|
||||
.map((anchor) => document.getElementById(anchor) as HTMLElement)
|
||||
.map((element: HTMLElement) => ({
|
||||
id: element.id,
|
||||
top: element.getBoundingClientRect().top - offset,
|
||||
scrolledToBottom:
|
||||
window.innerHeight + window.pageYOffset >=
|
||||
document.body.offsetHeight,
|
||||
}))
|
||||
.filter((element) => element.scrolledToBottom || element.top <= 0)
|
||||
.sort((a, b) => (a.top < b.top ? -1 : 1))
|
||||
.map((anchor) => anchor.id)
|
||||
.pop();
|
||||
|
||||
// Set active anchor and related url hash
|
||||
if (lastPassedAnchor && activeAnchor !== lastPassedAnchor) {
|
||||
const { href, hash } = window.location;
|
||||
const urlWithoutHash = href.replace(hash, "");
|
||||
const urlWithAnchor = `${urlWithoutHash}#${lastPassedAnchor}`;
|
||||
const title = document.title;
|
||||
window.history.replaceState(window.history.state, title, urlWithAnchor);
|
||||
setActiveAnchor(lastPassedAnchor);
|
||||
}
|
||||
};
|
||||
window.addEventListener("scroll", scrollListener);
|
||||
return () => {
|
||||
window.removeEventListener("scroll", scrollListener);
|
||||
};
|
||||
}, [anchors, activeAnchor]);
|
||||
|
||||
return (
|
||||
<ActiveAnchorContext.Provider
|
||||
value={{
|
||||
activeAnchor,
|
||||
registerAnchor: useCallback((anchor) => {
|
||||
setAnchors((anchors) => [...anchors, anchor]);
|
||||
}, []),
|
||||
unregisterAnchor: useCallback((anchor) => {
|
||||
setAnchors((anchors) => anchors.filter((a) => a !== anchor));
|
||||
}, []),
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ActiveAnchorContext.Provider>
|
||||
);
|
||||
};
|
||||
export const useStore = () => useContext(ActiveAnchorContext);
|
||||
@@ -1,3 +0,0 @@
|
||||
export { default as AccordionAnchorMenu } from "./AccordionAnchorMenu";
|
||||
export { AccordionAnchorMenuCollapsable } from "./AccordionAnchorMenuCollapsable";
|
||||
export { default as AccordionAnchorMenuItem } from "./AccordionAnchorMenuItem";
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Meta, Canvas } from "@storybook/addon-docs";
|
||||
import { AccordionAnchorMenu } from "../../index";
|
||||
import { Success } from "@navikt/ds-react";
|
||||
|
||||
<Meta title="ds-react/accordion-anchor-menu/intro" />
|
||||
|
||||
# AccordionAnchorMenu
|
||||
|
||||
NOTE: Komponenten er ikke oppdatert og er veldig buggy. Ville ungått bruk av denne om mulig og bare brukt
|
||||
vanlig `AccordionMenu`. Hvorvidt vi kommer til å oppdatere denne og ta den med i 1.0 er usikkert.
|
||||
|
||||
`AccordionAnchorMenu` er en meny-komponent som implementerer `AccordionMenu` med context
|
||||
for lytting på aktiv anchor/heading. Dette vil si at active-state settes automatisk.
|
||||
når man scroller forbi den relevante linken på siden.
|
||||
@@ -1,125 +0,0 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
AccordionAnchorMenu as Menu,
|
||||
AccordionAnchorMenuCollapsable as Collapsable,
|
||||
AccordionAnchorMenuItem as Item,
|
||||
} from "../index";
|
||||
import {
|
||||
ProductPageLayout as Layout,
|
||||
ProductPageSection as Section,
|
||||
ProductPagePanel as Panel,
|
||||
} from "../../index";
|
||||
import { Right } from "../../layouts/stories/components/sections/Right";
|
||||
import { LightBulb, Telephone } from "@navikt/ds-icons";
|
||||
import { MainOne } from "../../layouts/stories/components/sections/Main";
|
||||
import { MainTwo } from "../../layouts/stories/components/sections/Main";
|
||||
import { MainThree } from "../../layouts/stories/components/sections/Main";
|
||||
import { Link, HashRouter as Router } from "react-router-dom";
|
||||
|
||||
export default {
|
||||
title: "ds-react/accordion-anchor-menu",
|
||||
component: { Menu },
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
},
|
||||
};
|
||||
|
||||
export const All = () => (
|
||||
<Layout title={"Nunc et lorem"}>
|
||||
<Section left sticky withPadding={false}>
|
||||
<Menu title={"Minima"}>
|
||||
<Item href={"#leo-quis"}>Leo quis</Item>
|
||||
<Collapsable title={"Proin accumsan"}>
|
||||
<Item href={"#nulla-pariatur"}>Nulla pariatur</Item>
|
||||
<Item href={"#luctus-justo"}>Luctus justo</Item>
|
||||
</Collapsable>
|
||||
<Item href={"#maecenas-in-pretium"}>Maecenas in pretium</Item>
|
||||
</Menu>
|
||||
</Section>
|
||||
<Section whiteBackground={false} withPadding={false}>
|
||||
<Panel
|
||||
title={"Leo quis"}
|
||||
anchor={"leo-quis"}
|
||||
highlight={true}
|
||||
icon={<LightBulb />}
|
||||
>
|
||||
<MainOne title={false} />
|
||||
</Panel>
|
||||
<Panel title={"Proin accumsan"} anchor={"proin-accumsan"}>
|
||||
<MainTwo title={false} />
|
||||
</Panel>
|
||||
<Panel
|
||||
title={"Maecenas in pretium"}
|
||||
anchor={"maecenas-in-pretium"}
|
||||
icon={<Telephone />}
|
||||
>
|
||||
<MainThree title={false} />
|
||||
</Panel>
|
||||
</Section>
|
||||
<Section right sticky>
|
||||
<Right />
|
||||
</Section>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
export const ReactRouter = () => (
|
||||
<Layout title={"Nunc et lorem"}>
|
||||
<Section left sticky withPadding={false}>
|
||||
<Menu>
|
||||
<Item component={Link} to="/link1">
|
||||
Leo quis
|
||||
</Item>
|
||||
<Collapsable title={"Proin accumsan"}>
|
||||
<Item component={Link} to="/link2">
|
||||
Nulla pariatur
|
||||
</Item>
|
||||
<Item component={Link} to="/link3">
|
||||
Luctus justo
|
||||
</Item>
|
||||
</Collapsable>
|
||||
<Collapsable title={"Sint cupidatat"}>
|
||||
<Item component={Link} to="/link4">
|
||||
Nulla pariatur
|
||||
</Item>
|
||||
<Item component={Link} to="/link5">
|
||||
Luctus justo
|
||||
</Item>
|
||||
</Collapsable>
|
||||
<Item component={Link} to="/link6">
|
||||
Maecenas in pretium
|
||||
</Item>
|
||||
</Menu>
|
||||
</Section>
|
||||
<Section whiteBackground={false} withPadding={false}>
|
||||
<Panel
|
||||
title={"Leo quis"}
|
||||
anchor={"leo-quis"}
|
||||
highlight={true}
|
||||
icon={<LightBulb />}
|
||||
>
|
||||
<MainOne title={false} />
|
||||
</Panel>
|
||||
<Panel title={"Proin accumsan"} anchor={"proin-accumsan"}>
|
||||
<MainTwo title={false} />
|
||||
</Panel>
|
||||
<Panel
|
||||
title={"Maecenas in pretium"}
|
||||
anchor={"maecenas-in-pretium"}
|
||||
icon={<Telephone />}
|
||||
>
|
||||
<MainThree title={false} />
|
||||
</Panel>
|
||||
</Section>
|
||||
<Section right sticky>
|
||||
<Right />
|
||||
</Section>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
ReactRouter.decorators = [
|
||||
(Story) => (
|
||||
<Router>
|
||||
<Story />
|
||||
</Router>
|
||||
),
|
||||
];
|
||||
@@ -1,7 +1,8 @@
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -82,7 +82,7 @@ const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
|
||||
}}
|
||||
>
|
||||
<fieldset
|
||||
{...omit(rest, ["errorId"])}
|
||||
{...omit(rest, ["errorId", "error", "size"])}
|
||||
{...inputProps}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { forwardRef, SelectHTMLAttributes } from "react";
|
||||
import cl from "classnames";
|
||||
import { Expand } from "@navikt/ds-icons";
|
||||
import { BodyShort, Label } from "..";
|
||||
import { BodyShort, Label, omit } from "..";
|
||||
import ErrorMessage from "./ErrorMessage";
|
||||
import { FormFieldProps, useFormField } from "./useFormField";
|
||||
|
||||
@@ -78,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(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import cl from "classnames";
|
||||
import { BodyShort, Label } from "..";
|
||||
import { BodyShort, Label, omit } from "..";
|
||||
import ErrorMessage from "./ErrorMessage";
|
||||
import { FormFieldProps, useFormField } from "./useFormField";
|
||||
|
||||
@@ -70,7 +70,7 @@ const TextField = forwardRef<HTMLInputElement, TextFieldProps>((props, ref) => {
|
||||
</BodyShort>
|
||||
)}
|
||||
<input
|
||||
{...rest}
|
||||
{...omit(rest, ["error", "errorId", "size"])}
|
||||
{...inputProps}
|
||||
ref={ref}
|
||||
type="text"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import TextareaAutosize from "@material-ui/core/TextareaAutosize";
|
||||
import { BodyShort, Label } from "..";
|
||||
import { BodyShort, Label, omit } from "..";
|
||||
import ErrorMessage from "./ErrorMessage";
|
||||
import { FormFieldProps, useFormField } from "./useFormField";
|
||||
import { useId } from "..";
|
||||
@@ -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(
|
||||
|
||||
@@ -16,6 +16,10 @@ export interface CheckboxProps
|
||||
* Hides label and makes it viewable for screen-readers only.
|
||||
*/
|
||||
hideLabel?: boolean;
|
||||
/**
|
||||
* The value of the HTML element.
|
||||
*/
|
||||
value?: string;
|
||||
}
|
||||
|
||||
const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
|
||||
|
||||
@@ -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."
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -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";
|
||||
|
||||
@@ -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,60 +0,0 @@
|
||||
import cl from "classnames";
|
||||
import React, { Children, forwardRef, HTMLAttributes, useEffect } from "react";
|
||||
import { ContentContainer, Title } from "../..";
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,72 +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;
|
||||
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 "../../../..";
|
||||
|
||||
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 "../../../..";
|
||||
|
||||
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 "../../../..";
|
||||
|
||||
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,4 +1,4 @@
|
||||
import { useEffect, useLayoutEffect, useState } from "react";
|
||||
import { useLayoutEffect, useState } from "react";
|
||||
import ShortUuid from "short-uuid";
|
||||
|
||||
const canUseDOM = (): boolean => {
|
||||
|
||||
@@ -21,10 +21,11 @@
|
||||
Dette repoet inneholder følgende:
|
||||
|
||||
- [Alle felleskomponenter](https://github.com/navikt/nav-frontend-moduler/tree/master/packages/) i NAVs frontend-rammeverk forvaltet av designsystemet
|
||||
- [Felleskomponenter V2](https://github.com/navikt/nav-frontend-moduler/tree/master/@navikt/) oppdaterte og scopede pakker for en bedre brukeropplevelse
|
||||
- [Felleskomponenter V2 (WIP)](https://github.com/navikt/nav-frontend-moduler/tree/master/@navikt/) oppdaterte og scopede pakker for en bedre brukeropplevelse
|
||||
- [Kildekoden](https://github.com/navikt/nav-frontend-moduler/tree/master/website) til vår nettside; [design.nav.no](https://design.nav.no) som tilbyr dokumentasjon for komponentene og NAVs designsystem generelt
|
||||
- [Eksempler på forskjellige frontend-oppsett](https://github.com/navikt/nav-frontend-moduler/tree/master/examples) til applikasjoner som skal bruke komponentene
|
||||
|
||||
- [Storybook](https://navikt.github.io/Designsystemet/?path=/story/ds-react-kom-i-gang--page) for v2 komponenter (wip) og eldre komponenter.
|
||||
|
||||
## Bidra
|
||||
|
||||
Gå til [CONTRIBUTING.md](https://github.com/navikt/nav-frontend-moduler/blob/master/CONTRIBUTING.md)
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
@@ -1,48 +0,0 @@
|
||||
# Nytt oppsett for design.nav.no
|
||||
|
||||
Planener er at nytt design og innhold for design.nav.no vil bli utviklet her med hjelp av nextjs.
|
||||
|
||||
## Kom i gang
|
||||
|
||||
> Note: Kjøres fra root, ikke docs/package.json
|
||||
|
||||
- `yarn install`
|
||||
- `yarn boot`
|
||||
- `yarn next-dev`
|
||||
|
||||
## Nextjs default Readme
|
||||
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
|
||||
|
||||
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
|
||||
|
||||
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
@@ -1,200 +0,0 @@
|
||||
import { ErrorFilled, Settings, SuccessFilled } from "@navikt/ds-icons";
|
||||
import { Alert, Title, Link, BodyLong } from "@navikt/ds-react";
|
||||
import Alertstripe from "nav-frontend-alertstriper";
|
||||
import Chevron from "nav-frontend-chevron";
|
||||
import Ekspanderbartpanel from "nav-frontend-ekspanderbartpanel";
|
||||
import Etikett from "nav-frontend-etiketter";
|
||||
import Hjelpetekst from "nav-frontend-hjelpetekst";
|
||||
import {
|
||||
Hamburgerknapp,
|
||||
Menyknapp,
|
||||
Nesteknapp,
|
||||
Systemerknapp,
|
||||
Søkeknapp,
|
||||
Tilbakeknapp,
|
||||
Xknapp,
|
||||
} from "nav-frontend-ikonknapper";
|
||||
import { Knapp } from "nav-frontend-knapper";
|
||||
import Lenkepanel, { LenkepanelBase } from "nav-frontend-lenkepanel";
|
||||
import Lenke from "nav-frontend-lenker";
|
||||
import Lesmerpanel from "nav-frontend-lesmerpanel";
|
||||
import Modal from "nav-frontend-modal";
|
||||
import Panel from "nav-frontend-paneler";
|
||||
import Popover, { PopoverBase } from "nav-frontend-popover";
|
||||
import {
|
||||
BekreftCheckboksPanel,
|
||||
CheckboksPanelGruppe,
|
||||
Checkbox,
|
||||
CheckboxGruppe,
|
||||
Feiloppsummering,
|
||||
FnrInput,
|
||||
Input,
|
||||
Label,
|
||||
Radio,
|
||||
RadioGruppe,
|
||||
Select,
|
||||
SkjemaGruppe,
|
||||
Textarea,
|
||||
TextareaControlled,
|
||||
} from "nav-frontend-skjema";
|
||||
import Snakkeboble from "nav-frontend-snakkeboble";
|
||||
import Spinner from "nav-frontend-spinner";
|
||||
import Stegindikator from "nav-frontend-stegindikator";
|
||||
import "nav-frontend-tabell-style";
|
||||
import Tabs from "nav-frontend-tabs";
|
||||
import Tekstomrade from "nav-frontend-tekstomrade";
|
||||
import { ToggleGruppe, ToggleKnapp } from "nav-frontend-toggle";
|
||||
import {
|
||||
Element,
|
||||
Feilmelding,
|
||||
Ingress,
|
||||
Innholdstittel,
|
||||
Normaltekst,
|
||||
Sidetittel,
|
||||
Systemtittel,
|
||||
Undertekst,
|
||||
UndertekstBold,
|
||||
Undertittel,
|
||||
} from "nav-frontend-typografi";
|
||||
import Veileder from "nav-frontend-veileder";
|
||||
import Veilederpanel from "nav-frontend-veilederpanel";
|
||||
import EkspanderbartpanelExample from "../examples/ekspanderbartpanel/ekspanderbartpanel-base";
|
||||
import FormValidationExample from "../examples/form-validation/FormValidationExample";
|
||||
import ModalExample from "../examples/modal/modal-example";
|
||||
import BekreftcheckboxpanelExample2 from "../examples/navfrontendskjema/bekreftcheckboxpanel/Feilmelding";
|
||||
import BekreftcheckboxpanelExample1 from "../examples/navfrontendskjema/bekreftcheckboxpanel/Normal";
|
||||
import FnrInputExample from "../examples/navfrontendskjema/fnr-input-example";
|
||||
import RadioPanelGruppeExample from "../examples/navfrontendskjema/radiopanelgruppe";
|
||||
import TextareaExample from "../examples/navfrontendskjema/textarea-example";
|
||||
import PopoverDropdownEksempel from "../examples/popover/_popover-dropdown.example";
|
||||
import PopoverInputEksempel from "../examples/popover/_popover-input.example";
|
||||
import PopoverNormalEksempel from "../examples/popover/_popover-normal.example";
|
||||
import PopoverOrienteringEksempel from "../examples/popover/_popover-orientering.example";
|
||||
import Palette from "../examples/resources/colors/Palette";
|
||||
import IconDownload from "../examples/resources/icons/IconDownload";
|
||||
import IconPage from "../examples/resources/icons/IconPage";
|
||||
import TekstomradeExample from "../examples/tekstomrade/tekstomrade-example";
|
||||
import {
|
||||
ButtonIcon,
|
||||
FigmaIcon,
|
||||
GithubLogo,
|
||||
NAVLogoCircle,
|
||||
SketchLogo,
|
||||
TypoIcon,
|
||||
VeilederIcon,
|
||||
W3CLogo,
|
||||
ZeplinLogo,
|
||||
} from "./assets/svg";
|
||||
import Preview from "./code-preview/Preview";
|
||||
import Bash from "./code/Bash";
|
||||
import Import from "./code/Import";
|
||||
import Inline from "./code/Inline";
|
||||
import Npm from "./npm/Npm";
|
||||
import Proptable from "./props/Proptable";
|
||||
import TableOfContents from "./table-of-contents/TableOfContents";
|
||||
|
||||
const components = {
|
||||
h1: (props) => <Title size="2xl" level={1} spacing {...props} />,
|
||||
h2: (props) => <Title size="l" level={2} spacing {...props} />,
|
||||
h3: (props) => <Title size="s" level={3} spacing {...props} />,
|
||||
h4: (props) => <Title size="s" level={4} spacing {...props} />,
|
||||
p: (props) => <BodyLong size="m" spacing {...props} />,
|
||||
a: (props) => <Link {...props} />,
|
||||
code: (props) => <Inline {...props} />,
|
||||
SuccessIcon: () => (
|
||||
<SuccessFilled style={{ color: "var(--navds-color-green-70)" }} />
|
||||
),
|
||||
ErrorIcon: () => (
|
||||
<ErrorFilled style={{ color: "var(--navds-color-red-60)" }} />
|
||||
),
|
||||
Bash,
|
||||
Preview,
|
||||
Import,
|
||||
Npm,
|
||||
TableOfContents,
|
||||
Alert,
|
||||
Link,
|
||||
Knapp,
|
||||
Settings,
|
||||
Alertstripe,
|
||||
BekreftCheckboksPanel,
|
||||
CheckboksPanelGruppe,
|
||||
Chevron,
|
||||
Ekspanderbartpanel,
|
||||
Etikett,
|
||||
Element,
|
||||
Normaltekst,
|
||||
Undertittel,
|
||||
Innholdstittel,
|
||||
Systemtittel,
|
||||
Sidetittel,
|
||||
Undertekst,
|
||||
Feilmelding,
|
||||
UndertekstBold,
|
||||
Ingress,
|
||||
Lenke,
|
||||
FnrInput,
|
||||
Input,
|
||||
Feiloppsummering,
|
||||
Hjelpetekst,
|
||||
Hamburgerknapp,
|
||||
Tilbakeknapp,
|
||||
Nesteknapp,
|
||||
Xknapp,
|
||||
Søkeknapp,
|
||||
Menyknapp,
|
||||
Systemerknapp,
|
||||
SkjemaGruppe,
|
||||
Label,
|
||||
Lenkepanel,
|
||||
LenkepanelBase,
|
||||
Lesmerpanel,
|
||||
Modal,
|
||||
Panel,
|
||||
Popover,
|
||||
PopoverBase,
|
||||
Radio,
|
||||
RadioGruppe,
|
||||
Select,
|
||||
Checkbox,
|
||||
CheckboxGruppe,
|
||||
TextareaControlled,
|
||||
Textarea,
|
||||
Snakkeboble,
|
||||
Spinner,
|
||||
Stegindikator,
|
||||
Tabs,
|
||||
Tekstomrade,
|
||||
ToggleGruppe,
|
||||
ToggleKnapp,
|
||||
Veileder,
|
||||
Veilederpanel,
|
||||
Proptable,
|
||||
ButtonIcon,
|
||||
TypoIcon,
|
||||
VeilederIcon,
|
||||
NAVLogoCircle,
|
||||
W3CLogo,
|
||||
SketchLogo,
|
||||
FigmaIcon,
|
||||
ZeplinLogo,
|
||||
GithubLogo,
|
||||
BekreftcheckboxpanelExample1,
|
||||
BekreftcheckboxpanelExample2,
|
||||
EkspanderbartpanelExample,
|
||||
FnrInputExample,
|
||||
ModalExample,
|
||||
PopoverDropdownEksempel,
|
||||
PopoverInputEksempel,
|
||||
PopoverNormalEksempel,
|
||||
PopoverOrienteringEksempel,
|
||||
RadioPanelGruppeExample,
|
||||
TekstomradeExample,
|
||||
TextareaExample,
|
||||
FormValidationExample,
|
||||
Palette,
|
||||
IconPage,
|
||||
IconDownload,
|
||||
};
|
||||
|
||||
export default components;
|
||||
@@ -1,6 +0,0 @@
|
||||
<svg width="77" height="48" viewBox="0 0 77 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 34.4688L4.90367 22.3328H9.61534L4.71792 34.4688H0Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M60.5095 34.4688L65.3504 22.3328H67.9191L63.0785 34.4688H60.5095Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.0298 34.4688L74.8699 22.3328H76.2341L71.3934 34.4688H70.0298Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M56.055 22.3327H51.7901C51.7901 22.3327 51.4962 22.3327 51.3922 22.5923L49.032 29.8176L46.6737 22.5923C46.5698 22.3327 46.2741 22.3327 46.2741 22.3327H38.0738C37.8963 22.3327 37.7474 22.481 37.7474 22.6574V25.1111C37.7474 23.1647 35.6763 22.3327 34.4635 22.3327C31.7477 22.3327 29.9297 24.1215 29.3636 26.8411C29.3329 25.0369 29.183 24.3905 28.697 23.7284C28.4738 23.4041 28.1511 23.1314 27.7998 22.9059C27.0764 22.4821 26.4268 22.3327 25.0308 22.3327H23.3917C23.3917 22.3327 23.0955 22.3327 22.991 22.5923L21.4996 26.2883V22.6574C21.4996 22.481 21.3519 22.3327 21.1747 22.3327H17.3818C17.3818 22.3327 17.089 22.3327 16.9825 22.5923L15.432 26.4355C15.432 26.4355 15.2772 26.8198 15.6311 26.8198H17.089V34.143C17.089 34.3248 17.2321 34.4688 17.4147 34.4688H21.1747C21.3519 34.4688 21.4996 34.3248 21.4996 34.143V26.8198H22.9651C23.8061 26.8198 23.9842 26.8428 24.3114 26.9953C24.5085 27.0697 24.686 27.2202 24.7829 27.3938C24.9811 27.767 25.0308 28.2152 25.0308 29.5367V34.143C25.0308 34.3248 25.1768 34.4688 25.3572 34.4688H28.9609C28.9609 34.4688 29.3682 34.4688 29.5292 34.0666L30.3279 32.0927C31.3898 33.5801 33.1377 34.4688 35.3099 34.4688H35.7845C35.7845 34.4688 36.1944 34.4688 36.3566 34.0666L37.7474 30.622V34.143C37.7474 34.3248 37.8963 34.4688 38.0738 34.4688H41.7524C41.7524 34.4688 42.1583 34.4688 42.3213 34.0666C42.3213 34.0666 43.7926 30.4138 43.7983 30.3862H43.8005C43.8571 30.0823 43.4731 30.0823 43.4731 30.0823H42.16V23.8145L46.2911 34.0666C46.4525 34.4688 46.8592 34.4688 46.8592 34.4688H51.205C51.205 34.4688 51.614 34.4688 51.7754 34.0666L56.3552 22.7258C56.5137 22.3327 56.055 22.3327 56.055 22.3327V22.3327ZM37.7474 30.0823H35.2764C34.2928 30.0823 33.4927 29.2859 33.4927 28.3012C33.4927 27.3182 34.2928 26.5167 35.2764 26.5167H35.9674C36.9485 26.5167 37.7474 27.3182 37.7474 28.3012V30.0823ZM35.5908 47.9835C22.3436 47.9835 11.6021 37.2426 11.6021 23.9935C11.6021 10.7429 22.3436 0 35.5908 0C48.8427 0 59.5854 10.7429 59.5854 23.9935C59.5854 37.2426 48.8427 47.9835 35.5908 47.9835Z" fill="white"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB |
@@ -1,592 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
/* eslint-disable max-len */
|
||||
|
||||
export const CheckIcon = (props) => {
|
||||
const { fill = "#38a161", ...rest } = props;
|
||||
return (
|
||||
<svg
|
||||
version="1.1"
|
||||
fill={fill}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
focusable="false"
|
||||
{...rest}
|
||||
>
|
||||
{rest.title && <title>{rest.title}</title>}
|
||||
<path
|
||||
d="M23.854,5.396l-3.5-3.5c-0.195-0.195-0.512-0.195-0.707,0L7.5,14.043l-3.146-3.146c-0.195-0.195-0.512-0.195-0.707,0
|
||||
l-3.5,3.5c-0.195,0.195-0.195,0.512,0,0.707l7,7C7.244,22.201,7.372,22.25,7.5,22.25s0.256-0.049,0.354-0.146l16-16
|
||||
C24.049,5.908,24.049,5.592,23.854,5.396z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const CrossIcon = (props) => {
|
||||
const { fill = "#C30000", ...rest } = props;
|
||||
return (
|
||||
<svg
|
||||
version="1.1"
|
||||
fill={fill}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
{...rest}
|
||||
>
|
||||
{rest.title && <title>{rest.title}</title>}
|
||||
<path
|
||||
d="M17.207,12.01l6.658-6.634c0.096-0.093,0.149-0.22,0.149-0.353c0-0.133-0.053-0.26-0.146-0.354L19.375,0.16
|
||||
c-0.092-0.094-0.221-0.147-0.352-0.147h-0.002c-0.133,0-0.26,0.052-0.352,0.146l-6.66,6.634L5.375,0.134
|
||||
C5.283,0.04,5.154-0.013,5.023-0.014H5.021c-0.133,0-0.258,0.053-0.352,0.146L0.16,4.624c-0.195,0.194-0.195,0.511-0.002,0.707
|
||||
l6.635,6.659l-6.66,6.634c-0.195,0.194-0.195,0.511,0,0.707l4.49,4.509c0.094,0.094,0.221,0.146,0.354,0.146h0.002
|
||||
c0.131,0,0.258-0.052,0.352-0.146l6.66-6.634l6.633,6.659c0.098,0.099,0.227,0.148,0.355,0.148c0.127,0,0.254-0.049,0.352-0.146
|
||||
l4.51-4.491c0.195-0.194,0.195-0.511,0-0.707L17.207,12.01z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const NAVLogo = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="navLogo"
|
||||
width="90"
|
||||
height="57"
|
||||
viewBox="0 0 269 169"
|
||||
focusable="false"
|
||||
>
|
||||
<defs>
|
||||
<path d="M22.407 43.417V.687H.564v42.73h21.843z" />
|
||||
</defs>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path
|
||||
fill="#C30000"
|
||||
d="M125.31 168.942c-46.642 0-84.46-37.817-84.46-84.465C40.85 37.824 78.667 0 125.31 0c46.657 0 84.48 37.824 84.48 84.477 0 46.648-37.823 84.465-84.48 84.465zM0 121.359l17.265-42.73h16.589l-17.243 42.73zM213.044 121.359l17.044-42.73h9.044l-17.043 42.73z"
|
||||
/>
|
||||
<g transform="translate(246 77.942)">
|
||||
<path fill="#C30000" d="M.564 43.417L17.604.687h4.803L5.364 43.418z" />
|
||||
</g>
|
||||
<path
|
||||
fill="#FEFEFE"
|
||||
d="M197.36 78.63h-15.016s-1.035 0-1.4.914l-8.31 25.439-8.304-25.44c-.366-.913-1.407-.913-1.407-.913h-28.872c-.625 0-1.149.522-1.149 1.143v8.639c0-6.853-7.292-9.782-11.562-9.782-9.562 0-15.963 6.298-17.956 15.873-.108-6.352-.636-8.628-2.347-10.96-.786-1.141-1.922-2.101-3.159-2.895-2.547-1.492-4.834-2.018-9.749-2.018h-5.77s-1.044 0-1.412.914l-5.25 13.013V79.773c0-.621-.52-1.143-1.145-1.143H61.198s-1.03 0-1.406.914l-5.459 13.53s-.545 1.354.701 1.354h5.133v25.784c0 .64.504 1.147 1.147 1.147h13.238c.624 0 1.144-.507 1.144-1.147V94.428h5.16c2.961 0 3.588.08 4.74.618.694.262 1.32.792 1.66 1.403.698 1.314.873 2.892.873 7.545v16.218c0 .64.514 1.147 1.15 1.147h12.687s1.434 0 2.001-1.416l2.812-6.95c3.74 5.237 9.893 8.366 17.541 8.366h1.671s1.443 0 2.014-1.416l4.897-12.128v12.397c0 .64.524 1.147 1.15 1.147h12.951s1.43 0 2.003-1.416c0 0 5.18-12.861 5.2-12.958h.008c.2-1.07-1.153-1.07-1.153-1.07h-4.623V83.847l14.545 36.096c.568 1.416 2 1.416 2 1.416h15.301s1.44 0 2.008-1.416l16.125-39.93c.558-1.383-1.057-1.383-1.057-1.383zm-64.458 27.285h-8.7c-3.463 0-6.28-2.804-6.28-6.271 0-3.461 2.817-6.283 6.28-6.283h2.433c3.454 0 6.267 2.822 6.267 6.283v6.27z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const NAVLogoWhite = ({ ...props }) => (
|
||||
<svg
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 269 169"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable="false"
|
||||
{...props}
|
||||
>
|
||||
<path d="M0 121.359L17.265 78.6299H33.854L16.611 121.359H0Z" fill="white" />
|
||||
<path
|
||||
d="M213.044 121.359L230.088 78.6299H239.132L222.089 121.359H213.044Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M246.563 121.359L263.604 78.6299H268.407L251.364 121.359H246.563Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M197.36 78.6299H182.344C182.344 78.6299 181.309 78.6299 180.943 79.5439L172.633 104.983L164.33 79.5439C163.964 78.6299 162.923 78.6299 162.923 78.6299H134.051C133.426 78.6299 132.902 79.1519 132.902 79.7729V88.4119C132.902 81.5589 125.61 78.6299 121.34 78.6299C111.778 78.6299 105.377 84.9279 103.384 94.5029C103.276 88.1509 102.748 85.8749 101.037 83.5439C100.251 82.4019 99.1154 81.4419 97.8784 80.6479C95.3314 79.1559 93.0444 78.6299 88.1294 78.6299H82.3584C82.3584 78.6299 81.3154 78.6299 80.9474 79.5439L75.6964 92.5569V79.7729C75.6964 79.1519 75.1764 78.6299 74.5524 78.6299H61.1984C61.1984 78.6299 60.1674 78.6299 59.7924 79.5439L54.3334 93.0749C54.3334 93.0749 53.7884 94.4279 55.0344 94.4279H60.1674V120.212C60.1674 120.852 60.6714 121.359 61.3144 121.359H74.5524C75.1764 121.359 75.6964 120.852 75.6964 120.212V94.4279H80.8564C83.8174 94.4279 84.4444 94.5089 85.5964 95.0459C86.2904 95.3079 86.9154 95.8379 87.2564 96.4489C87.9544 97.7629 88.1294 99.3409 88.1294 103.994V120.212C88.1294 120.852 88.6434 121.359 89.2784 121.359H101.966C101.966 121.359 103.4 121.359 103.967 119.943L106.779 112.993C110.518 118.23 116.672 121.359 124.32 121.359H125.991C125.991 121.359 127.434 121.359 128.005 119.943L132.902 107.815V120.212C132.902 120.852 133.426 121.359 134.051 121.359H147.003C147.003 121.359 148.432 121.359 149.006 119.943C149.006 119.943 154.186 107.082 154.206 106.985H154.214C154.413 105.915 153.061 105.915 153.061 105.915H148.438V83.8469L162.983 119.943C163.551 121.359 164.983 121.359 164.983 121.359H180.284C180.284 121.359 181.724 121.359 182.292 119.943L198.417 80.0139C198.975 78.6299 197.36 78.6299 197.36 78.6299ZM132.902 105.915H124.202C120.739 105.915 117.922 103.111 117.922 99.6438C117.922 96.1828 120.739 93.3608 124.202 93.3608H126.635C130.089 93.3608 132.902 96.1828 132.902 99.6438V105.915ZM125.309 168.942C78.6681 168.942 40.8491 131.125 40.8491 84.477C40.8491 37.824 78.6681 0 125.309 0C171.967 0 209.79 37.824 209.79 84.477C209.79 131.125 171.967 168.942 125.309 168.942Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const NAVLogoCircle = () => (
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 168.9 168.9"
|
||||
focusable="false"
|
||||
>
|
||||
<path
|
||||
fill="#C30000"
|
||||
d="M84.5,168.9C37.8,168.9,0,131.1,0,84.5C0,37.8,37.8,0,84.5,0c46.7,0,84.5,37.8,84.5,84.5
|
||||
C168.9,131.1,131.1,168.9,84.5,168.9L84.5,168.9z"
|
||||
/>
|
||||
<path
|
||||
fill="#FEFEFE"
|
||||
d="M156.5,78.6h-15c0,0-1,0-1.4,0.9l-8.3,25.4l-8.3-25.4c-0.4-0.9-1.4-0.9-1.4-0.9H93.2c-0.6,0-1.1,0.5-1.1,1.1
|
||||
v8.6c0-6.9-7.3-9.8-11.6-9.8c-9.6,0-16,6.3-18,15.9c-0.1-6.4-0.6-8.6-2.3-11c-0.8-1.1-1.9-2.1-3.2-2.9c-2.5-1.5-4.8-2-9.7-2h-5.8
|
||||
c0,0-1,0-1.4,0.9l-5.2,13V79.8c0-0.6-0.5-1.1-1.1-1.1H20.3c0,0-1,0-1.4,0.9l-5.5,13.5c0,0-0.5,1.4,0.7,1.4h5.1v25.8
|
||||
c0,0.6,0.5,1.1,1.1,1.1h13.2c0.6,0,1.1-0.5,1.1-1.1V94.4H40c3,0,3.6,0.1,4.7,0.6c0.7,0.3,1.3,0.8,1.7,1.4c0.7,1.3,0.9,2.9,0.9,7.5
|
||||
v16.2c0,0.6,0.5,1.1,1.2,1.1h12.7c0,0,1.4,0,2-1.4l2.8-6.9c3.7,5.2,9.9,8.4,17.5,8.4h1.7c0,0,1.4,0,2-1.4l4.9-12.1v12.4
|
||||
c0,0.6,0.5,1.1,1.1,1.1h13c0,0,1.4,0,2-1.4c0,0,5.2-12.9,5.2-13h0c0.2-1.1-1.2-1.1-1.2-1.1h-4.6V83.8l14.5,36.1c0.6,1.4,2,1.4,2,1.4
|
||||
h15.3c0,0,1.4,0,2-1.4L157.6,80C158.1,78.6,156.5,78.6,156.5,78.6L156.5,78.6z M92.1,105.9h-8.7c-3.5,0-6.3-2.8-6.3-6.3
|
||||
c0-3.5,2.8-6.3,6.3-6.3h2.4c3.5,0,6.3,2.8,6.3,6.3V105.9L92.1,105.9z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const TypoIcon = (props) => (
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 76.4 47.8"
|
||||
xmlSpace="preserve"
|
||||
{...props}
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M0,46.9L14.7,0h12.7l14.7,46.9H30.9L28,35.8H13.7l-2.9,11.2H0z M17,23.2l-1.2,4.3h10l-1.1-4.3c-0.7-2.4-1.3-4.8-1.9-7.5
|
||||
c-0.6-2.6-1.2-5.2-1.9-7.6h-0.3c-0.6,2.5-1.2,5.1-1.8,7.7C18.3,18.3,17.7,20.8,17,23.2z"
|
||||
/>
|
||||
<path
|
||||
d="M56.4,47.8c-1.6,0-3.1-0.3-4.4-0.8c-1.3-0.6-2.4-1.3-3.3-2.3c-0.9-1-1.6-2.1-2.1-3.4C46,40,45.7,38.5,45.7,37
|
||||
c0-3.7,1.6-6.7,4.8-8.8c3.2-2.1,8.3-3.5,15.3-4.2c-0.1-1.6-0.6-2.8-1.4-3.8c-0.8-0.9-2.2-1.4-4.2-1.4c-1.5,0-3.1,0.3-4.6,0.9
|
||||
c-1.5,0.6-3.1,1.4-4.9,2.4l-3.8-7c2.3-1.4,4.7-2.5,7.2-3.4c2.5-0.9,5.2-1.3,8-1.3c4.6,0,8.1,1.3,10.5,3.9c2.4,2.6,3.6,6.7,3.6,12.2
|
||||
v20.4h-8.6L67,43.3h-0.3c-1.5,1.3-3.1,2.4-4.8,3.3C60.2,47.4,58.4,47.8,56.4,47.8z M60,39.6c1.2,0,2.2-0.3,3.1-0.8
|
||||
c0.9-0.5,1.8-1.3,2.7-2.2v-6.3c-3.7,0.5-6.3,1.3-7.8,2.3c-1.4,1-2.2,2.2-2.2,3.6c0,1.2,0.4,2,1.1,2.6C57.7,39.3,58.7,39.6,60,39.6z
|
||||
"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const ButtonIcon = (props) => (
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 145 47"
|
||||
xmlSpace="preserve"
|
||||
{...props}
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
style={{ fill: "#ffffff" }}
|
||||
d="M141,46H4c-1.7,0-3-1.3-3-3V4c0-1.7,1.3-3,3-3h137c1.6,0,3,1.3,3,3v39C144,44.7,142.6,46,141,46z"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: "#0067c5" }}
|
||||
d="M141,47H4c-2.2,0-4-1.8-4-4V4c0-2.2,1.8-4,4-4h137c2.2,0,4,1.8,4,4v39C145,45.2,143.2,47,141,47z M4,2
|
||||
C2.9,2,2,2.9,2,4v39c0,1.1,0.9,2,2,2h137c1.1,0,2-0.9,2-2V4c0-1.1-0.9-2-2-2H4z"
|
||||
/>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
style={{ fill: "#0067c5" }}
|
||||
d="M46.3,29.6V17.9h2.6v4.8H49l3.5-4.8h2.9l-3.5,4.7l4.2,7.1h-2.9l-2.9-5l-1.4,1.8v3.1H46.3z"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: "#0067c5" }}
|
||||
d="M57.3,29.6V17.9H60l3.1,5.8l1.2,2.6h0.1c-0.1-0.6-0.1-1.3-0.2-2.1C64,23.4,64,22.7,64,22v-4.1h2.5v11.7h-2.7
|
||||
l-3.1-5.9l-1.2-2.6h-0.1c0.1,0.6,0.1,1.3,0.2,2.1c0.1,0.7,0.1,1.5,0.1,2.2v4.2H57.3z"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: "#0067c5" }}
|
||||
d="M67.8,29.6l3.7-11.7h3.2l3.7,11.7h-2.8l-0.7-2.8h-3.6l-0.7,2.8H67.8z M72,23.7l-0.3,1.1h2.5L74,23.7
|
||||
c-0.2-0.6-0.3-1.2-0.5-1.9c-0.2-0.7-0.3-1.3-0.5-1.9H73c-0.1,0.6-0.3,1.3-0.4,1.9C72.4,22.5,72.2,23.1,72,23.7z"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: "#0067c5" }}
|
||||
d="M79.6,29.6V17.9h4c0.6,0,1.3,0.1,1.8,0.2c0.6,0.1,1.1,0.3,1.5,0.6s0.8,0.7,1,1.2s0.4,1.1,0.4,1.8
|
||||
c0,0.7-0.1,1.3-0.4,1.8c-0.2,0.5-0.6,0.9-1,1.2c-0.4,0.3-0.9,0.6-1.5,0.7s-1.1,0.2-1.8,0.2h-1.5v4H79.6z M82.2,23.5h1.3
|
||||
c1.4,0,2.2-0.6,2.2-1.9c0-0.6-0.2-1-0.6-1.3c-0.4-0.3-0.9-0.4-1.7-0.4h-1.2V23.5z"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: "#0067c5" }}
|
||||
d="M90.3,29.6V17.9h4c0.6,0,1.3,0.1,1.8,0.2s1.1,0.3,1.5,0.6s0.8,0.7,1,1.2S99,21,99,21.7c0,0.7-0.1,1.3-0.4,1.8
|
||||
c-0.2,0.5-0.6,0.9-1,1.2c-0.4,0.3-0.9,0.6-1.5,0.7c-0.6,0.2-1.1,0.2-1.8,0.2H93v4H90.3z M93,23.5h1.3c1.4,0,2.2-0.6,2.2-1.9
|
||||
c0-0.6-0.2-1-0.6-1.3c-0.4-0.3-0.9-0.4-1.7-0.4H93V23.5z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const VeilederIcon = () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 93" focusable="false">
|
||||
<path
|
||||
fill="#e7e5e2"
|
||||
d="M14 50.7C15 52.3 17.9 81 26.5 81S39 51.8 39 50.3c-13.2-7.6-25 .4-25 .4z"
|
||||
/>
|
||||
<path
|
||||
fill="#5c4378"
|
||||
d="M38.7 50.2c6 2.9 15.3 10.9 15.3 18.3V93H0V68.5c0-7.1 8.5-14.8 14.5-18-.3.2-.5.3-.5.3 1 1.7 3.8 9.2 12.4 9.2C35 60 39 51.9 39 50.4c-.1-.1-.2-.2-.3-.2z"
|
||||
/>
|
||||
<path
|
||||
fill="#d2242a"
|
||||
d="M46.7 76H31.2c-.7 0-1.3-.6-1.2-1.3v-8.5c0-.7.6-1.3 1.3-1.3h15.5c.7 0 1.3.6 1.3 1.3v8.5c-.1.7-.7 1.3-1.4 1.3"
|
||||
/>
|
||||
<path
|
||||
fill="#fff"
|
||||
d="M42.9 71c0 2.1-1.7 3.8-3.8 3.8-2.1 0-3.8-1.7-3.8-3.8s1.7-3.8 3.8-3.8c2.1 0 3.8 1.7 3.8 3.8m-8.7 1.7h-.7l.8-1.9h.7l-.8 1.9zm9.3 0H43l.8-1.9h.5l-.8 1.9zm1.2 0h-.2l.8-1.9h.2l-.8 1.9z"
|
||||
/>
|
||||
<path
|
||||
fill="#c52d35"
|
||||
d="M36.2 72.7h.6s.1 0 .1-.1v-1.8s0-.1-.1-.1h-.6s-.1 0-.1.1l-.2.6v.1h.2l.1 1.2c0-.1 0 0 0 0"
|
||||
/>
|
||||
<path
|
||||
fill="#c52d35"
|
||||
d="M37.5 72.7h.6s.1 0 .1-.1v-1.8s0-.1-.1-.1h-.9s-.1 0-.1.1l-.2.6-.1.1h.5c.1 0 .2.1.2.2v1c-.1-.1-.1 0 0 0m2.6-1.9h-.6s-.1 0-.1.1v1.8s0 .1.1.1h.6s.1 0 .1-.1l.2-.6V72h-.2l-.1-1.2"
|
||||
/>
|
||||
<path
|
||||
fill="#c52d35"
|
||||
d="M37.7 72.7h.4s.1 0 .1-.1l.2-.6v-.1h-.2c0 .1-.5.8-.5.8zm3.9-1.9h.7s.1 0 0 .1l-.7 1.8H41l.6-1.9"
|
||||
/>
|
||||
<path
|
||||
fill="#c52d35"
|
||||
d="M40.8 70.8h-1c-.1 0 .3.1.3.1l.7 1.7s0 .1.1.1h.6l-.7-1.9m-1.3.6v.4s-.1-.4-.3-.4c-.3 0-.3.2-.3.3 0 .1.1.3.2.3h.5l-.3.7H39c-.2 0-.9-.3-.9-.9 0-.6.5-1 .9-1 .2-.1.5.2.5.6 0-.1 0-.1 0 0z"
|
||||
/>
|
||||
<path
|
||||
fill="#5a1f57"
|
||||
d="M39.9 66.7h-1.6c-.1 0-.2-.1-.2-.2v-.3c0-.1.1-.2.2-.2h1.6c.1 0 .2.1.2.2v.3c0 .2-.1.2-.2.2"
|
||||
/>
|
||||
<path fill="#c2b5cf" d="M38.7 66.5h.9V64h-.9v2.5z" />
|
||||
<path
|
||||
fill="#e7e5e2"
|
||||
d="M47.2 35.3C44.7 45.6 36.6 53.1 27 53.1S9.3 45.6 6.8 35.3c-.2.1-.5.1-.8.1-1.1 0-2-.8-2-1.7v-7c0-1 .9-1.7 2-1.7h.2C7.7 13.1 16.4 4 27 4c10.6 0 19.3 9.1 20.8 21h.2c1.1 0 2 .8 2 1.7v7c0 1-.9 1.7-2 1.7-.3 0-.5 0-.8-.1z"
|
||||
/>
|
||||
<path
|
||||
fill="#635e59"
|
||||
d="M19 27.6c-1.4.1-1.9-2-1.4-3.4.1-.3.6-1.5 1.4-1.5.8 0 1.2.7 1.3.8.6 1.4.3 4-1.3 4.1m16.2 0c1.4.1 1.9-2 1.4-3.4-.1-.3-.6-1.5-1.4-1.5-.8 0-1.2.7-1.3.8-.6 1.4-.3 4 1.3 4.1"
|
||||
/>
|
||||
<path
|
||||
fill="#d1bfa3"
|
||||
d="M26.8 34.6c-.4 0-.7-.1-1-.2-.3-.1-.4-.4-.3-.7.1-.3.4-.4.7-.3.5.2 1.5.1 2.2-.4.7-.4 1.1-1 1.2-1.5.1-.4-.1-.9-.4-1.3-.2-.2-.8-.2-1.6-.1-.3 0-.5-.1-.6-.4 0-.3.1-.5.4-.6 1.2-.2 2.1 0 2.6.6.5.7.8 1.4.6 2.1-.1.8-.7 1.6-1.7 2.2-.6.3-1.4.6-2.1.6z"
|
||||
/>
|
||||
<path
|
||||
fill="#593a32"
|
||||
d="M27.1 42.1h-.3c-5.3-.2-7.3-4.1-7.4-4.3-.1-.3 0-.6.2-.7.2-.1.6 0 .7.2.1.1 1.9 3.6 6.6 3.8 4.7.2 6.4-3.7 6.4-3.7.1-.3.4-.4.7-.3.3.1.4.4.3.7-.1 0-2.1 4.3-7.2 4.3z"
|
||||
/>
|
||||
<path
|
||||
fill="#f6b873"
|
||||
d="M6.6 30.7c.1-.1.1-.2.1-.3v-2c-.1-5.6 1.8-8.1 3.4-10.1 0 0-1 4.3-.3 3.4 3.8-5 21.4-1.6 25-8.1.5 3.6-4.1 4.6-4.1 4.6 3.7.7 6.9-.8 7.7-2.5.3 1.4-.6 2.4-1.9 3.4 4.5-.9 4.6-4 4.6-4 .6 4.1 5.3 2.5 5.3 9.3v6c0 .3.2.6.5.6h.5c.3 0 .5-.3.5-.6V26c.3-15.6-8.5-26-20.6-26C15.9 0 5 10.4 5 24.1v6.3c0 .4.2.6.5.6h.6c.2 0 .3-.1.5-.3"
|
||||
/>
|
||||
<path
|
||||
fill="#f6b873"
|
||||
d="M25.9 43.4c-4.4 0-8-1.4-8-3.2s3.6-3.2 8-3.2 8 1.4 8 3.2c0 1.8-3.6 3.2-8 3.2m.8-9.4c-2.9 0-4.7.7-8.8 2.1-12.7 4.6-11.6-14-11.6-14C3.4 46 18.6 52 26.5 52c8.1 0 24.1-8.1 21-30 0 0 .4 17.1-12.9 13.8-3.7-.9-5-1.8-7.9-1.8z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const GithubLogo = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 32.58 31.77"
|
||||
focusable="false"
|
||||
>
|
||||
<path d="M16.29,0a16.29,16.29,0,0,0-5.15,31.75c.82.15,1.11-.36,1.11-.79s0-1.41,0-2.77C7.7,29.18,6.74,26,6.74,26a4.36,4.36,0,0,0-1.81-2.39c-1.47-1,.12-1,.12-1a3.43,3.43,0,0,1,2.49,1.68,3.48,3.48,0,0,0,4.74,1.36,3.46,3.46,0,0,1,1-2.18c-3.62-.41-7.42-1.81-7.42-8a6.3,6.3,0,0,1,1.67-4.37,5.94,5.94,0,0,1,.16-4.31s1.37-.44,4.48,1.67a15.41,15.41,0,0,1,8.16,0c3.11-2.11,4.47-1.67,4.47-1.67A5.91,5.91,0,0,1,25,11.07a6.3,6.3,0,0,1,1.67,4.37c0,6.26-3.81,7.63-7.44,8a3.85,3.85,0,0,1,1.11,3c0,2.18,0,3.94,0,4.47s.29.94,1.12.78A16.29,16.29,0,0,0,16.29,0Z" />
|
||||
</svg>
|
||||
);
|
||||
export const GithubLogoEm = ({ ...props }) => (
|
||||
<svg
|
||||
width="1em"
|
||||
height="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 32.58 31.77"
|
||||
focusable="false"
|
||||
{...props}
|
||||
>
|
||||
<path d="M16.29,0a16.29,16.29,0,0,0-5.15,31.75c.82.15,1.11-.36,1.11-.79s0-1.41,0-2.77C7.7,29.18,6.74,26,6.74,26a4.36,4.36,0,0,0-1.81-2.39c-1.47-1,.12-1,.12-1a3.43,3.43,0,0,1,2.49,1.68,3.48,3.48,0,0,0,4.74,1.36,3.46,3.46,0,0,1,1-2.18c-3.62-.41-7.42-1.81-7.42-8a6.3,6.3,0,0,1,1.67-4.37,5.94,5.94,0,0,1,.16-4.31s1.37-.44,4.48,1.67a15.41,15.41,0,0,1,8.16,0c3.11-2.11,4.47-1.67,4.47-1.67A5.91,5.91,0,0,1,25,11.07a6.3,6.3,0,0,1,1.67,4.37c0,6.26-3.81,7.63-7.44,8a3.85,3.85,0,0,1,1.11,3c0,2.18,0,3.94,0,4.47s.29.94,1.12.78A16.29,16.29,0,0,0,16.29,0Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const SuccessIcon = () => (
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" focusable="false">
|
||||
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g transform="translate(-16.000000, -20.000000)">
|
||||
<g transform="translate(16.000000, 20.000000)">
|
||||
<g>
|
||||
<path
|
||||
d="M12,0 C5.383,0 0,5.384 0,12 C0,18.616 5.383,24 12,24 C18.616,24 24,18.616 24,12 C24,5.384 18.616,0 12,0 Z"
|
||||
fill="#1C6937"
|
||||
fillRule="nonzero"
|
||||
/>
|
||||
<path
|
||||
d="M9.63993168,14.4414307 L16.0998211,8.60231554 C16.4920344,8.24700834 17.1087604,8.26567481 17.4763929,8.64623502 C17.8442028,9.02697893 17.8231421,9.62435747 17.430152,9.98049024 L10.2805711,16.4435337 C10.0985537,16.6069711 9.8612111,16.6956522 9.61751913,16.6956522 C9.36153632,16.6956522 9.11545171,16.5990262 8.92853154,16.419824 L6.54589388,14.1121315 C6.16586146,13.7440529 6.16586146,13.1465019 6.54589388,12.7784232 C6.92592631,12.4103446 7.54288359,12.4103446 7.92291602,12.7784232 L9.63993168,14.4414307 Z"
|
||||
fill="#FFFFFF"
|
||||
fillRule="nonzero"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const ErrorIcon = () => (
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" focusable="false">
|
||||
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g transform="translate(-16.000000, -20.000000)">
|
||||
<g transform="translate(16.000000, 20.000000)">
|
||||
<g strokeWidth="1" fillRule="evenodd" fill="#A13A28">
|
||||
<path
|
||||
d="M11.9989565,0 C5.39478261,0 0.0125217391,5.37182609 8.24610291e-16,11.976 C-0.00626086957,15.1815652 1.23547826,18.1972174 3.49773913,20.4688696 C5.76,22.7394783 8.77147826,23.9937391 11.9770435,24 L12,24 C18.6031304,24 23.9864348,18.6271304 24,12.021913 C24.0125217,5.40626087 18.6396522,0.0125217391 11.9989565,0 Z"
|
||||
fillRule="nonzero"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M12,10.6512393 L15.3719018,7.27933749 C15.7443518,6.9068875 16.3482125,6.9068875 16.7206625,7.27933749 C17.0931125,7.65178748 17.0931125,8.25564822 16.7206625,8.62809821 L13.3487607,12 L16.7206625,15.3719018 C17.0931125,15.7443518 17.0931125,16.3482125 16.7206625,16.7206625 C16.3482125,17.0931125 15.7443518,17.0931125 15.3719018,16.7206625 L12,13.3487607 L8.62809821,16.7206625 C8.25564822,17.0931125 7.65178748,17.0931125 7.27933749,16.7206625 C6.9068875,16.3482125 6.9068875,15.7443518 7.27933749,15.3719018 L10.6512393,12 L7.27933749,8.62809821 C6.9068875,8.25564822 6.9068875,7.65178748 7.27933749,7.27933749 C7.65178748,6.9068875 8.25564822,6.9068875 8.62809821,7.27933749 L12,10.6512393 Z"
|
||||
fill="#FFFFFF"
|
||||
fillRule="nonzero"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const SketchLogo = () => (
|
||||
<svg
|
||||
viewBox="0 0 494 447"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable="false"
|
||||
>
|
||||
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g transform="translate(-9.000000, -28.000000)">
|
||||
<g transform="translate(9.000000, 28.000000)">
|
||||
<g fill="#FFAE00">
|
||||
<polygon
|
||||
transform="translate(247.000000, 223.500000) rotate(-180.000000) translate(-247.000000, -223.500000) "
|
||||
points="247 5.68434189e-14 494 287 387 432 247 447 107 432 -2.84217094e-13 287"
|
||||
/>
|
||||
</g>
|
||||
<g transform="translate(0.000000, 160.000000)" fill="#EC6C00">
|
||||
<polygon
|
||||
transform="translate(247.000000, 143.500000) rotate(-180.000000) translate(-247.000000, -143.500000) "
|
||||
points="247 1.13686838e-13 494 287 -5.68434189e-14 287"
|
||||
/>
|
||||
</g>
|
||||
<g transform="translate(100.000000, 160.000000)" fill="#FFAE00">
|
||||
<polygon
|
||||
transform="translate(147.000000, 143.500000) rotate(-180.000000) translate(-147.000000, -143.500000) "
|
||||
points="147 0 294 287 2.84217094e-13 287"
|
||||
/>
|
||||
</g>
|
||||
<g transform="translate(100.000000, 0.000000)" fill="#FFEFB4">
|
||||
<polygon
|
||||
transform="translate(147.000000, 80.000000) rotate(-180.000000) translate(-147.000000, -80.000000) "
|
||||
points="147 160 294 2.70983236e-12 5.68434189e-14 -5.68434189e-14"
|
||||
/>
|
||||
</g>
|
||||
<g transform="translate(0.000000, 15.000000)" fill="#FFAE00">
|
||||
<polygon
|
||||
transform="translate(53.500000, 72.500000) rotate(-180.000000) translate(-53.500000, -72.500000) "
|
||||
points="-2.27373675e-13 145 55 72 107 2.72848411e-12 6 5.68434189e-14"
|
||||
/>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(440.500000, 87.500000) scale(-1, 1) translate(-440.500000, -87.500000) translate(387.000000, 15.000000)"
|
||||
fill="#FFAE00"
|
||||
>
|
||||
<polygon
|
||||
transform="translate(53.500000, 72.500000) rotate(-180.000000) translate(-53.500000, -72.500000) "
|
||||
points="-2.27373675e-13 145 55 72 107 2.72848411e-12 6 5.68434189e-14"
|
||||
/>
|
||||
</g>
|
||||
<g transform="translate(100.000000, 0.000000)" fill="#FED305">
|
||||
<polygon
|
||||
transform="translate(73.500000, 80.000000) rotate(-180.000000) translate(-73.500000, -80.000000) "
|
||||
points="140 145 147 2.95585778e-12 2.27373675e-13 160"
|
||||
/>
|
||||
</g>
|
||||
<g transform="translate(247.000000, 0.000000)" fill="#FED305">
|
||||
<polygon
|
||||
transform="translate(73.500000, 80.000000) scale(-1, 1) rotate(-180.000000) translate(-73.500000, -80.000000) "
|
||||
points="140 145 147 0 -1.42108547e-14 160"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const ZeplinLogo = () => (
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 41.6 32.7"
|
||||
focusable="false"
|
||||
>
|
||||
<g transform="translate(0.64018885)">
|
||||
<g transform="matrix(1.2117164,0,0,1.2117164,-46.63877,7.1317533)">
|
||||
<path fill="#F89920" d="M41.5,13.3l-3.6-4l11-4l1.7,4.7L41.5,13.3z" />
|
||||
<path fill="#FFBE22" d="M41.5,13.2l-0.2,5.4l11-4l-1.7-4.7L41.5,13.2z" />
|
||||
<path
|
||||
fill="#F0670A"
|
||||
d="M72,2.2c1.6,4.5-3.5,10.5-11.3,13.4c-7.9,2.9-15.6,1.5-17.3-3
|
||||
L72,2.2z"
|
||||
/>
|
||||
<path
|
||||
fill="#FFD00E"
|
||||
d="M72,2.2c-1.7-4.5-9.4-5.8-17.3-3c-7.9,2.9-12.9,8.8-11.3,13.4
|
||||
L72,2.2z"
|
||||
/>
|
||||
<path
|
||||
fill="#F89920"
|
||||
d="M72,2.2c1,3-4.5,7.8-12.3,10.6c-7.8,2.8-15.1,2.7-16.3-0.2
|
||||
L72,2.2z"
|
||||
/>
|
||||
<path
|
||||
fill="#FFBE22"
|
||||
d="M72,2.2c-1.2-3-8.4-3.1-16.3-0.2c-7.8,2.9-13.3,7.6-12.3,10.6
|
||||
L72,2.2z"
|
||||
/>
|
||||
<path
|
||||
fill="#F0670A"
|
||||
d="M58.8-1.9c-0.7-2.6-1.6-4-2.6-4c-1.9,0.1-2.5,6-1.9,13.6
|
||||
c0.6,7.7,2.2,13.4,4.2,13.4c1.2,0,1.8-1.9,2.1-5.2c0-0.1-0.1,0-0.1-0.1c0,0,0-0.1-0.1-0.1l-0.3,0c-0.2,3.2-0.8,5-1.7,5
|
||||
c-1.6,0-3.2-5.7-3.8-13c-0.6-7.3,0-13.1,1.5-13.2c0.7,0,1.5,1.3,2.2,3.7C58.5-1.8,58.8-1.9,58.8-1.9z"
|
||||
/>
|
||||
<path
|
||||
fill="#F0670A"
|
||||
d="M49.6-3.7C48-2.8,50.4,2.7,54.7,9c4.4,6.3,8.6,10.5,10.3,9.5
|
||||
c0.9-0.6,0.7-2.3-0.5-5c0-0.1-0.2-0.1-0.3-0.1c-0.1,0-0.1,0.2-0.1,0.3c0,0,0,0,0,0c1.1,2.5,1.4,4.1,0.7,4.5
|
||||
c-1.4,0.8-5.6-3.3-9.8-9.4c-4.1-6-6.5-11.4-5.3-12.2c0.7-0.4,2.3,0.6,4.4,2.7c0,0,0.2,0.2,0.2,0.2c0.1,0,0-0.1,0.1-0.2
|
||||
c0.1-0.1,0.1-0.2,0-0.3c0,0,0,0,0,0C52.2-3.2,50.5-4.3,49.6-3.7L49.6-3.7z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const W3CLogo = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
viewBox="0 0 154 103"
|
||||
focusable="false"
|
||||
>
|
||||
<rect x="0" y="0" width="154" height="103" fill="#1a5e9a" />
|
||||
<g transform="translate(0 12.5)">
|
||||
<g>
|
||||
<path
|
||||
fill="#FFFFFF"
|
||||
d="M100.383,38.538c-2.512-4.137-6.217-6.994-11.107-8.563l13.933-24V1.366H76.076h-9.584H66.2L52.548,47.757 L38.905,1.366h-9.886l4.52,15.153l-9.227,31.238L10.665,1.366H0.782L23.37,77.59h0.942l14.117-47.236L52.548,77.59h0.94 l19.341-65.265l0.909-1.547h15.917L76.467,33.545v4.518h3.772c4.836,0,8.373,1.475,10.636,4.426 c1.945,2.506,2.915,6.051,2.915,10.631c0,4.143-0.907,7.688-2.726,10.635c-1.819,2.951-4.047,4.42-6.683,4.42 c-2.506,0-4.692-0.829-6.547-2.491c-1.847-1.659-3.344-3.935-4.47-6.815l-7.722,3.193c1.566,4.77,3.986,8.547,7.247,11.34 c3.259,2.788,7.097,4.188,11.491,4.188c5.828,0,10.581-2.354,14.252-7.057c3.674-4.704,5.517-10.512,5.517-17.413 C104.15,47.537,102.889,42.673,100.383,38.538z"
|
||||
/>
|
||||
<g>
|
||||
<path
|
||||
fill="#FFFFFF"
|
||||
d="M142.451,0.939l1.606,9.73l-5.677,10.841c0,0-2.176-4.603-5.783-7.148 c-3.045-2.145-5.034-2.611-8.131-1.969c-3.987,0.822-8.507,5.582-10.477,11.454c-2.363,7.028-2.383,10.427-2.462,13.552 c-0.133,5.002,0.655,7.963,0.655,7.963s-3.438-6.36-3.407-15.682c0.028-6.652,1.069-12.689,4.141-18.643 c2.713-5.229,6.742-8.372,10.316-8.744c3.692-0.384,6.616,1.398,8.875,3.325c2.366,2.021,4.756,6.446,4.756,6.446L142.451,0.939z "
|
||||
/>
|
||||
<path
|
||||
fill="#FFFFFF"
|
||||
d="M143.151,55.996c0,0-2.511,4.474-4.068,6.201c-1.563,1.722-4.351,4.765-7.799,6.281 c-3.454,1.517-5.258,1.806-8.671,1.479c-3.404-0.327-6.571-2.296-7.681-3.121c-1.106-0.822-3.936-3.248-5.537-5.5 c-1.604-2.262-4.109-6.777-4.109-6.777s1.392,4.527,2.27,6.447c0.502,1.104,2.048,4.482,4.239,7.427 c2.038,2.754,6.011,7.477,12.052,8.544c6.041,1.064,10.186-1.644,11.211-2.298c1.025-0.656,3.19-2.472,4.558-3.936 c1.431-1.526,2.782-3.477,3.536-4.645c0.552-0.856,1.439-2.59,1.439-2.59L143.151,55.996z"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
fill="#FFFFFF"
|
||||
d="M149.896,2.222c0.654,0,0.957,0.184,0.957,0.639 c0,0.436-0.303,0.593-0.938,0.593h-0.593V2.222H149.896L149.896,2.222z M150.022,1.768h-1.401v3.72h0.7V3.901h0.691l0.758,1.586 h0.781l-0.828-1.697c0.537-0.108,0.848-0.473,0.848-1.002C151.571,2.113,151.061,1.768,150.022,1.768L150.022,1.768z M152.781,3.718c0,0.758-0.291,1.46-0.828,1.978c-0.563,0.548-1.265,0.839-2.039,0.839c-0.729,0-1.447-0.3-1.986-0.847 c-0.537-0.548-0.836-1.249-0.836-1.996c0-0.749,0.311-1.478,0.865-2.042c0.52-0.53,1.22-0.813,1.983-0.813 c0.783,0,1.485,0.292,2.032,0.849C152.5,2.214,152.781,2.926,152.781,3.718L152.781,3.718z M149.932,0.411 c-0.885,0-1.676,0.316-2.276,0.929c-0.636,0.649-0.992,1.486-0.992,2.352c0,0.867,0.337,1.667,0.956,2.295 c0.628,0.639,1.44,0.983,2.312,0.983c0.856,0,1.684-0.344,2.331-0.973c0.62-0.601,0.956-1.403,0.956-2.305 c0-0.876-0.347-1.697-0.948-2.307C151.645,0.746,150.825,0.411,149.932,0.411L149.932,0.411z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const Cog = () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" focusable="false">
|
||||
<path d="M23.5 10h-2.854c-.2-.79-.454-1.667-.778-2.332L21.9 5.636a.498.498 0 0 0 0-.708l-2.83-2.826a.499.499 0 0 0-.707 0l-2.032 2.031c-.665-.324-1.542-.578-2.331-.777V.5a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5v2.856c-.789.199-1.666.453-2.331.777L5.637 2.102a.499.499 0 0 0-.707 0L2.101 4.929a.5.5 0 0 0 0 .707l2.033 2.033c-.323.662-.578 1.54-.779 2.331H.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h2.855c.2.791.455 1.668.778 2.331L2.1 18.364a.5.5 0 0 0 0 .708L4.93 21.9c.188.188.52.188.707 0l2.032-2.032c.663.322 1.54.577 2.331.778V23.5a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-2.854c.791-.201 1.668-.456 2.331-.778l2.034 2.032a.5.5 0 0 0 .707 0l2.827-2.828a.499.499 0 0 0 0-.707l-2.032-2.033c.323-.663.578-1.54.778-2.331H23.5a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.501zM12 16c-2.205 0-4-1.795-4-4s1.795-4 4-4c2.206 0 4 1.795 4 4s-1.794 4-4 4z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const LinkIcon = () => (
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
focusable="false"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M6.5,22.8c-0.9,0-1.8-0.4-2.5-1L2.3,20c-1.4-1.4-1.4-3.6,0-5l4-4c0.9-0.9,2.6-0.9,3.5,0l0.1,0.1l-0.7,0.7l-0.1-0.1
|
||||
c-0.6-0.6-1.6-0.6-2.1,0l-4,4c-1,1-1,2.6,0,3.5L4.7,21C5.7,22,7.3,22,8.3,21l4-4c0.6-0.6,0.6-1.5,0-2.1l-0.1-0.1l0.7-0.7l0.1,0.1
|
||||
c1,1,1,2.6,0,3.5l-4,4C8.3,22.4,7.5,22.8,6.5,22.8z M8.5,16.2l-0.7-0.7l7.8-7.8l0.7,0.7L8.5,16.2z M16,13.7c-0.7,0-1.3-0.3-1.8-0.7
|
||||
l-0.1-0.1l0.7-0.7l0.1,0.1c0.6,0.6,1.6,0.6,2.1,0l4-4c1-1,1-2.6,0-3.5L19.3,3C18.3,2,16.7,2,15.7,3l-4,4c-0.6,0.6-0.6,1.5,0,2.1
|
||||
l0.1,0.1l-0.7,0.7l-0.1-0.1c-1-1-1-2.6,0-3.5l4-4C16.4,1,18.7,1,20,2.3L21.7,4c1.4,1.4,1.4,3.6,0,5l-4,4
|
||||
C17.3,13.4,16.7,13.7,16,13.7z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const FileIcon = () => (
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
focusable="false"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M20.5,24h-17C3.2,24,3,23.8,3,23.5v-23C3,0.2,3.2,0,3.5,0h11c0,0,0,0,0,0c0.1,0,0.3,0.1,0.4,0.1l6,6
|
||||
C20.9,6.2,21,6.4,21,6.5c0,0,0,0,0,0v17C21,23.8,20.8,24,20.5,24z M4,23h16V7h-5.5C14.2,7,14,6.8,14,6.5V1H4V23z M15,6h4.3L15,1.7
|
||||
V6z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const CopyIcon = ({ color }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
focusable="false"
|
||||
>
|
||||
<g stroke={color ? color : "#000"} fill="none">
|
||||
<path d="M20.5 20.5h-14v-20h8l6 6zM14.5.5v6h6M17.5 20.5v3h-14v-20h3" />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const FigmaIcon = ({ ...props }) => (
|
||||
<svg
|
||||
{...props}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 38 57"
|
||||
focusable="false"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
fill="#1abcfe"
|
||||
d="M19 28.5a9.5 9.5 0 1 1 19 0 9.5 9.5 0 0 1-19 0z"
|
||||
/>
|
||||
<path
|
||||
fill="#0acf83"
|
||||
d="M0 47.5A9.5 9.5 0 0 1 9.5 38H19v9.5a9.5 9.5 0 1 1-19 0z"
|
||||
/>
|
||||
<path fill="#ff7262" d="M19 0v19h9.5a9.5 9.5 0 1 0 0-19H19z" />
|
||||
<path
|
||||
fill="#f24e1e"
|
||||
d="M0 9.5A9.5 9.5 0 0 0 9.5 19H19V0H9.5A9.5 9.5 0 0 0 0 9.5z"
|
||||
/>
|
||||
<path
|
||||
fill="#a259ff"
|
||||
d="M0 28.5A9.5 9.5 0 0 0 9.5 38H19V19H9.5A9.5 9.5 0 0 0 0 28.5z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const Edit = (props) => {
|
||||
return (
|
||||
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M22.835 1.165a3.976 3.976 0 010 5.623L8.073 21.549.682 24 0 23.318l2.45-7.392L17.21 1.165a3.977 3.977 0 015.624 0zm-4.218 7.029l-2.811-2.812L4.188 17l-1.393 4.205 4.207-1.395L18.618 8.194zM21.43 2.57a1.989 1.989 0 00-2.703-.1l-.108.1-1.406 1.406 2.811 2.812 1.406-1.406a1.988 1.988 0 00.101-2.703l-.1-.109z"
|
||||
fill="#262626"
|
||||
focusable="false"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -1,95 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import Tabs from "../tabs/Tabs";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import Bash from "../code/Bash";
|
||||
import Prettier from "prettier/standalone";
|
||||
import ParserBabel from "prettier/parser-babel";
|
||||
import "./preview.css";
|
||||
import cl from "classnames";
|
||||
|
||||
const prettierOptions = {
|
||||
semi: true,
|
||||
parser: "babel",
|
||||
plugins: [ParserBabel],
|
||||
jsxBracketSameLine: true,
|
||||
printWidth: 60,
|
||||
};
|
||||
|
||||
interface PreviewProps {
|
||||
react?: string;
|
||||
html?: React.ReactElement;
|
||||
children?: React.ReactElement;
|
||||
hideHtml?: boolean;
|
||||
defaultClosed?: boolean;
|
||||
noCode?: boolean;
|
||||
}
|
||||
|
||||
const Preview = ({
|
||||
children,
|
||||
react,
|
||||
html,
|
||||
noCode,
|
||||
defaultClosed = false,
|
||||
hideHtml = false,
|
||||
}: PreviewProps) => {
|
||||
const [tab, setTab] = useState(defaultClosed ? null : 0);
|
||||
const handleChange = (x: number) => {
|
||||
if (tab === x) {
|
||||
setTab(null);
|
||||
} else {
|
||||
setTab(x);
|
||||
}
|
||||
};
|
||||
|
||||
const reactFormat =
|
||||
!noCode && Prettier.format(react, prettierOptions).slice(0, -2);
|
||||
const htmlFormat = () =>
|
||||
!noCode &&
|
||||
!!children &&
|
||||
!hideHtml &&
|
||||
Prettier.format(
|
||||
renderToStaticMarkup(
|
||||
html ??
|
||||
(React.Children.count(children) > 1 ? (
|
||||
<div>{children}</div>
|
||||
) : (
|
||||
children
|
||||
))
|
||||
),
|
||||
prettierOptions
|
||||
)
|
||||
.slice(0, -2)
|
||||
.replace(` data-reactroot=""`, "");
|
||||
|
||||
const tabs = !hideHtml && !!children ? ["REACT", "HTML/CSS"] : ["REACT"];
|
||||
|
||||
return (
|
||||
<div className={"preview__wrapper"}>
|
||||
{!!children && (
|
||||
<div
|
||||
className={cl("preview__container", {
|
||||
"preview__container--no-code": noCode,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
{!noCode && (
|
||||
<>
|
||||
<Tabs tabs={tabs} tab={tab} onChange={(x) => handleChange(x)} />
|
||||
{tab === 0 && <Bash code={reactFormat} language="jsx" copy />}
|
||||
|
||||
{(!hideHtml || !!children) && tab === 1 && (
|
||||
<Bash
|
||||
code={process.browser ? htmlFormat() : `<div />`}
|
||||
language="jsx"
|
||||
copy
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Preview;
|
||||
@@ -1,29 +0,0 @@
|
||||
.preview__wrapper {
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
background-color: var(--bg-secondary);
|
||||
margin-bottom: 3rem;
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.preview__container {
|
||||
border-bottom: 2px solid var(--code-divider);
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.preview__container--no-code {
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.preview__container > * {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.preview__container figcaption {
|
||||
text-align: center;
|
||||
padding: 0.5em;
|
||||
font-style: italic;
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
import copy from "copy-to-clipboard";
|
||||
import Prism from "prismjs";
|
||||
import cl from "classnames";
|
||||
import { ErrorFilled, Copy, SuccessFilled } from "@navikt/ds-icons";
|
||||
import { Popover } from "@navikt/ds-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import "prismjs/components/prism-jsx.min";
|
||||
import "./bash.css";
|
||||
|
||||
type PrismLanguages =
|
||||
| "extend"
|
||||
| "insertBefore"
|
||||
| "DFS"
|
||||
| "markup"
|
||||
| "html"
|
||||
| "mathml"
|
||||
| "svg"
|
||||
| "xml"
|
||||
| "ssml"
|
||||
| "atom"
|
||||
| "rss"
|
||||
| "css"
|
||||
| "clike"
|
||||
| "javascript"
|
||||
| "js"
|
||||
| "jsx";
|
||||
|
||||
export const copyCode = (content) => {
|
||||
if (typeof content === "string") {
|
||||
copy(content, {
|
||||
format: "text/plain",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const Bash = ({
|
||||
code,
|
||||
terminal = false,
|
||||
copy = true,
|
||||
language = "html",
|
||||
good,
|
||||
bad,
|
||||
...props
|
||||
}: {
|
||||
code: string;
|
||||
terminal?: boolean;
|
||||
copy?: boolean;
|
||||
language?: PrismLanguages;
|
||||
good?: boolean;
|
||||
bad?: boolean;
|
||||
}) => {
|
||||
const highlighted = terminal
|
||||
? code
|
||||
: Prism.highlight(code, Prism.languages[language], language);
|
||||
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
const [openPopover, setOpenPopover] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (openPopover) {
|
||||
timeoutRef.current = setTimeout(() => setOpenPopover(false), 1500);
|
||||
return () => timeoutRef.current && clearTimeout(timeoutRef.current);
|
||||
}
|
||||
}, [openPopover]);
|
||||
|
||||
const handleCopy = () => {
|
||||
copyCode(code);
|
||||
setOpenPopover(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={"bash__preWrapper"}>
|
||||
<pre
|
||||
className={cl("bash__pre", {
|
||||
"bash__pre--good": !!good,
|
||||
"bash__pre--bad": !!bad,
|
||||
})}
|
||||
>
|
||||
<code
|
||||
className={cl("bash__code", {
|
||||
bash__codeCopy: copy,
|
||||
bash__terminal: terminal,
|
||||
})}
|
||||
{...props}
|
||||
dangerouslySetInnerHTML={{ __html: highlighted }}
|
||||
/>
|
||||
{copy && (
|
||||
<>
|
||||
<button
|
||||
ref={buttonRef}
|
||||
className={"bash__copyButton"}
|
||||
onClick={() => handleCopy()}
|
||||
>
|
||||
<Copy />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</pre>
|
||||
{(good || bad) && (
|
||||
<div className="bash__good-bad">
|
||||
{good && (
|
||||
<>
|
||||
<SuccessFilled style={{ color: "var(--navds-color-green-50)" }} />
|
||||
Gjør dette!
|
||||
</>
|
||||
)}
|
||||
{bad && (
|
||||
<>
|
||||
<ErrorFilled style={{ color: "var(--navds-color-red-60)" }} />
|
||||
Ikke gjør dette!
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Popover
|
||||
className="bash__popover"
|
||||
role="alert"
|
||||
anchorEl={buttonRef.current}
|
||||
open={openPopover}
|
||||
onClose={() => setOpenPopover(false)}
|
||||
placement="right"
|
||||
arrow={false}
|
||||
>
|
||||
Kopiert!
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Bash;
|
||||
@@ -1,22 +0,0 @@
|
||||
import Bash from "./Bash";
|
||||
|
||||
interface ImportProps {
|
||||
from: string;
|
||||
imports: string | string[];
|
||||
namedExport?: boolean;
|
||||
}
|
||||
|
||||
const Import = ({ namedExport = true, from, imports }: ImportProps) => {
|
||||
const genCode = () => {
|
||||
if (Array.isArray(imports)) {
|
||||
return `import { ${imports.join(", ")} } from "${from}";`;
|
||||
} else if (!namedExport) {
|
||||
return `import ${imports} from "${from}";`;
|
||||
} else {
|
||||
return `import { ${imports} } from "${from}";`;
|
||||
}
|
||||
};
|
||||
return <Bash code={genCode()} copy language="jsx"></Bash>;
|
||||
};
|
||||
|
||||
export default Import;
|
||||
@@ -1,7 +0,0 @@
|
||||
import "./bash.css";
|
||||
|
||||
const Inline = ({ children }) => (
|
||||
<code className="inline-code">{children}</code>
|
||||
);
|
||||
|
||||
export default Inline;
|
||||
@@ -1,80 +0,0 @@
|
||||
.bash__pre {
|
||||
padding: 1rem;
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
background-color: var(--bg-code);
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-family: var(--navds-font-family);
|
||||
}
|
||||
|
||||
.bash__pre--good {
|
||||
border-bottom: 8px solid var(--navds-color-green-50);
|
||||
}
|
||||
|
||||
.bash__pre--bad {
|
||||
border-bottom: 8px solid var(--navds-color-red-60);
|
||||
}
|
||||
|
||||
.bash__good-bad {
|
||||
margin-top: -1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 0.5rem;
|
||||
}
|
||||
|
||||
.bash__preWrapper {
|
||||
position: relative;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.bash__terminal {
|
||||
color: var(--color-code);
|
||||
}
|
||||
|
||||
.bash__code {
|
||||
color: var(--color-code);
|
||||
font-family: var(--font-family-code);
|
||||
font-size: 1rem;
|
||||
padding-right: 4rem;
|
||||
}
|
||||
|
||||
.bash__terminal::before {
|
||||
content: "$ ";
|
||||
}
|
||||
|
||||
.bash__copyButton {
|
||||
position: absolute;
|
||||
top: 1.5rem;
|
||||
right: 0.5rem;
|
||||
background-color: var(--bg-code);
|
||||
color: white;
|
||||
font-size: 1.5rem;
|
||||
padding: 0.5rem;
|
||||
border: none;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.bash__copyButton:hover {
|
||||
background-color: var(--navds-color-gray-60);
|
||||
}
|
||||
|
||||
.bash__copyButton:focus {
|
||||
outline: var(--outline-code);
|
||||
outline-offset: var(--outline-offset);
|
||||
}
|
||||
|
||||
.bash__popover {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.inline-code {
|
||||
color: #c30000;
|
||||
font-family: var(--font-family-code);
|
||||
display: inline-block;
|
||||
padding: 0 0.125rem;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import cl from "classnames";
|
||||
import Header from "./header/Header";
|
||||
import Sidebar from "./sidebar/Sidebar";
|
||||
import { ContentContainer } from "@navikt/ds-react";
|
||||
import { useMediaQuery } from "react-responsive";
|
||||
import useKeypress from "react-use-keypress";
|
||||
import { useEffect, useState } from "react";
|
||||
import "./theme.css";
|
||||
import "./layout.css";
|
||||
|
||||
interface LayoutProps {
|
||||
children?: React.ReactNode;
|
||||
menu: any[];
|
||||
}
|
||||
|
||||
const Layout = ({ children, menu }: LayoutProps) => {
|
||||
const [sidebar, setSidebar] = useState(false);
|
||||
|
||||
const small = useMediaQuery({
|
||||
query: "(max-width: 959px)",
|
||||
});
|
||||
|
||||
useKeypress("Escape", () => {
|
||||
setSidebar(false);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setSidebar(!small);
|
||||
}, [small]);
|
||||
|
||||
useEffect(() => {
|
||||
document.body.classList.add("lightTheme");
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div id="pageWrapper" className={cl("pageWrapper")}>
|
||||
<Header sidebar={sidebar} onSidebarChange={(x) => setSidebar(x)} />
|
||||
<Sidebar
|
||||
menu={menu}
|
||||
sidebar={sidebar}
|
||||
small={small}
|
||||
onSidebarChange={(x) => setSidebar(x)}
|
||||
/>
|
||||
<main className={"contentWrapper"}>
|
||||
<ContentContainer>
|
||||
<div className={"content"}>{children}</div>
|
||||
</ContentContainer>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Layout;
|
||||
@@ -1,42 +0,0 @@
|
||||
import Link from "next/link";
|
||||
import NavLogo from "../../assets/navLogo.svg";
|
||||
import { HamburgerFilled } from "@navikt/ds-icons";
|
||||
import cl from "classnames";
|
||||
import "../layout.css";
|
||||
|
||||
interface HeaderProps {
|
||||
className?: string;
|
||||
sidebar: boolean;
|
||||
onSidebarChange: (x: boolean) => void;
|
||||
}
|
||||
|
||||
const Header = ({
|
||||
className,
|
||||
sidebar,
|
||||
onSidebarChange,
|
||||
...props
|
||||
}: HeaderProps) => {
|
||||
return (
|
||||
<header className={"header"}>
|
||||
<button
|
||||
onClick={() => onSidebarChange(!sidebar)}
|
||||
className={cl("header__link", "header__icon", {
|
||||
"header__icon--hidden": sidebar,
|
||||
})}
|
||||
tabIndex={!sidebar ? 0 : -1}
|
||||
>
|
||||
<HamburgerFilled />
|
||||
</button>
|
||||
<Link href="/">
|
||||
<button className={"header__link"}>
|
||||
<NavLogo />
|
||||
<span className="header__link-title navds-title navds-title--m">
|
||||
NAV Designsystem
|
||||
</span>
|
||||
</button>
|
||||
</Link>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
@@ -1,145 +0,0 @@
|
||||
.pageWrapper {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-areas:
|
||||
"header header"
|
||||
"sidebar content";
|
||||
height: 100vh;
|
||||
background-color: var(--bg-primary);
|
||||
}
|
||||
|
||||
.header {
|
||||
grid-area: header;
|
||||
display: flex;
|
||||
z-index: 99;
|
||||
color: #fff;
|
||||
height: 5rem;
|
||||
background-color: #c30000;
|
||||
}
|
||||
|
||||
.header__link {
|
||||
background: none;
|
||||
border: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 3rem;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header__icon {
|
||||
color: #fff;
|
||||
font-size: 1.5rem;
|
||||
height: 5rem;
|
||||
width: 5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar__icon {
|
||||
color: var(--navds-color-blue-50);
|
||||
height: 5rem;
|
||||
width: 5rem;
|
||||
font-size: 1.5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sidebar__icon:focus {
|
||||
outline: 2px solid var(--navds-color-blue-50);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.header__icon--hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.header__link:focus {
|
||||
outline: 2px solid white;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.header__link-title {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
grid-area: sidebar;
|
||||
flex-direction: column;
|
||||
width: 300px;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
background-color: var(--bg-secondary);
|
||||
box-shadow: inset -2px 0px 0px var(--sidebar-shadow);
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.contentWrapper {
|
||||
grid-area: content;
|
||||
overflow-y: auto;
|
||||
overflow: visible;
|
||||
margin: 0 auto 0 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.contentWrapper > * li {
|
||||
margin-bottom: 0.75rem;
|
||||
line-height: 1.375rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
@media (max-width: 959px) {
|
||||
.sidebar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 447px) {
|
||||
.header__link {
|
||||
column-gap: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar__mobile {
|
||||
z-index: 999;
|
||||
display: flex;
|
||||
background-color: var(--bg-secondary);
|
||||
flex-direction: column;
|
||||
color: var(--text-color);
|
||||
overflow-y: auto;
|
||||
position: fixed;
|
||||
left: -300px;
|
||||
min-height: 100vh;
|
||||
border-right: var(--sidebar-divider);
|
||||
}
|
||||
|
||||
.sidebar__mobile--open {
|
||||
transition: transform 250ms cubic-bezier(0.6, 0.05, 0.28, 0.91);
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.sidebar--overlay {
|
||||
display: block;
|
||||
z-index: 200;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
transition: background 0.15s linear;
|
||||
}
|
||||
|
||||
.sidebar--overlay--fade {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import { useRouter } from "next/router";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
AccordionMenu,
|
||||
AccordionMenuCollapsable,
|
||||
AccordionMenuItem,
|
||||
} from "@navikt/ds-react";
|
||||
import React from "react";
|
||||
import parseUrl from "url-parse";
|
||||
|
||||
const MenuLink = (node) => {
|
||||
const { asPath } = useRouter();
|
||||
|
||||
return (
|
||||
<Link href={node.pathName} passHref>
|
||||
<AccordionMenuItem active={parseUrl(asPath).pathname === node.pathName}>
|
||||
{node.title}
|
||||
</AccordionMenuItem>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
const isActive = (children, path) => {
|
||||
const active = children.find((child) => {
|
||||
return child.children
|
||||
? isActive(child.children, path)
|
||||
: child.pathName === path;
|
||||
});
|
||||
return !!active;
|
||||
};
|
||||
|
||||
const mapToComponents = (node, path) => {
|
||||
const active = node.children ? isActive(node.children, path) : false;
|
||||
|
||||
return node.children ? (
|
||||
<AccordionMenuCollapsable
|
||||
defaultOpen={active}
|
||||
key={node.title}
|
||||
title={node.title}
|
||||
>
|
||||
{node.children.map((item) => mapToComponents(item, path))}
|
||||
</AccordionMenuCollapsable>
|
||||
) : (
|
||||
<MenuLink key={node.title} {...node} />
|
||||
);
|
||||
};
|
||||
|
||||
const Menu = ({ menu }) => {
|
||||
const { asPath } = useRouter();
|
||||
return (
|
||||
<AccordionMenu>
|
||||
{menu.map((item) => mapToComponents(item, parseUrl(asPath).pathname))}
|
||||
</AccordionMenu>
|
||||
);
|
||||
};
|
||||
|
||||
export default Menu;
|
||||
@@ -1,50 +0,0 @@
|
||||
import cl from "classnames";
|
||||
import { Close } from "@navikt/ds-icons";
|
||||
import "../layout.css";
|
||||
import Menu from "./Menu";
|
||||
|
||||
interface SidebarProps {
|
||||
classname?: string;
|
||||
sidebar: boolean;
|
||||
small: boolean;
|
||||
onSidebarChange: (x: boolean) => void;
|
||||
menu: any[];
|
||||
}
|
||||
|
||||
const Sidebar = ({
|
||||
sidebar,
|
||||
small,
|
||||
onSidebarChange,
|
||||
menu = [],
|
||||
}: SidebarProps) => {
|
||||
return (
|
||||
<>
|
||||
{sidebar && small && (
|
||||
<div
|
||||
onClick={() => onSidebarChange(false)}
|
||||
className={cl("sidebar--overlay", {
|
||||
"sidebar--overlay--fade": sidebar,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={cl("sidebar", {
|
||||
sidebar__mobile: small,
|
||||
"sidebar__mobile--open": small && sidebar,
|
||||
})}
|
||||
>
|
||||
{small && sidebar && (
|
||||
<button
|
||||
onClick={() => onSidebarChange(!sidebar)}
|
||||
className={"sidebar__icon"}
|
||||
>
|
||||
<Close />
|
||||
</button>
|
||||
)}
|
||||
<Menu menu={menu} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
||||
@@ -1,25 +0,0 @@
|
||||
:root {
|
||||
--bg-primary: #faf9f9;
|
||||
--font-family-code: "Source Code Pro", monospace;
|
||||
}
|
||||
|
||||
.darkTheme {
|
||||
--theme: "dark";
|
||||
}
|
||||
|
||||
.lightTheme {
|
||||
--theme: "light";
|
||||
--bg-primary: #faf9f9;
|
||||
--bg-secondary: #fff;
|
||||
--sidebar-shadow: #e7e9e9;
|
||||
--outline: 1px solid var(--navds-color-gray-40);
|
||||
--tab-color: var(--navds-color-blue-50);
|
||||
--tab-color-active: var(--navds-color-darkgray);
|
||||
--tab-border: 4px solid var(--navds-color-blue-50);
|
||||
--outline-focus: 2px solid var(--navds-color-blue-80);
|
||||
--outline-offset: -2px;
|
||||
--bg-code: var(--navds-color-gray-90);
|
||||
--color-code: #fff;
|
||||
--code-divider: var(--sidebar-shadow);
|
||||
--outline-code: 2px solid var(--color-code);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import getConfig from "next/config";
|
||||
import Import from "../code/Import";
|
||||
import "./npm.css";
|
||||
|
||||
const Npm = ({
|
||||
packName,
|
||||
imports,
|
||||
namedExport,
|
||||
}: {
|
||||
packName: string;
|
||||
imports: string | string[];
|
||||
namedExport?: boolean;
|
||||
}) => {
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
const packs = publicRuntimeConfig.packages.filter(
|
||||
(pack) => pack.name === packName
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{packs.map(({ name, data }) => (
|
||||
<div key={name}>
|
||||
<Import from={name} imports={imports} namedExport={namedExport} />
|
||||
{/* TODO: Move to separate component? */}
|
||||
{/* <span className={style.badges}>
|
||||
<span className={"npm__.badges"}>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={`https://www.npmjs.com/package/${name}`}
|
||||
>
|
||||
<img
|
||||
src={`https://badgen.net/npm/v/${name}/?style=for-the-badge&logo=appveyor`}
|
||||
alt="Versjonsbadge for npm-pakken"
|
||||
/>
|
||||
</a>
|
||||
</span> */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Npm;
|
||||
@@ -1,5 +0,0 @@
|
||||
.npm__badges {
|
||||
display: flex;
|
||||
column-gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
import classnames from "classnames";
|
||||
|
||||
import "./overflowdetector.css";
|
||||
|
||||
const OverflowDetector = ({ ...props }) => {
|
||||
const scroller = useRef<HTMLDivElement>();
|
||||
const inner = useRef<HTMLDivElement>();
|
||||
|
||||
const [overflowLeft, setOverflowLeft] = useState(false);
|
||||
const [overflowRight, setOverflowRight] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("resize", checkOverflow);
|
||||
checkOverflow();
|
||||
return () => {
|
||||
window.removeEventListener("resize", checkOverflow);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const checkOverflow = () => {
|
||||
const scr = scroller.current;
|
||||
const inn = inner.current;
|
||||
|
||||
if (scr && inn) {
|
||||
if (scr.offsetWidth < inn.offsetWidth) {
|
||||
if (scr.scrollLeft !== 0) {
|
||||
setOverflowLeft(true);
|
||||
}
|
||||
if (scr.scrollLeft + scr.offsetWidth < inn.offsetWidth) {
|
||||
setOverflowRight(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const scrollAttr =
|
||||
overflowRight || overflowLeft
|
||||
? {
|
||||
tabIndex: 0,
|
||||
role: "region",
|
||||
"aria-label": "Eksempel",
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames("overflow-detector", {
|
||||
"overflow-detector--shadow-left": overflowLeft,
|
||||
"overflow-detector--shadow-right": overflowRight,
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className="overflow-detector__scroller"
|
||||
onScroll={checkOverflow}
|
||||
ref={scroller}
|
||||
{...scrollAttr}
|
||||
>
|
||||
<div className="overflow-detector__inner" ref={inner}>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OverflowDetector;
|
||||
@@ -1,40 +0,0 @@
|
||||
.overflow-detector {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.overflow-detector__scroller {
|
||||
overflow: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.overflow-detector__scroller:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px var(--navds-color-blue-80);
|
||||
}
|
||||
|
||||
.overflow-detector__inner {
|
||||
display: inline-block;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.overflow-detector--shadow-left::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 20px;
|
||||
opacity: 0.1;
|
||||
left: 0;
|
||||
background: linear-gradient(to right, rgba(0, 0, 0, 1), transparent);
|
||||
}
|
||||
|
||||
.overflow-detector--shadow-right::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 20px;
|
||||
opacity: 0.1;
|
||||
right: 0;
|
||||
background: linear-gradient(to left, rgba(0, 0, 0, 1), transparent);
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
import getConfig from "next/config";
|
||||
import { useState } from "react";
|
||||
import "./proptable.css";
|
||||
import Inline from "../code/Inline";
|
||||
import "nav-frontend-tabell-style";
|
||||
import { Select } from "nav-frontend-skjema";
|
||||
import Import from "../code/Import";
|
||||
|
||||
const Proptable = ({
|
||||
names,
|
||||
defaultExport,
|
||||
from,
|
||||
}: {
|
||||
names: string[];
|
||||
defaultExport?: string;
|
||||
from: string;
|
||||
}) => {
|
||||
const [tab, setTab] = useState(0);
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
const props = publicRuntimeConfig.props
|
||||
.filter((comp) => [...names, defaultExport].includes(comp.displayName))
|
||||
.map((comp) => {
|
||||
return { ...comp, defaultExport: comp.displayName === defaultExport };
|
||||
})
|
||||
.sort((a, b) => a.defaultValue === b.defaultValue);
|
||||
|
||||
const headers = ["Prop", "Type", "Description"];
|
||||
|
||||
const ProptableHeader = (props) => <th key={props.index}>{props.val}</th>;
|
||||
|
||||
const parsePropValue = (val) => {
|
||||
if (val && typeof val === "object") {
|
||||
if (val.name === "enum") {
|
||||
return val.value.map((x) => x.value).join(" | ");
|
||||
}
|
||||
val = val.name || val.value;
|
||||
}
|
||||
if (val === null || typeof val === "undefined" || val.length <= 0) {
|
||||
return "-";
|
||||
}
|
||||
return val.toString();
|
||||
};
|
||||
|
||||
const parseDescription = (desc) => {
|
||||
const found = desc.match(/^@deprecated(.*)/);
|
||||
if (found) {
|
||||
return (
|
||||
<span>
|
||||
<strong>{found[0]}</strong>
|
||||
{found[1]}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return desc;
|
||||
};
|
||||
|
||||
const PropTypeTableRow = (props) => {
|
||||
return (
|
||||
<tr className="proptable__tr">
|
||||
<td>
|
||||
<div>
|
||||
<strong>{parsePropValue(props.val.name)}</strong>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<Inline>{parsePropValue(props.val.type)}</Inline>
|
||||
</div>
|
||||
</td>
|
||||
{/* <td>
|
||||
<div>{parsePropValue(props.val.defaultValue)}</div>
|
||||
</td> */}
|
||||
<td>
|
||||
<div>{parseDescription(parsePropValue(props.val.description))}</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="proptable__wrapper">
|
||||
<>
|
||||
<h3>Komponenter</h3>
|
||||
|
||||
<Select
|
||||
onChange={(x) => setTab(Number(x.target.value))}
|
||||
label="Velg komponent"
|
||||
>
|
||||
{props.map((x, i) => (
|
||||
<option key={i + x} value={i}>
|
||||
{x.displayName}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
<Import
|
||||
from={from}
|
||||
imports={props[tab].displayName}
|
||||
namedExport={!props[tab].defaultExport}
|
||||
/>
|
||||
<table className="tabell tabell--stripet proptable__table">
|
||||
<thead>
|
||||
<tr>
|
||||
{headers.map((header, index) => (
|
||||
<ProptableHeader val={header} index={index} key={index} />
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{props[tab].props
|
||||
.filter((item) => item.name.indexOf("aria-") !== 0)
|
||||
.map((prop, key) => (
|
||||
<PropTypeTableRow
|
||||
val={{
|
||||
...prop,
|
||||
defaultValue: prop.defaultValue ? prop.defaultValue : "-",
|
||||
}}
|
||||
key={key}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Proptable;
|
||||
@@ -1,9 +0,0 @@
|
||||
.proptable__wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.proptable__table {
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { useContext } from "react";
|
||||
import { Next } from "@navikt/ds-icons";
|
||||
import { Title } from "@navikt/ds-react";
|
||||
import { PagePropsContext } from "../../pages/_app";
|
||||
import "./tableOfContents.css";
|
||||
|
||||
const TableOfContents = () => {
|
||||
const { tableOfContents } = useContext<any>(PagePropsContext);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title size="l" spacing level={2}>
|
||||
Innhold
|
||||
</Title>
|
||||
<ul className={"toc__ul"}>
|
||||
{tableOfContents?.map(({ heading, slug }) => (
|
||||
<li key={slug} className={"toc__li navds-body-short"}>
|
||||
<Next
|
||||
aria-label="Pil peker på lenke"
|
||||
focusable="false"
|
||||
role="img"
|
||||
aria-hidden
|
||||
/>
|
||||
<a href={`#${slug}`}>{heading}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableOfContents;
|
||||
@@ -1,62 +0,0 @@
|
||||
.toc__ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.toc__li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
color: var(--navds-color-blue-50);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: margin 100ms linear;
|
||||
column-gap: 0.25rem;
|
||||
padding: 0.25rem 0;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.toc__li > a {
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
var(--navds-color-text-link) 0%,
|
||||
var(--navds-color-text-link) 100%
|
||||
);
|
||||
background-size: 0px 2px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
transition: background-size 0.15s;
|
||||
}
|
||||
|
||||
.toc__li > svg {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.toc__li:hover > a {
|
||||
background-size: 100% 2px;
|
||||
}
|
||||
|
||||
.toc__li:focus-within > a {
|
||||
color: var(--navds-color-darkgray);
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
var(--navds-color-darkgray) 0%,
|
||||
var(--navds-color-darkgray) 100%
|
||||
);
|
||||
background-size: 100% 2px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.toc__li:focus-within > svg {
|
||||
color: var(--navds-color-darkgray);
|
||||
}
|
||||
|
||||
.toc__li > a:active {
|
||||
color: var(--navds-color-text-inverse);
|
||||
background-color: var(--navds-color-blue-80);
|
||||
background-size: 0px 2px;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import "./tabs.css";
|
||||
import cl from "classnames";
|
||||
|
||||
interface TabsProps {
|
||||
onChange: (tab: number) => void;
|
||||
tabs: string[];
|
||||
tab: number;
|
||||
}
|
||||
|
||||
const Tabs = ({ onChange, tabs, tab, ...props }: TabsProps) => {
|
||||
const handleClick = (x: number) => {
|
||||
onChange(x);
|
||||
};
|
||||
|
||||
return (
|
||||
<ul className={"tabs__ul"}>
|
||||
{tabs.map((t, x) => (
|
||||
<li key={t + x} className={"tabs__li"}>
|
||||
<button
|
||||
className={cl("tabs__button", { tabs__buttonActive: x === tab })}
|
||||
onClick={() => handleClick(x)}
|
||||
>
|
||||
{t}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tabs;
|
||||
@@ -1,33 +0,0 @@
|
||||
.tabs__ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.tabs__li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.tabs__button {
|
||||
color: var(--tab-color);
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0.5rem 1.5rem 0.25rem 1.5rem;
|
||||
font-weight: var(--navds-font-weight-bold);
|
||||
border-bottom: 4px solid transparent;
|
||||
}
|
||||
|
||||
.tabs__button:hover {
|
||||
border-bottom: 4px solid var(--navds-color-darkgray);
|
||||
color: var(--navds-color-darkgray);
|
||||
}
|
||||
|
||||
.tabs__button:focus {
|
||||
outline: var(--outline-focus);
|
||||
outline-offset: var(--outline-offset);
|
||||
}
|
||||
|
||||
.tabs__buttonActive {
|
||||
border-bottom: var(--tab-border);
|
||||
color: var(--tab-color-active);
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
---
|
||||
title: Tilgjengelighet i NAV
|
||||
rank: 1
|
||||
---
|
||||
|
||||
# Tilgjengelighet i NAV
|
||||
|
||||
Å leve med nedsatt funksjonsevne fører ofte med seg utfordringer i
|
||||
dagliglivet, deriblant bruk av teknologi. Defor skal alle digitale løsninger
|
||||
vi bygger i NAV være universelt utformet slik at de aller fleste kan klare seg
|
||||
selv. Utdypende informasjon om hvordan håndtere universell utforming av IT i NAV
|
||||
finner du på <a href="https://navikt.github.io/uu/">https://navikt.github.io/uu/</a>
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Nødvendig for noen, bra for alle
|
||||
|
||||
I følge Verdens helseorganisasjon lever omtrent [15 prosent av verdens befolkning](https://www.who.int/disabilities/world_report/2011/report/en/) med en eller annen form for permanent nedsatt funksjonsevne. Samtidig kan vi alle oppleve å få midlertidig nedsatt funksjonsevne som følge av f.eks. uhell eller sykdom. Det betyr at tilpasninger som er nødvendig for noen, kan være bra for alle i blant.
|
||||
|
||||
<Preview noCode>
|
||||
<Undertittel>Eksempler:</Undertittel>
|
||||
<ul>
|
||||
<li>
|
||||
Tekstede videoer er bra for hørselshemmede og bra for en pendler på toget.
|
||||
</li>
|
||||
<li>
|
||||
God lesbarhet er ikke bare nødvendig for sterkt synshemmede, det er også
|
||||
fint for de som «bare» har glemt lesebrillene hjemme.
|
||||
</li>
|
||||
<li>
|
||||
At nettsidene kan brukes med tastaturet er bra både for en med nedsatt
|
||||
motorikk og en med senebetennelse.
|
||||
</li>
|
||||
</ul>
|
||||
</Preview>
|
||||
|
||||
### Eksempler på funksjonshemninger
|
||||
|
||||
<table className="tabell">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Permanent</th>
|
||||
<th>Midlertidig</th>
|
||||
<th>Situasjonsbetinget</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Bevegelse</th>
|
||||
<td>Én arm</td>
|
||||
<td>Brukket arm</td>
|
||||
<td>Nybakt forelder</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Syn</th>
|
||||
<td>Blind</td>
|
||||
<td>Glemt briller</td>
|
||||
<td>Uoppmerksom sjåfør</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Hørsel</th>
|
||||
<td>Døv</td>
|
||||
<td>Øreinfeksjon</td>
|
||||
<td>Bartender</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Tale</th>
|
||||
<td>Ikke-verbal</td>
|
||||
<td>Laryngitt</td>
|
||||
<td>Sterk aksent</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Lovkrav
|
||||
|
||||
NAV, i likhet med alle andre offentlige og private virksomheter, er pålagt å etterleve hovedregelen om at alle IKT-løsninger skal være universelt utformet.\*
|
||||
|
||||
Vi oppfordrer alle til å gjøre seg kjent med og bruke følgende ressurser aktivt:
|
||||
|
||||
<LenkepanelBase className="resource-link" href="https://uu.difi.no" border>
|
||||
<div>
|
||||
<Undertittel className="Linkpanel__heading">
|
||||
Universell utforming, Difi (uu.difi.no)
|
||||
</Undertittel>
|
||||
<p>
|
||||
Tilsynsmyndighetenes offentlige ressursportal for universell utforming av
|
||||
digitale tjenester.
|
||||
</p>
|
||||
</div>
|
||||
</LenkepanelBase>
|
||||
|
||||
<LenkepanelBase
|
||||
className="resource-link"
|
||||
href="https://www.w3.org/TR/WCAG21/"
|
||||
border
|
||||
>
|
||||
<div>
|
||||
<Undertittel className="Linkpanel__heading">
|
||||
Web Content Accessibility Guidelines (WCAG) 2.1
|
||||
</Undertittel>
|
||||
<p>
|
||||
Neste versjon av W3s internasjonale standard med teknisk spesifikasjon for
|
||||
minimumskrav (nivå A og AA) alle digitale løsninger må oppfylle.
|
||||
</p>
|
||||
</div>
|
||||
</LenkepanelBase>
|
||||
|
||||
<Alert variant="info">
|
||||
* Per nå gir{" "}
|
||||
<Link href="https://lovdata.no/dokument/SF/forskrift/2013-06-21-732">
|
||||
forskriften
|
||||
</Link>{" "}
|
||||
egentlig unntak for noen typer systemer (som f.eks. interne
|
||||
saksbehandlingsystemer). Vi har uansett bestemt at våre internsystemer likevel
|
||||
skal oppfylle kravene på samme måte som systemer vi lager mot allmennheten - i
|
||||
tråd med NAVs ønske om å ikke ekskludere noen og støtte alle våre ansatte
|
||||
gjennom hele arbeidslivet.
|
||||
</Alert>
|
||||
<br />
|
||||
<Alert variant="warning">
|
||||
Merk at nivå A og AA i WCAG kun spesifiserer de kravene som er{" "}
|
||||
<strong>absolutt minimum</strong> av det vi må oppfylle. Det bør være et mål i
|
||||
seg selv å gjøre mer enn bare det som er minimum.
|
||||
</Alert>
|
||||
|
||||
## Bruk designsystemet
|
||||
|
||||
Ved å bruke Designsystemet får du mye gratis hjelp, og en bra start i både design- og utviklingsprosessen. Vi har lagt ned mye tid og arbeid for å sikre at komponentene og retningslinjene i Designsystemet er utformet i henhold til offentlige krav til universell utforming. Besøk tilgjengelighets-fanen på de forskjellige [komponent-sidene](/components) for å lese mer om hvilke hensyn du bør være klar over for den enkelte komponent.
|
||||
|
||||
Samtidig er det mange hensyn som ikke blir løst av designsystemet alene, og alle på teamet har et felles ansvar for å sikre at løsningene dere lager blir universelt utformet.
|
||||
|
||||
## Tips for å unngå vanlige feil
|
||||
|
||||
Dette er noen av de viktigste tingene du bør huske på for å unngå de vanligste feilene. Vær likevel bevisst på at disse punktene ikke er komplett.
|
||||
|
||||
### For designere
|
||||
|
||||
[Flere tips for produktdesignere](https://navikt.github.io/uu/hvordan-faa-det-til/tips-etter-rolle/Produktdesigner/) og [tjenestedesignere](https://navikt.github.io/uu/hvordan-faa-det-til/tips-etter-rolle/Tjenestedesigner/) finner du på uu-sidene.
|
||||
|
||||
1. Bruk aktuell versjon av [NAVs komponent- og illustrasjonsbibliotek](/resources/new-project#for-designere) når du designer.
|
||||
2. Design for grupper med spesielle behov («ytterkantene»). Spør deg selv: Hadde bestemoren min klart å bruke tjenesten? [Om inklusiv design (University of Cambridge)](http://www.inclusivedesigntoolkit.com/whatis/whatis.html)
|
||||
3. Husk [god kontrast](/resources/colors/accessibility#krav-til-kontrast), både på tekst, interaktive elementer, grafer og illustrasjoner.
|
||||
4. Husk [beskrivende alt-tekster](/accessibility/alt-text) på bilder, illustrasjoner og grafer.
|
||||
5. Når [farge](/resources/colors/accessibility) benyttes for å gjøre informasjon tydeligere, skal du alltid bruke noe i tillegg til farge som formidler samme informasjon. Da vil innholdet også fungere for personer som ikke kan oppfatte farge, og man kan skrive ut i svart-hvitt uten at fremhevet informasjon blir borte.
|
||||
6. Video: Husk å ha en tekstversjon som har samme innhold som videoen på siden, samt tekste video og bruk nyeste versjon av QBrick. Snart kommer en lovendring om at videoer også må være synstolket. Det betyr at man skal tilby en audiobeskrivelse av det som vises i videoen som ikke blir tydelig av selve lydsporet.
|
||||
7. Språk og begreper: Skriv så forståelig som mulig og test teksten på reelle brukere. Bruk beskrivende overskrifter, deloverskrifter og punktlister der det er hensiktsmessig. Husk å ha en hovedoverskrift som beskriver hovedinnholdet på siden. Les mer om [tekst og struktur (Difi)]([https://uu.difi.no/krav-og-regelverk/losningsforslag-web/tekst-og-struktur) og våre [retningslinjer for språk](https://design.nav.no/resources/language)
|
||||
8. Linkr: Skriv Linktekster slik at det er tydelig hvor Linkn går. Ikke åpne Linkr i ny fane/vindu. Se [retningslinjer for gode Linkr](https://design.nav.no/components/Link/accessibility).
|
||||
9. Lag gode og [beskrivende feilmeldinger (DigDir)](https://uu.difi.no/krav-og-regelverk/losningsforslag-web/feilhandtering) og pass på at meldingene er i tråd med Designsystemet.
|
||||
10. Test med reelle brukere, også med personer som bruker hjelpemidler. Bruk Sanselaben i Fyrstikkaleen.
|
||||
|
||||
### For utviklere
|
||||
|
||||
[Flere tips for utviklere(https://navikt.github.io/uu/hvordan-faa-det-til/tips-etter-rolle/Utvikler/) på uu-sidene.
|
||||
|
||||
1. Bruk [komponentene våre](/components).
|
||||
2. Sjekk at koderekkefølgen gjenspeiler den visuelle rekkefølgen.
|
||||
3. Test at alt kan betjenes med tastatur og at fokusmarkering flyttes i forventet rekkefølge.
|
||||
4. Bruk de [semantiske egenskapene i HTML (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Semantics).
|
||||
5. Sjekk at du har med [hopp-Linkne (W3)](https://www.w3.org/TR/WCAG21/#bypass-blocks) og at de fungerer.
|
||||
6. Sjekk at du har med [riktig <title> (W3)](https://www.w3.org/TR/WCAG21/#page-titled). Formen skal være `[hovedinnhold/overskrift på siden] - www.nav.no`
|
||||
7. Pass på riktig [overskriftshierarki (DigDir)](https://uu.difi.no/krav-og-regelverk/losningsforslag-web/tekst-og-struktur)
|
||||
8. Sjekk at HTMLen din [validerer (W3)](https://validator.w3.org).
|
||||
9. Bruk [WAI-Aria (W3)](https://www.w3.org/WAI/standards-guidelines/aria) der standard HTML ikke er tilstrekkelig, for eksempel på [feilmeldinger](https://www.w3.org/TR/WCAG21/#status-messages)
|
||||
10. Bruk automatiserte testverktøy (som f.eks. [WAVE](https://wave.webaim.org) eller [Sortsite](https://www.powermapper.com/products/sortsite/)) aktivt og ofte.
|
||||
11. Test med skjermleser på egen hånd. Med for eksempel [ChromeVox](https://www.chromevox.com), [VoiceOver på Mac](https://webaim.org/articles/voiceover/), eller [TalkBack på Android](https://support.google.com/accessibility/android/answer/6283677?hl=en) er dette enklere enn du tror.
|
||||
12. Hvis mulig, bruk [automatisert testing](https://navikt.github.io/uu/hvordan-faa-det-til/UU-testing/automatisert-testing/) i utviklingsprosessen. Husk at dette dekker maks 20-30 prosent av potensielle feil.
|
||||
13. Test med reelle brukere, også med personer som bruker hjelpemidler. Bruk Sanselaben i Fyrstikkaleen.
|
||||
@@ -1,67 +0,0 @@
|
||||
---
|
||||
title: Verktøy for UU-testing
|
||||
rank: 5
|
||||
---
|
||||
|
||||
# Verktøy for uu-testing
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
<br />
|
||||
|
||||
<Alert variant="warning">
|
||||
<strong>VIKTIG!</strong> Før du tar i bruk noen av verktøyene nedenfor, må du
|
||||
huske at sikkerhet og personvern SKAL ivaretas. Sørg derfor for at du tester
|
||||
på testmiljøer og lignende som har fiktiv testdata. En av grunnene til dette
|
||||
er at noen av utvidelsene til nettlesere KAN sende data til servere utenfor
|
||||
NAV.
|
||||
</Alert>
|
||||
|
||||
## Manuell testing med skjermleser
|
||||
|
||||
Det finnes flere forskjellige skjermlesere. Vi anbefaler at du tester med en eller flere skjermlesere, og at du i tillegg brukertester med noen som bruker skjermleser til daglig.
|
||||
|
||||
- [**Voice over**](https://webaim.org/articles/voiceover/) - Gratis innebygd skjermleser på Mac og iPhone.
|
||||
- Se video: [_Screen Reader Basics: VoiceOver -- A11ycasts #07_](https://www.youtube.com/watch?v=5R-6WvAihms)
|
||||
- Se video: [_Assistive Tech: VoiceOver on iOS_](https://www.youtube.com/watch?v=bCHpdjvxBws)
|
||||
- Guide med shortcuts og mer info: [_Using VoiceOver to Evaluate Web Accessibility_](https://webaim.org/articles/voiceover/)
|
||||
- [**JAWS**](https://webaim.org/articles/jaws/) - Den mest populære skjermleseren til Windows. Kan være kostbar. Standard-skjermleser til våre interne ansatte på jobb.
|
||||
- Guide med shortcuts og mer info: [_Using JAWS to Evaluate Web Accessibility_](https://webaim.org/articles/jaws/)
|
||||
- [**NVDA**](https://webaim.org/articles/nvda/) - Populær og gratis skjermleser til Windows.
|
||||
- Se video: [_Screen Reader Basics: NVDA -- A11ycasts #09_](https://www.youtube.com/watch?v=Jao3s_CwdRU)
|
||||
- Guide med shortcuts og mer info: [_Using NVDA to Evaluate Web Accessibility_](https://webaim.org/articles/nvda/)
|
||||
- [_Download NVDA_](https://www.nvaccess.org/)
|
||||
- [**TalkBack**](https://support.google.com/accessibility/android/answer/6283677?hl=en) - Gratis skjermleser til Android.
|
||||
- Se video: [_Assistive Tech: TalkBack_](https://www.youtube.com/watch?v=0Zpzl4EKCco)
|
||||
|
||||
## Automatisk analyse
|
||||
|
||||
- [**W3Cs kodevalidator**](https://validator.w3.org/) - W3Cs verktøy for å teste om markup-en er valide (ikke direkte uu-tester, men sjekker om koden er i tråd med HTML-standarden, som er en viktig forutsetning for å møte uu-krav). Har blitt brukt i tilsyn.
|
||||
- [**Chrome DevTools**](https://developers.google.com/web/tools/chrome-devtools/) - gratis sett med webutviklerverktøy som ligger integrert i Google Chrome-nettleseren. Kan hjelpe deg med å redigere/manipulere en hvilken som helst nettside/tjeneste og raskt diagnostisere problemer.
|
||||
- Se video: [_The new way to test accessibility with Chrome DevTools - A11ycasts #23_](https://www.youtube.com/watch?v=b0Q5Zp_yKaU)
|
||||
- [**Lighthouse**](https://developers.google.com/web/tools/lighthouse/) (del av Chrome DevTools) - gir rask og detaljert analyse av nettsider med kriterier for ytelse, tilgjengelighet, progressive webapps, beste praksis, søkemotoroptimalisering for både mobile og desktop. Kan kjøres rett i Chrome DevTools, fra kommandolinjen, eller som en nodemodul
|
||||
- **Web Developer Toolbar** ([Chrome](https://chrome.google.com/webstore/detail/web-developer-toolbar/deeboegbjcnfgidliakhpoapnpomphji)/[Firefox](https://addons.mozilla.org/en-US/firefox/addon/web-developer/)) - gratis utvidelse med et hav av muligheter til å manipulere og validere nettsider.
|
||||
- [**ARC Toolkit**](https://chrome.google.com/webstore/detail/arc-toolkit/chdkkkccnlfncngelccgbgfmjebmkmce) - gratis utvidelse til Chrome med rike verktøy for å teste opp mot WCAG 2.0, WCAG 2.1, EN 301 549, Section 508.
|
||||
- [**Visual Aria**](https://chrome.google.com/webstore/detail/visual-aria/lhbmajchkkmakajkjenkchhnhbadmhmk) - gratis utvidelse til Chrome som gir en visuell oversikt over ARIA-attributter som brukes på en nettside, inkludert live regioner, roller, nøsting og fokushåndtering.
|
||||
- [**WAVE**](https://wave.webaim.org/) - gratis utvidelse til Chrome og Firefox som evaluerer tilgjengeligheten på nettsider og gir en veldig visuell tilbakemelding.
|
||||
- [**AXE Coconut**](https://chrome.google.com/webstore/detail/axe-coconut/iobddmbdndbbbfjopjdgadphaoihpojp) - gratis utvidelse for Chrome
|
||||
- Se video: [_Testing Shadow DOM with aXe Coconut - A11ycasts #26_](https://www.youtube.com/watch?v=1uyQdC3LqLo)
|
||||
- [**SortSite**](https://www.powermapper.com/products/sortsite/) - godt verktøy for validering av grensesnittkode opp mot W3C-standarder som WCAG 2.0/2.1, HTML5, CSS3, etc. Gir en god oversikt sammen med en god beskrivelse av hva som er feil, hvor feilen er og hvordan den kan fikses. Pris ca NOK 8000,- per lisens.
|
||||
- [**SiteImprove**](https://siteimprove.com/nb-no/) - godt verktøy som gir deg en lettfattelig og god oversikt over problemer og forbedringsområder. Som f.eks. dårlig kodekvalitet og kvalitetsfeil som brutte lenker og stavefeil, kontrastforhold som er for dårlig, m.m. Verktøy tester opp mot W3Cs standarder som f.eks. HTML5 og WCAG 2.0/2.1 og man kan filtrere funnene på roller (utvikler, redaktør, etc). God beskrivelse for hva som er feil og hvordan det kan fikses. Har blitt brukt i tilsyn.
|
||||
- [**Total Validator Pro**](http://www.totalvalidator.com/) - et av de bedre verktøyene til validering av kildekode og støtte for universell utforming. Pro-versjonen til kr 250,- (NAV har 30 lisenser).
|
||||
- [**Adobe Acrobat DC (PDF)**](https://helpx.adobe.com/no/acrobat/user-guide.html?topic=/no/no/acrobat/morehelp/accessibility_tags_and_reflow.ug.js) - validering av PDF-skjema opp mot W3C standarder som WCAG 2.0/2.1 (Verktøy>Tilgjengelighet>Tilgjengelighetskontroll eller Full kontroll. NAV har lisenser på dette.
|
||||
|
||||
## Lese- og skrivevansker
|
||||
|
||||
- [**Dyslexia Formatter**](https://chrome.google.com/webstore/detail/dyslexia-formatter/kggkghfhlppjclojgphbploiaipgogoc) - gratis utvidelse til Chrome som gjør det enklere å tilegne seg informasjon og bruke nettbaserte tjenester for folk med dysleksi
|
||||
|
||||
## Kontrastforhold
|
||||
|
||||
- [**http://contrastchecker.com/**](http://contrastchecker.com/) - her kan du legge inn fargekodene dine og få et konkret svar om kontrastforholdet er i tråd med WCAG-kravene. Du kan også se gråtoner som fargeblind (arkfaner øverst til høyre)
|
||||
- [**https://webaim.org/resources/contrastchecker/**](https://webaim.org/resources/contrastchecker/)
|
||||
- [**http://accessible-colors.com/**](http://accessible-colors.com/)
|
||||
|
||||
## Mobil- og nettleserkompatibilitet
|
||||
|
||||
- [**BrowserStack**](https://www.browserstack.com) - Instant access to 1200+ real mobile devices and browsers. Ship mobile apps and websites that work for everyone, every time… Lisenser kjøpt inn. Ikke gratis
|
||||
- [**Sauce Labs**](https://saucelabs.com) - tester om løsningen fungerer på kjente nettlesere, operativsystem og enheter. Lisenser på gang. Ikke gratis
|
||||
@@ -1,102 +0,0 @@
|
||||
---
|
||||
title: Alt-tekster
|
||||
rank: 1
|
||||
---
|
||||
|
||||
# Alternative tekster (alt-tekster)
|
||||
|
||||
Alle meningsbærende bilder skal ha en beskrivende alt-tekst.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Hva er en alt-tekst?
|
||||
|
||||
En alt-tekst (kort for alternativ tekst) er en tekst som vises eller leses opp når bildet ikke vises for brukeren. Dette kan være fordi:
|
||||
|
||||
- Bildet ble ikke funnet
|
||||
- Brukeren har skrudd av bildenedlasting
|
||||
- Brukeren har dårlig internettoppkobling
|
||||
- Brukeren bruker en skjermleser (for eksempel bilde)
|
||||
- Brukeren bruker en rent tekstbasert nettleser (f.eks. Lynx)
|
||||
|
||||
<Alert variant="info">
|
||||
Begrepet «bilde» favner i denne konteksten både fotografier, illustrasjoner,
|
||||
logoer, ikoner, grafer, infografikk og annen type grafikk.
|
||||
</Alert>
|
||||
|
||||
## Bilder uten alt-tekst
|
||||
|
||||
Bilder som ikke er meningsbærende (for eksempel bare til pynt eller overflødig) skal ikke ha noe alt-text, men <strong>husk</strong> å gi dem et tomt alt-attributt:
|
||||
|
||||
<Bash good code={`<img src="pynt.jpg" alt="" />`} />
|
||||
|
||||
<Bash bad code={`<img src="pynt.jpg" />`} />
|
||||
|
||||
<br />
|
||||
<Alert variant="warning">
|
||||
Skjermlesere trenger et tomt alt-attributt for å vite at de skal ignorere
|
||||
bildet. For bilder uten alt-attributt er det fare for at skjermlesere leser
|
||||
opp kilde-attributtet i stedet.
|
||||
</Alert>
|
||||
|
||||
## Er bildet «meningsbærende»?
|
||||
|
||||
Det er ikke alltid enkelt å vite om bildet er meningsbærende eller rent dekorativt.
|
||||
|
||||
En god start kan være å «leke skjermleser»: prøv å les opp siden som den skulle blitt lest for en bruker med skjermleser. Går brukeren glipp av relevant informasjon hvis du hopper over bildene?
|
||||
|
||||
Hvis bildene bare gjentar informasjon som er tilgjengelig i nærheten som ren tekst er alt-tekster på disse overfødig.
|
||||
|
||||
<Preview noCode>
|
||||
<Undertittel>Beslutningstre for alt-tekster</Undertittel>
|
||||
<div className="decision-tree-promo">
|
||||
<div className="decision-tree-screenshot">
|
||||
<img
|
||||
src={"/alt-decision-tree.png"}
|
||||
width="250px"
|
||||
alt="Skjermbilde av beslutningstreet på W3C sine nettsider."
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
Hvis du er i tvil anbefaler vi å bruke W3C sitt beslutningstre for å
|
||||
finne ut om man trenger alt-tekster eller ikke:
|
||||
</p>
|
||||
<Lenkepanel
|
||||
className="resource-link"
|
||||
href="https://www.w3.org/WAI/tutorials/images/decision-tree/"
|
||||
border
|
||||
>
|
||||
<div className="w3clogo">
|
||||
<W3CLogo />
|
||||
</div>
|
||||
<Undertittel className="lenkepanel__heading">
|
||||
Alt-text decision tree (W3C)
|
||||
</Undertittel>
|
||||
</Lenkepanel>
|
||||
</div>
|
||||
</div>
|
||||
</Preview>
|
||||
|
||||
## Hvordan skrive alt-tekster
|
||||
|
||||
<Lenkepanel
|
||||
className="resource-link"
|
||||
href="https://www.w3.org/WAI/tutorials/images/tips/"
|
||||
border
|
||||
>
|
||||
<div className="w3clogo">
|
||||
<W3CLogo />
|
||||
</div>
|
||||
<Undertittel className="lenkepanel__heading">Tips & tricks</Undertittel>
|
||||
</Lenkepanel>
|
||||
|
||||
<Lenkepanel
|
||||
className="resource-link"
|
||||
href="https://uu.difi.no/krav-og-regelverk/kom-i-gang/e-laeringskurs-om-universell-utforming-av-nettinnhold"
|
||||
border
|
||||
>
|
||||
<Undertittel className="lenkepanel__heading">
|
||||
E-læringskurs for redaktører og skribenter (Difi)
|
||||
</Undertittel>
|
||||
</Lenkepanel>
|
||||
@@ -1,128 +0,0 @@
|
||||
---
|
||||
title: "HTML: Disabled"
|
||||
rank: 3
|
||||
---
|
||||
|
||||
# Bruk av Disabled-attributtet
|
||||
|
||||
Disabled attributten gir oss muligheten til å hindre brukeren i å påvirke
|
||||
diverse HTML-Elementer som fks: input og button, men på bekostning av UX og
|
||||
UU.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Hvorfor unngå disable attributten?
|
||||
|
||||
Bruk av `disabled` kan virke som en veldig grei måte å hindre brukeren tilgang til forskjellige elementer, men glemmer ofte hva vi da krever av brukeren.
|
||||
|
||||
- Ikke alle brukerene vet at elementet <i><u>kan</u></i> være deaktivert, som da fører til forvirring.
|
||||
- Deaktiverte elementer har ofte dårlig kontrast.
|
||||
- Man forventer at brukeren skal vite hvorfor de ikke kan bruke elementet, men dette er ikke alltid tilfellet.
|
||||
- Deaktiverte elementer uten mulighet til fokus vil gjøre det vanskelig for skjermlesere å få all informasjonen den trenger.
|
||||
|
||||
## Alternativ
|
||||
|
||||
Så hva kan man bruke som erstattning for skjema-elementer og knapper da?
|
||||
|
||||
Et alternativ er å fjerne elementet helt fra siden hvis brukeren ikke skal kunne ta det i bruk.
|
||||
Her må man da også være sikker på at brukeren ikke vil "savne" dette elementet og da blir forvirret når det ikke er å finne på siden, eventuelt kan man også fortelle brukeren hvorfor muligheten ikke er der.
|
||||
|
||||
<br />
|
||||
|
||||
<Preview noCode>
|
||||
<RadioGruppe
|
||||
legend="Når ønsker du å reservere bord?"
|
||||
description="Lunsjservering er desverre ikke tilgjengelig grunnet ombygging av resturant."
|
||||
>
|
||||
<Radio label={"Frokost"} name="tid" />
|
||||
<Radio label={"Middag"} name="tid" />
|
||||
</RadioGruppe>
|
||||
|
||||
<Bash
|
||||
good
|
||||
code={`<RadioGruppe
|
||||
legend="Når ønsker du å reservere bord?"
|
||||
description="Lunsjservering er desverre ikke tilgjengelig grunnet ombygging av resturant."
|
||||
>
|
||||
<Radio label={"Frokost"} name="tid" />
|
||||
<Radio label={"Middag"} name="tid" />
|
||||
</RadioGruppe>`}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
<br />
|
||||
<Preview noCode>
|
||||
<RadioGruppe legend="Når ønsker du å reservere bord?">
|
||||
<Radio label={"Frokost"} name="tid" />
|
||||
<Radio label={"Lunsj"} name="tid" disabled />
|
||||
<Radio label={"Middag"} name="tid" />
|
||||
</RadioGruppe>
|
||||
|
||||
<Bash
|
||||
bad
|
||||
code={`<RadioGruppe legend="Når ønsker du å reservere bord?">
|
||||
<Radio label={"Frokost"} name="tid" />
|
||||
<Radio label={"Lunsj"} name="tid" disabled />
|
||||
<Radio label={"Middag"} name="tid" />
|
||||
</RadioGruppe>`}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<Preview noCode>
|
||||
<Knapp className="doButton" type="hoved">
|
||||
Neste
|
||||
</Knapp>
|
||||
<Feiloppsummering
|
||||
className="botMargin"
|
||||
tittel="For å gå videre må du rette opp følgende:"
|
||||
feil={[
|
||||
{ skjemaelementId: "1", feilmelding: "Du må oppgi et navn" },
|
||||
{ skjemaelementId: "2", feilmelding: "Du må oppgi en adresse" },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Bash
|
||||
good
|
||||
code={`<Knapp type="hoved">
|
||||
Neste
|
||||
</Knapp>
|
||||
<Feiloppsummering
|
||||
tittel="For å gå videre må du rette opp følgende:"
|
||||
feil={[
|
||||
{ skjemaelementId: "1", feilmelding: "Du må oppgi et navn" },
|
||||
{ skjemaelementId: "2", feilmelding: "Du må oppgi en adresse" },
|
||||
]}
|
||||
/>`}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
<br />
|
||||
|
||||
<Preview noCode>
|
||||
<Knapp className="botMargin" type="hoved" disabled>
|
||||
Neste
|
||||
</Knapp>
|
||||
<Bash
|
||||
bad
|
||||
code={`<Knapp type="hoved" disabled>
|
||||
Neste
|
||||
</Knapp>`}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
<br />
|
||||
|
||||
## Mer om disabled-attributtet
|
||||
|
||||
<Lenkepanel
|
||||
className="resource-link"
|
||||
href="https://uxdesign.cc/why-you-shouldnt-include-disabled-interaction-elements-in-your-design-system-76a2d4307faf"
|
||||
border
|
||||
>
|
||||
<Undertittel className="lenkepanel__heading">
|
||||
Artikkel om bruk av `disabled`
|
||||
</Undertittel>
|
||||
</Lenkepanel>
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: Tilgjengelighet
|
||||
rank: 5
|
||||
---
|
||||
@@ -1,124 +0,0 @@
|
||||
---
|
||||
title: "HTML: Placeholders"
|
||||
rank: 2
|
||||
---
|
||||
|
||||
# Bruk av placeholder-attributtet
|
||||
|
||||
Placeholder attributten representere et <i>kort</i> hint med intensjon om å
|
||||
hjelpe brukeren med data utfylling. Dessverre er det en del problemer som
|
||||
stopper den fra å gjøre akkurat dette i flere tilfeller.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Hvorfor unngå placeholders
|
||||
|
||||
Selv om placeholders kan virke som en kjempegod snarvei for å gi brukeren enkel og praktisk informasjon, vil det i enkelte tilfeller føre til dårlige brukeropplevelser.
|
||||
|
||||
- En placeholder forsvinner når feltet blir utfylt. Dette kan være spesielt utfordrende for personer med kognitive vansker (f.eks. hukommelse).
|
||||
- Ikke alle skjermlesere leser opp placeholder.
|
||||
- Har dårlig kontrast. WCAG krever at tekst skal ha en kontrast på 4,5:1, men om man forsøker å oppfylle dette kravet her vil det bli vanskelig å se at det faktisk er en placeholder og ikke vanlig tekst som er skrevet i input-feltet. Heller ikke alle nettlesere støtter [styling av placeholder](https://caniuse.com/#feat=css-placeholder).
|
||||
|
||||
<Preview noCode>
|
||||
<img
|
||||
src={"/placeholder-contrast.png"}
|
||||
alt="Eksempelbilde som viser hvorfor styling og høy kontrast av placeholder kan være upraktisk."
|
||||
/>
|
||||
|
||||
<figcaption>
|
||||
Er adressen allerede utfylt?
|
||||
</figcaption>
|
||||
</Preview>
|
||||
|
||||
- Kan være vanskelig å skjønne i høykontrastmodus.
|
||||
- Blir ikke oversatt med auto-translate.
|
||||
|
||||
## Alternativ
|
||||
|
||||
Vår anbefaling er å heller bruke vanlige labels, `description`-propen eller [Hjelpetekst](/components/hjelpetekst)-komponenter i nærheten av feltet.
|
||||
|
||||
<Preview noCode>
|
||||
<Input
|
||||
label="Password"
|
||||
description="8-16 Characters, containing atleast 2 numbers"
|
||||
type="password"
|
||||
/>
|
||||
<Bash
|
||||
good
|
||||
code={`<Input
|
||||
label="Password"
|
||||
description="8-16 Characters, containing atleast 2 numbers"
|
||||
type="password"
|
||||
/>`}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
<Preview noCode>
|
||||
<Input
|
||||
label="Password"
|
||||
placeholder="8-16 Characters, containing atleast 2 numbers"
|
||||
/>
|
||||
<Bash
|
||||
bad
|
||||
code={`<Input
|
||||
label="Password"
|
||||
placeholder="8-16 Characters, containing atleast 2 numbers"
|
||||
/>`}
|
||||
/>
|
||||
</Preview>
|
||||
<br />
|
||||
|
||||
<Preview noCode>
|
||||
<Input
|
||||
label={
|
||||
<div style={{ display: "flex" }}>
|
||||
E-Mail
|
||||
<Hjelpetekst style={{ marginLeft: "0.5rem" }}>
|
||||
Example: ola.nordmann@norge.no
|
||||
</Hjelpetekst>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<Bash
|
||||
good
|
||||
code={`<Input
|
||||
label={
|
||||
<div style={{ display: "flex" }}>
|
||||
E-Mail
|
||||
<Hjelpetekst style={{ marginLeft: "0.5rem" }}>
|
||||
Example: ola.nordmann@norge.no
|
||||
</Hjelpetekst>
|
||||
</div>
|
||||
}
|
||||
/>`}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
<Preview noCode>
|
||||
<Input label="E-Mail" placeholder="ola.nordmann@norge.no" />
|
||||
<Bash
|
||||
bad
|
||||
code={`<Input label="E-Mail" placeholder="ola.nordmann@norge.no" />`}
|
||||
/>
|
||||
</Preview>
|
||||
## Mer om Placeholders
|
||||
|
||||
<Lenkepanel
|
||||
className="resource-link"
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/CSS/::placeholder"
|
||||
border
|
||||
>
|
||||
<Undertittel className="lenkepanel__heading">
|
||||
Bruk og erfaringer fra Mozilla (MDN web docs)
|
||||
</Undertittel>
|
||||
</Lenkepanel>
|
||||
|
||||
<Lenkepanel
|
||||
className="resource-link"
|
||||
href="https://www.smashingmagazine.com/2018/06/placeholder-attribute/"
|
||||
border
|
||||
>
|
||||
<Undertittel className="lenkepanel__heading">
|
||||
Artikkel om bruk av placeholders (Smashing Magazine)
|
||||
</Undertittel>
|
||||
</Lenkepanel>
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: Komponenter
|
||||
rank: 1
|
||||
---
|
||||
@@ -1,92 +0,0 @@
|
||||
---
|
||||
title: Ikonknapper
|
||||
---
|
||||
|
||||
# Ikonknapper
|
||||
|
||||
Denne pakken inneholder en samling med ferdig-komponerte knapper med tilhørende ikon.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Tilbake-/Nesteknapp
|
||||
|
||||
<Preview
|
||||
react={`<Proptable><Tilbakeknapp />
|
||||
<Nesteknapp /></Proptable>`}
|
||||
>
|
||||
<Tilbakeknapp />
|
||||
<Nesteknapp />
|
||||
</Preview>
|
||||
|
||||
## Søkeknapp
|
||||
|
||||
<Preview react={`<Søkeknapp />`}>
|
||||
<Søkeknapp />
|
||||
</Preview>
|
||||
|
||||
<Preview
|
||||
react={`<Søkeknapp>
|
||||
<span>Valgfri tekst</span>
|
||||
</Søkeknapp>`}
|
||||
>
|
||||
<Søkeknapp>
|
||||
<span>Valgfri tekst</span>
|
||||
</Søkeknapp>
|
||||
</Preview>
|
||||
|
||||
## Menyknapp
|
||||
|
||||
<Preview react={`<Menyknapp />`}>
|
||||
<Menyknapp />
|
||||
</Preview>
|
||||
|
||||
<Preview
|
||||
react={`<Menyknapp>
|
||||
<span>Valgfri tekst</span>
|
||||
</Menyknapp>`}
|
||||
>
|
||||
<Menyknapp>
|
||||
<span>Valgfri tekst</span>
|
||||
</Menyknapp>
|
||||
</Preview>
|
||||
|
||||
## Hamburgerknapp
|
||||
|
||||
<Preview react={`<Hamburgerknapp />`}>
|
||||
<Hamburgerknapp />
|
||||
</Preview>
|
||||
|
||||
## Systemerknapp
|
||||
|
||||
<Preview react={`<Systemerknapp />`}>
|
||||
<Systemerknapp />
|
||||
</Preview>
|
||||
|
||||
## Xknapp
|
||||
|
||||
<Preview react={`<Xknapp />`}>
|
||||
<Xknapp />
|
||||
</Preview>
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-ikonknapper nav-frontend-chevron classnames nav-frontend-chevron-style prop-types react nav-frontend-ikoner-assets nav-frontend-knapper nav-frontend-js-utils lodash.throttle nav-frontend-knapper-style nav-frontend-core nav-frontend-typografi-style --save`}
|
||||
/>
|
||||
|
||||
## Proptable
|
||||
|
||||
<Proptable
|
||||
names={[
|
||||
"Xknapp",
|
||||
"Tilbakeknapp",
|
||||
"Systemerknapp",
|
||||
"Søkeknapp",
|
||||
"Nesteknapp",
|
||||
"Menyknapp",
|
||||
"Hamburgerknapp",
|
||||
]}
|
||||
from="nav-frontend-ikonknapper"
|
||||
/>
|
||||
@@ -1,337 +0,0 @@
|
||||
---
|
||||
title: Lenkepanel
|
||||
---
|
||||
|
||||
# Lenkepanel
|
||||
|
||||
Lenkepanel er klikkbare paneler, og kan brukes til lenker med høy prioritet. For eksempel sider som har hovedinnganger til forskjellige seksjoner.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-lenkepanel classnames nav-frontend-lenkepanel-style nav-frontend-chevron-style nav-frontend-core nav-frontend-paneler-style nav-frontend-typografi nav-frontend-typografi-style prop-types react --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-lenkepanel" imports="Lenkepanel" defaultExport />
|
||||
|
||||
## Normal
|
||||
|
||||
<Preview
|
||||
react={`<Lenkepanel href="#" border>
|
||||
Lenketekst
|
||||
</Lenkepanel>`}
|
||||
>
|
||||
<Lenkepanel href="#" border>
|
||||
Lenketekst
|
||||
</Lenkepanel>
|
||||
</Preview>
|
||||
|
||||
## Endre tekststørrelse
|
||||
|
||||
For å endre tekststørrelsen kan man sende inn en annen
|
||||
[typografitype](#/resources/typografi) i `tittelProps`-propen.
|
||||
|
||||
<Preview
|
||||
react={`<Lenkepanel href="#" tittelProps="normaltekst" border>
|
||||
Lenketekst
|
||||
</Lenkepanel>`}
|
||||
>
|
||||
<Lenkepanel href="#" tittelProps="normaltekst" border>
|
||||
Lenketekst
|
||||
</Lenkepanel>
|
||||
</Preview>
|
||||
|
||||
## Avansert innhold
|
||||
|
||||
Hvis man bruker `LenkepanelBase` kan man bestemme et helt egendefinert React/HTML-innhold. Husk
|
||||
å gi tittelen i innholdet ditt klassenavnet `lenkepanel__heading` slik at dette får riktig hover-stil.
|
||||
Øvrige stiler må dere ordne selv, og det kan være lurt å øke paddingen på lenkepanelet til `2rem` eller mer
|
||||
hvis innholdet skal være mer enn bare en tittel.
|
||||
|
||||
<Preview
|
||||
react={`<LenkepanelBase href="#" style={{ padding: "2rem 2.5rem 2rem 2rem" }} border>
|
||||
<div style={{ display: "flex", alignItems: "center" }}>
|
||||
<div>
|
||||
<svg
|
||||
style={{ marginRight: "2rem" }}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="110"
|
||||
height="110"
|
||||
>
|
||||
<defs>
|
||||
<path id="a" d="M.686.654h4.399v5.852H.686z"></path>
|
||||
</defs>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path fill="transparent" d="M-287-1518H993V543H-287z"></path>
|
||||
<rect
|
||||
width="796"
|
||||
height="181"
|
||||
fill="transparent"
|
||||
rx="8"
|
||||
transform="translate(-45 -36)"
|
||||
></rect>
|
||||
<circle cx="55" cy="55" r="55" fill="#CCDEE6"></circle>
|
||||
<g fill="#D8D8D8">
|
||||
<path
|
||||
fill="#337C9B"
|
||||
d="M32.034 5.834l-11.606 3.11-9.517 2.55-4.637 1.242 1.284 4.794 9.069 33.843 1.284 4.795 4.637-1.243 9.518-2.55 11.605-3.11c2.561-.686 4.063-3.389 3.353-6.037L37.956 9.385c-.71-2.648-3.361-4.238-5.922-3.551"
|
||||
></path>
|
||||
<path
|
||||
fill="#38363A"
|
||||
d="M38.322 51.833l1.77-.474-12.12-45.233-1.77.474z"
|
||||
></path>
|
||||
<path
|
||||
fill="#CE2128"
|
||||
d="M26.593 57.996l-1.179-.613-.713 1.12-.93-3.47 1.892-.507z"
|
||||
></path>
|
||||
</g>
|
||||
<path
|
||||
fill="#FFF"
|
||||
d="M61.773 69.14l8.95 38.112a2.524 2.524 0 0 0 3.036 1.881l32.913-7.745a2.528 2.528 0 0 0 1.88-3.04L98.279 54.591a2.526 2.526 0 0 0-3.037-1.883L68.425 59.02l-6.652 10.12z"
|
||||
></path>
|
||||
<path
|
||||
fill="#C0C0BE"
|
||||
d="M68.425 59.02l1.326 5.645a2.527 2.527 0 0 1-1.88 3.038l-6.098 1.436 6.652-10.12z"
|
||||
></path>
|
||||
<path
|
||||
stroke="#8E9294"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="2.152"
|
||||
d="M68.902 74.197l11.982-2.82m-10.721 8.19l24.874-5.853M71.424 84.937l24.873-5.853"
|
||||
></path>
|
||||
<path
|
||||
stroke="#8E9294"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="2.264"
|
||||
d="M72.685 90.307l24.873-5.854M73.857 95.297l24.873-5.853M75.021 100.7l24.874-5.853"
|
||||
></path>
|
||||
<path
|
||||
fill="#CCDEE6"
|
||||
d="M21.698 86.68c-5.726-3.643-7.42-11.243-3.78-16.976 3.64-5.733 11.231-7.427 16.958-3.784 5.727 3.643 7.42 11.243 3.78 16.976-3.639 5.733-11.231 7.427-16.958 3.784z"
|
||||
></path>
|
||||
<path
|
||||
fill="#C42B34"
|
||||
d="M9.283 106.905a2.772 2.772 0 0 1-.851-3.823l8.759-13.798a2.765 2.765 0 0 1 3.817-.852 2.77 2.77 0 0 1 .851 3.822l-8.758 13.799a2.764 2.764 0 0 1-3.818.852"
|
||||
></path>
|
||||
<path
|
||||
fill="#2E3137"
|
||||
d="M19.032 90.912c-.86-.547-1.348-1.318-.801-2.179l1.826-2.877a1.841 1.841 0 0 1 2.546-.567 1.847 1.847 0 0 1 .566 2.547l-1.826 2.878c-.547.86-1.452.744-2.31.198"
|
||||
></path>
|
||||
<path
|
||||
fill="#D84B55"
|
||||
d="M16.41 91l-8.266 13.021a.925.925 0 0 0 .283 1.275.92.92 0 0 0 1.272-.284l7.912-12.463c-.713-.47-1.083-1.039-1.2-1.549"
|
||||
></path>
|
||||
<path
|
||||
fill="#2E3137"
|
||||
d="M27.811 87.523a11.115 11.115 0 0 1-1.117-.196 11.283 11.283 0 0 1-3.577-1.48c-5.295-3.369-6.866-10.423-3.502-15.723 3.366-5.301 10.412-6.874 15.709-3.504 5.296 3.368 6.866 10.422 3.5 15.723a11.317 11.317 0 0 1-2.86 3.053 11.4 11.4 0 0 1-4.72 2.029c-1.127.203-2.284.24-3.433.098m12.57-4.19c3.911-6.16 2.085-14.358-4.069-18.271-6.154-3.915-14.342-2.089-18.253 4.072-3.91 6.16-2.085 14.356 4.07 18.271 6.153 3.915 14.343 2.09 18.252-4.072"
|
||||
></path>
|
||||
<path
|
||||
fill="#FFD399"
|
||||
d="M93.445 12.554c2.45 5.367.088 11.707-5.274 14.159-5.361 2.452-11.695.088-14.145-5.279-2.449-5.368-.088-11.707 5.275-14.16 5.361-2.452 11.695-.088 14.144 5.28"
|
||||
></path>
|
||||
<path
|
||||
fill="#FFD399"
|
||||
d="M91.45 28.239l-4.274 1.954a2.697 2.697 0 0 1-3.574-1.334l-2.775-6.08a2.7 2.7 0 0 1 1.333-3.578l4.274-1.955a2.696 2.696 0 0 1 3.575 1.334l2.775 6.08a2.702 2.702 0 0 1-1.333 3.579"
|
||||
></path>
|
||||
<path
|
||||
fill="#5A5C5D"
|
||||
d="M94.1 30.6l-6.9 3.156a1.255 1.255 0 0 1-1.043-2.284l6.902-3.155a1.253 1.253 0 1 1 1.04 2.282m1.275 2.794l-6.9 3.156a1.254 1.254 0 1 1-1.041-2.283l6.9-3.156a1.254 1.254 0 0 1 1.041 2.283m-1.682 1.387l-3.044 1.392c-.458.21-.4.889.09 1.006.685.164 1.425.11 2.115-.207a3.25 3.25 0 0 0 1.54-1.464c.233-.449-.241-.936-.701-.727"
|
||||
></path>
|
||||
<g transform="rotate(-69 92.268 -44.056)">
|
||||
<mask id="b" fill="#fff">
|
||||
<use xlinkHref="#a"></use>
|
||||
</mask>
|
||||
<path
|
||||
fill="#C42B34"
|
||||
d="M.732 4.08l.397-1.844a1.999 1.999 0 1 1 3.91.842l-.396 1.846A2 2 0 1 1 .732 4.08"
|
||||
mask="url(#b)"
|
||||
></path>
|
||||
</g>
|
||||
<path
|
||||
fill="#E1CFB4"
|
||||
d="M86.458 79.011l-1.334 7.43 6.268-4.21-2.12-2.355z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FECB86"
|
||||
d="M103.266 56.87l-1.644-1.073-14.841 22.72 1.643 1.072z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FAA736"
|
||||
d="M104.912 57.945l-1.644-1.074-14.841 22.72 1.644 1.073z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FECB86"
|
||||
d="M90.071 80.664l1.644 1.072 14.842-22.72-1.645-1.072zm-3.306-.951c.31.203.774-.055 1.188.215a.513.513 0 0 1 .152.15l.32-.488-1.644-1.073-.297.453s-.028.542.281.743"
|
||||
></path>
|
||||
<path
|
||||
fill="#FAA736"
|
||||
d="M88.106 80.078c.205.277.111.67.548.956.44.286.764.042 1.098.118l.32-.488-1.648-1.075-.318.489z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FECB86"
|
||||
d="M89.752 81.152a.507.507 0 0 1 .198.08c.414.27.365.797.675 1 .311.204.794-.041.794-.041l.296-.454-1.644-1.073-.32.488z"
|
||||
></path>
|
||||
<path
|
||||
fill="#535756"
|
||||
d="M85.123 86.44l2.22-1.488-1.749-1.14zm21.434-27.423l-4.935-3.22.437-.67 4.935 3.22z"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<Systemtittel className="lenkepanel__heading" style={{ marginTop: 0 }}>
|
||||
Dagpenger
|
||||
</Systemtittel>
|
||||
<p>
|
||||
Du kan få dagpenger når du er arbeidsledig og har mistet inntekten
|
||||
din.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</LenkepanelBase>`}
|
||||
>
|
||||
<LenkepanelBase href="#" style={{ padding: "2rem 2.5rem 2rem 2rem" }} border>
|
||||
<div style={{ display: "flex", alignItems: "center" }}>
|
||||
<div>
|
||||
<svg
|
||||
style={{ marginRight: "2rem" }}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="110"
|
||||
height="110"
|
||||
>
|
||||
<defs>
|
||||
<path id="a" d="M.686.654h4.399v5.852H.686z"></path>
|
||||
</defs>
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<path fill="transparent" d="M-287-1518H993V543H-287z"></path>
|
||||
<rect
|
||||
width="796"
|
||||
height="181"
|
||||
fill="transparent"
|
||||
rx="8"
|
||||
transform="translate(-45 -36)"
|
||||
></rect>
|
||||
<circle cx="55" cy="55" r="55" fill="#CCDEE6"></circle>
|
||||
<g fill="#D8D8D8">
|
||||
<path
|
||||
fill="#337C9B"
|
||||
d="M32.034 5.834l-11.606 3.11-9.517 2.55-4.637 1.242 1.284 4.794 9.069 33.843 1.284 4.795 4.637-1.243 9.518-2.55 11.605-3.11c2.561-.686 4.063-3.389 3.353-6.037L37.956 9.385c-.71-2.648-3.361-4.238-5.922-3.551"
|
||||
></path>
|
||||
<path
|
||||
fill="#38363A"
|
||||
d="M38.322 51.833l1.77-.474-12.12-45.233-1.77.474z"
|
||||
></path>
|
||||
<path
|
||||
fill="#CE2128"
|
||||
d="M26.593 57.996l-1.179-.613-.713 1.12-.93-3.47 1.892-.507z"
|
||||
></path>
|
||||
</g>
|
||||
<path
|
||||
fill="#FFF"
|
||||
d="M61.773 69.14l8.95 38.112a2.524 2.524 0 0 0 3.036 1.881l32.913-7.745a2.528 2.528 0 0 0 1.88-3.04L98.279 54.591a2.526 2.526 0 0 0-3.037-1.883L68.425 59.02l-6.652 10.12z"
|
||||
></path>
|
||||
<path
|
||||
fill="#C0C0BE"
|
||||
d="M68.425 59.02l1.326 5.645a2.527 2.527 0 0 1-1.88 3.038l-6.098 1.436 6.652-10.12z"
|
||||
></path>
|
||||
<path
|
||||
stroke="#8E9294"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="2.152"
|
||||
d="M68.902 74.197l11.982-2.82m-10.721 8.19l24.874-5.853M71.424 84.937l24.873-5.853"
|
||||
></path>
|
||||
<path
|
||||
stroke="#8E9294"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="2.264"
|
||||
d="M72.685 90.307l24.873-5.854M73.857 95.297l24.873-5.853M75.021 100.7l24.874-5.853"
|
||||
></path>
|
||||
<path
|
||||
fill="#CCDEE6"
|
||||
d="M21.698 86.68c-5.726-3.643-7.42-11.243-3.78-16.976 3.64-5.733 11.231-7.427 16.958-3.784 5.727 3.643 7.42 11.243 3.78 16.976-3.639 5.733-11.231 7.427-16.958 3.784z"
|
||||
></path>
|
||||
<path
|
||||
fill="#C42B34"
|
||||
d="M9.283 106.905a2.772 2.772 0 0 1-.851-3.823l8.759-13.798a2.765 2.765 0 0 1 3.817-.852 2.77 2.77 0 0 1 .851 3.822l-8.758 13.799a2.764 2.764 0 0 1-3.818.852"
|
||||
></path>
|
||||
<path
|
||||
fill="#2E3137"
|
||||
d="M19.032 90.912c-.86-.547-1.348-1.318-.801-2.179l1.826-2.877a1.841 1.841 0 0 1 2.546-.567 1.847 1.847 0 0 1 .566 2.547l-1.826 2.878c-.547.86-1.452.744-2.31.198"
|
||||
></path>
|
||||
<path
|
||||
fill="#D84B55"
|
||||
d="M16.41 91l-8.266 13.021a.925.925 0 0 0 .283 1.275.92.92 0 0 0 1.272-.284l7.912-12.463c-.713-.47-1.083-1.039-1.2-1.549"
|
||||
></path>
|
||||
<path
|
||||
fill="#2E3137"
|
||||
d="M27.811 87.523a11.115 11.115 0 0 1-1.117-.196 11.283 11.283 0 0 1-3.577-1.48c-5.295-3.369-6.866-10.423-3.502-15.723 3.366-5.301 10.412-6.874 15.709-3.504 5.296 3.368 6.866 10.422 3.5 15.723a11.317 11.317 0 0 1-2.86 3.053 11.4 11.4 0 0 1-4.72 2.029c-1.127.203-2.284.24-3.433.098m12.57-4.19c3.911-6.16 2.085-14.358-4.069-18.271-6.154-3.915-14.342-2.089-18.253 4.072-3.91 6.16-2.085 14.356 4.07 18.271 6.153 3.915 14.343 2.09 18.252-4.072"
|
||||
></path>
|
||||
<path
|
||||
fill="#FFD399"
|
||||
d="M93.445 12.554c2.45 5.367.088 11.707-5.274 14.159-5.361 2.452-11.695.088-14.145-5.279-2.449-5.368-.088-11.707 5.275-14.16 5.361-2.452 11.695-.088 14.144 5.28"
|
||||
></path>
|
||||
<path
|
||||
fill="#FFD399"
|
||||
d="M91.45 28.239l-4.274 1.954a2.697 2.697 0 0 1-3.574-1.334l-2.775-6.08a2.7 2.7 0 0 1 1.333-3.578l4.274-1.955a2.696 2.696 0 0 1 3.575 1.334l2.775 6.08a2.702 2.702 0 0 1-1.333 3.579"
|
||||
></path>
|
||||
<path
|
||||
fill="#5A5C5D"
|
||||
d="M94.1 30.6l-6.9 3.156a1.255 1.255 0 0 1-1.043-2.284l6.902-3.155a1.253 1.253 0 1 1 1.04 2.282m1.275 2.794l-6.9 3.156a1.254 1.254 0 1 1-1.041-2.283l6.9-3.156a1.254 1.254 0 0 1 1.041 2.283m-1.682 1.387l-3.044 1.392c-.458.21-.4.889.09 1.006.685.164 1.425.11 2.115-.207a3.25 3.25 0 0 0 1.54-1.464c.233-.449-.241-.936-.701-.727"
|
||||
></path>
|
||||
<g transform="rotate(-69 92.268 -44.056)">
|
||||
<mask id="b" fill="#fff">
|
||||
<use xlinkHref="#a"></use>
|
||||
</mask>
|
||||
<path
|
||||
fill="#C42B34"
|
||||
d="M.732 4.08l.397-1.844a1.999 1.999 0 1 1 3.91.842l-.396 1.846A2 2 0 1 1 .732 4.08"
|
||||
mask="url(#b)"
|
||||
></path>
|
||||
</g>
|
||||
<path
|
||||
fill="#E1CFB4"
|
||||
d="M86.458 79.011l-1.334 7.43 6.268-4.21-2.12-2.355z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FECB86"
|
||||
d="M103.266 56.87l-1.644-1.073-14.841 22.72 1.643 1.072z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FAA736"
|
||||
d="M104.912 57.945l-1.644-1.074-14.841 22.72 1.644 1.073z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FECB86"
|
||||
d="M90.071 80.664l1.644 1.072 14.842-22.72-1.645-1.072zm-3.306-.951c.31.203.774-.055 1.188.215a.513.513 0 0 1 .152.15l.32-.488-1.644-1.073-.297.453s-.028.542.281.743"
|
||||
></path>
|
||||
<path
|
||||
fill="#FAA736"
|
||||
d="M88.106 80.078c.205.277.111.67.548.956.44.286.764.042 1.098.118l.32-.488-1.648-1.075-.318.489z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FECB86"
|
||||
d="M89.752 81.152a.507.507 0 0 1 .198.08c.414.27.365.797.675 1 .311.204.794-.041.794-.041l.296-.454-1.644-1.073-.32.488z"
|
||||
></path>
|
||||
<path
|
||||
fill="#535756"
|
||||
d="M85.123 86.44l2.22-1.488-1.749-1.14zm21.434-27.423l-4.935-3.22.437-.67 4.935 3.22z"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<Systemtittel className="lenkepanel__heading" style={{ marginTop: 0 }}>
|
||||
Dagpenger
|
||||
</Systemtittel>
|
||||
<p>
|
||||
Du kan få dagpenger når du er arbeidsledig og har mistet inntekten
|
||||
din.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</LenkepanelBase>
|
||||
</Preview>
|
||||
@@ -1,190 +0,0 @@
|
||||
---
|
||||
title: Lenke
|
||||
---
|
||||
|
||||
# Lenke
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-lenker classnames nav-frontend-lenker-style nav-frontend-core prop-types react --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-lenker" imports="Lenke" defaultExport />
|
||||
|
||||
## Normal
|
||||
|
||||
Tekstlenker skal ha fargen [@navBla](/resources/colors) (#0067C5) med normal underlinje som forsvinner ved hover.
|
||||
Ved fokus skal lenken få hvit tekstfarge uten underlinje og bakgrunnsfarge [@fokusFarge](/resources/colors) (#254B6D).
|
||||
|
||||
<Preview
|
||||
react={`<div>Dette er en <Lenke href="#">tekstlenke</Lenke> i en setning.</div>`}
|
||||
>
|
||||
Dette er en <Lenke href="#">tekstlenke</Lenke> i en setning.
|
||||
</Preview>
|
||||
|
||||
## På farget bakgrunn
|
||||
|
||||
På en bakgrunn der @navBla ikke har tilstrekkelig kontrast (minimum 4.5:1) anbefaler vi å bruke @navMorkGra.
|
||||
|
||||
<Preview
|
||||
react={`<Alertstripe type="suksess">
|
||||
Dette er en <Lenke href="#">tekstlenke</Lenke> på farget bakgrunn.
|
||||
</Alertstripe>`}
|
||||
>
|
||||
<Alertstripe type="suksess">
|
||||
Dette er en <Lenke href="#">tekstlenke</Lenke> på farget bakgrunn.
|
||||
</Alertstripe>
|
||||
</Preview>
|
||||
|
||||
## Med ikon
|
||||
|
||||
<Alert variant="info">
|
||||
Når du bruker ikoner er det viktig at du pakker inn teksten med{" "}
|
||||
<code><span></code>-elementer for å påse riktig avstand til ikonet.
|
||||
</Alert>
|
||||
|
||||
<Preview
|
||||
react={`<><Lenke href="#">
|
||||
<span>Lenke med ikon</span>
|
||||
<Settings />
|
||||
</Lenke>
|
||||
<Lenke href="#">
|
||||
<Settings />
|
||||
<span>Lenke med ikon</span>
|
||||
</Lenke></>`}
|
||||
>
|
||||
<Lenke href="#">
|
||||
<span>Lenke med ikon</span>
|
||||
<Settings />
|
||||
</Lenke>
|
||||
<Lenke href="#">
|
||||
<Settings />
|
||||
<span>Lenke med ikon</span>
|
||||
</Lenke>
|
||||
</Preview>
|
||||
|
||||
### Skalering
|
||||
|
||||
Ikoner inne i lenker vil skalere med tekst-størrelsen:
|
||||
|
||||
<Preview
|
||||
react={`<><Innholdstittel>
|
||||
<Lenke href="#">
|
||||
<span>ikonet skaleres</span>
|
||||
<Settings />
|
||||
</Lenke>
|
||||
</Innholdstittel>
|
||||
<Innholdstittel>
|
||||
<Lenke href="#">
|
||||
<Settings />
|
||||
<span>ikonet skaleres</span>
|
||||
</Lenke>
|
||||
</Innholdstittel></>`}
|
||||
>
|
||||
<Innholdstittel>
|
||||
<Lenke href="#">
|
||||
<span>ikonet skaleres</span>
|
||||
<Settings />
|
||||
</Lenke>
|
||||
</Innholdstittel>
|
||||
<Innholdstittel>
|
||||
<Lenke href="#">
|
||||
<Settings />
|
||||
<span>ikonet skaleres</span>
|
||||
</Lenke>
|
||||
</Innholdstittel>
|
||||
</Preview>
|
||||
|
||||
### I tekst-blokker
|
||||
|
||||
Ikoner skal også fungere fint på lenker midt inne i større tekst-blokker:
|
||||
|
||||
<Preview
|
||||
react={`<div>Morbi blandit mauris lacus, eget tincidunt velit fringilla in. Sed sodales
|
||||
placerat leo pretium iaculis. Sed lacinia dolor ac consequat blandit.
|
||||
Pellentesque tempor in magna a viverra. Etiam mollis orci et ligula euismod,
|
||||
id dictum elit vehicula. Morbi augue erat, dapibus eu lorem eu, viverra
|
||||
malesuada odio.{" "}
|
||||
<Lenke href="#">
|
||||
<Settings />
|
||||
<span>
|
||||
Cras finibus odio ac venenatis interdum. Mauris ac accumsan libero. In ac
|
||||
libero tincidunt, ultrices risus at, posuere velit. Pellentesque et mollis
|
||||
ipsum.
|
||||
</span>
|
||||
</Lenke>{" "}
|
||||
Aliquam porttitor sed justo fermentum pretium. Praesent at tortor ut ex cursus
|
||||
volutpat ac quis eros. Proin laoreet egestas dui, ac condimentum orci lobortis
|
||||
vitae. Etiam semper aliquam magna, ac consectetur elit laoreet non.
|
||||
Pellentesque vel interdum mauris.</div>`}
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Morbi blandit mauris lacus, eget tincidunt velit fringilla in. Sed sodales
|
||||
placerat leo pretium iaculis. Sed lacinia dolor ac consequat blandit.
|
||||
Pellentesque tempor in magna a viverra. Etiam mollis orci et ligula
|
||||
euismod, id dictum elit vehicula. Morbi augue erat, dapibus eu lorem eu,
|
||||
viverra malesuada odio.
|
||||
</p>{" "}
|
||||
<Lenke href="#">
|
||||
<Settings />
|
||||
<span>
|
||||
Cras finibus odio ac venenatis interdum. Mauris ac accumsan libero. In
|
||||
ac libero tincidunt, ultrices risus at, posuere velit. Pellentesque et
|
||||
mollis ipsum.
|
||||
</span>
|
||||
</Lenke>{" "}
|
||||
<p>
|
||||
Aliquam porttitor sed justo fermentum pretium. Praesent at tortor ut ex
|
||||
cursus volutpat ac quis eros. Proin laoreet egestas dui, ac condimentum
|
||||
orci lobortis vitae. Etiam semper aliquam magna, ac consectetur elit
|
||||
laoreet non. Pellentesque vel interdum mauris.
|
||||
</p>
|
||||
</div>
|
||||
</Preview>
|
||||
|
||||
## Tilgjengelighet
|
||||
|
||||
### Beskrivende tekstinnhold i lenken
|
||||
|
||||
Gode lenker er svært viktig for personer som bruker skjermleser. Det er ikke uvanlig at disse brukerne starter med kun en liste over alle tilgjengelige lenker på en nettside, for å forsøke å få oversikt over navigeringsmulighetene på siden. En slik liste viser bare selve lenketeksten, og hvis lenkene ikke er beskrivende blir det vanskelig å forstå hvor de leder brukeren videre.
|
||||
|
||||
Tekstlenker skal beskrive hva de lenker til. Det skal ikke bare stå "her" eller "les mer". I tilfeller hvor dette ikke er mulig, bør man passe på at den øvrige teksten rundt lenken kan fungere som en beskrivelse. På den måten vil formålet til lenken gi mer mening.
|
||||
|
||||
### Dokumenter
|
||||
|
||||
Hvis det lenkes til et dokument, bør man bruke den formelle tittelen på dokumentet; "Digitaliseringstrategi 2020". Og hvis man lenker til en nedlastbar fil skal man også inkludere fil-formatet i parentes bak lenken; "Digitaliseringstrategi 2020 (PDF)".
|
||||
|
||||
### Fargeblindhet
|
||||
|
||||
Understrek under lenkene gjør at de skiller seg ut med mer enn bare fargen. Ved hjelp av understrek kan også fargeblinde personer raskt legge merke til lenkene, og de er mye enklere å se på skjermer med dårlig oppløsning.
|
||||
|
||||
### Åpne ny fane
|
||||
|
||||
Som hovedregel skal vi unngå å åpne lenker i ny fane. Denne hovedregelen gjelder uavhengig av om lenken fører til et annet domene/nettsted eller ikke. Bakgrunnen for denne regelen er at automatisk åpning av nye tabs ofte oppleves forvirrende for brukere som har vansker med å oppfatte visuell informasjon, spesielt brukere med skjermleser.
|
||||
|
||||
Det finnes likevel noen unntak til denne hovedregelen, hvor automatisk åpning av ny fane anbefales:
|
||||
|
||||
- Hvis klikk på lenken kan føre til at brukeren taper informasjon. F.eks. hvis brukeren er inne i et langt skjema, eller en stegvis prosess, hvor informasjonen de har oppgitt vil gå tapt om brukeren navigerer bort fra siden.
|
||||
- Hvis brukeren er pålogget i en side hvor påloggingen kan bli avbrutt hvis brukerne navigerer bort fra siden. Dette tilfellet er uansett lite aktuelt for nav.no, da innlogging på våre sider blir håndtert av ID-porten (hvor autentisering er tidsbestemt og fortsetter å gjelde selv om bruker navigerer bort fra nav.no).
|
||||
|
||||
Se også [WCAG G200: Opening new windows and tabs from a link only when necessary](https://www.w3.org/TR/WCAG20-TECHS/G200.html)
|
||||
|
||||
<!--
|
||||
### Retningslinjer for språk
|
||||
|
||||
- [Slik skriver vi 4.7: Når du bruker lenker](/resources/language#4.7-når-du-bruker-lenker)
|
||||
- [Slik skriver vi 4.8: Ikke bruk nedlastbare filer som word, ppt, pdf etc.](/resources/language#4.8-ikke-bruk-nedlastbare-filer-som-word,-ppt,-pdf-etc.)
|
||||
-->
|
||||
|
||||
### Mer informasjon
|
||||
|
||||
- [WCAG 1.3.1: Informasjon og relasjoner, nivå A](https://uu.difi.no/krav-og-regelverk/wcag-20-standarden/131-informasjon-og-relasjoner-niva)
|
||||
- [WCAG 2.4.9: Formål med lenke (bare lenke, nivå AAA)](https://uu.difi.no/krav-og-regelverk/wcag-20-standarden/ikke-lovpalagte-krav/249-formal-med-lenke-bare-lenke-niva-aaa)
|
||||
- [WCAG 1.4.1: Bruk av farge, nivå A](https://uu.difi.no/krav-og-regelverk/wcag-20-standarden/141-bruk-av-farge-niva)
|
||||
- [Tekst om lenker på uu.difi.no](https://uu.difi.no/krav-og-regelverk/losningsforslag-web/lenker)
|
||||
@@ -1,156 +0,0 @@
|
||||
---
|
||||
title: Stegindikator
|
||||
---
|
||||
|
||||
# Stegindikator
|
||||
|
||||
Stegindikatoren skal vise stegvis progresjon gjennom en prosess.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-stegindikator classnames nav-frontend-js-utils lodash.throttle prop-types react nav-frontend-stegindikator-style nav-frontend-core nav-frontend-typografi-style --save`}
|
||||
/>
|
||||
|
||||
<Npm
|
||||
packName="nav-frontend-stegindikator"
|
||||
imports="Stegindikator"
|
||||
defaultExport
|
||||
/>
|
||||
|
||||
## Normal
|
||||
|
||||
<Preview
|
||||
react={`<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
{ label: "Konklusjonen", disabled: true },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
/>`}
|
||||
>
|
||||
<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
{ label: "Konklusjonen", disabled: true },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Med label
|
||||
|
||||
<Preview
|
||||
react={`<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
{ label: "Konklusjonen", disabled: true },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
visLabel
|
||||
/>`}
|
||||
>
|
||||
<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
{ label: "Konklusjonen", disabled: true },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
visLabel
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Kompakt
|
||||
|
||||
<Preview
|
||||
react={`<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
{ label: "Konklusjonen", disabled: true },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
kompakt
|
||||
/>`}
|
||||
>
|
||||
<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
{ label: "Konklusjonen", disabled: true },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
kompakt
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Kompakt med label
|
||||
|
||||
<Preview
|
||||
react={`<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
{ label: "Konklusjonen", disabled: true },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
kompakt
|
||||
visLabel
|
||||
/>`}
|
||||
>
|
||||
<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
{ label: "Konklusjonen", disabled: true },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
kompakt
|
||||
visLabel
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Autoresponsiv
|
||||
|
||||
Denne versjonen vil kontinuerlig overvåke tilgjenglig konteiner-plass og automatisk
|
||||
bytte visningsmodus for å tilpasse seg bredden.
|
||||
|
||||
<Preview
|
||||
react={`<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
visLabel
|
||||
autoResponsiv
|
||||
/>`}
|
||||
>
|
||||
<Stegindikator
|
||||
steg={[
|
||||
{ label: "Dette steget først" },
|
||||
{ label: "Og så dette steget", aktiv: true },
|
||||
{ label: "Deretter må du gjøre dette" },
|
||||
]}
|
||||
onChange={() => {}}
|
||||
visLabel
|
||||
autoResponsiv
|
||||
/>
|
||||
</Preview>
|
||||
@@ -1,95 +0,0 @@
|
||||
---
|
||||
title: Tabs
|
||||
---
|
||||
|
||||
# Tabs
|
||||
|
||||
Tabs er en meny som gir brukeren mulighet til å bytte mellom lagvis inndelt innhold.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-tabs classnames nav-frontend-js-utils lodash.throttle prop-types react nav-frontend-tabs-style nav-frontend-core nav-frontend-typografi-style --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-tabs" imports="Tabs" defaultExport />
|
||||
|
||||
## Normal
|
||||
|
||||
<Preview
|
||||
react={`<Tabs
|
||||
tabs={[{ label: "Første" }, { label: "Andre" }, { label: "Tredje" }]}
|
||||
onChange={() => {}}
|
||||
/>`}
|
||||
>
|
||||
<Tabs
|
||||
tabs={[{ label: "Første" }, { label: "Andre" }, { label: "Tredje" }]}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Kombinasjon med panel
|
||||
|
||||
Komponenten passer fint i kombinasjon med [Panel](/components/panel), hvor normal variant bør plasseres
|
||||
utenfor og langs øverste kant av panelet.
|
||||
|
||||
<Alert variant="info">
|
||||
Inntil videre må du manuelt håndtere visning av riktig panel-innhold når aktiv
|
||||
tab endres. Du må også skru av
|
||||
<code className="inline">border</code> og <code className="inline">
|
||||
border-radius
|
||||
</code> langs toppen av panelet. Vi jobber med å lage en mer avansert <code className="inline">
|
||||
TabPanel
|
||||
</code> komponent som er tenkt å både fikse disse stilene for deg, og håndtere
|
||||
automatisk visning av riktig panel-innhold avhengig av aktiv tab.
|
||||
</Alert>
|
||||
|
||||
<Preview
|
||||
react={`<><Tabs
|
||||
tabs={[{ label: "Første" }, { label: "Andre" }, { label: "Tredje" }]}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<Panel
|
||||
border
|
||||
style={{ borderTop: 0, borderTopLeftRadius: 0, borderTopRightRadius: 0 }}
|
||||
>
|
||||
Innhold her.
|
||||
</Panel></>`}
|
||||
>
|
||||
<Tabs
|
||||
tabs={[{ label: "Første" }, { label: "Andre" }, { label: "Tredje" }]}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<Panel
|
||||
border
|
||||
style={{ borderTop: 0, borderTopLeftRadius: 0, borderTopRightRadius: 0 }}
|
||||
>
|
||||
Innhold her.
|
||||
</Panel>
|
||||
</Preview>
|
||||
|
||||
## Kompakt
|
||||
|
||||
<Preview
|
||||
react={`<Tabs
|
||||
tabs={[{ label: "Første" }, { label: "Andre" }, { label: "Tredje" }]}
|
||||
onChange={() => {}}
|
||||
kompakt
|
||||
/>`}
|
||||
>
|
||||
<Tabs
|
||||
tabs={[{ label: "Første" }, { label: "Andre" }, { label: "Tredje" }]}
|
||||
onChange={() => {}}
|
||||
kompakt
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Tilgjengelighet
|
||||
|
||||
### Tastaturnavigering
|
||||
|
||||
Støtte for tastaturnavigering i Tabs er basert på [W3 sine anbefalinger](https://www.w3.org/TR/wai-aria-practices/#tabpanel), med noen modifikasjoner etter råd og innspill fra våre egne UU-eksperter. Vi har valgt å la alle tabs være tilgjengelige med tabbing, i motsetning til W3 sine anbefalinger om å begrense dette til kun aktiv tab. Konsumenten står fritt til å bestemme om pil-navigering automatisk bytter aktiv tab (default), eller kun flytter fokus. Det gjør man ved å sette `arrowKeysAutoSwitchTabs` property til `false`).
|
||||
@@ -1,115 +0,0 @@
|
||||
---
|
||||
title: ToggleGruppe
|
||||
---
|
||||
|
||||
# ToggleGruppe
|
||||
|
||||
ToggleGruppe er en samling av flere ToggleKnapper. ToggleGruppe tar seg også av styling av ToggleKnapper slik at disse står helt inntil hverandre.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-toggle classnames nav-frontend-js-utils lodash.throttle prop-types react nav-frontend-toggle-style nav-frontend-core nav-frontend-knapper-style nav-frontend-typografi-style --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-toggle" imports="ToggleGruppe" />
|
||||
|
||||
## Normal
|
||||
|
||||
I default varianten kan man bare aktivere èn ToggleKnapp om gangen.
|
||||
|
||||
<Preview
|
||||
react={`<ToggleGruppe
|
||||
defaultToggles={[
|
||||
{ children: "Mandag", pressed: true },
|
||||
{ children: "Tirsdag" },
|
||||
{ children: "Onsdag" },
|
||||
]}
|
||||
/>`}
|
||||
>
|
||||
<ToggleGruppe
|
||||
defaultToggles={[
|
||||
{ children: "Mandag", pressed: true },
|
||||
{ children: "Tirsdag" },
|
||||
{ children: "Onsdag" },
|
||||
]}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## MultiSelect
|
||||
|
||||
For å tillate flere aktive ToggleKnapper samtidig kan man bruke `multiSelect` propen.
|
||||
|
||||
<Preview
|
||||
react={`<ToggleGruppe
|
||||
defaultToggles={[
|
||||
{ children: "Mandag", pressed: true },
|
||||
{ children: "Tirsdag" },
|
||||
{ children: "Onsdag" },
|
||||
]}
|
||||
multiSelect
|
||||
/>`}
|
||||
>
|
||||
<ToggleGruppe
|
||||
defaultToggles={[
|
||||
{ children: "Mandag", pressed: true },
|
||||
{ children: "Tirsdag" },
|
||||
{ children: "Onsdag" },
|
||||
]}
|
||||
multiSelect
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Minst én
|
||||
|
||||
Bruk `minstEn` propen for å håndheve at det alltid må være èn ToggleKnapp som er valgt.
|
||||
|
||||
<Preview
|
||||
react={`<ToggleGruppe
|
||||
defaultToggles={[
|
||||
{ children: "Mandag" },
|
||||
{ children: "Tirsdag" },
|
||||
{ children: "Onsdag" },
|
||||
]}
|
||||
minstEn
|
||||
/>`}
|
||||
>
|
||||
<ToggleGruppe
|
||||
defaultToggles={[
|
||||
{ children: "Mandag" },
|
||||
{ children: "Tirsdag" },
|
||||
{ children: "Onsdag" },
|
||||
]}
|
||||
minstEn
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Kompakt
|
||||
|
||||
ToggleGruppe støtter også en `kompakt` variant som kan passe bra hvis ToggleKnappene har lite tekstinnhold eller bare ikoner.
|
||||
|
||||
<Preview
|
||||
react={`<ToggleGruppe
|
||||
defaultToggles={[
|
||||
{ children: "B", pressed: true },
|
||||
{ children: <em style={{ paddingLeft: 2, paddingRight: 2 }}>I</em> },
|
||||
{ children: <span style={{ textDecoration: "underline" }}>U</span> },
|
||||
]}
|
||||
multiSelect
|
||||
kompakt
|
||||
/>`}
|
||||
>
|
||||
<ToggleGruppe
|
||||
defaultToggles={[
|
||||
{ children: "B", pressed: true },
|
||||
{ children: <em style={{ paddingLeft: 2, paddingRight: 2 }}>I</em> },
|
||||
{ children: <span style={{ textDecoration: "underline" }}>U</span> },
|
||||
]}
|
||||
multiSelect
|
||||
kompakt
|
||||
/>
|
||||
</Preview>
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
title: ToggleKnapp
|
||||
---
|
||||
|
||||
# ToggleKnapp
|
||||
|
||||
ToggleKnapp har to tilstander; på eller av. Komponenten kan brukes alene eller kombinert med flere i en ToggleGruppe.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-toggle classnames nav-frontend-js-utils lodash.throttle prop-types react nav-frontend-toggle-style nav-frontend-core nav-frontend-knapper-style nav-frontend-typografi-style --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-toggle" imports="ToggleKnapp" />
|
||||
|
||||
## Normal
|
||||
|
||||
<Preview react={`<ToggleKnapp>Toggle</ToggleKnapp>`}>
|
||||
<ToggleKnapp>Toggle</ToggleKnapp>
|
||||
</Preview>
|
||||
|
||||
## Kompakt
|
||||
|
||||
<Preview react={`<ToggleKnapp kompakt>Toggle</ToggleKnapp>`}>
|
||||
<ToggleKnapp kompakt>Toggle</ToggleKnapp>
|
||||
</Preview>
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: Actions
|
||||
rank: 1
|
||||
---
|
||||
@@ -1,272 +0,0 @@
|
||||
---
|
||||
title: Knapp
|
||||
---
|
||||
|
||||
# Knapp
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-knapper classnames nav-frontend-js-utils
|
||||
lodash.throttle prop-types react nav-frontend-knapper-style nav-frontend-core
|
||||
nav-frontend-typografi-style --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-knapper" imports="Knapp" />
|
||||
|
||||
## Normal
|
||||
|
||||
Dette er hvordan en normal knapp skal se ut. De fleste knappene i løsningene våre skal se
|
||||
slik ut. Hvis du er i tvil om hvilken knapp du skal bruke, er det sikkert denne som er
|
||||
riktig.
|
||||
|
||||
<Preview react={`<Knapp>Normal</Knapp>`}>
|
||||
<Knapp>Normal</Knapp>
|
||||
</Preview>
|
||||
|
||||
## Hovedknapp
|
||||
|
||||
Denne knappen skal brukes der løsningen/siden har en tydelig hoved-/primær-funksjon (f.eks.
|
||||
"Lagre" eller "Send søknad"). Merk at det som regel bare skal finnes èn eneste hovedknapp
|
||||
på en og samme side. Et mulig unntak til denne regelen kan være inne i en modal-rute som
|
||||
legger seg oppå det øvrige innholdet hvor det er tillatt med en ekstra hoved- eller
|
||||
fare-knapp ved behov.
|
||||
|
||||
<Preview react={`<Knapp type="hoved">Hovedknapp</Knapp>`}>
|
||||
<Knapp type="hoved">Hovedknapp</Knapp>
|
||||
</Preview>
|
||||
|
||||
## Fareknapp
|
||||
|
||||
Denne knappen skal brukes på samme måte som hovedknapp, men bare der hoved-/primær-funksjonen
|
||||
kan føre til tap av viktig lagret informasjon (f.eks. "Slett") eller ellers bety svært negative
|
||||
konsekvenser hvis handlingen ikke var ønsket (f.eks. som en bekreftelse på at brukeren ikke lenger
|
||||
ønsker å motta ytelser).
|
||||
|
||||
<Preview react={`<Knapp type="fare">Fareknapp</Knapp>`}>
|
||||
<Knapp type="fare">Fareknapp</Knapp>
|
||||
</Preview>
|
||||
|
||||
## Flatknapp
|
||||
|
||||
Denne knappen kan brukes som et alternativ til normal knapp ved behov.
|
||||
|
||||
<Preview react={`<Knapp type="flat">Flatknapp</Knapp>`}>
|
||||
<Knapp type="flat">Flatknapp</Knapp>
|
||||
</Preview>
|
||||
|
||||
## Disabled
|
||||
|
||||
Alle knappene har støtte for disabled stil.
|
||||
|
||||
<Alert variant="warning">
|
||||
Merk at disabled knapper bør unngås, og at man heller bør bruke vanlige
|
||||
knapper kombinert med tydelige feilmeldinger hvis handlingen av en eller annen
|
||||
grunn ikke er tillatt.
|
||||
</Alert>
|
||||
|
||||
<Preview
|
||||
react={`<><Knapp disabled>Normal</Knapp>
|
||||
<Knapp type="hoved" disabled>
|
||||
Hoved
|
||||
</Knapp>
|
||||
<Knapp type="fare" disabled>
|
||||
Fare
|
||||
</Knapp>
|
||||
<Knapp type="flat" disabled>
|
||||
Flat
|
||||
</Knapp></>`}
|
||||
>
|
||||
<Knapp disabled>Normal</Knapp>
|
||||
|
||||
<Knapp type="hoved" disabled>
|
||||
Hoved
|
||||
</Knapp>
|
||||
|
||||
<Knapp type="fare" disabled>
|
||||
Fare
|
||||
</Knapp>
|
||||
|
||||
<Knapp type="flat" disabled>
|
||||
Flat
|
||||
</Knapp>
|
||||
</Preview>
|
||||
|
||||
## Mini
|
||||
|
||||
Alle knappene kan rendres i en mindre `32px` versjon.
|
||||
|
||||
<Alert variant="warning">
|
||||
Som hovedregel skal vi <strong>alltid</strong> bruke de store knappene våre.
|
||||
For tilfeller med svært begrenset plass kan de mindre knappene brukes
|
||||
<strong> unntaksvis ved klart behov</strong>.
|
||||
</Alert>
|
||||
|
||||
<Preview
|
||||
react={`<><Knapp mini>Normal</Knapp>
|
||||
<Knapp type="hoved" mini>
|
||||
Hoved
|
||||
</Knapp>
|
||||
<Knapp type="fare" mini>
|
||||
Fare
|
||||
</Knapp>
|
||||
<Knapp type="flat" mini>
|
||||
Flat
|
||||
</Knapp>
|
||||
<Knapp disabled mini>
|
||||
Disabled
|
||||
</Knapp></>`}
|
||||
>
|
||||
<Knapp mini>Normal</Knapp>
|
||||
<Knapp type="hoved" mini>
|
||||
Hoved
|
||||
</Knapp>
|
||||
<Knapp type="fare" mini>
|
||||
Fare
|
||||
</Knapp>
|
||||
<Knapp type="flat" mini>
|
||||
Flat
|
||||
</Knapp>
|
||||
<Knapp disabled mini>
|
||||
Disabled
|
||||
</Knapp>
|
||||
</Preview>
|
||||
|
||||
### Kompakt
|
||||
|
||||
Bruk `kompakt` for å redusere høyre-/venstre-padding på knappene.
|
||||
|
||||
<Preview
|
||||
react={`<Knapp kompakt>
|
||||
<Settings />
|
||||
<span>Knapp</span>
|
||||
</Knapp>`}
|
||||
>
|
||||
<button className="knapp knapp--kompakt">
|
||||
<Settings />
|
||||
<span>Knapp</span>
|
||||
</button>
|
||||
</Preview>
|
||||
|
||||
## Med ikon
|
||||
|
||||
<Alert variant="info">
|
||||
Når du bruker ikoner er det viktig at du pakker inn teksten med
|
||||
<code> <span></code>-elementer for å påse riktig avstand til ikonet.
|
||||
</Alert>
|
||||
<br />
|
||||
<Alert variant="warning">
|
||||
Husk at knapper med bare ikoner også må få en tekst-verdi av hensyn til
|
||||
skjermlesere. Utility-klassen <code>sr-only</code> som gis av{" "}
|
||||
<Link href="https://github.com/navikt/nav-frontend-moduler/blob/master/packages/node_modules/nav-frontend-core/less/_mixins.less">
|
||||
mixins-fila i Core-pakken
|
||||
</Link>{" "}
|
||||
kan brukes for å skjule teksten visuelt.
|
||||
</Alert>
|
||||
|
||||
<Preview
|
||||
react={`<><Knapp>
|
||||
<Settings />
|
||||
<span>Normal</span>
|
||||
</Knapp>
|
||||
<Knapp type="hoved">
|
||||
<Settings />
|
||||
<span>Hoved</span>
|
||||
</Knapp>
|
||||
<Knapp type="fare">
|
||||
<Settings />
|
||||
<span>Fare</span>
|
||||
</Knapp>
|
||||
<Knapp type="flat">
|
||||
<Settings />
|
||||
<span>Flat</span>
|
||||
</Knapp>
|
||||
<Knapp disabled>
|
||||
<Settings />
|
||||
<span>Disabled</span>
|
||||
</Knapp>
|
||||
<Knapp>
|
||||
<Settings />
|
||||
<span className="sr-only">Knapp</span>
|
||||
</Knapp></>`}
|
||||
>
|
||||
<Knapp>
|
||||
<Settings />
|
||||
<span>Normal</span>
|
||||
</Knapp>
|
||||
<Knapp type="hoved">
|
||||
<Settings />
|
||||
<span>Hoved</span>
|
||||
</Knapp>
|
||||
<Knapp type="fare">
|
||||
<Settings />
|
||||
<span>Fare</span>
|
||||
</Knapp>
|
||||
<Knapp type="flat">
|
||||
<Settings />
|
||||
<span>Flat</span>
|
||||
</Knapp>
|
||||
<Knapp disabled>
|
||||
<Settings />
|
||||
<span>Disabled</span>
|
||||
</Knapp>
|
||||
<Knapp>
|
||||
<Settings />
|
||||
<span className="sr-only">Knapp</span>
|
||||
</Knapp>
|
||||
|
||||
</Preview>
|
||||
|
||||
## Med spinner
|
||||
|
||||
Alle knappene våre har støtte for å vise en spinner.
|
||||
|
||||
<Preview
|
||||
react={`<><Knapp spinner>Normal</Knapp>
|
||||
<Knapp type="hoved" spinner>Hoved</Knapp>
|
||||
<Knapp type="fare" spinner>Fare</Knapp>
|
||||
<Knapp type="flat" spinner>Flat</Knapp>
|
||||
<Knapp disabled spinner>
|
||||
Disabled
|
||||
</Knapp></>`}
|
||||
>
|
||||
<Knapp spinner>Normal</Knapp>
|
||||
|
||||
<Knapp type="hoved" spinner>
|
||||
Hoved
|
||||
</Knapp>
|
||||
|
||||
<Knapp type="fare" spinner>
|
||||
Fare
|
||||
</Knapp>
|
||||
|
||||
<Knapp type="flat" spinner>
|
||||
Flat
|
||||
</Knapp>
|
||||
|
||||
<Knapp disabled spinner>
|
||||
Disabled
|
||||
</Knapp>
|
||||
</Preview>
|
||||
|
||||
## Tilgjengelighet
|
||||
|
||||
### Unngå lenker som knapper
|
||||
|
||||
For å oppfylle [WCAGs suksesskriterium 1.3.1](https://uu.difi.no/krav-og-regelverk/wcag-20-standarden/131-informasjon-og-relasjoner-niva) skal ting være kodet som det det ser ut som. Derfor skal ting som ser ut som knapper være nettopp knapper og ikke lenker.
|
||||
|
||||
### Bakgrunnskontrast
|
||||
|
||||
Ved bruk av standard/sekundær eller flatknapp bør man passe på at bakgrunnsfargen der de plasseres er enten hvit eller lys grå slik at kontrastkravene fra WCAG blir oppfylt.
|
||||
|
||||
### Fareknappen
|
||||
|
||||
Fareknappen skiller seg bare ut med farge, og bryter dermed egentlig med [WCAGs suksesskriterium 1.4.1](https://uu.difi.no/krav-og-regelverk/wcag-20-standarden/141-bruk-av-farge-niva). Vi har likevel valgt å ikke tilsette noe label for skjermleser. Dette har vi gjort fordi selve navnet på knappen forteller hva son skjer hvis man trykker på den, og fordi en ekstra label vil, etter vår vurdering, kunne snarere tilføye støy enn å skape mer oversikt for skjermleserbrukere.
|
||||
|
||||
### Knapper med bare ikon
|
||||
|
||||
Husk at knapper med bare ikoner også må få en tekst-verdi av hensyn til skjermlesere. Utility-klassen `sr-only` som gis av [mixins-fila i Core-pakken](https://github.com/navikt/nav-frontend-moduler/blob/master/packages/nav-frontend-core/less/_mixins.less) kan brukes for å skjule teksten visuelt.
|
||||
@@ -1,98 +0,0 @@
|
||||
---
|
||||
title: Alertstriper
|
||||
---
|
||||
|
||||
# Alertstriper
|
||||
|
||||
Alertstripen er en komponent som benyttes for å gi brukeren varsler av ymse slag, og komponenten støtter forskjellige visninger basert på hvilken type varsel som formidles til brukeren.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-alertstriper classnames nav-frontend-alertstriper-style nav-frontend-core nav-frontend-ikoner-assets nav-frontend-paneler-style nav-frontend-typografi-style nav-frontend-typografi prop-types react --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-alertstriper" imports="AlertStripe" defaultExport />
|
||||
|
||||
## Default striper
|
||||
|
||||
<Preview
|
||||
react={`<><Alertstripe type="info">Nå kan du sende inn søknaden.</Alertstripe>
|
||||
<Alertstripe type="suksess">Du har sendt søknaden.</Alertstripe>
|
||||
<Alertstripe type="advarsel">
|
||||
Det er mange som bruker nav.no nå, derfor kan det ta litt tid før søknaden
|
||||
din kommer fram.
|
||||
</Alertstripe>
|
||||
<Alertstripe type="feil">
|
||||
Det er ikke mulig å sende søknaden akkurat nå, vennligst prøv igjen senere.
|
||||
Du er velkommen til å <Link href="#">følge med på hvordan det går</Link>.
|
||||
</Alertstripe></>`}
|
||||
>
|
||||
<Alertstripe type="info">Nå kan du sende inn søknaden.</Alertstripe>
|
||||
<Alertstripe type="suksess">Du har sendt søknaden.</Alertstripe>
|
||||
<Alertstripe type="advarsel">
|
||||
Det er mange som bruker nav.no nå, derfor kan det ta litt tid før søknaden
|
||||
din kommer fram.
|
||||
</Alertstripe>
|
||||
<Alertstripe type="feil">
|
||||
Det er ikke mulig å sende søknaden akkurat nå, vennligst prøv igjen senere.
|
||||
Du er velkommen til å <Link href="#">følge med på hvordan det går</Link>.
|
||||
</Alertstripe>
|
||||
</Preview>
|
||||
|
||||
## Inline striper
|
||||
|
||||
<Preview
|
||||
react={`<><Alertstripe type="info" form="inline">
|
||||
Nå kan du sende inn søknaden.
|
||||
</Alertstripe>
|
||||
<Alertstripe type="suksess" form="inline">
|
||||
Du har sendt søknaden.
|
||||
</Alertstripe>
|
||||
<Alertstripe type="advarsel" form="inline">
|
||||
Det er mange som bruker nav.no nå, derfor kan det ta litt tid før søknaden
|
||||
din kommer fram.
|
||||
</Alertstripe>
|
||||
<Alertstripe type="feil" form="inline">
|
||||
Det er ikke mulig å sende søknaden akkurat nå, vennligst prøv igjen senere.
|
||||
Du er velkommen til å <Link href="#">følge med på hvordan det går</Link>.
|
||||
</Alertstripe></>`}
|
||||
>
|
||||
<Alertstripe type="info" form="inline">
|
||||
Nå kan du sende inn søknaden.
|
||||
</Alertstripe>
|
||||
<Alertstripe type="suksess" form="inline">
|
||||
Du har sendt søknaden.
|
||||
</Alertstripe>
|
||||
<Alertstripe type="advarsel" form="inline">
|
||||
Det er mange som bruker nav.no nå, derfor kan det ta litt tid før søknaden
|
||||
din kommer fram.
|
||||
</Alertstripe>
|
||||
<Alertstripe type="feil" form="inline">
|
||||
Det er ikke mulig å sende søknaden akkurat nå, vennligst prøv igjen senere.
|
||||
Du er velkommen til å <Link href="#">følge med på hvordan det går</Link>.
|
||||
</Alertstripe>
|
||||
</Preview>
|
||||
|
||||
## Tilgjengelighet
|
||||
|
||||
### Dynamisk visning
|
||||
|
||||
Hvis alertstripene skal dukke opp dynamisk, for eksempel som en reaksjon på noe brukeren gjør, er det viktig at det allerede ligger et element på siden som har definert en såkalt "live region" hvor Alertstripene skal bli rendret i. Dette kan gjøres ved å gi container-elementet et `aria-live`-attributt med verdien `polite` eller `assertive`.
|
||||
|
||||
<Bash code={`<div aria-live="polite">
|
||||
<!-- her kommer det en Alertstripe når brukeren klikker på noe -->
|
||||
</div>`}/>
|
||||
|
||||
Merk at `aria-live="assertive"` bør brukes varsomt og kun når det er nødvendig å få brukerens oppmerksomhet umiddelbart. Et alternativ er å gi konteiner-elementet et `role="alert"`-attributt, som er akkurat det samme som å sette `aria-live="assertive"` og `aria-atomic="true`.
|
||||
|
||||
### Mer informasjon
|
||||
|
||||
- [Using ARIA role=alert or Live Regions to Identify Errors (W3.org)](https://www.w3.org/TR/WCAG20-TECHS/ARIA19.html)
|
||||
- [ARIA Live Regions (Mozilla Developer Network)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions)
|
||||
- [Using the alert role (Mozilla Developer Network)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_alert_role)
|
||||
- [User Notifications (W3.org)](https://www.w3.org/WAI/tutorials/forms/notifications/)
|
||||
@@ -1,53 +0,0 @@
|
||||
---
|
||||
title: Chevron
|
||||
---
|
||||
|
||||
# Chevron
|
||||
|
||||
Disse ikonene bruker vi for å forsterke forventing man kan til av interaksjonen med en modul.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-chevron classnames nav-frontend-chevron-style prop-types react --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-chevron" imports="Chevron" defaultExport />
|
||||
|
||||
## Liten (default)
|
||||
|
||||
<Preview
|
||||
react={`<><Chevron type={"venstre"} />
|
||||
<Chevron type={"høyre"} />
|
||||
<Chevron type={"opp"} />
|
||||
<Chevron type={"ned"} /></>`}
|
||||
>
|
||||
<Chevron type={"venstre"} />
|
||||
<Chevron type={"høyre"} />
|
||||
<Chevron type={"opp"} />
|
||||
<Chevron type={"ned"} />
|
||||
</Preview>
|
||||
|
||||
## Stor
|
||||
|
||||
<Preview
|
||||
react={`<><Chevron stor type={"venstre"} />
|
||||
<Chevron stor type={"høyre"} />
|
||||
<Chevron stor type={"opp"} />
|
||||
<Chevron stor type={"ned"} /></>`}
|
||||
>
|
||||
<Chevron stor type={"venstre"} />
|
||||
<Chevron stor type={"høyre"} />
|
||||
<Chevron stor type={"opp"} />
|
||||
<Chevron stor type={"ned"} />
|
||||
</Preview>
|
||||
|
||||
## Tilgjengelighet
|
||||
|
||||
### Tilhørighet og avstand
|
||||
|
||||
Prøv å unngå at chevron står for langt unna teksten den hører til. Er det for stor avstand blir det vanskelig for personer som bruker forstørrelsesprogramvare å se hvilke elmenter som hører sammen.
|
||||
@@ -1,112 +0,0 @@
|
||||
---
|
||||
title: Ekspanderbartpanel
|
||||
---
|
||||
|
||||
# Ekspanderbartpanel
|
||||
|
||||
Ekspanderbartpanel er et panel som kan ekspandere eller kollapse innhold. Komponenten bruker npm-pakken React-collapse og extender props fra den.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-ekspanderbartpanel @types/react-collapse classnames nav-frontend-ekspanderbartpanel-style nav-frontend-chevron-style nav-frontend-core nav-frontend-paneler-style nav-frontend-typografi-style nav-frontend-js-utils lodash.throttle prop-types react react-collapse --save`}
|
||||
/>
|
||||
|
||||
<Npm
|
||||
packName="nav-frontend-ekspanderbartpanel"
|
||||
imports="Ekspanderbartpanel"
|
||||
defaultExport
|
||||
/>
|
||||
|
||||
## Normal
|
||||
|
||||
<Preview
|
||||
react={`<Ekspanderbartpanel tittel="Klikk her for å åpne/lukke panelet">
|
||||
Panelet vil da ekspandere og vise innholdet.
|
||||
</Ekspanderbartpanel>`}
|
||||
>
|
||||
<Ekspanderbartpanel tittel="Klikk her for å åpne/lukke panelet">
|
||||
Panelet vil da ekspandere og vise innholdet.
|
||||
</Ekspanderbartpanel>
|
||||
</Preview>
|
||||
|
||||
## Endre tekststørrelse
|
||||
|
||||
For å endre tekst-størrelsen på åpne/lukke-knappen kan man sende inn en annen
|
||||
[typografi-type](/components/typografi) via `tittel`-propen.
|
||||
|
||||
<Preview
|
||||
react={`<Ekspanderbartpanel
|
||||
tittel={<Normaltekst>Klikk her for å åpne/lukke panelet</Normaltekst>}
|
||||
>
|
||||
Panelet vil da ekspandere og vise innholdet.
|
||||
</Ekspanderbartpanel>`}
|
||||
>
|
||||
<Ekspanderbartpanel
|
||||
tittel={<Normaltekst>Klikk her for å åpne/lukke panelet</Normaltekst>}
|
||||
>
|
||||
Panelet vil da ekspandere og vise innholdet.
|
||||
</Ekspanderbartpanel>
|
||||
</Preview>
|
||||
|
||||
## Avansert innhold i åpne/lukke-knapp
|
||||
|
||||
Komponentens `tittel`-prop støtter rikt HTML-innhold.
|
||||
|
||||
<Preview
|
||||
react={`<Ekspanderbartpanel
|
||||
tittel={
|
||||
<div>
|
||||
<Undertittel>Klikk her for å åpne/lukke panelet</Undertittel>
|
||||
<Etikett type="suksess">En etikett</Etikett>
|
||||
<Etikett type="fokus" style={{ marginLeft: "0.5rem" }}>
|
||||
En annen etikett
|
||||
</Etikett>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
Panelet vil da ekspandere og vise innholdet.
|
||||
</Ekspanderbartpanel>`}
|
||||
>
|
||||
<Ekspanderbartpanel
|
||||
tittel={
|
||||
<div>
|
||||
<Undertittel>Klikk her for å åpne/lukke panelet</Undertittel>
|
||||
<Etikett type="suksess">En etikett</Etikett>
|
||||
<Etikett type="fokus" style={{ marginLeft: "0.5rem" }}>
|
||||
En annen etikett
|
||||
</Etikett>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
Panelet vil da ekspandere og vise innholdet.
|
||||
</Ekspanderbartpanel>
|
||||
</Preview>
|
||||
|
||||
## Kontroller komponenten selv
|
||||
|
||||
Styr komponent fra ekstern state (controlled components).
|
||||
|
||||
<Preview
|
||||
react={`<div>
|
||||
<Knapp onClick={() => setOpen(true)} style={btnStyle}>
|
||||
Åpne
|
||||
</Knapp>
|
||||
<Knapp onClick={() => setOpen(false)} style={btnStyle}>
|
||||
Lukke
|
||||
</Knapp>
|
||||
<EkspanderbartpanelBase
|
||||
tittel="Kan også klikke her"
|
||||
apen={open}
|
||||
onClick={() => setOpen((open) => !open)}
|
||||
>
|
||||
Alt innholdet ditt
|
||||
</EkspanderbartpanelBase>
|
||||
</div>`}
|
||||
>
|
||||
<EkspanderbartpanelExample />
|
||||
</Preview>
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
title: Etikett
|
||||
---
|
||||
|
||||
# Etikett
|
||||
|
||||
Etiketter er ment for rask visuell kategorisering og organisering av elementer, ved bruk av farge og beskrivende nøkkelord.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-etiketter classnames nav-frontend-core nav-frontend-etiketter-style nav-frontend-typografi nav-frontend-typografi-style prop-types react --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-etiketter" imports="Etikett" defaultExport />
|
||||
|
||||
## Alle etiketter side om side
|
||||
|
||||
Vi bruker etiketter for å vise status i en handling. Standard farger på etikettene er basert på
|
||||
informasjon til brukere, men man kan skape egne etikker med eget farge og nøkkelord. Bruk etiketter
|
||||
sparsomt. Mange etiketter med forskjellige farger og grupperinger kan skape mer rot en orden.
|
||||
|
||||
<Preview
|
||||
react={`<><Etikett type="suksess">Suksess</Etikett>
|
||||
<Etikett type="info">Info</Etikett>
|
||||
<Etikett type="advarsel">Advarsel</Etikett>
|
||||
<Etikett type="fokus">Fokus</Etikett></>`}
|
||||
>
|
||||
<Etikett type="suksess">Suksess</Etikett>
|
||||
<Etikett type="info">Info</Etikett>
|
||||
<Etikett type="advarsel">Advarsel</Etikett>
|
||||
<Etikett type="fokus">Fokus</Etikett>
|
||||
</Preview>
|
||||
|
||||
## Mini
|
||||
|
||||
Alle etiketter kan rendres i en mindre `24px` versjon med `14px` font.
|
||||
|
||||
<Alert variant="warning">
|
||||
Som hovedregel burde man alltid bruke de normale etikettene våre. For
|
||||
tilfeller med svært begrenset plass kan de mindre etikettene brukes{" "}
|
||||
<strong>unntaksvis ved klart behov</strong>.
|
||||
</Alert>
|
||||
|
||||
<Preview
|
||||
react={`<><Etikett mini type="suksess">
|
||||
Suksess
|
||||
</Etikett>
|
||||
<Etikett mini type="info">
|
||||
Info
|
||||
</Etikett>
|
||||
<Etikett mini type="advarsel">
|
||||
Advarsel
|
||||
</Etikett>
|
||||
<Etikett mini type="fokus">
|
||||
Fokus
|
||||
</Etikett></>`}
|
||||
>
|
||||
<Etikett mini type="suksess">
|
||||
Suksess
|
||||
</Etikett>
|
||||
<Etikett mini type="info">
|
||||
Info
|
||||
</Etikett>
|
||||
<Etikett mini type="advarsel">
|
||||
Advarsel
|
||||
</Etikett>
|
||||
<Etikett mini type="fokus">
|
||||
Fokus
|
||||
</Etikett>
|
||||
</Preview>
|
||||
|
||||
## Tilgjengelighet
|
||||
|
||||
### Farge og tekst må høre sammen
|
||||
|
||||
Pass på at fargen og teksten på etiketten alltid samsvarer med hverandre. Da forhinder du at personer med dårlig fargesyn, eller en dårlig skjerm, går glipp av informasjon.
|
||||
|
||||
### Mer informasjon
|
||||
|
||||
- [WCAG 1.4.1: Bruk av farge](https://uu.difi.no/krav-og-regelverk/wcag-20-standarden/141-bruk-av-farge-niva)
|
||||
@@ -1,137 +0,0 @@
|
||||
---
|
||||
title: Hjelpetekst
|
||||
---
|
||||
|
||||
# Hjelpetekst
|
||||
|
||||
Hjelpetekst er en knapp som kan åpne en Popover med kontekstuell informasjon.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-hjelpetekst classnames nav-frontend-hjelpetekst-style nav-frontend-core nav-frontend-typografi-style nav-frontend-ikoner-assets nav-frontend-js-utils lodash.throttle prop-types react nav-frontend-popover nav-frontend-popover-style react-dom --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-hjelpetekst" imports="Hjelpetekst" defaultExport />
|
||||
|
||||
## Normal
|
||||
|
||||
Hjelpetekst brukes når brukeren kan trenge mer informasjon, men hvor det ikke er naturlig
|
||||
å bruke plass på det i grensesnittet. Dette kan for eksempel være for å forklare vanskelige
|
||||
begreper, gi veiledning i utfylling av skjema-felter eller utdype bakgrunn for et regelverk.
|
||||
|
||||
<Preview
|
||||
react={`<Hjelpetekst>
|
||||
Innholdet vil vises når brukeren klikker på knappen.
|
||||
</Hjelpetekst>`}
|
||||
>
|
||||
<Hjelpetekst>
|
||||
Innholdet vil vises når brukeren klikker på knappen.
|
||||
</Hjelpetekst>
|
||||
</Preview>
|
||||
|
||||
## Kombinasjon med skjemafelt
|
||||
|
||||
For å enkelt knytte Hjelpetekst-komponenten til et skjemafelt kan komponenten sendes inn
|
||||
via `label`-propen til skjemafeltet.
|
||||
|
||||
<Preview
|
||||
react={`<Input
|
||||
id="min-input"
|
||||
label={
|
||||
<div style={{ display: "flex" }}>
|
||||
Fødselsnummer
|
||||
<Hjelpetekst style={{ marginLeft: "0.5rem" }}>
|
||||
Innholdet vil vises når brukeren klikker på knappen.
|
||||
</Hjelpetekst>
|
||||
</div>
|
||||
}
|
||||
/>`}
|
||||
>
|
||||
<Input
|
||||
id="min-input"
|
||||
label={
|
||||
<div style={{ display: "flex" }}>
|
||||
Fødselsnummer
|
||||
<Hjelpetekst style={{ marginLeft: "0.5rem" }}>
|
||||
Innholdet vil vises når brukeren klikker på knappen.
|
||||
</Hjelpetekst>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</Preview>
|
||||
|
||||
## Posisjon av popup
|
||||
|
||||
Du kan bestemme hvor popup-ruten dukker opp.
|
||||
|
||||
<Preview
|
||||
react={`<><Hjelpetekst type="over">Denne vil åpnes over knappen.</Hjelpetekst>
|
||||
<Hjelpetekst type="over-venstre">
|
||||
Denne vil åpnes over knappen, justert fra venstre kant.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="over-hoyre">
|
||||
Denne vil åpnes over knappen, justert fra høyre kant.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="under">Denne vil åpnes under knappen.</Hjelpetekst>
|
||||
<Hjelpetekst type="under-venstre">
|
||||
Denne vil åpnes under knappen, justert fra venstre kant.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="under-hoyre">
|
||||
Denne vil åpnes under knappen, justert fra høyre kant.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="venstre">
|
||||
Denne vil åpnes til venstre for knappen.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="hoyre">Denne vil åpnes til høyre for knappen.</Hjelpetekst></>`}
|
||||
>
|
||||
<Hjelpetekst type="over">Denne vil åpnes over knappen.</Hjelpetekst>
|
||||
<Hjelpetekst type="over-venstre">
|
||||
Denne vil åpnes over knappen, justert fra venstre kant.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="over-hoyre">
|
||||
Denne vil åpnes over knappen, justert fra høyre kant.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="under">Denne vil åpnes under knappen.</Hjelpetekst>
|
||||
<Hjelpetekst type="under-venstre">
|
||||
Denne vil åpnes under knappen, justert fra venstre kant.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="under-hoyre">
|
||||
Denne vil åpnes under knappen, justert fra høyre kant.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="venstre">
|
||||
Denne vil åpnes til venstre for knappen.
|
||||
</Hjelpetekst>
|
||||
<Hjelpetekst type="hoyre">Denne vil åpnes til høyre for knappen.</Hjelpetekst>
|
||||
</Preview>
|
||||
|
||||
## Tilgjengelighet
|
||||
|
||||
### Assosiasjon
|
||||
|
||||
Hjelpeteksten bør få en logisk kobling til elementet som det forsøker å beskrive/støtte.
|
||||
|
||||
Om hjelpeteksten må plasseres på utsiden av `<label>`, eller på andre måter ikke har noen annen logisk kobling til elementet som det forsøker å beskrive, kan dette løses ved å bruke `aria-describedby` og `aria-labelledby` slik:
|
||||
|
||||
<Bash
|
||||
code={`<>
|
||||
<span id="mitt-faguttrykk" aria-describedby="min-hjelpetekst">
|
||||
Restarbeidsevne
|
||||
</span>
|
||||
<Hjelpetekst
|
||||
id="min-hjelpetekst"
|
||||
aria-labelledby="mitt-faguttrykk"
|
||||
>
|
||||
Mulighet til å jobbe litt eller delvis
|
||||
</Hjelpetekst>
|
||||
</>`}
|
||||
/>
|
||||
|
||||
### Mer informasjon
|
||||
|
||||
- [WCAG 1.1.1: Ikke-tekstlig innhold](https://uu.difi.no/krav-og-regelverk/wcag-20-standarden/111-ikke-tekstlig-innhold-niva)
|
||||
- [WCAG 3.3.5: Hjelp](https://uu.difi.no/krav-og-regelverk/wcag-20-standarden/ikke-lovpalagte-krav/335-hjelp-niva-aaa)
|
||||
@@ -1,65 +0,0 @@
|
||||
---
|
||||
title: Lesmerpanel
|
||||
---
|
||||
|
||||
# Lesmerpanel
|
||||
|
||||
Lesmerpanel er en komponent som lar deg ekspandere og kollapse innhold. Passer for lengre tekster og infopanel der ikke alt innhold er like relevant. Komponenten bruker npm-pakken React-collapse og extender props fra den.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-lesmerpanel classnames nav-frontend-chevron nav-frontend-chevron-style prop-types react nav-frontend-js-utils lodash.throttle nav-frontend-lesmerpanel-style nav-frontend-core nav-frontend-paneler-style react-collapse --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-lesmerpanel" imports="Lesmerpanel" defaultExport />
|
||||
|
||||
## Normal
|
||||
|
||||
<Preview
|
||||
react={`<Lesmerpanel
|
||||
intro={
|
||||
<span>
|
||||
Introduksjonstekst her som <a href="#">kan være HTML</a>
|
||||
</span>
|
||||
}
|
||||
border
|
||||
>
|
||||
<div>
|
||||
<p style={{ marginTop: 0 }}>
|
||||
Du bestemmer selv om du vil bruke sykmeldingen eller avbryte den. Du kan
|
||||
også jobbe i kombinasjon med sykmelding. Det kommer an på hva sykdommen
|
||||
din tillater og hva det er praktisk mulig å få til på arbeidsplassen.
|
||||
</p>
|
||||
<p>
|
||||
Greit å vite: Arbeidsgiveren har plikt til å legge til rette for at du
|
||||
kan jobbe helt eller delvis selv om du er syk.
|
||||
</p>
|
||||
</div>
|
||||
</Lesmerpanel>`}
|
||||
>
|
||||
<Lesmerpanel
|
||||
intro={
|
||||
<span>
|
||||
Introduksjonstekst her som <a href="#">kan være HTML</a>
|
||||
</span>
|
||||
}
|
||||
border
|
||||
>
|
||||
<div>
|
||||
<p style={{ marginTop: 0 }}>
|
||||
Du bestemmer selv om du vil bruke sykmeldingen eller avbryte den. Du kan
|
||||
også jobbe i kombinasjon med sykmelding. Det kommer an på hva sykdommen
|
||||
din tillater og hva det er praktisk mulig å få til på arbeidsplassen.
|
||||
</p>
|
||||
<p>
|
||||
Greit å vite: Arbeidsgiveren har plikt til å legge til rette for at du
|
||||
kan jobbe helt eller delvis selv om du er syk.
|
||||
</p>
|
||||
</div>
|
||||
</Lesmerpanel>
|
||||
</Preview>
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
title: Modal
|
||||
---
|
||||
|
||||
# Modal
|
||||
|
||||
Modal er et midtstilt vindu som legger seg over det andre innholdet, med en mørk gjennomsiktig bakgrunn. Komponenten bruker npm-pakken React-modal og extender props fra den.
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-modal @types/react-modal classnames nav-frontend-lukknapp nav-frontend-lukknapp-style nav-frontend-core prop-types react nav-frontend-modal-style nav-frontend-paneler-style react-modal --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-modal" imports="Modal" defaultExport />
|
||||
|
||||
## Normal
|
||||
|
||||
Når modalen åpnes vil den legge seg over det andre innholdet på siden. Modalen kan lukkes igjen ved å klikke på
|
||||
lukk-knappen, klikke utenfor modalruten eller ved å trykke "Esc" på tastaturet. Innholdet i modalruten kan
|
||||
bestemmes helt fritt.
|
||||
|
||||
<Preview
|
||||
hideHtml
|
||||
react={`<div>
|
||||
<Knapp onClick={() => setOpen(true)}>Klikk for å åpne modal</Knapp>
|
||||
<Modal
|
||||
isOpen={open}
|
||||
onRequestClose={() => setOpen(false)}
|
||||
closeButton
|
||||
contentLabel="Min modalrute"
|
||||
>
|
||||
<div style={{ padding: "2rem 2.5rem" }}>Innhold her</div>
|
||||
</Modal>
|
||||
</div>`}
|
||||
>
|
||||
<ModalExample />
|
||||
</Preview>
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
title: Panel
|
||||
---
|
||||
|
||||
# Panel
|
||||
|
||||
<TableOfContents />
|
||||
|
||||
## Teknisk
|
||||
|
||||
<Bash
|
||||
terminal
|
||||
copy
|
||||
code={`npm install nav-frontend-paneler classnames nav-frontend-paneler-style nav-frontend-core nav-frontend-typografi nav-frontend-typografi-style prop-types react --save`}
|
||||
/>
|
||||
|
||||
<Npm packName="nav-frontend-paneler" imports="Panel" defaultExport />
|
||||
|
||||
## Normal
|
||||
|
||||
Paneler brukes til å ramme inn innhold. På hvit bakgrunn bør paneler få en 1px tykk border med farge
|
||||
[@navGra20](/resources/colors) (#C6C2BF). Intern avstand fra panelkant til innhold skal være
|
||||
minimum `16px` (`1rem`).
|
||||
|
||||
<Preview react={`<Panel border>Et helt vanlig panel med innhold.</Panel>`}>
|
||||
<Panel border>Et helt vanlig panel med innhold.</Panel>
|
||||
</Preview>
|
||||
Loaded 100 of 191 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user