mirror of
https://github.com/navikt/aksel.git
synced 2026-10-13 09:12:03 +00:00
Compare commits
52
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c52069377 | ||
|
|
4ed374750e | ||
|
|
9b005c6812 | ||
|
|
b5b98f44d3 | ||
|
|
f8779a5cc2 | ||
|
|
5fbd4b8f80 | ||
|
|
8663d185c3 | ||
|
|
8a77776e2e | ||
|
|
aef7582f15 | ||
|
|
5b8e79262e | ||
|
|
6dd062c947 | ||
|
|
03c46a69b1 | ||
|
|
8cc79da072 | ||
|
|
ab6a853d10 | ||
|
|
6076462d75 | ||
|
|
fa1478673f | ||
|
|
e577c60263 | ||
|
|
000f7318a6 | ||
|
|
6ab2228c88 | ||
|
|
5b08e97b1f | ||
|
|
0637092224 | ||
|
|
ad5c0e8a2b | ||
|
|
6173ede6a7 | ||
|
|
90da6be37e | ||
|
|
4b1424daf2 | ||
|
|
318b8c8ac6 | ||
|
|
4dd746d27d | ||
|
|
ffcfe79c18 | ||
|
|
5d8d2ffba9 | ||
|
|
c785316086 | ||
|
|
7087f160e8 | ||
|
|
235e48a843 | ||
|
|
93fc5dc6ae | ||
|
|
5c49902ffb | ||
|
|
c9c148e050 | ||
|
|
adf9de3c63 | ||
|
|
26612e371d | ||
|
|
b194506943 | ||
|
|
79dbffff1d | ||
|
|
0359934bb9 | ||
|
|
2723363fa0 | ||
|
|
d56bc72977 | ||
|
|
e203d669e1 | ||
|
|
90c06964a3 | ||
|
|
c35850a5e5 | ||
|
|
fd2ebe2629 | ||
|
|
206cdaa2ce | ||
|
|
42bc4288f5 | ||
|
|
3d7cc1112c | ||
|
|
00fec86f80 | ||
|
|
d631e4b611 | ||
|
|
3097afe082 |
No files matched your search
@@ -0,0 +1,8 @@
|
||||
.navds-accordion-anchor-menu {
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.navds-accordion-anchor-menu__title {
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
.navds-accordion-menu__list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: var(--navds-font-weight-bold);
|
||||
}
|
||||
|
||||
.navds-accordion-menu-collapsable__button {
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
font: inherit;
|
||||
text-align: inherit;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-weight: var(--navds-font-weight-bold);
|
||||
color: var(--navds-color-text-link);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.navds-accordion-menu-collapsable .navds-accordion-menu__list,
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-collapsable__button {
|
||||
font-weight: var(--navds-font-weight-regular);
|
||||
}
|
||||
|
||||
.navds-accordion-menu-item,
|
||||
.navds-accordion-menu-collapsable__button {
|
||||
display: flex;
|
||||
padding: 0.75rem 1rem;
|
||||
line-height: 1.5rem; /* TODO: fix typography. */
|
||||
}
|
||||
|
||||
.navds-accordion-menu-collapsable__expand-icon {
|
||||
font-size: 1.5rem;
|
||||
color: var(--navds-color-text-link);
|
||||
flex-shrink: 0;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.navds-accordion-menu-collapsable--open
|
||||
> .navds-accordion-menu-collapsable__button
|
||||
> .navds-accordion-menu-collapsable__expand-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.navds-accordion-menu-collapsable .navds-accordion-menu-item,
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-collapsable__button {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-item,
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-collapsable
|
||||
.navds-accordion-menu-collapsable__button {
|
||||
padding-left: 3rem;
|
||||
}
|
||||
|
||||
.navds-accordion-menu-item:focus,
|
||||
.navds-accordion-menu-collapsable__button:focus {
|
||||
outline: 3px solid var(--navds-text-focus);
|
||||
outline-offset: -3px;
|
||||
}
|
||||
|
||||
.navds-accordion-menu-item:hover,
|
||||
.navds-accordion-menu-collapsable__button:hover {
|
||||
background-color: var(--navds-color-gray-20);
|
||||
}
|
||||
|
||||
.navds-accordion-menu-item--active {
|
||||
box-shadow: inset 0.5rem 0 var(--navds-color-text-link);
|
||||
color: var(--navds-color-text);
|
||||
text-decoration: none;
|
||||
font-weight: var(--navds-font-weight-bold);
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
.navds-accordion__chevron {
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
transition: 300ms transform;
|
||||
transform: rotateZ(0deg);
|
||||
flex-shrink: 0;
|
||||
margin-left: 1rem;
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
@import "print.css";
|
||||
@import "utility.css";
|
||||
|
||||
html:focus-within {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--navds-font-family);
|
||||
line-height: 1.375;
|
||||
@@ -16,3 +20,18 @@ body {
|
||||
a {
|
||||
color: var(--navds-color-text-link);
|
||||
}
|
||||
|
||||
/* https://web.dev/prefers-reduced-motion/ */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
animation-delay: -1ms !important;
|
||||
animation-duration: 1ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
background-attachment: initial !important;
|
||||
scroll-behavior: auto !important;
|
||||
transition-duration: 0s !important;
|
||||
transition-delay: 0s !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
.navds-copy-to-clipboard {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
column-gap: 0.5em;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.navds-copy-to-clipboard__popover {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
@import "baseline/baseline.css";
|
||||
@import "accordion.css";
|
||||
@import "accordion-anchor-menu.css";
|
||||
@import "accordion-menu.css";
|
||||
@import "alert.css";
|
||||
@import "button.css";
|
||||
@import "content-container.css";
|
||||
@import "copy-to-clipboard.css";
|
||||
@import "grid.css";
|
||||
@import "internal-header.css";
|
||||
@import "layout.css";
|
||||
@import "layouts.css";
|
||||
@import "link.css";
|
||||
@import "modal.css";
|
||||
@import "popover.css";
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
.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--sticky > * {
|
||||
top: var(--navds-grid-gutter-small);
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
.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--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) {
|
||||
.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) {
|
||||
.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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
/*****************
|
||||
* .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--sticky > * {
|
||||
top: calc(var(--navds-grid-gutter-small) + var(--decorator-sticky-offset));
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
.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) {
|
||||
.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) {
|
||||
.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: 0.25rem 0.85rem;
|
||||
}
|
||||
|
||||
@media (min-width: 448px) {
|
||||
.navds-layout__header-title {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************
|
||||
* .navds-layout__body *
|
||||
************************/
|
||||
|
||||
.navds-layout__body {
|
||||
background: var(--navds-layout-background-gray);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.navds-layout__panel-copy-icon {
|
||||
color: var(--navds-color-text-link);
|
||||
margin-right: 0.5rem;
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
|
||||
.navds-layout__panel-popover-content {
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
.navds-layout__panel-copy-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
margin: 0 1rem 0 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
|
||||
.navds-modal__overlay {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
z-index: var(--navds-z-index-modal-overlay);
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.9",
|
||||
"private": false,
|
||||
"description": "Css for NAV Designsystem components",
|
||||
"author": "NAV Designsystem team",
|
||||
@@ -21,7 +21,7 @@
|
||||
"watch-css": "postcss -w --use postcss-import -o dist/index.css index.css"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^0.1.0",
|
||||
"@navikt/ds-tokens": "^0.1.2",
|
||||
"normalize.css": "^8.0.1",
|
||||
"postcss": "^8.2.7",
|
||||
"postcss-cli": "^8.3.1",
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
box-shadow: 0 0.05rem 0.25rem 0.125rem rgba(0, 0, 0, 0.08);
|
||||
border: var(--navds-border-default);
|
||||
border-radius: 2px;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.navds-popover--small {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.navds-popover--hidden {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-icons",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"private": false,
|
||||
"description": "NAVs egne ikoner i SVG og React format",
|
||||
"repository": {
|
||||
@@ -22,6 +22,7 @@
|
||||
"files": [
|
||||
"/cjs",
|
||||
"/esm",
|
||||
"/src",
|
||||
"/svg"
|
||||
],
|
||||
"scripts": {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import cl from "classnames";
|
||||
import React, {
|
||||
Children,
|
||||
forwardRef,
|
||||
ForwardRefExoticComponent,
|
||||
HTMLAttributes,
|
||||
} from "react";
|
||||
import { default as Section, SectionProps } from "./Section";
|
||||
|
||||
export interface LayoutWithSubComponents
|
||||
extends ForwardRefExoticComponent<LayoutProps> {
|
||||
Section: ForwardRefExoticComponent<SectionProps>;
|
||||
}
|
||||
|
||||
export interface LayoutProps extends HTMLAttributes<HTMLElement> {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const Layout = forwardRef<HTMLDivElement, LayoutProps>(
|
||||
({ children, className, ...rest }, ref) => {
|
||||
const columns = Children.count(children);
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-layout__container",
|
||||
`navds-layout__container--${columns}-columns`,
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
) as LayoutWithSubComponents;
|
||||
|
||||
Layout.Section = Section;
|
||||
export default Layout;
|
||||
@@ -1,3 +0,0 @@
|
||||
export { default as Layout } from "./Layout";
|
||||
export * from "./Layout";
|
||||
export * from "./Section";
|
||||
@@ -1,94 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { useEffect } from "react";
|
||||
import { ContentContainer } from "../../index";
|
||||
import { Layout } from "../index";
|
||||
import { Left } from "./components/sections/Left";
|
||||
import { Main } from "./components/sections/Main";
|
||||
import { Right } from "./components/sections/Right";
|
||||
import "./components/styles.css";
|
||||
|
||||
export default {
|
||||
title: "ds-react/layout/Article",
|
||||
component: { Layout },
|
||||
decorators: [
|
||||
(Story) => {
|
||||
useEffect(() => {
|
||||
document.getElementById("decorator-header").style.display = "block";
|
||||
document.getElementById("decorator-footer").style.display = "block";
|
||||
return () => {
|
||||
document.getElementById("decorator-header").style.display = "none";
|
||||
document.getElementById("decorator-footer").style.display = "none";
|
||||
};
|
||||
}, []);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
backgrounds: {
|
||||
default: "NAV gray",
|
||||
values: [
|
||||
{
|
||||
name: "NAV gray",
|
||||
value: "#f1f1f1",
|
||||
},
|
||||
{
|
||||
name: "white",
|
||||
value: "#ffffff",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const ThreeColumns = () => (
|
||||
<ContentContainer>
|
||||
<Layout>
|
||||
<Layout.Section left sticky>
|
||||
<Left />
|
||||
</Layout.Section>
|
||||
<Layout.Section>
|
||||
<Main />
|
||||
</Layout.Section>
|
||||
<Layout.Section right sticky>
|
||||
<Right />
|
||||
</Layout.Section>
|
||||
</Layout>
|
||||
</ContentContainer>
|
||||
);
|
||||
|
||||
export const TwoColumnsLeft = () => (
|
||||
<ContentContainer>
|
||||
<Layout>
|
||||
<Layout.Section left sticky>
|
||||
<Left />
|
||||
</Layout.Section>
|
||||
<Layout.Section>
|
||||
<Main />
|
||||
</Layout.Section>
|
||||
</Layout>
|
||||
</ContentContainer>
|
||||
);
|
||||
|
||||
export const TwoColumnsRight = () => (
|
||||
<ContentContainer>
|
||||
<Layout>
|
||||
<Layout.Section>
|
||||
<Main />
|
||||
</Layout.Section>
|
||||
<Layout.Section right sticky>
|
||||
<Right />
|
||||
</Layout.Section>
|
||||
</Layout>
|
||||
</ContentContainer>
|
||||
);
|
||||
|
||||
export const OneColumn = () => (
|
||||
<ContentContainer>
|
||||
<Layout>
|
||||
<Layout.Section>
|
||||
<Main />
|
||||
</Layout.Section>
|
||||
</Layout>
|
||||
</ContentContainer>
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.13",
|
||||
"private": false,
|
||||
"description": "NAV designsystem react components",
|
||||
"author": "NAV Designsystem team",
|
||||
@@ -24,17 +24,20 @@
|
||||
},
|
||||
"files": [
|
||||
"/cjs",
|
||||
"/esm"
|
||||
"/esm",
|
||||
"/src"
|
||||
],
|
||||
"scripts": {
|
||||
"cjs-package": "copyfiles -f config/package.json cjs",
|
||||
"build": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && yarn cjs-package",
|
||||
"watch": "tsc --watch -p tsconfig.json"
|
||||
"clean": "rm -rf cjs esm",
|
||||
"build": "yarn run clean && tsc && tsc -p tsconfig-esm.json && yarn cjs-package",
|
||||
"watch": "tsc --watch -p tsconfig-esm.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-icons": "^0.2.0",
|
||||
"@navikt/ds-icons": "^0.2.1",
|
||||
"@popperjs/core": "^2.5.4",
|
||||
"classnames": "^2.2.6",
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"react-collapse": "^5.1.0",
|
||||
"react-merge-refs": "^1.1.0",
|
||||
"react-modal": "3.12.1",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import { AccordionMenu as BaseAccordionMenu } from "../accordion-menu";
|
||||
import { Heading } from "../index";
|
||||
import { ActiveAnchorProvider } from "./ActiveAnchorStore";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface AccordionAnchorMenuProps
|
||||
extends HTMLAttributes<HTMLDivElement> {
|
||||
title?: string;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const AccordionAnchorMenu = forwardRef<
|
||||
HTMLDivElement,
|
||||
AccordionAnchorMenuProps
|
||||
>(({ children, title, className, ...rest }, ref) => (
|
||||
<div
|
||||
className={cl("navds-accordion-anchor-menu", className)}
|
||||
ref={ref}
|
||||
{...rest}
|
||||
>
|
||||
{title && (
|
||||
<Heading
|
||||
level={2}
|
||||
size="medium"
|
||||
className="navds-accordion-anchor-menu__title"
|
||||
>
|
||||
{title}
|
||||
</Heading>
|
||||
)}
|
||||
<ActiveAnchorProvider>
|
||||
<BaseAccordionMenu aria-label={title || "Meny"}>
|
||||
{children}
|
||||
</BaseAccordionMenu>
|
||||
</ActiveAnchorProvider>
|
||||
</div>
|
||||
));
|
||||
|
||||
export default AccordionAnchorMenu;
|
||||
@@ -0,0 +1 @@
|
||||
export { AccordionMenuCollapsable as AccordionAnchorMenuCollapsable } from "../accordion-menu";
|
||||
@@ -0,0 +1,39 @@
|
||||
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;
|
||||
@@ -0,0 +1,69 @@
|
||||
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 }) => {
|
||||
const [anchors, setAnchors] = useState<string[]>([]);
|
||||
const [activeAnchor, setActiveAnchor] = useState<string>();
|
||||
|
||||
useEffect(() => {
|
||||
const scrollListener = () => {
|
||||
const offset = 100;
|
||||
const lastPassedAnchor = anchors
|
||||
.map((anchor) => document.getElementById(anchor))
|
||||
.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.pushState(lastPassedAnchor, 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);
|
||||
@@ -0,0 +1,3 @@
|
||||
export { default as AccordionAnchorMenu } from "./AccordionAnchorMenu";
|
||||
export { AccordionAnchorMenuCollapsable } from "./AccordionAnchorMenuCollapsable";
|
||||
export { default as AccordionAnchorMenuItem } from "./AccordionAnchorMenuItem";
|
||||
@@ -0,0 +1,141 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
AccordionAnchorMenu as Menu,
|
||||
AccordionAnchorMenuCollapsable as Collapsable,
|
||||
AccordionAnchorMenuItem as Item,
|
||||
} from "../index";
|
||||
import { useEffect } from "react";
|
||||
import { ProductPageLayout } 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 },
|
||||
decorators: [
|
||||
(Story) => {
|
||||
useEffect(() => {
|
||||
document.getElementById("decorator-header").style.display = "block";
|
||||
document.getElementById("decorator-footer").style.display = "block";
|
||||
return () => {
|
||||
document.getElementById("decorator-header").style.display = "none";
|
||||
document.getElementById("decorator-footer").style.display = "none";
|
||||
};
|
||||
}, []);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
},
|
||||
};
|
||||
|
||||
export const All = () => (
|
||||
<ProductPageLayout title={"Nunc et lorem"}>
|
||||
<ProductPageLayout.Section left sticky withPadding={false}>
|
||||
<Menu title={"Minima"} smoothScrollBehavior>
|
||||
<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>
|
||||
</ProductPageLayout.Section>
|
||||
<ProductPageLayout.Section whiteBackground={false} withPadding={false}>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Leo quis"}
|
||||
anchor={"leo-quis"}
|
||||
highlight={true}
|
||||
icon={<LightBulb />}
|
||||
>
|
||||
<MainOne title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Proin accumsan"}
|
||||
anchor={"proin-accumsan"}
|
||||
>
|
||||
<MainTwo title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Maecenas in pretium"}
|
||||
anchor={"maecenas-in-pretium"}
|
||||
icon={<Telephone />}
|
||||
>
|
||||
<MainThree title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
</ProductPageLayout.Section>
|
||||
<ProductPageLayout.Section right sticky>
|
||||
<Right />
|
||||
</ProductPageLayout.Section>
|
||||
</ProductPageLayout>
|
||||
);
|
||||
|
||||
export const ReactRouter = () => (
|
||||
<ProductPageLayout title={"Nunc et lorem"}>
|
||||
<ProductPageLayout.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>
|
||||
</ProductPageLayout.Section>
|
||||
<ProductPageLayout.Section whiteBackground={false} withPadding={false}>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Leo quis"}
|
||||
anchor={"leo-quis"}
|
||||
highlight={true}
|
||||
icon={<LightBulb />}
|
||||
>
|
||||
<MainOne title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Proin accumsan"}
|
||||
anchor={"proin-accumsan"}
|
||||
>
|
||||
<MainTwo title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Maecenas in pretium"}
|
||||
anchor={"maecenas-in-pretium"}
|
||||
icon={<Telephone />}
|
||||
>
|
||||
<MainThree title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
</ProductPageLayout.Section>
|
||||
<ProductPageLayout.Section right sticky>
|
||||
<Right />
|
||||
</ProductPageLayout.Section>
|
||||
</ProductPageLayout>
|
||||
);
|
||||
|
||||
ReactRouter.decorators = [
|
||||
(Story) => (
|
||||
<Router>
|
||||
<Story />
|
||||
</Router>
|
||||
),
|
||||
];
|
||||
@@ -0,0 +1,25 @@
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import cl from "classnames";
|
||||
import MenuItems from "./MenuItems";
|
||||
|
||||
export interface AccordionMenuProps extends HTMLAttributes<HTMLElement> {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const AccordionMenu = forwardRef<HTMLElement, AccordionMenuProps>(
|
||||
({ children, className, ...rest }, ref) => {
|
||||
return (
|
||||
<nav
|
||||
role="navigation"
|
||||
ref={ref}
|
||||
className={cl("navds-accordion-menu", className)}
|
||||
{...rest}
|
||||
>
|
||||
<MenuItems>{children}</MenuItems>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default AccordionMenu;
|
||||
@@ -0,0 +1,44 @@
|
||||
import React, { forwardRef, HTMLAttributes, useState } from "react";
|
||||
import cl from "classnames";
|
||||
import { Expand } from "@navikt/ds-icons";
|
||||
import MenuItems from "./MenuItems";
|
||||
|
||||
export interface AccordionMenuCollapsableProps
|
||||
extends HTMLAttributes<HTMLDivElement> {
|
||||
title: string;
|
||||
defaultOpen?: boolean;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const AccordionMenuCollapsable = forwardRef<
|
||||
HTMLDivElement,
|
||||
AccordionMenuCollapsableProps
|
||||
>(({ children, defaultOpen = false, title, className, ...rest }, ref) => {
|
||||
const [isOpen, setIsOpen] = useState(defaultOpen);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cl("navds-accordion-menu-collapsable", className, {
|
||||
"navds-accordion-menu-collapsable--open": isOpen,
|
||||
})}
|
||||
{...rest}
|
||||
>
|
||||
<button
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="navds-accordion-menu-collapsable__button"
|
||||
>
|
||||
{title}
|
||||
<Expand
|
||||
role="img"
|
||||
aria-label={isOpen ? "Pil peker opp" : "Pil peker ned"}
|
||||
className="navds-accordion-menu-collapsable__expand-icon"
|
||||
/>
|
||||
</button>
|
||||
{isOpen && <MenuItems>{children}</MenuItems>}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default AccordionMenuCollapsable;
|
||||
@@ -0,0 +1,40 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import { OverridableComponent } from "../util";
|
||||
import cl from "classnames";
|
||||
|
||||
export type AccordionMenuItemType = OverridableComponent<AccordionMenuItemProps>;
|
||||
|
||||
export interface AccordionMenuItemProps {
|
||||
props: {
|
||||
children: React.ReactNode;
|
||||
active?: boolean;
|
||||
} & React.HTMLAttributes<HTMLAnchorElement>;
|
||||
defaultComponent: "a";
|
||||
}
|
||||
|
||||
const AccordionMenuItem: AccordionMenuItemType = forwardRef(
|
||||
(
|
||||
{
|
||||
children,
|
||||
component: Component = "a",
|
||||
active = false,
|
||||
className,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
ref={ref}
|
||||
className={cl("navds-accordion-menu-item", className, {
|
||||
"navds-accordion-menu-item--active": active,
|
||||
})}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default AccordionMenuItem;
|
||||
@@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
const MenuItems = ({ children }) => (
|
||||
<ul className="navds-accordion-menu__list">
|
||||
{React.Children.toArray(children).map((child, i) => (
|
||||
<li key={i} className="navds-accordion-menu__list-item">
|
||||
{child}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
|
||||
export default MenuItems;
|
||||
@@ -0,0 +1,6 @@
|
||||
export { default as AccordionMenu } from "./AccordionMenu";
|
||||
export { default as AccordionMenuCollapsable } from "./AccordionMenuCollapsable";
|
||||
export {
|
||||
default as AccordionMenuItem,
|
||||
AccordionMenuItemType,
|
||||
} from "./AccordionMenuItem";
|
||||
@@ -0,0 +1,160 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
AccordionMenu,
|
||||
AccordionMenuItem as Item,
|
||||
AccordionMenuCollapsable as Collapsable,
|
||||
} from "../index";
|
||||
import { NavLink, HashRouter as Router } from "react-router-dom";
|
||||
|
||||
export default {
|
||||
title: "ds-react/accordion-menu",
|
||||
component: { AccordionMenu },
|
||||
parameters: {
|
||||
backgrounds: {
|
||||
default: "light",
|
||||
values: [
|
||||
{
|
||||
name: "light",
|
||||
value: "#F1F1F1",
|
||||
},
|
||||
{
|
||||
name: "white",
|
||||
value: "#fff",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const All = () => (
|
||||
<div
|
||||
style={{
|
||||
background: "white",
|
||||
maxWidth: 288,
|
||||
}}
|
||||
>
|
||||
<AccordionMenu>
|
||||
<Item href="#leo">Leo</Item>
|
||||
<Collapsable title="Proin">
|
||||
<Item href="#nulla" active>
|
||||
Nulla
|
||||
</Item>
|
||||
<Item href="#luctus">Luctus</Item>
|
||||
</Collapsable>
|
||||
<Collapsable title="Accumsan">
|
||||
<Item href="#justo" ariaCurrent="page">
|
||||
Justo
|
||||
</Item>
|
||||
<Item href="#pariatur" active ariaCurrent="page">
|
||||
Pariatur
|
||||
</Item>
|
||||
<Collapsable title="Proin">
|
||||
<Item href="#nulla" active>
|
||||
Nulla
|
||||
</Item>
|
||||
<Item href="#luctus">Luctus</Item>
|
||||
</Collapsable>
|
||||
</Collapsable>
|
||||
<Item href="#justo" active>
|
||||
Justo
|
||||
</Item>
|
||||
<Item href="#pariatur">Pariatur</Item>
|
||||
</AccordionMenu>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const ReactRouter = () => (
|
||||
<AccordionMenu>
|
||||
<Collapsable title="Nivå 1 – 3 rems høy">
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/1"
|
||||
>
|
||||
Nivå 2 innrykk 2 rems
|
||||
</Item>
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/2"
|
||||
>
|
||||
Subtitle 3
|
||||
</Item>
|
||||
</Collapsable>
|
||||
<Collapsable title="Skjema og søknad">
|
||||
<Collapsable title="Satser">
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/3"
|
||||
>
|
||||
Nivå 3 – 3 rems innrykk Har du rett til dagpenger når du mottar annen
|
||||
økonomisk støtte fra NAV?
|
||||
</Item>
|
||||
</Collapsable>
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/4"
|
||||
>
|
||||
Subtitle 2
|
||||
</Item>
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/5"
|
||||
>
|
||||
Subtitle 3
|
||||
</Item>
|
||||
</Collapsable>
|
||||
<Collapsable title="Sakbehandlingstider">
|
||||
<Collapsable title="Subtitle 4 Lang tittel på andre nivå lorem ipsum">
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/6"
|
||||
>
|
||||
Subtitle 5
|
||||
</Item>
|
||||
</Collapsable>
|
||||
</Collapsable>
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/7"
|
||||
>
|
||||
Internasjonalt
|
||||
</Item>
|
||||
<Collapsable title="Meld fra om endringer lang tittel på første nivå">
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/8"
|
||||
>
|
||||
Subtitle 6
|
||||
</Item>
|
||||
</Collapsable>
|
||||
<Item
|
||||
component={NavLink}
|
||||
activeClassName="navds-accordion-menu-item--active"
|
||||
to="/9"
|
||||
>
|
||||
Nivå 1
|
||||
</Item>
|
||||
</AccordionMenu>
|
||||
);
|
||||
|
||||
ReactRouter.decorators = [
|
||||
(Story) => (
|
||||
<Router>
|
||||
<div
|
||||
style={{
|
||||
background: "white",
|
||||
maxWidth: 288,
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
</div>
|
||||
</Router>
|
||||
),
|
||||
];
|
||||
+24
-1
@@ -1,16 +1,39 @@
|
||||
import React, { forwardRef, useEffect, useRef, useState } from "react";
|
||||
import cl from "classnames";
|
||||
import { UnmountClosed, Collapse } from "react-collapse";
|
||||
|
||||
import { Expand } from "@navikt/ds-icons";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
export interface AccordionProps
|
||||
extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Content on interactive surface of component
|
||||
*/
|
||||
heading: React.ReactNode;
|
||||
/**
|
||||
* Opens component if 'true', closes if 'false'
|
||||
* Using this props removes automatic control of open-state
|
||||
* @default false
|
||||
*/
|
||||
open?: boolean;
|
||||
/**
|
||||
* Callback for when user interacts with component
|
||||
*
|
||||
* @param {object} event
|
||||
*/
|
||||
onClick?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
||||
/**
|
||||
* Removes content-element from dom when closed
|
||||
* @default false
|
||||
*/
|
||||
renderContentWhenClosed?: boolean;
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -8,8 +8,22 @@ import {
|
||||
} from "@navikt/ds-icons";
|
||||
|
||||
export interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* Decides what design the alert will have
|
||||
*/
|
||||
variant: "error" | "warning" | "info" | "success";
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Reduces padding on component
|
||||
* @default "medium"
|
||||
*/
|
||||
size?: "medium" | "small";
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -2,8 +2,29 @@ import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Decides component design and interactions
|
||||
* @default "primary"
|
||||
*/
|
||||
variant?: "primary" | "secondary" | "action" | "danger";
|
||||
/**
|
||||
* Reduces internal padding for component
|
||||
* @default "medium"
|
||||
*/
|
||||
size?: "medium" | "small";
|
||||
/**
|
||||
* Prevent the user from interacting with the button: it cannot be pressed or focused.
|
||||
* @default false
|
||||
*/
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
File renamed without changes.
File renamed without changes.
+11
-1
@@ -1,7 +1,17 @@
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export type ContentContainerProps = HTMLAttributes<HTMLDivElement>;
|
||||
export interface ContentContainerProps extends HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
classNames?: string;
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const ContentContainer = forwardRef<HTMLDivElement, ContentContainerProps>(
|
||||
({ children, className, ...rest }, ref) => (
|
||||
<div
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,81 @@
|
||||
import { Files } from "@navikt/ds-icons";
|
||||
import copy from "copy-to-clipboard";
|
||||
import cl from "classnames";
|
||||
import React, {
|
||||
forwardRef,
|
||||
HTMLAttributes,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import mergeRefs from "react-merge-refs";
|
||||
import { Popover, Button } from "../index";
|
||||
|
||||
export interface CopyToClipboardProps
|
||||
extends HTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Text to be copied to clipboard
|
||||
*/
|
||||
text: string;
|
||||
/**
|
||||
* Description of text, examples: "personnummer", "navn", "epost" etc.
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Use a differnet icon to display
|
||||
* @default "Files" from @navikt/ds-icons
|
||||
*/
|
||||
icon?: React.ReactElement;
|
||||
}
|
||||
|
||||
const CopyToClipboard = forwardRef<HTMLButtonElement, CopyToClipboardProps>(
|
||||
({ children, text, label, icon, className, ...rest }, ref) => {
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
const mergedRef = mergeRefs([buttonRef, ref]);
|
||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
const [openPopover, setOpenPopover] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (openPopover) {
|
||||
timeoutRef.current = setTimeout(() => setOpenPopover(false), 2000);
|
||||
return () => timeoutRef.current && clearTimeout(timeoutRef.current);
|
||||
}
|
||||
}, [openPopover]);
|
||||
|
||||
const title = `Kopier ${label} (${text})`;
|
||||
|
||||
const handleClick = () => {
|
||||
copy(text);
|
||||
setOpenPopover(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
ref={mergedRef}
|
||||
variant="secondary"
|
||||
title={title}
|
||||
className={cl("navds-copy-to-clipboard", className)}
|
||||
onClick={handleClick}
|
||||
{...rest}
|
||||
>
|
||||
{icon ? <>{icon}</> : <Files aria-label="Fil ikon for kopiering" />}
|
||||
{children ? children : <span className="sr-only">{title}</span>}
|
||||
</Button>
|
||||
<Popover
|
||||
role="alert"
|
||||
anchorEl={buttonRef.current}
|
||||
open={openPopover}
|
||||
onClose={() => setOpenPopover(false)}
|
||||
placement="right"
|
||||
arrow={false}
|
||||
className="navds-copy-to-clipboard__popover"
|
||||
>
|
||||
{label}
|
||||
</Popover>
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default CopyToClipboard;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as CopyToClipboard } from "./CopyToClipboard";
|
||||
export * from "./CopyToClipboard";
|
||||
@@ -0,0 +1,41 @@
|
||||
import * as React from "react";
|
||||
|
||||
import { CopyToClipboard } from "../index";
|
||||
import { Link } from "@navikt/ds-icons";
|
||||
|
||||
export default {
|
||||
title: "@ds-react/copy-to-clipboard",
|
||||
component: CopyToClipboard,
|
||||
};
|
||||
|
||||
export const All = () => {
|
||||
const label = "pi";
|
||||
|
||||
const text = "3.14159265359";
|
||||
return (
|
||||
<div>
|
||||
<h2>Fritstående knapp</h2>
|
||||
<CopyToClipboard label={label} text={text} />
|
||||
|
||||
<h2>Sammen med tekst</h2>
|
||||
<CopyToClipboard label={label} text={text}>
|
||||
Kopier tekst
|
||||
</CopyToClipboard>
|
||||
|
||||
<h2>Tilpasser seg fontstørrelse</h2>
|
||||
<CopyToClipboard label={label} text={text} style={{ fontSize: "0.8rem" }}>
|
||||
Kopier tekst
|
||||
</CopyToClipboard>
|
||||
|
||||
<h2>Custom icon</h2>
|
||||
<CopyToClipboard
|
||||
icon={<Link />}
|
||||
label={label}
|
||||
text={text}
|
||||
style={{ fontSize: "0.8rem" }}
|
||||
>
|
||||
Kopier tekst
|
||||
</CopyToClipboard>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -3,9 +3,29 @@ import cl from "classnames";
|
||||
|
||||
type Column = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
||||
export interface CellProps extends HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
/**
|
||||
* Cell columns on width < 448px
|
||||
*/
|
||||
xs: Column;
|
||||
/**
|
||||
* Cell columns on min-width: 448
|
||||
*/
|
||||
sm?: Column;
|
||||
/**
|
||||
* Cell columns on min-width: 648
|
||||
*/
|
||||
md?: Column;
|
||||
/**
|
||||
* Cell columns on min-width: 960px
|
||||
*/
|
||||
lg?: Column;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export type GridProps = HTMLAttributes<HTMLDivElement>;
|
||||
export interface GridProps extends HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
}
|
||||
const Grid = forwardRef<HTMLDivElement, GridProps>(
|
||||
({ children, className, ...rest }, ref) => (
|
||||
<div ref={ref} className={cl("navds-grid", className)} {...rest}>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,3 +1,13 @@
|
||||
export {
|
||||
AccordionAnchorMenu,
|
||||
AccordionAnchorMenuCollapsable,
|
||||
AccordionAnchorMenuItem,
|
||||
} from "./accordion-anchor-menu";
|
||||
export {
|
||||
AccordionMenu,
|
||||
AccordionMenuCollapsable,
|
||||
AccordionMenuItem,
|
||||
} from "./accordion-menu";
|
||||
export { Accordion, AccordionProps } from "./accordion/index";
|
||||
export { Alert, AlertProps } from "./alert/index";
|
||||
export { Button, ButtonProps } from "./button/index";
|
||||
@@ -6,6 +16,7 @@ export {
|
||||
ContentContainerProps,
|
||||
} from "./content-container/index";
|
||||
export { Cell, CellProps, Grid, GridProps } from "./grid/index";
|
||||
export { CopyToClipboard } from "./copy-to-clipboard/index";
|
||||
export {
|
||||
InternalHeader,
|
||||
InternalHeaderProps,
|
||||
@@ -14,7 +25,11 @@ export {
|
||||
InternalHeaderUser,
|
||||
InternalHeaderUserProps,
|
||||
} from "./internal-header/index";
|
||||
export { Layout, LayoutProps, SectionProps } from "./layout/index";
|
||||
export {
|
||||
ProductPageLayout,
|
||||
ProductPageLayoutProps,
|
||||
ProductPageLayoutSectionProps,
|
||||
} from "./layouts/index";
|
||||
export { Link, LinkProps } from "./link/index";
|
||||
export { Modal, ModalProps } from "./modal/index";
|
||||
export { Popover, PopoverProps } from "./popover/index";
|
||||
+7
@@ -2,7 +2,14 @@ import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface InternalHeaderProps extends HTMLAttributes<HTMLElement> {
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const InternalHeader = forwardRef<HTMLElement, InternalHeaderProps>(
|
||||
+11
@@ -2,7 +2,18 @@ import React, { forwardRef, HTMLAttributes, createElement } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface InternalHeaderTitleProps extends HTMLAttributes<HTMLElement> {
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Tag this component will use. Usefull for defining a button/link
|
||||
* @default "h1"
|
||||
*/
|
||||
element?: keyof React.ReactHTML;
|
||||
}
|
||||
|
||||
+10
@@ -3,7 +3,17 @@ import cl from "classnames";
|
||||
|
||||
export interface InternalHeaderUserProps
|
||||
extends HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* user name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* user ident
|
||||
*/
|
||||
ident: string;
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,3 @@
|
||||
export { default as ProductPageLayout } from "./product-page/Layout";
|
||||
export { LayoutProps as ProductPageLayoutProps } from "./product-page/Layout";
|
||||
export { SectionProps as ProductPageLayoutSectionProps } from "./product-page/Section";
|
||||
@@ -0,0 +1,69 @@
|
||||
import React, { useEffect, Children, forwardRef } from "react";
|
||||
import { ForwardRefExoticComponent, HTMLAttributes } from "react";
|
||||
import { default as Section, SectionProps } from "./Section";
|
||||
import { default as Panel, PanelProps } from "./Panel";
|
||||
import { ContentContainer, Heading, OverridableComponent } from "../../";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface LayoutWithSubComponents
|
||||
extends ForwardRefExoticComponent<LayoutProps> {
|
||||
Section: ForwardRefExoticComponent<SectionProps>;
|
||||
Panel: OverridableComponent<PanelProps>;
|
||||
}
|
||||
|
||||
export interface LayoutProps extends HTMLAttributes<HTMLElement> {
|
||||
title: string;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const Layout = forwardRef<HTMLDivElement, LayoutProps>(
|
||||
({ children, title, className, ...rest }, ref) => {
|
||||
const columns = Children.toArray(children).length;
|
||||
const classNames = cl(
|
||||
"navds-layout__container",
|
||||
`navds-layout__container--${columns}-columns`,
|
||||
className
|
||||
);
|
||||
|
||||
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={classNames} {...rest}>
|
||||
<div className={cl("navds-layout__header-content")}>
|
||||
<Heading
|
||||
size={"xxl"}
|
||||
className={cl("navds-layout__header-title")}
|
||||
level={1}
|
||||
>
|
||||
{title}
|
||||
</Heading>
|
||||
</div>
|
||||
</div>
|
||||
</ContentContainer>
|
||||
</div>
|
||||
<div id={"navds-layout-body"} className={"navds-layout__body"}>
|
||||
<ContentContainer>
|
||||
<div className={classNames} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
</ContentContainer>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
) as LayoutWithSubComponents;
|
||||
|
||||
Layout.Section = Section;
|
||||
Layout.Panel = Panel;
|
||||
export default Layout;
|
||||
@@ -0,0 +1,101 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { forwardRef, ReactNode } from "react";
|
||||
import cl from "classnames";
|
||||
import { Button, Heading, Popover } from "../../";
|
||||
import { Attachment } from "@navikt/ds-icons";
|
||||
import { OverridableComponent } from "../../util";
|
||||
|
||||
export interface PanelProps {
|
||||
props: {
|
||||
title: string;
|
||||
icon?: ReactNode;
|
||||
highlight?: boolean;
|
||||
anchor?: string;
|
||||
whiteBackground?: boolean;
|
||||
withPadding?: boolean;
|
||||
} & React.HTMLAttributes<HTMLDivElement>;
|
||||
defaultComponent: "div";
|
||||
}
|
||||
|
||||
const Panel: OverridableComponent<PanelProps> = forwardRef(
|
||||
(
|
||||
{
|
||||
title,
|
||||
highlight,
|
||||
icon,
|
||||
anchor,
|
||||
component: Component = "div",
|
||||
className,
|
||||
children,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
|
||||
const [copied, setIsCopied] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const header = document.getElementById("navds-layout-body");
|
||||
header?.classList.add("navds-layout__body--padding");
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Component
|
||||
ref={ref}
|
||||
id={anchor}
|
||||
className={cl(
|
||||
"navds-layout__panel",
|
||||
icon && "navds-layout__panel--icon-margin",
|
||||
highlight && "navds-layout__panel--highlight",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{icon && <div className={"navds-layout__panel-icon"}>{icon}</div>}
|
||||
<Heading size={"xl"} className={"navds-layout__panel-title"} level={2}>
|
||||
{title}
|
||||
</Heading>
|
||||
{anchor && (
|
||||
<div className={"navds-layout__panel-copy"}>
|
||||
<Button
|
||||
ref={(el) => setAnchorEl(el)}
|
||||
variant={"secondary"}
|
||||
className={"navds-layout__panel-copy-button"}
|
||||
onClick={() => {
|
||||
setIsCopied(true);
|
||||
const { href, hash } = window.location;
|
||||
const urlWithoutHash = href.replace(hash, "");
|
||||
copyToClipboard(`${urlWithoutHash}#${anchor}`);
|
||||
setTimeout(() => {
|
||||
setIsCopied(false);
|
||||
}, 1000);
|
||||
}}
|
||||
>
|
||||
<Attachment className={"navds-layout__panel-copy-icon"} />
|
||||
<span>Kopier lenke</span>
|
||||
</Button>
|
||||
<Popover anchorEl={anchorEl} open={copied} onClose={() => {}}>
|
||||
<div className="navds-layout__panel-popover-content">Kopiert</div>
|
||||
</Popover>
|
||||
</div>
|
||||
)}
|
||||
<div className={"navds-layout__panel-content"}>{children}</div>
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const copyToClipboard = (text: string) => {
|
||||
const textArea = document.createElement("textarea");
|
||||
textArea.value = text;
|
||||
textArea.style.top = "0";
|
||||
textArea.style.left = "0";
|
||||
textArea.style.position = "fixed";
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(textArea);
|
||||
};
|
||||
|
||||
export default Panel;
|
||||
File renamed without changes.
+4
-4
@@ -4,16 +4,16 @@ import { Button, Link } from "../../../../index";
|
||||
export const Left = () => (
|
||||
<ul className={"navds-story-menu"}>
|
||||
<li>
|
||||
<Link href={"#"}>Iusto odio dignissimos</Link>
|
||||
<Link href={"#leo-quis"}>Leo quis</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={"#"}>Nam libero tempore</Link>
|
||||
<Link href={"#proin-accumsan"}>Proin accumsan</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={"#"}>Reiciendis voluptatibus</Link>
|
||||
<Link href={"#nulla-pariatur"}>Nulla pariatur?</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={"#"}>Earum rerum</Link>
|
||||
<Link href={"#maecenas-in-pretium"}>Maecenas in pretium</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Button>Søk ...</Button>
|
||||
+67
-35
@@ -6,21 +6,42 @@ import {
|
||||
Heading,
|
||||
Link,
|
||||
Paragraph,
|
||||
Alert,
|
||||
} from "../../../../index";
|
||||
|
||||
export const Main = () => (
|
||||
export const Main = ({ title = true }) => (
|
||||
<>
|
||||
<MainOne title={title} />
|
||||
<MainTwo title={title} />
|
||||
<MainThree title={title} />
|
||||
</>
|
||||
);
|
||||
|
||||
export const MainOne = ({ title = true }) => (
|
||||
<div>
|
||||
<Heading className={"navds-story-section"} level={1} size={"xl"}>
|
||||
Quis autem
|
||||
</Heading>
|
||||
{title && (
|
||||
<Heading level={1} size={"xl"} id={"leo-quis"}>
|
||||
Leo quis
|
||||
</Heading>
|
||||
)}
|
||||
<Paragraph>
|
||||
Sed ullamcorper quam eget lorem volutpat, quis cursus risus fermentum.
|
||||
Quisque varius ornare nulla, ut condimentum sapien dapibus non. Nullam
|
||||
eget interdum nibh
|
||||
</Paragraph>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const MainTwo = ({ title = true }) => (
|
||||
<div>
|
||||
{title && (
|
||||
<Heading level={1} size={"xl"} id={"proin-accumsan"}>
|
||||
Proin accumsan
|
||||
</Heading>
|
||||
)}
|
||||
<Paragraph 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.
|
||||
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut
|
||||
fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem
|
||||
sequi nesciunt.
|
||||
</Paragraph>
|
||||
<Grid className={"section"}>
|
||||
<Cell xs={6}>
|
||||
@@ -32,30 +53,15 @@ export const Main = () => (
|
||||
</Grid>
|
||||
<Paragraph className={"section"}>
|
||||
Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet,
|
||||
consectetur, adipisci velit, sed quia non numquam eius modi tempora
|
||||
incidunt ut labore et dolore magnam aliquam quaerat voluptatem.{" "}
|
||||
consectetur, adipisci velit, sed quia non numquam eius modi tempora.
|
||||
</Paragraph>
|
||||
<Alert variant="info" className={"section"}>
|
||||
Suspendisse potenti. Interdum et malesuada fames ac ante ipsum primis in
|
||||
faucibus.
|
||||
</Alert>
|
||||
<Paragraph className={"section"}>
|
||||
Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis
|
||||
suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem
|
||||
vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil
|
||||
molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla
|
||||
pariatur?
|
||||
</Paragraph>
|
||||
<Heading className={"section"} level={2} size={"xl"}>
|
||||
<Heading level={2} size={"large"} id={"nulla-pariatur"}>
|
||||
Nulla pariatur?
|
||||
</Heading>
|
||||
<Paragraph className={"section"}>
|
||||
Etiam viverra neque sit amet libero dapibus tincidunt. Pellentesque quis
|
||||
imperdiet erat. Morbi sodales bibendum volutpat. Sed malesuada risus
|
||||
lorem, in elementum purus commodo eget. Mauris maximus congue efficitur.
|
||||
Cras vestibulum id metus sed pellentesque.
|
||||
imperdiet erat. Morbi sodales bibendum volutpat.
|
||||
</Paragraph>
|
||||
|
||||
<table className={"section tabell tabell--stripet"}>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -89,16 +95,11 @@ export const Main = () => (
|
||||
<Paragraph className={"section"}>
|
||||
Curabitur a purus pretium, condimentum magna ac, pellentesque diam. Nulla
|
||||
facilisi. Nullam consequat, dui sed bibendum faucibus, metus mauris
|
||||
commodo tortor, eget mollis nunc augue eu elit. Ut nec fringilla odio, eu
|
||||
scelerisque tellus.
|
||||
</Paragraph>
|
||||
<Paragraph className={"section"}>
|
||||
Proin nec luctus justo. Pellentesque et dapibus libero. Phasellus non elit
|
||||
eget justo mattis venenatis. In hac habitasse platea dictumst. Proin nunc
|
||||
ipsum, ornare eu pretium in, aliquet non velit. Nullam efficitur tincidunt
|
||||
leo, vel tempus nibh consectetur sed. Etiam porttitor finibus erat varius
|
||||
rhoncus. Sed ac augue imperdiet, porta tellus vitae, aliquam est.
|
||||
commodo tortor.
|
||||
</Paragraph>
|
||||
<Heading level={2} size={"large"} id={"luctus-justo"}>
|
||||
Luctus justo
|
||||
</Heading>
|
||||
<Paragraph className={"section"}>
|
||||
Nunc eget consectetur felis, id scelerisque sapien. Ut id feugiat nulla,
|
||||
ut cursus sem. In viverra felis vitae aliquet finibus.
|
||||
@@ -106,3 +107,34 @@ export const Main = () => (
|
||||
<Button>Søk ...</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const MainThree = ({ title = true }) => (
|
||||
<div>
|
||||
{title && (
|
||||
<Heading level={1} size={"xl"} id={"maecenas-in-pretium"}>
|
||||
Maecenas in pretium
|
||||
</Heading>
|
||||
)}
|
||||
<Paragraph>
|
||||
Sed ullamcorper quam eget lorem volutpat, quis cursus risus fermentum.
|
||||
Quisque varius ornare nulla, ut condimentum sapien dapibus non. Nullam
|
||||
eget interdum nibh
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
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.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
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.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
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.
|
||||
</Paragraph>
|
||||
</div>
|
||||
);
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,102 @@
|
||||
import * as React from "react";
|
||||
import { useEffect } from "react";
|
||||
import { ProductPageLayout } 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: ProductPageLayout,
|
||||
decorators: [
|
||||
(Story) => {
|
||||
useEffect(() => {
|
||||
document.getElementById("decorator-header").style.display = "block";
|
||||
document.getElementById("decorator-footer").style.display = "block";
|
||||
return () => {
|
||||
document.getElementById("decorator-header").style.display = "none";
|
||||
document.getElementById("decorator-footer").style.display = "none";
|
||||
};
|
||||
}, []);
|
||||
return <Story />;
|
||||
},
|
||||
],
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
},
|
||||
};
|
||||
|
||||
const title = "Nunc et lorem";
|
||||
export const ThreeColumns = () => (
|
||||
<ProductPageLayout title={title}>
|
||||
<ProductPageLayout.Section left sticky>
|
||||
<Left />
|
||||
</ProductPageLayout.Section>
|
||||
<ProductPageLayout.Section whiteBackground={false} withPadding={false}>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Leo quis"}
|
||||
anchor={"leo-quis"}
|
||||
highlight={true}
|
||||
icon={<LightBulb />}
|
||||
>
|
||||
<MainOne title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Proin accumsan"}
|
||||
anchor={"proin-accumsan"}
|
||||
>
|
||||
<MainTwo title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Maecenas in pretium"}
|
||||
anchor={"maecenas-in-pretium"}
|
||||
icon={<Telephone />}
|
||||
>
|
||||
<MainThree title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
</ProductPageLayout.Section>
|
||||
<ProductPageLayout.Section right sticky>
|
||||
<Right />
|
||||
</ProductPageLayout.Section>
|
||||
</ProductPageLayout>
|
||||
);
|
||||
|
||||
export const TwoColumnsLeft = () => (
|
||||
<ProductPageLayout title={title}>
|
||||
<ProductPageLayout.Section left sticky>
|
||||
<Left />
|
||||
</ProductPageLayout.Section>
|
||||
<ProductPageLayout.Section>
|
||||
<ProductPageLayout.Panel
|
||||
title={"Leo quis"}
|
||||
anchor={"leo-quis"}
|
||||
highlight={true}
|
||||
icon={<LightBulb />}
|
||||
>
|
||||
<MainOne title={false} />
|
||||
</ProductPageLayout.Panel>
|
||||
<Main />
|
||||
</ProductPageLayout.Section>
|
||||
</ProductPageLayout>
|
||||
);
|
||||
|
||||
export const TwoColumnsRight = () => (
|
||||
<ProductPageLayout title={title}>
|
||||
<ProductPageLayout.Section>
|
||||
<Main />
|
||||
</ProductPageLayout.Section>
|
||||
<ProductPageLayout.Section right sticky>
|
||||
<Right />
|
||||
</ProductPageLayout.Section>
|
||||
</ProductPageLayout>
|
||||
);
|
||||
|
||||
export const OneColumn = () => (
|
||||
<ProductPageLayout title={title}>
|
||||
<ProductPageLayout.Section>
|
||||
<Main />
|
||||
</ProductPageLayout.Section>
|
||||
</ProductPageLayout>
|
||||
);
|
||||
@@ -3,6 +3,14 @@ import cl from "classnames";
|
||||
|
||||
export interface LinkProps
|
||||
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Link anchor should direct to
|
||||
*/
|
||||
File renamed without changes.
File renamed without changes.
@@ -5,9 +5,6 @@ import mergeRefs from "react-merge-refs";
|
||||
import { Close } from "@navikt/ds-icons";
|
||||
import { Button } from "../index";
|
||||
|
||||
// TODO: Has to be documented well that the user has to import react-modal and call
|
||||
// ReactModal.setAppElement("#root")
|
||||
|
||||
export interface ModalProps {
|
||||
/**
|
||||
* Content of modal
|
||||
@@ -27,7 +24,7 @@ export interface ModalProps {
|
||||
*/
|
||||
shouldCloseOnOverlayClick?: boolean;
|
||||
/**
|
||||
* User defined classname for wrapper element
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
@@ -36,7 +33,14 @@ export interface ModalProps {
|
||||
contentClassName?: string;
|
||||
}
|
||||
|
||||
const Modal = forwardRef<ReactModal, ModalProps>(
|
||||
type ModalLifecycle = {
|
||||
setAppElement?: (element: any) => void;
|
||||
};
|
||||
|
||||
const Modal: ModalLifecycle &
|
||||
React.ForwardRefExoticComponent<
|
||||
ModalProps & React.RefAttributes<ReactModal>
|
||||
> = forwardRef<ReactModal, ModalProps>(
|
||||
(
|
||||
{
|
||||
children,
|
||||
@@ -89,8 +93,6 @@ const Modal = forwardRef<ReactModal, ModalProps>(
|
||||
}
|
||||
);
|
||||
|
||||
export const setAppElement = (element) => {
|
||||
ReactModal.setAppElement(element);
|
||||
};
|
||||
Modal.setAppElement = (element) => ReactModal.setAppElement(element);
|
||||
|
||||
export default Modal;
|
||||
File renamed without changes.
+1
-2
@@ -1,13 +1,12 @@
|
||||
import React, { useState } from "react";
|
||||
import { Modal } from "../index";
|
||||
import ReactModal from "react-modal";
|
||||
|
||||
export default {
|
||||
title: "ds-react/modal",
|
||||
component: Modal,
|
||||
};
|
||||
|
||||
ReactModal.setAppElement("#root");
|
||||
Modal.setAppElement("#root");
|
||||
|
||||
export const All = () => {
|
||||
const [open, setOpen] = useState(true);
|
||||
@@ -27,12 +27,23 @@ export interface PopoverProps extends HTMLAttributes<HTMLDivElement> {
|
||||
* Content rendered inside popover
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Orientation for popover
|
||||
* @default 'auto'
|
||||
* @default "right"
|
||||
*/
|
||||
placement?: Placement;
|
||||
size?: "medium" | "small";
|
||||
/**
|
||||
* Deteremines if popover contains an arrow
|
||||
*/
|
||||
arrow?: boolean;
|
||||
/**
|
||||
* Distance from anchor to popover
|
||||
*/
|
||||
offset?: number;
|
||||
}
|
||||
|
||||
const useEventLister = (event: string, callback) =>
|
||||
@@ -46,20 +57,20 @@ const useEventLister = (event: string, callback) =>
|
||||
const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
children,
|
||||
anchorEl,
|
||||
arrow = true,
|
||||
open,
|
||||
onClose,
|
||||
children,
|
||||
placement = "right",
|
||||
className,
|
||||
size = "medium",
|
||||
offset,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const popoverRef = useRef<HTMLDivElement | null>(null);
|
||||
const mergedRef = mergeRefs([popoverRef, ref]);
|
||||
const arrowRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const close = useCallback(() => open && onClose(), [open, onClose]);
|
||||
|
||||
@@ -106,17 +117,10 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
||||
{
|
||||
placement,
|
||||
modifiers: [
|
||||
{
|
||||
name: "arrow",
|
||||
options: {
|
||||
padding: 8,
|
||||
element: arrowRef.current,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "offset",
|
||||
options: {
|
||||
offset: [0, 16],
|
||||
offset: [0, offset ?? arrow ? 16 : 4],
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -130,7 +134,7 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
||||
return (
|
||||
<div
|
||||
ref={mergedRef}
|
||||
className={cl("navds-popover", `navds-popover--${size}`, className, {
|
||||
className={cl("navds-popover", className, {
|
||||
"navds-popover--hidden": !open || !anchorEl,
|
||||
})}
|
||||
aria-live="polite"
|
||||
@@ -141,11 +145,13 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
||||
style={styles.popper}
|
||||
>
|
||||
{children}
|
||||
<div
|
||||
ref={arrowRef}
|
||||
style={styles.arrow}
|
||||
className="navds-popover__arrow"
|
||||
/>
|
||||
{arrow && (
|
||||
<div
|
||||
data-popper-arrow
|
||||
style={styles.arrow}
|
||||
className="navds-popover__arrow"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
File renamed without changes.
+1
-25
@@ -27,7 +27,7 @@ const Template = (props) => {
|
||||
{props.placement}
|
||||
</div>
|
||||
<Popover {...props} anchorEl={anchorEl} onClose={() => {}} open>
|
||||
Contents
|
||||
<div style={{ margin: "1rem" }}>Contents</div>
|
||||
</Popover>
|
||||
</>
|
||||
);
|
||||
@@ -56,27 +56,3 @@ export const All = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Small = () => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
margin: "4rem 8rem 4rem 8rem",
|
||||
}}
|
||||
>
|
||||
{placements.map((placement) => (
|
||||
<div
|
||||
style={{
|
||||
width: "20%",
|
||||
height: "100px",
|
||||
margin: "4rem",
|
||||
}}
|
||||
>
|
||||
<Template placement={placement} size="small" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -2,7 +2,14 @@ import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
/**
|
||||
* Component content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Changes background-color and border-color
|
||||
*/
|
||||
@@ -10,11 +17,12 @@ export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
}
|
||||
|
||||
const Tag = forwardRef<HTMLSpanElement, TagProps>(
|
||||
({ children, className, variant }, ref) => {
|
||||
({ children, className, variant, ...rest }, ref) => {
|
||||
return (
|
||||
<span
|
||||
ref={ref}
|
||||
className={cl("navds-tag", className, `navds-tag--${variant}`)}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -2,12 +2,13 @@
|
||||
"extends": "../../utilities/build/tsconfig-pakker.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./esm",
|
||||
"rootDir": "./",
|
||||
"rootDir": "./src",
|
||||
"esModuleInterop": true,
|
||||
"module": "ES2020",
|
||||
"target": "ES2015",
|
||||
"sourceMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["./*"]
|
||||
"include": ["./src"],
|
||||
"exclude": ["./src/*/stories"]
|
||||
}
|
||||
@@ -2,12 +2,13 @@
|
||||
"extends": "../../utilities/build/tsconfig-pakker.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./cjs",
|
||||
"rootDir": "./",
|
||||
"rootDir": "./src",
|
||||
"esModuleInterop": true,
|
||||
"module": "commonjs",
|
||||
"target": "es2015",
|
||||
"sourceMap": false,
|
||||
"declaration": false
|
||||
},
|
||||
"include": ["./*"]
|
||||
"include": ["./src"],
|
||||
"exclude": ["./src/*/stories"]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tokens",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.2",
|
||||
"private": false,
|
||||
"description": "Auto-generated design-tokens for NAV design-systems framework",
|
||||
"author": "NAV Designsystem team",
|
||||
|
||||
@@ -25,8 +25,12 @@ module.exports = {
|
||||
white: { value: white },
|
||||
darkgray: { value: darkgray },
|
||||
gray: {
|
||||
40: { value: "#b7b1a9" },
|
||||
60: { value: "#78706a" },
|
||||
90: { value: "#262626" },
|
||||
80: { value: "#4F4F4F" },
|
||||
60: { value: "#6A6A6A" },
|
||||
40: { value: "#A0A0A0" },
|
||||
20: { value: "#C9C9C9" },
|
||||
10: { value: "#F1F1F1" },
|
||||
},
|
||||
...Object.entries(baseColors).reduce(
|
||||
(colors, [name, color]) => ({
|
||||
@@ -170,6 +174,10 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
layout: {
|
||||
background: {
|
||||
white: { value: "#FFFFFF" },
|
||||
gray: { value: "#F1F1F1" },
|
||||
},
|
||||
padding: {
|
||||
small: { value: "1rem" },
|
||||
mediumAndLarger: { value: "2.5rem" },
|
||||
|
||||
@@ -1,7 +1,68 @@
|
||||
# Endringslogg
|
||||
|
||||
## 08. April 2021
|
||||
|
||||
### Gråskala er endret i `nav-frontend-core`
|
||||
|
||||
[#1068](https://github.com/navikt/nav-frontend-moduler/pull/1068)
|
||||
|
||||
- Gråfargene er endret til en mer nøytral og leselig farge enn tidligere.
|
||||
- Alle pakker som bruker `nav-frontend-core` eller har tilknytning til den (inkludert selve pakken) er minor bumpet fra x.0.x -> x.1.0.
|
||||
- Letteste måten å oppdatere pakkene på er å kjøre `npm update`
|
||||
- Hvis man ønsker å bumpe pakkene manuelt så kan alle `nav-frontend-*` pakker minor bumpes til x.1.x utenom disse:
|
||||
- - nav-frontend-chevron-style
|
||||
- - nav-frontend-chevron
|
||||
- - nav-frontend-fullbreddeknapp-style
|
||||
- - nav-frontend-grid-style
|
||||
- - nav-frontend-ikoner-assets
|
||||
- - nav-frontend-js-utils
|
||||
- - nav-frontend-spinner-style
|
||||
- - nav-frontend-spinner
|
||||
|
||||
## 07. April 2021
|
||||
|
||||
### Sourcemapping ds-icons og ds-react
|
||||
|
||||
[#1064](https://github.com/navikt/nav-frontend-moduler/pull/1064)
|
||||
[#1065](https://github.com/navikt/nav-frontend-moduler/pull/1065)
|
||||
|
||||
## 24. Mars 2021
|
||||
|
||||
### Smoothscroll og reduced animations
|
||||
|
||||
[#1055](https://github.com/navikt/nav-frontend-moduler/pull/1055)
|
||||
|
||||
- `@navikt/ds-css` sin baseline setter nå `scroll-behavior: smooth;` på html by default
|
||||
- Ved `(prefers-reduced-motion: reduce)` vil baseline redusere animasjoner.
|
||||
|
||||
## 10. Mars 2021
|
||||
|
||||
### @navikt/ds-react importerer nå ikke styling i selve komponenten
|
||||
|
||||
[#1030](https://github.com/navikt/nav-frontend-moduler/pull/1030)
|
||||
|
||||
- Dette betyr at pakken `@navikt/ds-css` må importeres separat ved å endten linke til pakken i `<head>` eller importere den høyt i dom-strukturen.
|
||||
|
||||
### @navikt/ds-react og @navikt/ds-icons er nå treeshakable
|
||||
|
||||
[#1033](https://github.com/navikt/nav-frontend-moduler/pull/1033)
|
||||
|
||||
- Begge pakkene defaulter nå til esm versjonen av pakken. De vanligste bundlerne hånterer da treeshaking selv når pakken blir brukt. Hvis man man ønsker å ta i bruk Commonjs versjonen kan man importere direkte fra `cjs` dir i pakken
|
||||
|
||||
```bash
|
||||
Esm -> import { Button } from "@navikt/ds-react";
|
||||
Cjs -> import { Button } from "@navikt/ds-react/cjs";
|
||||
```
|
||||
|
||||
Siden eks noen test-libraries ikke støtter ESM enda kan man legge denne til i jest config for å bruke pakkene:
|
||||
|
||||
```
|
||||
"moduleNameMapper": {
|
||||
"@navikt/ds-react(.*)": "@navikt/ds-react/cjs$1",
|
||||
"@navikt/ds-icons(.*)": "@navikt/ds-icons/cjs$1"
|
||||
}
|
||||
```
|
||||
|
||||
### Oppdatert feil-styling og state-handling for skjemakomponenter
|
||||
|
||||
[#1018](https://github.com/navikt/nav-frontend-moduler/pull/1018)
|
||||
|
||||
@@ -7,6 +7,8 @@ slik at mest mulig av fremtidige moduler er å finne her og fungerer etter de be
|
||||
|
||||
## TL;DR
|
||||
|
||||
Vi bruker yarn pga yarn workspaces. Har du ikke yarn? `npm i -g yarn`
|
||||
|
||||
```sh
|
||||
git clone git@github.com:navikt/nav-frontend-moduler.git
|
||||
cd nav-frontend-moduler
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
import { Settings, SuccessFilled, ErrorFilled } from "@navikt/ds-icons";
|
||||
import { Alert, Heading, Link, Paragraph } 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 BekreftcheckboxpanelExample2 from "../examples/navfrontendskjema/bekreftcheckboxpanel/Feilmelding";
|
||||
import BekreftcheckboxpanelExample1 from "../examples/navfrontendskjema/bekreftcheckboxpanel/Normal";
|
||||
import EkspanderbartpanelExample from "../examples/ekspanderbartpanel/ekspanderbartpanel-base";
|
||||
import ModalExample from "../examples/modal/modal-example";
|
||||
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 TekstomradeExample from "../examples/tekstomrade/tekstomrade-example";
|
||||
import Preview from "./code-preview/Preview";
|
||||
import Bash from "./code/Bash";
|
||||
import Import from "./code/Import";
|
||||
import Npm from "./npm/Npm";
|
||||
import Inline from "./code/Inline";
|
||||
import TableOfContents from "./table-of-contents/TableOfContents";
|
||||
import FormValidationExample from "../examples/form-validation/FormValidationExample";
|
||||
import Palette from "../examples/resources/colors/Palette";
|
||||
import {
|
||||
ButtonIcon,
|
||||
TypoIcon,
|
||||
VeilederIcon,
|
||||
NAVLogoCircle,
|
||||
SketchLogo,
|
||||
FigmaIcon,
|
||||
W3CLogo,
|
||||
ZeplinLogo,
|
||||
GithubLogo,
|
||||
} from "./assets/svg";
|
||||
import IconPage from "../examples/resources/icons/IconPage";
|
||||
import IconDownload from "../examples/resources/icons/IconDownload";
|
||||
|
||||
const components = {
|
||||
h1: (props) => <Heading size="xxl" level={1} {...props} />,
|
||||
h2: (props) => <Heading size="large" level={2} {...props} />,
|
||||
h3: (props) => <Heading size="small" level={3} {...props} />,
|
||||
h4: (props) => <Heading size="small" level={4} {...props} />,
|
||||
p: (props) => <Paragraph size="medium" {...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,
|
||||
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;
|
||||
@@ -0,0 +1,6 @@
|
||||
<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>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,592 @@
|
||||
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="#3E3832"
|
||||
focusable="false"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,96 @@
|
||||
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 OverflowDetector from "../overflow-detector/OverflowDetector";
|
||||
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;
|
||||
@@ -0,0 +1,33 @@
|
||||
.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 > *:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.preview__container figcaption {
|
||||
text-align: center;
|
||||
padding: 0.5em;
|
||||
font-style: italic;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
import copy from "copy-to-clipboard";
|
||||
import Prism from "prismjs";
|
||||
import cl from "classnames";
|
||||
import { ErrorFilled, Files, 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()}
|
||||
>
|
||||
<Files />
|
||||
</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;
|
||||
@@ -0,0 +1,22 @@
|
||||
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;
|
||||
@@ -0,0 +1,7 @@
|
||||
import "./bash.css";
|
||||
|
||||
const Inline = ({ children }) => (
|
||||
<code className="inline-code">{children}</code>
|
||||
);
|
||||
|
||||
export default Inline;
|
||||
@@ -0,0 +1,80 @@
|
||||
.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;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
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;
|
||||
Loaded 100 of 273 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user