mirror of
https://github.com/navikt/aksel.git
synced 2026-10-13 01:02:02 +00:00
Compare commits
27
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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 {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--navds-font-family);
|
||||
line-height: 1.375;
|
||||
@@ -16,3 +20,16 @@ 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;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
@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 "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;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.5",
|
||||
"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.3",
|
||||
"version": "0.2.9",
|
||||
"private": false,
|
||||
"description": "NAV designsystem react components",
|
||||
"author": "NAV Designsystem team",
|
||||
@@ -24,15 +24,17 @@
|
||||
},
|
||||
"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",
|
||||
"clean": "rm -rf cjs esm",
|
||||
"build": "yarn run clean && tsc && tsc -p tsconfig-esm.json && yarn cjs-package",
|
||||
"watch": "tsc --watch -p tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-icons": "^0.2.0",
|
||||
"@navikt/ds-icons": "^0.2.1",
|
||||
"@popperjs/core": "^2.5.4",
|
||||
"classnames": "^2.2.6",
|
||||
"react-collapse": "^5.1.0",
|
||||
|
||||
@@ -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>
|
||||
),
|
||||
];
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -20,6 +20,11 @@ export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
* @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.
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.
@@ -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";
|
||||
@@ -14,7 +24,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";
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
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>
|
||||
);
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -37,10 +37,13 @@ export interface PopoverProps extends HTMLAttributes<HTMLDivElement> {
|
||||
*/
|
||||
placement?: Placement;
|
||||
/**
|
||||
* Small reduces padding on popover content
|
||||
* @default "medium"
|
||||
* Deteremines if popover contains an arrow
|
||||
*/
|
||||
size?: "medium" | "small";
|
||||
arrow?: boolean;
|
||||
/**
|
||||
* Distance from anchor to popover
|
||||
*/
|
||||
offset?: number;
|
||||
}
|
||||
|
||||
const useEventLister = (event: string, callback) =>
|
||||
@@ -54,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]);
|
||||
|
||||
@@ -114,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],
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -138,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"
|
||||
@@ -149,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>
|
||||
);
|
||||
};
|
||||
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.
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,49 @@
|
||||
# Endringslogg
|
||||
|
||||
## 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)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Heading, Paragraph, Alert, Link } from "@navikt/ds-react";
|
||||
import Bash from "./code/Bash";
|
||||
import Import from "./code/Import";
|
||||
import Preview from "./code-preview/Preview";
|
||||
import Npm from "./npm/Npm";
|
||||
import TableOfContents from "./table-of-contents/TableOfContents";
|
||||
import { Knapp, Hovedknapp, Fareknapp, Flatknapp } from "nav-frontend-knapper";
|
||||
import { Settings } from "@navikt/ds-icons";
|
||||
|
||||
export default {
|
||||
h1: (props) => <Heading size="xxl" level={1} {...props} />,
|
||||
h2: (props) => <Heading size="large" level={2} {...props} />,
|
||||
h3: (props) => <Heading size="small" level={3} {...props} />,
|
||||
p: (props) => <Paragraph size="medium" {...props} />,
|
||||
Bash,
|
||||
Preview,
|
||||
Import,
|
||||
Npm,
|
||||
TableOfContents,
|
||||
Alert,
|
||||
Link,
|
||||
Knapp,
|
||||
Fareknapp,
|
||||
Flatknapp,
|
||||
Hovedknapp,
|
||||
Settings,
|
||||
};
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { useState } from "react";
|
||||
import Tabs from "../tabs/Tabs";
|
||||
import style from "./preview.module.css";
|
||||
import { renderToString } from "react-dom/server";
|
||||
import Bash from "../code/Bash";
|
||||
import Prettier from "prettier/standalone";
|
||||
import ParserBabel from "prettier/parser-babel";
|
||||
import "./preview.css";
|
||||
|
||||
const prettierOptions = {
|
||||
semi: true,
|
||||
@@ -28,7 +28,11 @@ const Preview = ({
|
||||
}: PreviewProps) => {
|
||||
const [tab, setTab] = useState(0);
|
||||
const handleChange = (x: number) => {
|
||||
setTab(x);
|
||||
if (tab === x) {
|
||||
setTab(null);
|
||||
} else {
|
||||
setTab(x);
|
||||
}
|
||||
};
|
||||
|
||||
const reactFormat = Prettier.format(react, prettierOptions).slice(0, -2);
|
||||
@@ -43,12 +47,12 @@ const Preview = ({
|
||||
.slice(0, -2)
|
||||
.replace(` data-reactroot=""`, "");
|
||||
|
||||
const tabs = !hideHtml || !!children ? ["REACT", "HTML/CSS"] : ["REACT"];
|
||||
const tabs = !hideHtml && !!children ? ["REACT", "HTML/CSS"] : ["REACT"];
|
||||
|
||||
return (
|
||||
<div className={style.wrapper}>
|
||||
{!!children && <div className={style.preview}>{children}</div>}
|
||||
<Tabs tabs={tabs} onChange={(x) => handleChange(x)} />
|
||||
<div className={"preview__wrapper"}>
|
||||
{!!children && <div className={"preview__container"}>{children}</div>}
|
||||
<Tabs tabs={tabs} tab={tab} onChange={(x) => handleChange(x)} />
|
||||
{tab === 0 && <Bash code={reactFormat} language="jsx" copy />}
|
||||
|
||||
{(!hideHtml || !!children) && tab === 1 && (
|
||||
|
||||
+6
-2
@@ -1,4 +1,4 @@
|
||||
.wrapper {
|
||||
.preview__wrapper {
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
background-color: var(--bg-secondary);
|
||||
@@ -6,7 +6,11 @@
|
||||
outline: var(--outline);
|
||||
}
|
||||
|
||||
.preview {
|
||||
.preview__container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 0.5rem;
|
||||
row-gap: 0.5rem;
|
||||
border-bottom: 2px solid var(--code-divider);
|
||||
padding-bottom: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
@@ -1,11 +1,11 @@
|
||||
import copy from "copy-to-clipboard";
|
||||
import Prism from "prismjs";
|
||||
import style from "./bash.module.css";
|
||||
import cl from "classnames";
|
||||
import { Files } 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"
|
||||
@@ -66,42 +66,39 @@ const Bash = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={style.preWrapper}>
|
||||
<pre className={style.pre}>
|
||||
<div className={"bash__preWrapper"}>
|
||||
<pre className={"bash__pre"}>
|
||||
<code
|
||||
className={cl(style.code, {
|
||||
[style.codeCopy]: copy,
|
||||
[style.terminal]: terminal,
|
||||
className={cl("bash__code", {
|
||||
bash__codeCopy: copy,
|
||||
bash__terminal: terminal,
|
||||
})}
|
||||
{...props}
|
||||
dangerouslySetInnerHTML={{ __html: highlighted }}
|
||||
/>
|
||||
{copy && (
|
||||
<>
|
||||
<div className={style.buttonBackground}>
|
||||
<button
|
||||
ref={buttonRef}
|
||||
className={style.copyButton}
|
||||
onClick={() => handleCopy()}
|
||||
>
|
||||
<Files />
|
||||
</button>
|
||||
<Popover
|
||||
role="alert"
|
||||
anchorEl={buttonRef.current}
|
||||
open={openPopover}
|
||||
onClose={() => setOpenPopover(false)}
|
||||
size="small"
|
||||
placement="auto-start"
|
||||
/* arrow={false} */
|
||||
>
|
||||
Kode er kopiert
|
||||
</Popover>
|
||||
)
|
||||
</div>
|
||||
<button
|
||||
ref={buttonRef}
|
||||
className={"bash__copyButton"}
|
||||
onClick={() => handleCopy()}
|
||||
>
|
||||
<Files />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</pre>
|
||||
<Popover
|
||||
className="bash__popover"
|
||||
role="alert"
|
||||
anchorEl={buttonRef.current}
|
||||
open={openPopover}
|
||||
onClose={() => setOpenPopover(false)}
|
||||
placement="right"
|
||||
arrow={false}
|
||||
>
|
||||
Kopiert!
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
.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__preWrapper {
|
||||
position: relative;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
.pre {
|
||||
padding: 1rem;
|
||||
margin: 1rem 0 0 0;
|
||||
overflow: auto;
|
||||
width: calc(100vw - 2rem);
|
||||
background-color: var(--bg-code);
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
/* Fixer pixelbug på høyre side av bash-panel */
|
||||
box-shadow: inset -4px 0 0 var(--bg-code);
|
||||
}
|
||||
|
||||
.preWrapper {
|
||||
position: relative;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.terminal {
|
||||
color: var(--color-code);
|
||||
}
|
||||
|
||||
.code {
|
||||
padding-right: 4rem;
|
||||
color: var(--color-code);
|
||||
}
|
||||
|
||||
.terminal::before {
|
||||
content: "$ ";
|
||||
}
|
||||
|
||||
.buttonBackground {
|
||||
width: 3rem;
|
||||
background-color: var(--bg-code);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
margin: 1rem 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: calc(100% - 3rem - 0.5rem);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.copyButton {
|
||||
background-color: var(--bg-code);
|
||||
color: white;
|
||||
font-size: 1.5rem;
|
||||
padding: 0.5rem;
|
||||
border: none;
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
height: 2.5rem;
|
||||
width: 2.5rem;
|
||||
}
|
||||
|
||||
.copyButton:hover {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.copyButton:focus {
|
||||
outline: var(--outline-code);
|
||||
outline-offset: var(--outline-offset);
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
import cl from "classnames";
|
||||
import Header from "./header/Header";
|
||||
import Sidebar from "./sidebar/Sidebar";
|
||||
import Mdx from "./MdxProvider";
|
||||
import Toc from "../toc/Toc";
|
||||
import { Grid, Cell, ContentContainer } from "@navikt/ds-react";
|
||||
import { useMediaQuery } from "react-responsive";
|
||||
import useKeypress from "react-use-keypress";
|
||||
import { useEffect, useState } from "react";
|
||||
import style from "./layout.module.css";
|
||||
import "./theme.css";
|
||||
import "./layout.css";
|
||||
|
||||
interface LayoutProps {
|
||||
children?: React.ReactNode;
|
||||
menu: any[];
|
||||
}
|
||||
|
||||
const Layout = ({ children }: LayoutProps) => {
|
||||
const Layout = ({ children, menu }: LayoutProps) => {
|
||||
const [sidebar, setSidebar] = useState(false);
|
||||
|
||||
const small = useMediaQuery({
|
||||
@@ -28,22 +29,20 @@ const Layout = ({ children }: LayoutProps) => {
|
||||
}, [small]);
|
||||
|
||||
return (
|
||||
<div className={style.pageWrapper + " lightTheme"}>
|
||||
<div className={cl("pageWrapper", "lightTheme")}>
|
||||
<Header sidebar={sidebar} onSidebarChange={(x) => setSidebar(x)} />
|
||||
<Sidebar
|
||||
menu={menu}
|
||||
sidebar={sidebar}
|
||||
small={small}
|
||||
onSidebarChange={(x) => setSidebar(x)}
|
||||
/>
|
||||
<main className={style.contentWrapper}>
|
||||
{/* TEMP UNTIL LAYOUT UPDATE */}
|
||||
<main className={"contentWrapper"}>
|
||||
<ContentContainer>
|
||||
<Grid>
|
||||
<Cell className={style.content} xs={12} sm={12} md={10} lg={7}>
|
||||
<Mdx>{children}</Mdx>
|
||||
</Cell>
|
||||
<Cell xs={12} sm={1} md={2} lg={1} />
|
||||
<Cell xs={12} sm={12} md={8} lg={4}>
|
||||
<Toc />
|
||||
<Cell className={"content"} xs={12} sm={12} md={12} lg={12}>
|
||||
{children}
|
||||
</Cell>
|
||||
</Grid>
|
||||
</ContentContainer>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { MDXProvider } from "@mdx-js/react";
|
||||
import { Heading, Paragraph } from "@navikt/ds-react";
|
||||
import Bash from "../code/Bash";
|
||||
import Import from "../code/Import";
|
||||
import Preview from "../code-preview/Preview";
|
||||
import Npm from "../npm/Npm";
|
||||
/* import { Button } from "@navikt/ds-react"; */
|
||||
|
||||
const MdxWrapper = (props) => (
|
||||
<MDXProvider
|
||||
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} />,
|
||||
p: (props) => <Paragraph size="medium" {...props} />,
|
||||
Bash,
|
||||
Preview,
|
||||
Import,
|
||||
Npm,
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
export default MdxWrapper;
|
||||
@@ -2,7 +2,7 @@ import Link from "next/link";
|
||||
import NavLogo from "../../assets/navLogo.svg";
|
||||
import { HamburgerFilled } from "@navikt/ds-icons";
|
||||
import cl from "classnames";
|
||||
import style from "../layout.module.css";
|
||||
import "../layout.css";
|
||||
|
||||
interface HeaderProps {
|
||||
className?: string;
|
||||
@@ -17,20 +17,20 @@ const Header = ({
|
||||
...props
|
||||
}: HeaderProps) => {
|
||||
return (
|
||||
<header className={style.header}>
|
||||
<header className={"header"}>
|
||||
<button
|
||||
onClick={() => onSidebarChange(!sidebar)}
|
||||
className={cl(style.header__link, style.header__icon, {
|
||||
[style["header__icon--hidden"]]: sidebar,
|
||||
className={cl("header__link", "header__icon", {
|
||||
"header__icon--hidden": sidebar,
|
||||
})}
|
||||
tabIndex={!sidebar ? 0 : -1}
|
||||
>
|
||||
<HamburgerFilled />
|
||||
</button>
|
||||
<Link href="/">
|
||||
<button className={style.header__link}>
|
||||
<button className={"header__link"}>
|
||||
<NavLogo />
|
||||
<span className={style["header__link-title"]}>NAV Designsystem</span>
|
||||
<span className={"header__link-title"}>NAV Designsystem</span>
|
||||
</button>
|
||||
</Link>
|
||||
</header>
|
||||
|
||||
@@ -91,6 +91,9 @@
|
||||
overflow: visible;
|
||||
margin: 0 auto 0 0;
|
||||
width: 100%;
|
||||
|
||||
/* TMP UNTIL LAYOUT UPDATE */
|
||||
max-width: 520px;
|
||||
}
|
||||
|
||||
.content {
|
||||
@@ -0,0 +1,34 @@
|
||||
import { useRouter } from "next/router";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
AccordionMenu,
|
||||
AccordionMenuCollapsable,
|
||||
AccordionMenuItem,
|
||||
} from "@navikt/ds-react";
|
||||
|
||||
const MenuLink = (node) => {
|
||||
const { asPath } = useRouter();
|
||||
|
||||
return (
|
||||
<Link href={node.pathName} passHref>
|
||||
<AccordionMenuItem active={asPath === node.pathName}>
|
||||
{node.title}
|
||||
</AccordionMenuItem>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
const mapToComponents = (node) =>
|
||||
node.children ? (
|
||||
<AccordionMenuCollapsable key={node.title} title={node.title}>
|
||||
{node.children.map(mapToComponents)}
|
||||
</AccordionMenuCollapsable>
|
||||
) : (
|
||||
<MenuLink key={node.title} {...node} />
|
||||
);
|
||||
|
||||
const Menu = ({ menu }) => (
|
||||
<AccordionMenu>{menu.map(mapToComponents)}</AccordionMenu>
|
||||
);
|
||||
|
||||
export default Menu;
|
||||
@@ -1,48 +1,47 @@
|
||||
import Link from "next/link";
|
||||
import cl from "classnames";
|
||||
import { Close } from "@navikt/ds-icons";
|
||||
import style from "../layout.module.css";
|
||||
import "../layout.css";
|
||||
import Menu from "./Menu";
|
||||
|
||||
interface SidebarProps {
|
||||
classname?: string;
|
||||
sidebar: boolean;
|
||||
small: boolean;
|
||||
onSidebarChange: (x: boolean) => void;
|
||||
menu: any[];
|
||||
}
|
||||
|
||||
const Sidebar = ({
|
||||
sidebar,
|
||||
small,
|
||||
onSidebarChange,
|
||||
...props
|
||||
menu = [],
|
||||
}: SidebarProps) => {
|
||||
return (
|
||||
<>
|
||||
{sidebar && small && (
|
||||
<div
|
||||
onClick={() => onSidebarChange(false)}
|
||||
className={cl(style["sidebar--overlay"], {
|
||||
[style["sidebar--overlay--fade"]]: sidebar,
|
||||
className={cl("sidebar--overlay", {
|
||||
"sidebar--overlay--fade": sidebar,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={cl(style.sidebar, {
|
||||
[style.sidebar__mobile]: small,
|
||||
[style["sidebar__mobile--open"]]: small && sidebar,
|
||||
className={cl("sidebar", {
|
||||
sidebar__mobile: small,
|
||||
"sidebar__mobile--open": small && sidebar,
|
||||
})}
|
||||
>
|
||||
{small && sidebar && (
|
||||
<button
|
||||
onClick={() => onSidebarChange(!sidebar)}
|
||||
className={style.sidebar__icon}
|
||||
className={"sidebar__icon"}
|
||||
>
|
||||
<Close />
|
||||
</button>
|
||||
)}
|
||||
<Link href="/">Home</Link>
|
||||
<Link href="/komponenter">Komponenter</Link>
|
||||
<Link href="/komponenter/button">Button</Link>
|
||||
<Menu menu={menu} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
:root {
|
||||
--bg-primary: #faf9f9;
|
||||
--font-family-code: "Source Code Pro", monospace;
|
||||
}
|
||||
|
||||
.darkTheme {
|
||||
@@ -1,6 +1,6 @@
|
||||
import getConfig from "next/config";
|
||||
import Import from "../code/Import";
|
||||
import style from "./npm.module.css";
|
||||
import "./npm.css";
|
||||
|
||||
const Npm = ({
|
||||
packName,
|
||||
@@ -21,37 +21,21 @@ const Npm = ({
|
||||
<div>
|
||||
{packs.map(({ name, data }) => (
|
||||
<div key={name}>
|
||||
<span className={style.badges}>
|
||||
<Import from={name} imports={imports} namedExport={namedExport} />
|
||||
{/* TODO: Move to separate component? */}
|
||||
{/* <span className={style.badges}>
|
||||
<span className={"npm__.badges"}>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={`https://www.npmjs.com/package/${name}`}
|
||||
>
|
||||
<img src={`https://badgen.net/npm/v/${name}`} alt="123" />
|
||||
</a>
|
||||
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={`https://bundlephobia.com/result?p=${name}`}
|
||||
>
|
||||
<img
|
||||
src={`https://badgen.net/bundlephobia/tree-shaking/${name}`}
|
||||
alt="123"
|
||||
src={`https://badgen.net/npm/v/${name}/?style=for-the-badge&logo=appveyor`}
|
||||
alt="Versjonsbadge for npm-pakken"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href={`https://bundlephobia.com/result?p=${name}`}
|
||||
>
|
||||
<img
|
||||
src={`https://badgen.net/bundlephobia/min/${name}`}
|
||||
alt="123"
|
||||
/>
|
||||
</a>
|
||||
</span>
|
||||
<Import from={name} imports={imports} namedExport={namedExport} />
|
||||
</span> */}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.badges {
|
||||
.npm__badges {
|
||||
display: flex;
|
||||
column-gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
@@ -0,0 +1,32 @@
|
||||
import { useContext } from "react";
|
||||
import { Next } from "@navikt/ds-icons";
|
||||
import { Heading } from "@navikt/ds-react";
|
||||
import { PagePropsContext } from "../../pages/_app";
|
||||
import "./tableOfContents.css";
|
||||
|
||||
const TableOfContents = () => {
|
||||
const { tableOfContents } = useContext<any>(PagePropsContext);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading size="large" level={2}>
|
||||
Innhold
|
||||
</Heading>
|
||||
<ul className={"toc__ul"}>
|
||||
{tableOfContents?.map(({ heading, slug }) => (
|
||||
<li key={slug} className={"toc__li"}>
|
||||
<Next
|
||||
aria-label="Pil peker på lenke"
|
||||
focusable="false"
|
||||
role="img"
|
||||
aria-hidden
|
||||
/>
|
||||
<a href={`#${slug}`}>{heading}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableOfContents;
|
||||
Loaded 100 of 131 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user