Compare commits

...
Author SHA1 Message Date
github-actions[bot] ffcfe79c18 Lerna versionbump [ci skip]
- @navikt/ds-react@0.2.7
2021-04-06 07:28:27 +00:00
Andreas Nordahl 5d8d2ffba9 Add disabled to button props (#1063) 2021-04-06 09:14:23 +02:00
github-actions[bot] c785316086 Lerna versionbump [ci skip]
- @navikt/ds-icons@0.2.1
 - @navikt/ds-react@0.2.6
2021-04-06 06:55:27 +00:00
Jakob Havstein Eriksen 7087f160e8 Legger til sources i ds-icons (#1064)
* Inkludér src i tarball, for sourcemaps

* Fjern output-mapper før bygg for å unngå ts-feilmeldinger

Eksempel på feilmelding:

error TS5055: Cannot write file
'/Users/jakob/dev/nav-frontend-moduler/@navikt/ds-react/esm/typography/Heading.d.ts'
because it would overwrite input file.
2021-04-06 08:44:49 +02:00
Karina LudwigandAndreas Nordahl 235e48a843 Update overview.mdx (#1060)
* Update overview.mdx

* fix html structure. p in p is not legal

Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
2021-03-31 10:35:26 +02:00
Karina Ludwig 93fc5dc6ae Update overview.mdx (#1061) 2021-03-31 10:28:57 +02:00
github-actions[bot] 5c49902ffb Lerna versionbump [ci skip]
- @navikt/ds-css@0.2.5
2021-03-30 08:00:35 +00:00
Andreas NordahlandKen c9c148e050 use accordion menu in docs (#1057)
* use accordion menu in docs

* la til internal-padding for sidebar

* menu update

* oppdatert keys

Co-authored-by: Ken <ken.aleksander@gmail.com>
2021-03-30 09:47:25 +02:00
Andreas Nordahl adf9de3c63 inset outline accordion menu (#1058) 2021-03-30 09:36:51 +02:00
github-actions[bot] 26612e371d Lerna versionbump [ci skip]
- @navikt/ds-css@0.2.4
 - @navikt/ds-react@0.2.5
 - @navikt/ds-tokens@0.1.2
2021-03-25 15:35:16 +00:00
Andreas NordahlandKen b194506943 Accordion menu refactor (#1054)
* accordion-menu-refactor

* lint

* styling

* smaller padding for items

* remove placeholder hover and focus style

* use accordion-menu in accordion-anchor-menu

* delete old css

* balance title margins

* aria-current

* remove smooth scrolling code

* remove unused import

* fikset smoothscroll

* fix reponsive padding for accordion-anchor-menu in product page

* accordion-menu focus and hover style

* oppdatert export navn

* oppdatert export navn anchor-menu

* oppdatert index import/export

* oppdatert props

* increase height

* remove unused style

Co-authored-by: Ken <ken.aleksander@gmail.com>
2021-03-25 16:20:26 +01:00
github-actions[bot] 79dbffff1d Lerna versionbump [ci skip]
- @navikt/ds-css@0.2.3
2021-03-24 14:11:12 +00:00
Ken 0359934bb9 Smooth scrollbehavior baseline.css (#1055) 2021-03-24 14:58:44 +01:00
github-actions[bot] 2723363fa0 Lerna versionbump [ci skip]
- @navikt/ds-css@0.2.2
 - @navikt/ds-react@0.2.4
 - @navikt/ds-tokens@0.1.1
2021-03-22 13:22:25 +00:00
d56bc72977 Rename Layout til ProductPageLayout, legg til tittel og container (#1022)
* Rename Layout til ProductPageLayout, legg til tittel og container

* Juster padding på header

* Korriger mobil-visning

* Korriger brekkpunkt

* Del opp css

* Fjern ubrukt import

* Korriger klassenavn

* Legg på --decorator-sticky-offset på sticky-menyer

* Legg modul under riktig mappe

* Merge

* Oppdater ds-icons

* Fjern react-dom

* Revert package.json endringer

* Fiks typo i package.json

* Legg inn avhengighet til @navikt/nav-dekoratoren-moduler

* Oppdater versjon av @navikt/nav-dekoratoren-moduler

* Refaktorer css

* Fiks identering

* Rename decorator function name

* Prettify

* Fiks react-import

* Flytt på import

* Fjern avhengigheten til nav-dekoratoren-moduler

* Sett bakgrunnsfarge på body

* Fjern nav-dekoratoren-moduler fra yarn lock

* Layout with panels (#1023)

* Legg til panel i layouts

* Oppdaters responsive regler

* Fiks posisjonen på ikonet

* Responsive tweak

* Rename klasser

* Legg til funksjonalitet for kopiering

* Endre til et mer logisk funksjonsnavn

* Engelsk klassenavn

* Legg til highlight param

* Oppdater eksempel

* Fiks linting

* Fjern ubrukte imports

* Fiks styling

* Oppdater anker

* Flytt id

* Fjern trailing slash

* Endre bakgrunn på body

* Bugfiks for copyToClipboard

* Flytt window.location inn i onClick

* Rename variabeler

* Fiks gutters

* Bugfixes

* Bugfixes

* Accordion menu (#1019)

* Legg til dekoratøren på content-container og layout i storybook

* Fjern duplikat bakgrunn

* Dytt footer til bunnen av siden

* Flytt styling til preview-head.html

* Legg til prettier ignore på en stygg linje

* Flytt env til toppen av fil

* Flytt docs-root

* Legg til accordion-menu

* Oppdater eksempeldata, dropdown -> collapsable

* V2

* Oppdater dummy-data

* Fiks linting

* Fiks imports

* Oppdater size

* Fiks feil på layout

* Korriger størrelser på teksten

* Merge

* Fiks logikk for aktivt element i sidemeny

* Legg komponent under riktig kategori

* fjernet bruken av nav-frontend- pakker

* endringer for venstre-notch active link

* width px -> rem for notch

* Accordion menu med Overridablecomponent (#1034)

* oppdatert til link

* now with overridable component

* ignore stories in eslint

* riktig styling

* imports opprydding

* fjernet console log

* Fiks skrivefeil i variabelnavn

* Kun rendre tittel dersom den er definert

* fikset active styling

* Legg padding på lenkene

* Refaktor styles

* Flytt tilbake styling

* Fjern ubrukt import

* Flytt komponenter opp en mappe

* Refaktor context

* Legg til hooks dependencies

* Flytt smoothScrollBehavior

* Fjern ubrukt import

* Refaktor register og unregister anchor

* Benytt useCallback for å forhindre infinite loop

* Rename store

* Forhindre duplikat variabeldefinisjon

* Endre default aria-label på nav

* Set url hash

* Revert store-endringer

* Oppdater beta-versjon

* Oppdater versjonsnr

* Endre overskrift

* Versjon 0.2.1-beta.1

* Rename variabler

* v0.2.1-beta.1

* Sjekk om brukeren har scrollet til bunnen av siden

* 0.2.1-beta.3

* IE11 support

* v0.2.1-beta.4

* Margin only if not last child

* v0.2.1-beta.5

* Rename css

* 0.2.1-beta.6

* Legg til overridable component

* Fjern prop

* v0.2.1-beta.7

* Fiks body-padding

* v0.2.1-beta.8

* v0.2.1-beta.8

* Fiks eslint-problemer

* Fjern ubrukt import

* Fiks signatur på funskjon

* Fjern anchor-interface

Co-authored-by: Ken <ken.aleksander@gmail.com>
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>

Co-authored-by: Ken <ken.aleksander@gmail.com>
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>

* use popover for copied-text

* oppdatert versjoner

Co-authored-by: Ken <ken.aleksander@gmail.com>
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
2021-03-22 14:07:34 +01:00
Andreas NordahlandKen e203d669e1 Refactor docs mdx handling (#1050)
* remove unused plugins and mdxproviders

* toc in getStaticProps

* unused imports

* strange next link behaviour

* moved mdxcomponents

* slugger slugging slugs

* fjernet ubrukte npm-pakker

Co-authored-by: Ken <ken.aleksander@gmail.com>
2021-03-22 10:04:07 +01:00
Andreas NordahlandKen 90c06964a3 dynamic docs menu PoC (#1047)
* dynamic docs menu PoC

* working menu

* render mdx

* remove stray parens

* null check

* npm works :)

* fix index page and toc

* fikset id for heading

Co-authored-by: Ken <ken.aleksander@gmail.com>
2021-03-19 12:01:44 +01:00
Ken c35850a5e5 Nextjs TableOfContents (#1048)
* oppdatert toc

* oppdatert toc

* pr fix

* css update
2021-03-19 11:31:58 +01:00
Henning Håkonsen fd2ebe2629 Update README.md (#1046) 2021-03-18 09:50:50 +01:00
Ken 206cdaa2ce Forsøk på manuell sidestruktur (#1045)
* demo sidebar

* flyttet menu

* fjernet route

* fikset imports

* refactored meny

* fikset key
2021-03-17 13:44:52 +01:00
github-actions[bot] 42bc4288f5 Lerna versionbump [ci skip]
- @navikt/ds-react@0.2.3
2021-03-17 10:37:50 +00:00
Ken 3d7cc1112c Oppdatert kommentarer for komponenter (#1043)
* accordion comments + props

* alert comments + props

* button comments + props

* contentcontainer comments + props

* grid comments + props

* grid + internal-header

* oppdatert alle componenter

* fjernet unødvendig endring i pr modal

* fikset popover

* fjernet prop-types fra komponenter
2021-03-17 11:26:13 +01:00
github-actions[bot] 00fec86f80 Lerna versionbump [ci skip]
- @navikt/ds-react@0.2.2
2021-03-16 13:23:29 +00:00
Ken d631e4b611 setappelement extender nå Modal komponent (#1044)
* setappelement implementert

* fjernet comments
2021-03-16 14:10:48 +01:00
Ken 3097afe082 Nextjs base-struktur med mdx v0.1 (#1040)
* nav-logo white

* base-struktur layout

* fjernet docs-old

* fjernet docs-old

* Code-preview, bash og npm  (#1041)

* laget code-preview

* fikset styling

* npm komponent
2021-03-16 11:08:14 +01:00
github-actions[bot] fe22c83bef Lerna versionbump [ci skip]
- @navikt/ds-react@0.2.1
 - nav-frontend-hjelpetekst@2.0.57
 - nav-frontend-popover@1.0.4
2021-03-16 09:30:14 +00:00
Ken 4684d487af Fikset @navikt/ds-react popover + TSerror for nav-frontend-popover (#1038)
* oppdatert vnext popover

* oppdatert nav-frontend popover
2021-03-16 10:17:18 +01:00
Ken 7485befdfa Stories typo fiks (#1036)
* Update introduction.stories.mdx

* install -> add
2021-03-16 10:15:53 +01:00
github-actions[bot] 313fd1558a Lerna versionbump [ci skip]
- @navikt/ds-css@0.2.1
2021-03-11 08:24:39 +00:00
Ken e184e872a1 Hot-reloading av css i storybook, watch script (#1037)
* hot-reloading av css, watch script

* fjernet postcss imports

* navn watch-script
2021-03-11 09:10:21 +01:00
Ken 65bd0a8be6 oppdatert stories for å forklare v0.2.0 oppsett (#1035) 2021-03-10 15:18:06 +01:00
Ken 1eadf5d287 Update package.json 2021-03-10 14:56:08 +01:00
Ken 541ef45b8e Update package.json 2021-03-10 14:55:48 +01:00
github-actions[bot] 709c20ed6d Lerna versionbump [ci skip]
- @navikt/ds-css@0.2.0
 - @navikt/ds-icons@0.2.0
 - @navikt/ds-react@0.2.0
2021-03-10 13:53:25 +00:00
Ken 6530211445 Fjernet css-imports i komponenter (vnext) (#1030)
* fjernet ds-react dep for css

* fjernet styling fra alle komponenter

* minified css

* flyttet normalize fra node til lokalt

* oppdatert pakke-versjoner

* fikset website deps

* Update preview.js

* yarn lock

* flyttet normalize til top

* fikset dist og sourcemap

* yarn lock

* fikset css imports

* storybook bruker nå kompilert index.css

* Endret css naming fra index -> komponentnavn (#1032)

* renamet css fra index -> navn

* flyttet css ut fra mapper

* css til beta
2021-03-10 14:36:58 +01:00
Ken 88a665f772 Tree-shakable ds-react og ds-icons (#1033)
* oppdatert ikonpakke for esm støttte

* ds-react med esm exports

* opprydding package.json, sideeffects

* oppdatert ds-react

* target es2015

* oppdatert ds-icons for esm

* oppdatert ds-icons for esm

* oppdatert ds-react script

* oppdatert clean script

* eslint fiks

* minor bump for pakker

* yarn lock
2021-03-10 13:51:11 +01:00
Ken dc2b063fda Update CHANGELOG.md 2021-03-10 10:07:50 +01:00
Ken 1414f85484 Update CHANGELOG.md 2021-03-10 10:03:14 +01:00
github-actions[bot] 2fd93bb2be Lerna versionbump [ci skip]
- nav-frontend-skjema-style@2.1.0
 - nav-frontend-skjema@3.1.0
2021-03-10 08:47:58 +00:00
Ken 1360789bc3 Endret feil-styling og state-handling for skjema-komponenter (#1018)
* bedre feilhåndtering for skjemaelementer

* oppdatert disabled + feil state

* yarn lockfile

* oppdatert stories

* oppdatert examples

* oppdatert yarn lock

* oppdatert versions

* oppdatert versions-2

* oppdatert version

* fikset state-styling

* yarn lock
2021-03-10 09:34:13 +01:00
Ken cecc905f58 Oppgradert storybook (#1027)
* oppdatert stories

* oppdatert nav-frontend stories

* oppdatert warnings, theme

* oppdatert ikoner stories

* oppdatert chromatic script

* flyttet env variabel

* oppdatert yarn lock
2021-03-08 13:49:40 +01:00
Audun Fauchald Strandandsnyk-bot 1cda942e61 fix: package.json to reduce vulnerabilities (#1028)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-GLOBPARENT-1016905

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
2021-03-08 13:45:32 +01:00
Ken ab3a4289ea Omskrevet hvordan react-docgen genereres (#1029)
* ny generering av docs

* gatsby bruker nå nye props

* flyttet docgen til gatsby build steg

* fjernet docgen copi

* yarn lock
2021-03-08 12:00:43 +01:00
Ken 9bafdd3c06 Satt opp nextjs for ny nettside (#1031)
* setup-ready

* flyttet useRoute

* config testing nextjs

* renamet til docs

* opprydding

* yarn lock

* oppdatert readme
2021-03-08 11:55:09 +01:00
219 changed files with 7319 additions and 2724 deletions

No files matched your search

+1 -1
View File
@@ -71,7 +71,7 @@ jobs:
- run: git remote set-url origin https://github-actions[bot]:$NAV_DS_TOKEN@github.com/$GITHUB_REPOSITORY.git
env:
NAV_DS_TOKEN: ${{secrets.GIT_REPO}}
- run: yarn lerna version patch --include-merged-tags --no-private --yes
- run: yarn lerna version patch --include-merged-tags --yes
- run: yarn lerna publish from-package --yes
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_AUTOMATION}}
+4
View File
@@ -111,3 +111,7 @@ utilities/**/css
@navikt/ds-icons/NAV-ikonpakke-svg.zip
*/**/NAV-ikonpakke-png.zip
*/**/NAV-ikonpakke-svg.zip
react-docgen.json
cjs
esm
+28 -3
View File
@@ -1,7 +1,32 @@
module.exports = {
webpackFinal: async (config, { configType }) => {
config.devServer = { stats: "errors-only" };
return config;
},
devServer: { stats: "errors-only" },
stories: [
"../packages/**/*.stories.@(js|jsx|ts|tsx)",
"../@navikt/**/*.stories.@(js|jsx|ts|tsx)",
"../.storybook/**/*.stories.@(mdx)",
"../packages/**/*.stories.@(js|jsx|ts|tsx|mdx)",
"../@navikt/**/*.stories.@(js|jsx|ts|tsx|mdx)",
],
addons: [
"@storybook/addon-links",
"@storybook/addon-docs",
{
name: "@storybook/addon-storysource",
options: {
loaderOptions: {
injectStoryParameters: false,
},
},
},
{
name: "@storybook/addon-essentials",
options: {
actions: false,
controls: { hideNoControlsWarning: true },
},
},
"@whitespace/storybook-addon-html",
],
addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
};
+6
View File
@@ -0,0 +1,6 @@
import { addons } from "@storybook/addons";
import NavTheme from "./theme.js";
addons.setConfig({
theme: NavTheme,
});
+5 -6
View File
@@ -1,14 +1,13 @@
import "nav-frontend-core";
import "@navikt/ds-css/baseline/index.css";
import "@navikt/ds-css/index.css";
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
options: {
// Makes sure `all` story is first
storySort: (a, b) => {
if (a[0].indexOf("all") !== -1) return -1;
if (b[0].indexOf("all") !== -1) return 1;
return 0;
storySort: {
method: "",
order: [],
locales: "",
},
},
};
@@ -0,0 +1,33 @@
import { Meta } from "@storybook/addon-docs/blocks";
<Meta title="ds-react/Kom i gang" />
# Ta i bruk `@navikt/ds-react` pakken
## Oppsett
```bash
yarn add @navikt/ds-react @navikt/ds-css
```
Siden stilene ikke importeres direkte i komponentene, så må man selv importere ds-css.
Dette gjøres for å la komponetene brukes i Nextjs prosjekter.
```bash
import "@navikt/ds-css"
```
Dette vil også legge css-variabler på :root. For å få dette til å fungere med IE11, kan denne pakken tas i bruk: https://jhildenbiddle.github.io/css-vars-ponyfill/#/
## Testing
For å støtte testing med eks Jest som ikke tillater ESM moduler, så kan denne configen legges til
```bash
"moduleNameMapper": {
"@navikt/ds-react(.*)": "@navikt/ds-react/cjs$1",
"@navikt/ds-icons(.*)": "@navikt/ds-icons/cjs$1"
}
```
Dette vil remappe komponentene (og ikonpakken) til å bruke CommonJs versjonen for testing
+6
View File
@@ -0,0 +1,6 @@
import { create } from "@storybook/theming";
export default create({
base: "light",
brandTitle: "NAV Designsystem",
});
+25 -5
View File
@@ -1,11 +1,31 @@
const path = require("path");
module.exports = (baseConfig) => {
baseConfig.config.module.rules.push({
test: /\.less$/,
loaders: ["style-loader", "css-loader", "less-loader"],
include: path.resolve(__dirname, "../packages/"),
});
baseConfig.config.module.rules.push(
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
include: [
path.resolve(__dirname, "../node_modules/@navikt/ds-css/index.css"),
],
},
{
test: /\.less$/,
loaders: ["style-loader", "css-loader", "less-loader"],
include: path.resolve(__dirname, "../packages/"),
}
);
baseConfig.config.resolve.alias = {
...baseConfig.config.resolve?.alias,
"./normalize.css": path.resolve(
__dirname,
"../node_modules/normalize.css/normalize.css"
),
"./@navikt/ds-tokens": path.resolve(
__dirname,
"../node_modules/@navikt/ds-tokens/dist/tokens.css"
),
};
return baseConfig.config;
};
+8
View File
@@ -0,0 +1,8 @@
.navds-accordion-anchor-menu {
padding: 1rem 0;
}
.navds-accordion-anchor-menu__title {
margin-left: 1rem;
margin-right: 1rem;
}
+85
View File
@@ -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;
File renamed without changes.
+35
View File
@@ -0,0 +1,35 @@
@import "@navikt/ds-tokens";
@import "normalize.css";
@import "Source-Sans-Pro-regular.css";
@import "Source-Sans-Pro-italic.css";
@import "Source-Sans-Pro-600.css";
@import "print.css";
@import "utility.css";
html {
scroll-behavior: smooth;
}
body {
font-family: var(--navds-font-family);
line-height: 1.375;
color: var(--navds-color-text-primary);
font-size: 1.125rem;
}
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;
}
}
-18
View File
@@ -1,18 +0,0 @@
@import url(~normalize.css);
@import url(~@navikt/ds-tokens/dist/tokens.css);
@import url(Source-Sans-Pro-regular.css);
@import url(Source-Sans-Pro-italic.css);
@import url(Source-Sans-Pro-600.css);
@import url(print.css);
@import url(utility.css);
body {
font-family: var(--navds-font-family);
line-height: 1.375;
color: var(--navds-color-text-primary);
font-size: 1.125rem;
}
a {
color: var(--navds-color-text-link);
}
File renamed without changes.
@@ -1,3 +1,23 @@
/**************************
* .navds-grid *
**************************/
.navds-grid {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-gap: var(--navds-grid-gutter-small);
}
@media (min-width: 448px) {
.navds-grid {
grid-gap: var(--navds-grid-gutter-medium-and-larger);
}
}
/**************************
* .navds-grid__cell *
**************************/
.navds-grid__cell--xs-1 {
grid-column: span 1;
}
-11
View File
@@ -1,11 +0,0 @@
.navds-grid {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-gap: var(--navds-grid-gutter-small);
}
@media (min-width: 448px) {
.navds-grid {
grid-gap: var(--navds-grid-gutter-medium-and-larger);
}
}
-2
View File
@@ -1,2 +0,0 @@
@import "./grid.css";
@import "./cell.css";
+15
View File
@@ -0,0 +1,15 @@
@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 "layouts.css";
@import "link.css";
@import "modal.css";
@import "popover.css";
@import "tag.css";
@import "typography.css";
+72
View File
@@ -0,0 +1,72 @@
/**************************
* .navds-header *
**************************/
.navds-header {
display: flex;
align-items: center;
background: var(--navds-color-darkgray);
color: white;
max-width: 100vw;
min-height: 50px;
}
.navds-header__column {
display: flex;
align-items: center;
}
/**************************
* .navds-header__title *
**************************/
.navds-header__title {
padding: 0 1.5rem 0 1.5rem;
border-right: 1px solid var(--navds-color-gray-40);
display: flex;
align-self: stretch;
align-items: center;
text-decoration: none;
margin: 0;
color: var(--navds-color-text-inverse);
font-size: var(--navds-font-size-medium);
font-weight: var(--navds-font-weight-bold);
line-height: var(--navds-font-line-height-medium);
}
.navds-header__title > span > a {
text-decoration: none;
color: inherit;
}
.navds-header__title > span > a:focus {
box-shadow: var(--navds-shadow-focus-on-dark);
outline: none;
}
/**************************
* .navds-header__user *
**************************/
.navds-header__user {
color: var(--navds-color-text-inverse);
padding: 0 1.5rem 0 1.5rem;
margin-left: auto;
border-left: 1px solid var(--navds-color-gray-40);
display: flex;
align-self: stretch;
align-items: center;
}
.navds-header__name {
margin-right: 1rem;
font-size: var(--navds-font-size-small);
font-weight: var(--navds-font-weight-bold);
line-height: var(--navds-font-line-height-small);
}
.navds-header__ident {
font-size: var(--navds-font-size-xs);
font-weight: var(--navds-font-weight-bold);
line-height: var(--navds-font-line-height-xs);
}
-16
View File
@@ -1,16 +0,0 @@
@import "./title.css";
@import "./user.css";
.navds-header {
display: flex;
align-items: center;
background: var(--navds-color-darkgray);
color: white;
max-width: 100vw;
min-height: 50px;
}
.navds-header__column {
display: flex;
align-items: center;
}
-23
View File
@@ -1,23 +0,0 @@
.navds-header__title {
padding: 0 1.5rem 0 1.5rem;
border-right: 1px solid var(--navds-color-gray-40);
display: flex;
align-self: stretch;
align-items: center;
text-decoration: none;
margin: 0;
color: var(--navds-color-text-inverse);
font-size: var(--navds-font-size-medium);
font-weight: var(--navds-font-weight-bold);
line-height: var(--navds-font-line-height-medium);
}
.navds-header__title > span > a {
text-decoration: none;
color: inherit;
}
.navds-header__title > span > a:focus {
box-shadow: var(--navds-shadow-focus-on-dark);
outline: none;
}
-22
View File
@@ -1,22 +0,0 @@
.navds-header__user {
color: var(--navds-color-text-inverse);
padding: 0 1.5rem 0 1.5rem;
margin-left: auto;
border-left: 1px solid var(--navds-color-gray-40);
display: flex;
align-self: stretch;
align-items: center;
}
.navds-header__name {
margin-right: 1rem;
font-size: var(--navds-font-size-small);
font-weight: var(--navds-font-weight-bold);
line-height: var(--navds-font-line-height-small);
}
.navds-header__ident {
font-size: var(--navds-font-size-xs);
font-weight: var(--navds-font-weight-bold);
line-height: var(--navds-font-line-height-xs);
}
-1
View File
@@ -1 +0,0 @@
@import "./layout.css";
-117
View File
@@ -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;
}
}
+322
View File
@@ -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;
}
}
File renamed without changes.
File renamed without changes.
+12 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "0.1.17",
"version": "0.2.5",
"private": false,
"description": "Css for NAV Designsystem components",
"author": "NAV Designsystem team",
@@ -15,8 +15,16 @@
"type": "git",
"url": "git+https://github.com/navikt/nav-frontend-moduler.git"
},
"dependencies": {
"@navikt/ds-tokens": "^0.1.0",
"normalize.css": "^8.0.1"
"main": "./dist/index.css",
"scripts": {
"build": "postcss --use postcss-import -o dist/index.css index.css",
"watch-css": "postcss -w --use postcss-import -o dist/index.css index.css"
},
"devDependencies": {
"@navikt/ds-tokens": "^0.1.2",
"normalize.css": "^8.0.1",
"postcss": "^8.2.7",
"postcss-cli": "^8.3.1",
"postcss-import": "^14.0.0"
}
}
@@ -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 {
File renamed without changes.
File renamed without changes.
+6
View File
@@ -0,0 +1,6 @@
{
"type": "commonjs",
"main": "index.js",
"typings": "../esm/index.d.ts",
"sideEffects": false
}
+5 -5
View File
@@ -1,7 +1,7 @@
// https://levelup.gitconnected.com/learn-svg-to-react-using-figma-api-be0a5f9c0ca
// used for reference/implementation
const api = require("axios");
import { create, get } from "axios";
// Requires user to add a personalized figma token in .env
const headers = {
@@ -11,7 +11,7 @@ const headers = {
* Api connection for icon components
* https://www.figma.com/file/UmEVH3pZ71uJPsSz9ilP3Y/NAV-ikoner-2.1-Figma-i-test?node-id=0%3A1
*/
const instanceFiles = api.create({
const instanceFiles = create({
baseURL: `https://api.figma.com/v1/files/${process.env.FILE_KEY}/components`,
headers,
});
@@ -19,7 +19,7 @@ const instanceFiles = api.create({
/**
* api endpoint for images
*/
const instanceImages = api.create({
const instanceImages = create({
baseURL: `https://api.figma.com/v1/images/${process.env.FILE_KEY}`,
headers,
});
@@ -45,9 +45,9 @@ const getSvgImageUrls = async (nodeIds) => {
/**
* Gets raw svg data from url
*/
const getIconContent = async (url) => api.get(url);
const getIconContent = async (url) => get(url);
module.exports = {
export default {
getNodeChildren,
getSvgImageUrls,
getIconContent,
+18 -19
View File
@@ -1,9 +1,9 @@
const api = require("./api");
const fs = require("fs");
const path = require("path");
const pLimit = require("p-limit");
const rimraf = require("rimraf");
const startCase = require("lodash.startcase");
import { getNodeChildren, getSvgImageUrls, getIconContent } from "./api";
import { existsSync, unlinkSync, writeFileSync, mkdirSync } from "fs";
import { resolve } from "path";
import pLimit from "p-limit";
import rimraf from "rimraf";
import startCase from "lodash.startcase";
const generateMetadata = (iconNodesArr) => {
return iconNodesArr
@@ -32,14 +32,14 @@ const main = async () => {
// Limiting to ~20 concurrent downloads seems to lead to fewer erros
const limit = pLimit(20);
const iconNodesArr = await api.getNodeChildren().catch((e) => {
const iconNodesArr = await getNodeChildren().catch((e) => {
throw e;
});
if (fs.existsSync(metadataFileName)) {
fs.unlinkSync(metadataFileName);
if (existsSync(metadataFileName)) {
unlinkSync(metadataFileName);
}
fs.writeFileSync(
writeFileSync(
metadataFileName,
JSON.stringify(generateMetadata(iconNodesArr), null, 4),
{
@@ -47,25 +47,24 @@ const main = async () => {
}
);
const iconUrls = await api.getSvgImageUrls(
const iconUrls = await getSvgImageUrls(
iconNodesArr.map((node) => node.node_id).join(",")
);
if (fs.existsSync(iconFolder)) {
if (existsSync(iconFolder)) {
rimraf.sync(iconFolder);
}
fs.mkdirSync(iconFolder);
mkdirSync(iconFolder);
console.log("Total icons: " + iconNodesArr.length);
await Promise.all(
iconUrls.map((url, x) =>
limit(() =>
api
.getIconContent(url)
getIconContent(url)
.then(({ data }) => {
fs.writeFileSync(
path.resolve(
writeFileSync(
resolve(
iconFolder,
`${startCase(iconNodesArr[x].name).replace(/\s/g, "")}.svg`
),
@@ -86,8 +85,8 @@ const main = async () => {
);
if (misses.length > 0) {
fs.writeFileSync(
path.resolve("./", `misses.txt`),
writeFileSync(
resolve("./", `misses.txt`),
JSON.stringify(misses, null, 4),
{
encoding: "utf8",
+8 -8
View File
@@ -1,7 +1,7 @@
const fs = require("fs");
const sharp = require("sharp");
const rimraf = require("rimraf");
const pLimit = require("p-limit");
import { existsSync, mkdirSync, readdirSync } from "fs";
import sharp from "sharp";
import rimraf from "rimraf";
import pLimit from "p-limit";
const convertToPng = async () => {
const inputDir = "./svg/";
@@ -11,14 +11,14 @@ const convertToPng = async () => {
const limit = pLimit(20);
if (fs.existsSync(outDir)) {
if (existsSync(outDir)) {
rimraf.sync(outDir);
}
fs.mkdirSync(outDir);
sizes.forEach((size) => fs.mkdirSync(outDir + size.toString()));
mkdirSync(outDir);
sizes.forEach((size) => mkdirSync(outDir + size.toString()));
await Promise.all(
fs.readdirSync(inputDir).map((file) => {
readdirSync(inputDir).map((file) => {
return limit(() =>
sizes.forEach((size) => {
const density = (100 * size) / 16;
+1 -1
View File
@@ -1,4 +1,4 @@
const zipdir = require("zip-dir");
import zipdir from "zip-dir";
const zipDir = async (dir, name) => {
await zipdir(dir, { saveTo: name }, function (err, buffer) {
+17 -12
View File
@@ -1,8 +1,12 @@
{
"name": "@navikt/ds-icons",
"version": "0.1.7",
"version": "0.2.1",
"private": false,
"description": "NAVs egne ikoner i SVG og React format",
"repository": {
"type": "git",
"url": "git+https://github.com/navikt/nav-frontend-moduler/tree/master/%40navikt/ds-icons"
},
"keywords": [
"NAV",
"designsystem",
@@ -10,29 +14,31 @@
],
"license": "MIT",
"author": "NAV",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"main": "esm/index.js",
"module": "esm/index.js",
"typings": "esm/index.d.ts",
"sideEffects": false,
"type": "module",
"files": [
"/lib",
"/cjs",
"/esm",
"/src",
"/svg"
],
"scripts": {
"cjs-package": "copyfiles -f config/package.json cjs",
"dl-icons": "FILE_KEY=UmEVH3pZ71uJPsSz9ilP3Y node -r dotenv/config figma-api/index.js dotenv_config_path=figma-api/.env",
"create-icons": "svgr --silent --typescript --ref --icon --title-prop --replace-attr-values \"#3E3832=currentColor\" -d src svg",
"convert-icons": "node figma-api/pngConverter.js",
"clean": "rm -rf src && rm -rf lib && rm -rf png && rm -rf NAV-ikonpakke-png.zip && rm -rf NAV-ikonpakke-svg.zip",
"build": "npm run clean && npm run create-icons && tsc && npm run convert-icons && node figma-api/zipIcons.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/navikt/nav-frontend-moduler/tree/master/%40navikt/ds-icons"
"clean": "rm -rf src && rm -rf esm && rm -rf cjs && rm -rf png && rm -rf NAV-ikonpakke-png.zip && rm -rf NAV-ikonpakke-svg.zip",
"build": "npm run clean && npm run create-icons && tsc && tsc -p tsconfig-esm.json && yarn cjs-package && npm run convert-icons && node figma-api/zipIcons.js"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
},
"devDependencies": {
"@svgr/cli": "^5.4.0",
"copyfiles": "^2.4.1",
"dotenv": "^8.2.0",
"lodash.kebabcase": "^4.1.1",
"lodash.startcase": "4.4.0",
@@ -40,6 +46,5 @@
"rimraf": "3.0.2",
"sharp": "0.27.1",
"zip-dir": "^2.0.0"
},
"sideEffects": false
}
}
@@ -0,0 +1,36 @@
import { Meta } from "@storybook/addon-docs/blocks";
<Meta title="ds-icons/Kom i gang" />
# Ta i bruk ikonpakken `@navikt/ds-icons`
Alle ikoner kan bli funnet her https://design.nav.no/resources/icons
## Oppsett
```bash
yarn add @navikt/ds-icons
```
```bash
Import { Expand } from `@navikt/ds-icons`;
<Expand
aria-label="Åpne meny"
role="img"
focusable="false"
/>
```
## Testing
For å støtte testing med eks Jest som ikke tillater ESM moduler, så kan denne configen legges til
```bash
"moduleNameMapper": {
"@navikt/ds-react(.*)": "@navikt/ds-react/cjs$1",
"@navikt/ds-icons(.*)": "@navikt/ds-icons/cjs$1"
}
```
Dette vil remappe Ikonpakken (og komponentpakken) til å bruke CommonJs versjonen for testing
+59 -29
View File
@@ -1,35 +1,65 @@
import React from "react";
// also exported from '@storybook/react' if you can deal with breaking changes in 6.1
// import { Story, Meta } from '@storybook/react/types-6-0';
import { storiesOf } from "@storybook/react";
import * as Icons from "../src";
export default {
title: "ds-icons/Ikoner",
argTypes: {
Icon: {
defaultValue: "System",
control: {
type: "select",
options: Object.entries(Icons).map(([Name, _]) => Name),
},
},
color: { control: "color" },
},
};
const iconsStories = storiesOf("@navikt/icons", module);
if (process.env.STORYBOOK_CHROMATIC === "true") {
const iconsStories = storiesOf("ds-icons/Ikoner", module);
Object.entries(Icons).forEach(([name, Icon]) => {
iconsStories.add(name, () => (
<div>
<Icon title="hello, world" />
<Icon style={{ height: "2em", width: "2em" }} />
<Icon style={{ height: "4em", width: "4em" }} />
<Icon style={{ height: "4em", width: "4em", color: "white" }} />
<Icon style={{ height: "4em", width: "4em", color: "crimson" }} />
<br />
<Icon style={{ height: "4em", width: "4em", backgroundColor: "#aaa" }} />
<Icon style={{ height: "4em", width: "4em", backgroundColor: "#777" }} />
<Icon style={{ height: "4em", width: "4em", backgroundColor: "#333" }} />
<Icon style={{ height: "4em", width: "4em", backgroundColor: "#000" }} />
<br />
<Icon
style={{ height: "4em", width: "4em", transform: "rotate(45deg)" }}
/>
<Icon
style={{ height: "4em", width: "4em", transform: "rotate(90deg)" }}
/>
<Icon
style={{ height: "4em", width: "4em", transform: "rotate(180deg)" }}
/>
</div>
));
});
Object.entries(Icons).forEach(([name, Icon]) => {
iconsStories.add(name, () => (
<div>
<Icon title="hello, world" />
<Icon style={{ height: "2em", width: "2em" }} />
<Icon style={{ height: "4em", width: "4em" }} />
<Icon style={{ height: "4em", width: "4em", color: "white" }} />
<Icon style={{ height: "4em", width: "4em", color: "crimson" }} />
<br />
<Icon
style={{ height: "4em", width: "4em", backgroundColor: "#aaa" }}
/>
<Icon
style={{ height: "4em", width: "4em", backgroundColor: "#777" }}
/>
<Icon
style={{ height: "4em", width: "4em", backgroundColor: "#333" }}
/>
<Icon
style={{ height: "4em", width: "4em", backgroundColor: "#000" }}
/>
<br />
<Icon
style={{ height: "4em", width: "4em", transform: "rotate(45deg)" }}
/>
<Icon
style={{ height: "4em", width: "4em", transform: "rotate(90deg)" }}
/>
<Icon
style={{ height: "4em", width: "4em", transform: "rotate(180deg)" }}
/>
</div>
));
});
}
const Template = ({ Icon, color, size, ...args }) => {
const Iconname = Icons[Icon];
return <Iconname style={{ fontSize: size, color }} {...args} />;
};
export const Ikon = Template.bind({});
Ikon.args = {
size: "24px",
};
+13
View File
@@ -0,0 +1,13 @@
{
"extends": "../../utilities/build/tsconfig-pakker.json",
"compilerOptions": {
"rootDir": "./src",
"esModuleInterop": true,
"module": "ES2020",
"target": "ES2015",
"outDir": "./esm",
"sourceMap": true,
"declaration": true
},
"include": ["./src"]
}
+5 -3
View File
@@ -1,11 +1,13 @@
{
"extends": "../../utilities/build/tsconfig-pakker.json",
"compilerOptions": {
"module": "ES6",
"outDir": "./lib",
"module": "commonjs",
"outDir": "./cjs",
"target": "es2015",
"rootDir": "./src",
"esModuleInterop": true,
"sourceMap": true
"sourceMap": false,
"declaration": false
},
"include": ["./src"]
}
@@ -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;
+6
View File
@@ -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 -2
View File
@@ -1,17 +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 "@navikt/ds-css/accordion/index.css";
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;
}
@@ -2,7 +2,7 @@ import React, { useState } from "react";
import { Accordion } from "../index";
export default {
title: "@navikt/accordion",
title: "ds-react/accordion",
component: Accordion,
};
+14 -1
View File
@@ -6,11 +6,24 @@ import {
InformationFilled,
SuccessFilled,
} from "@navikt/ds-icons";
import "@navikt/ds-css/alert/index.css";
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";
}
@@ -2,7 +2,7 @@ import React from "react";
import { Alert } from "../index";
export default {
title: "@navikt/alert",
title: "ds-react/alert",
component: Alert,
};
+21 -1
View File
@@ -1,10 +1,30 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import "@navikt/ds-css/button/index.css";
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>(
@@ -2,7 +2,7 @@ import React from "react";
import { Button } from "../index";
export default {
title: "@navikt/button",
title: "ds-react/button",
component: Button,
};
+6
View File
@@ -0,0 +1,6 @@
{
"type": "commonjs",
"main": "index.js",
"typings": "../esm/index.d.ts",
"sideEffects": false
}
@@ -1,8 +1,17 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import "@navikt/ds-css/content-container/index.css";
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
@@ -5,7 +5,7 @@ import "./style.css";
import { useEffect } from "react";
export default {
title: "@navikt/content-container",
title: "ds-react/content-container",
component: ContentContainer,
decorators: [
(Story) => {
+20 -1
View File
@@ -1,12 +1,31 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import "@navikt/ds-css/grid/index.css";
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;
}
+10 -2
View File
@@ -1,8 +1,16 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import "@navikt/ds-css/grid/index.css";
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}>
@@ -4,7 +4,7 @@ import { ContentContainer } from "../../index";
import "./styles.css";
export default {
title: "@navikt/grid",
title: "ds-react/grid",
component: { Grid, Cell },
parameters: {
layout: "fullscreen",
+15 -1
View File
@@ -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";
@@ -1,10 +1,15 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import "@navikt/ds-css/internal-header/index.css";
import "@navikt/ds-css/typography/index.css";
export interface InternalHeaderProps extends HTMLAttributes<HTMLElement> {
/**
* Component content
*/
children?: React.ReactNode;
/**
* @ignore
*/
className?: string;
}
const InternalHeader = forwardRef<HTMLElement, InternalHeaderProps>(
@@ -1,10 +1,19 @@
import React, { forwardRef, HTMLAttributes, createElement } from "react";
import cl from "classnames";
import "@navikt/ds-css/internal-header/index.css";
import "@navikt/ds-css/typography/index.css";
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;
}
@@ -1,11 +1,19 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import "@navikt/ds-css/internal-header/index.css";
import "@navikt/ds-css/typography/index.css";
export interface InternalHeaderUserProps
extends HTMLAttributes<HTMLDivElement> {
/**
* @ignore
*/
className?: string;
/**
* user name
*/
name: string;
/**
* user ident
*/
ident: string;
}
@@ -7,7 +7,7 @@ import {
} from "../index";
export default {
title: "@navikt/internal-header",
title: "ds-react/internal-header",
component: InternalHeader,
};
-41
View File
@@ -1,41 +0,0 @@
import "@navikt/ds-css/layout/index.css";
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;
-3
View File
@@ -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: "@navikt/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,108 +0,0 @@
import * as React from "react";
import {
Button,
Cell,
Grid,
Heading,
Link,
Paragraph,
Alert,
} from "../../../../index";
export const Main = () => (
<div>
<Heading className={"navds-story-section"} level={1} size={"xl"}>
Quis autem
</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}>
<Link href={"#"}>Ea voluptate</Link>
</Cell>
<Cell xs={6}>
<Link href={"#"}>Quis autem</Link>
</Cell>
</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.{" "}
</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"}>
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.
</Paragraph>
<table className={"section tabell tabell--stripet"}>
<thead>
<tr>
<th>ID</th>
<th>Fornavn</th>
<th>Etternavn</th>
<th>Rolle</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Jean-Luc</td>
<td>Picard</td>
<td>Kaptein</td>
</tr>
<tr>
<td>2</td>
<td>William</td>
<td>Riker</td>
<td>Kommandør</td>
</tr>
<tr>
<td>3</td>
<td>Geordi</td>
<td>La Forge</td>
<td>Sjefsingeniør</td>
</tr>
</tbody>
</table>
<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.
</Paragraph>
<Paragraph className={"section"}>
Nunc eget consectetur felis, id scelerisque sapien. Ut id feugiat nulla,
ut cursus sem. In viverra felis vitae aliquet finibus.
</Paragraph>
<Button>Søk ...</Button>
</div>
);
+3
View File
@@ -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;
@@ -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>
@@ -0,0 +1,145 @@
import * as React from "react";
import {
Button,
Cell,
Grid,
Heading,
Link,
Paragraph,
} from "../../../../index";
import Snakkeboble from "nav-frontend-snakkeboble";
export const Main = ({ title = true }) => (
<>
<MainOne title={title} />
<MainTwo title={title} />
<MainThree title={title} />
</>
);
export const MainOne = ({ title = true }) => (
<div>
{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.
</Paragraph>
<Grid className={"section"}>
<Cell xs={6}>
<Link href={"#"}>Ea voluptate</Link>
</Cell>
<Cell xs={6}>
<Link href={"#"}>Quis autem</Link>
</Cell>
</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.
</Paragraph>
<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.
</Paragraph>
<table className={"section tabell tabell--stripet"}>
<thead>
<tr>
<th>ID</th>
<th>Fornavn</th>
<th>Etternavn</th>
<th>Rolle</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Jean-Luc</td>
<td>Picard</td>
<td>Kaptein</td>
</tr>
<tr>
<td>2</td>
<td>William</td>
<td>Riker</td>
<td>Kommandør</td>
</tr>
<tr>
<td>3</td>
<td>Geordi</td>
<td>La Forge</td>
<td>Sjefsingeniør</td>
</tr>
</tbody>
</table>
<Paragraph className={"section"}>
Curabitur a purus pretium, condimentum magna ac, pellentesque diam. Nulla
facilisi. Nullam consequat, dui sed bibendum faucibus, metus mauris
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.
</Paragraph>
<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>
<Snakkeboble>Integer aliquam feugiat purus et imperdie</Snakkeboble>
<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>
<Snakkeboble pilHoyre={true}>
Integer aliquam feugiat purus et imperdie
</Snakkeboble>
<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>
);
@@ -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>
);
+8 -1
View File
@@ -1,9 +1,16 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import "@navikt/ds-css/link/index.css";
export interface LinkProps
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
/**
* Component content
*/
children: React.ReactNode;
/**
* @ignore
*/
className?: string;
/**
* Link anchor should direct to
*/
@@ -2,7 +2,7 @@ import React from "react";
import { Link } from "../index";
import { Add } from "@navikt/ds-icons";
export default {
title: "@navikt/link",
title: "ds-react/link",
component: Link,
};
+10 -9
View File
@@ -3,12 +3,8 @@ import cl from "classnames";
import ReactModal from "react-modal";
import mergeRefs from "react-merge-refs";
import { Close } from "@navikt/ds-icons";
import "@navikt/ds-css/modal/index.css";
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
@@ -28,7 +24,7 @@ export interface ModalProps {
*/
shouldCloseOnOverlayClick?: boolean;
/**
* User defined classname for wrapper element
* @ignore
*/
className?: string;
/**
@@ -37,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,
@@ -90,8 +93,6 @@ const Modal = forwardRef<ReactModal, ModalProps>(
}
);
export const setAppElement = (element) => {
ReactModal.setAppElement(element);
};
Modal.setAppElement = (element) => ReactModal.setAppElement(element);
export default Modal;
@@ -1,13 +1,12 @@
import React, { useState } from "react";
import { Modal } from "../index";
import ReactModal from "react-modal";
export default {
title: "@navikt/modal",
title: "ds-react/modal",
component: Modal,
};
ReactModal.setAppElement("#root");
Modal.setAppElement("#root");
export const All = () => {
const [open, setOpen] = useState(true);
+18 -12
View File
@@ -1,34 +1,39 @@
{
"name": "@navikt/ds-react",
"version": "0.1.2",
"version": "0.2.7",
"private": false,
"description": "NAV designsystem react components",
"author": "NAV Designsystem team",
"license": "MIT",
"keywords": [
"react",
"typescript",
"javascript"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/navikt/nav-frontend-moduler/tree/master/%40navikt/ds-react"
},
"main": "esm/index.js",
"module": "esm/index.js",
"typings": "esm/index.d.ts",
"sideEffects": false,
"type": "module",
"publishConfig": {
"access": "public"
},
"files": [
"/lib"
"/cjs",
"/esm"
],
"repository": {
"type": "git",
"url": "git+https://github.com/navikt/nav-frontend-moduler.git"
},
"scripts": {
"build": "tsc -p tsconfig.json",
"cjs-package": "copyfiles -f config/package.json cjs",
"clean": "rm -rf cjs esm",
"build": "yarn run clean && tsc && tsc -p tsconfig-esm.json && yarn cjs-package",
"watch": "tsc --watch -p tsconfig.json"
},
"dependencies": {
"@navikt/ds-css": "^0.1.17",
"@navikt/ds-icons": "^0.1.7",
"@navikt/ds-icons": "^0.2.1",
"@popperjs/core": "^2.5.4",
"classnames": "^2.2.6",
"react-collapse": "^5.1.0",
@@ -38,6 +43,7 @@
"uuid": "^8.3.2"
},
"devDependencies": {
"copyfiles": "^2.4.1",
"react-router-dom": "^5.2.0"
},
"peerDependencies": {
+17 -9
View File
@@ -9,7 +9,6 @@ import { usePopper } from "react-popper";
import { Placement } from "@popperjs/core";
import mergeRefs from "react-merge-refs";
import cl from "classnames";
import "@navikt/ds-css/popover/index.css";
export interface PopoverProps extends HTMLAttributes<HTMLDivElement> {
/**
@@ -28,12 +27,15 @@ 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";
}
const useEventLister = (event: string, callback) =>
@@ -53,7 +55,6 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(
children,
placement = "right",
className,
size = "medium",
...rest
},
ref
@@ -67,9 +68,16 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(
useEventLister(
"click",
useCallback(
(e: MouseEvent) =>
!popoverRef.current?.contains(e.target as Node) && close(),
[close]
(e: MouseEvent) => {
if (
![anchorEl, popoverRef.current].some((element) =>
element?.contains(e.target as Node)
)
) {
close();
}
},
[anchorEl, close]
)
);
@@ -124,8 +132,8 @@ const Popover = forwardRef<HTMLDivElement, PopoverProps>(
return (
<div
ref={mergedRef}
className={cl("navds-popover", `navds-popover--${size}`, className, {
"popover--hidden": !open || !anchorEl,
className={cl("navds-popover", className, {
"navds-popover--hidden": !open || !anchorEl,
})}
aria-live="polite"
aria-hidden={!open || !anchorEl}
@@ -3,7 +3,7 @@ import { Popover } from "../index";
import { Meta } from "@storybook/react/types-6-0";
import { placements } from "@popperjs/core";
export default {
title: "@navikt/popover",
title: "ds-react/popover",
component: Popover,
parameters: {
chromatic: { disable: true },
@@ -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>
);
};
+9 -2
View File
@@ -1,9 +1,15 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import "@navikt/ds-css/tag/index.css";
export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
/**
* Component content
*/
children: React.ReactNode;
/**
* @ignore
*/
className?: string;
/**
* Changes background-color and border-color
*/
@@ -11,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>
+1 -1
View File
@@ -2,7 +2,7 @@ import React from "react";
import { Tag } from "../index";
import { Meta } from "@storybook/react/types-6-0";
export default {
title: "@navikt/tag",
title: "ds-react/tag",
component: Tag,
} as Meta;
+13
View File
@@ -0,0 +1,13 @@
{
"extends": "../../utilities/build/tsconfig-pakker.json",
"compilerOptions": {
"outDir": "./esm",
"rootDir": "./",
"esModuleInterop": true,
"module": "ES2020",
"target": "ES2015",
"sourceMap": true,
"declaration": true
},
"include": ["./*"]
}
+5 -2
View File
@@ -1,10 +1,13 @@
{
"extends": "../../utilities/build/tsconfig-pakker.json",
"compilerOptions": {
"outDir": "./lib",
"outDir": "./cjs",
"rootDir": "./",
"esModuleInterop": true,
"sourceMap": true
"module": "commonjs",
"target": "es2015",
"sourceMap": false,
"declaration": false
},
"include": ["./*"]
}
-2
View File
@@ -1,5 +1,3 @@
import "@navikt/ds-css/typography/index.css";
export { default as Heading } from "./Heading";
export * from "./Heading";
export { default as Text } from "./Text";
@@ -2,7 +2,7 @@ import React from "react";
import { Heading, Text, Paragraph, Lead } from "../index";
export default {
title: "@navikt/typography",
title: "ds-react/typography",
component: Heading,
};
+1 -1
View File
@@ -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",
+10 -2
View File
@@ -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" },
Loaded 100 of 219 files, more files were not shown because too many files have changed in this diff. Show more