mirror of
https://github.com/navikt/aksel.git
synced 2026-10-15 02:02:02 +00:00
Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a170ca8998 | ||
|
|
347427c6e6 | ||
|
|
35aab3b672 | ||
|
|
5f4c0a7a2d | ||
|
|
fd120b65e0 | ||
|
|
3ae1be923e | ||
|
|
dab2c3f2c2 | ||
|
|
c0f1b8401e | ||
|
|
8ba8936fdd | ||
|
|
15c5845465 | ||
|
|
f6bc0c612f | ||
|
|
b796e306d5 | ||
|
|
0e9680dab9 | ||
|
|
6d2858c6e1 | ||
|
|
9294410ed8 | ||
|
|
e3653580e6 | ||
|
|
c9ab2e1516 | ||
|
|
bb1876df43 | ||
|
|
d98bff30f6 | ||
|
|
7f53011d91 | ||
|
|
4a451fe84a | ||
|
|
01adced0e7 | ||
|
|
e2bae872cf | ||
|
|
aff8f00ade | ||
|
|
ad28279bd3 |
No files matched your search
@@ -55,15 +55,17 @@ jobs:
|
||||
publish-npm:
|
||||
needs: test-build
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTOMATION }}
|
||||
if: github.event_name == 'push' && contains(github.event.head_commit.message, '[fix]') || contains(github.event.head_commit.message, '[feature]') || contains(github.event.head_commit.message, '[breaking]')
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: "0"
|
||||
token: ${{secrets.GIT_REPO}}
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
registry-url: http://registry.npmjs.org
|
||||
registry-url: https://registry.npmjs.org
|
||||
node-version: 14
|
||||
- name: Node-modules cache
|
||||
uses: actions/cache@v2
|
||||
@@ -93,17 +95,9 @@ jobs:
|
||||
- name: Update changed packages with MAJOR
|
||||
if: "contains(github.event.head_commit.message, '[breaking]')"
|
||||
run: yarn lerna version major --include-merged-tags --yes
|
||||
|
||||
- name: Create a .npmrc file for NPM
|
||||
run: |
|
||||
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
|
||||
npm whoami
|
||||
env:
|
||||
NPM_TOKEN: ${{secrets.NPM_AUTOMATION}}
|
||||
- name: Publish to NPM registry
|
||||
run: |
|
||||
yarn lerna publish from-package --yes
|
||||
rm .npmrc
|
||||
run: yarn lerna publish --no-verify-access from-package --yes
|
||||
|
||||
- name: Create a .npmrc file for the github package repository
|
||||
uses: FerLuisxd/create-npmrc@3
|
||||
with:
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
@import "panel.css";
|
||||
@import "link-panel.css";
|
||||
@import "speech-bubble.css";
|
||||
@import "table.css";
|
||||
|
||||
/* Navno spesific packages */
|
||||
@import "page-header.css";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "0.9.1",
|
||||
"version": "0.9.2",
|
||||
"private": false,
|
||||
"description": "Css for NAV Designsystem components",
|
||||
"author": "NAV Designsystem team",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
.navds-table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.navds-table__header {
|
||||
display: table-header-group;
|
||||
}
|
||||
|
||||
.navds-table__body {
|
||||
display: table-row-group;
|
||||
}
|
||||
|
||||
.navds-table__row {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.navds-table__cell {
|
||||
display: table-cell;
|
||||
padding: var(--navds-spacing-4);
|
||||
text-align: left;
|
||||
border-bottom: var(--navds-border-default);
|
||||
}
|
||||
|
||||
.navds-table--small .navds-table__cell {
|
||||
padding: var(--navds-spacing-2);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "0.10.2",
|
||||
"version": "0.10.3",
|
||||
"private": false,
|
||||
"description": "NAV designsystem react components",
|
||||
"author": "NAV Designsystem team",
|
||||
|
||||
@@ -15,6 +15,7 @@ export * from "./panel";
|
||||
export * from "./popover";
|
||||
export * from "./speech-bubble";
|
||||
export * from "./tag";
|
||||
export * from "./table";
|
||||
export * from "./typography";
|
||||
export * from "./util";
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
interface BodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {}
|
||||
|
||||
export interface BodyType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
BodyProps & React.RefAttributes<HTMLTableSectionElement>
|
||||
> {}
|
||||
|
||||
const Body: BodyType = forwardRef(({ className, ...rest }, ref) => (
|
||||
<tbody {...rest} ref={ref} className={cl("navds-table__body", className)} />
|
||||
));
|
||||
|
||||
export default Body;
|
||||
@@ -0,0 +1,15 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
interface DataCellProps extends React.HTMLAttributes<HTMLTableCellElement> {}
|
||||
|
||||
export interface DataCellType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
DataCellProps & React.RefAttributes<HTMLTableCellElement>
|
||||
> {}
|
||||
|
||||
const DataCell: DataCellType = forwardRef(({ className, ...rest }, ref) => (
|
||||
<td {...rest} ref={ref} className={cl("navds-table__cell", className)} />
|
||||
));
|
||||
|
||||
export default DataCell;
|
||||
@@ -0,0 +1,15 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
interface HeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {}
|
||||
|
||||
export interface HeaderType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
HeaderProps & React.RefAttributes<HTMLTableSectionElement>
|
||||
> {}
|
||||
|
||||
const Header: HeaderType = forwardRef(({ className, ...rest }, ref) => (
|
||||
<thead {...rest} ref={ref} className={cl("navds-table__header", className)} />
|
||||
));
|
||||
|
||||
export default Header;
|
||||
@@ -0,0 +1,15 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
interface HeaderCellProps extends React.HTMLAttributes<HTMLTableCellElement> {}
|
||||
|
||||
export interface HeaderCellType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
HeaderCellProps & React.RefAttributes<HTMLTableCellElement>
|
||||
> {}
|
||||
|
||||
const HeaderCell: HeaderCellType = forwardRef(({ className, ...rest }, ref) => (
|
||||
<th {...rest} ref={ref} className={cl("navds-table__cell", className)} />
|
||||
));
|
||||
|
||||
export default HeaderCell;
|
||||
@@ -0,0 +1,15 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
interface RowProps extends React.HTMLAttributes<HTMLTableRowElement> {}
|
||||
|
||||
export interface RowType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
RowProps & React.RefAttributes<HTMLTableRowElement>
|
||||
> {}
|
||||
|
||||
const Row: RowType = forwardRef(({ className, ...rest }, ref) => (
|
||||
<tr {...rest} ref={ref} className={cl("navds-table__row", className)} />
|
||||
));
|
||||
|
||||
export default Row;
|
||||
@@ -0,0 +1,42 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import Header, { HeaderType } from "./Header";
|
||||
import Body, { BodyType } from "./Body";
|
||||
import Row, { RowType } from "./Row";
|
||||
import HeaderCell, { HeaderCellType } from "./HeaderCell";
|
||||
import DataCell, { DataCellType } from "./DataCell";
|
||||
|
||||
export interface TableProps extends React.HTMLAttributes<HTMLTableElement> {
|
||||
/**
|
||||
* Changes padding
|
||||
* @default "medium"
|
||||
*/
|
||||
size?: "medium" | "small";
|
||||
}
|
||||
|
||||
export interface TableType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
TableProps & React.RefAttributes<HTMLTableElement>
|
||||
> {
|
||||
Header: HeaderType;
|
||||
Body: BodyType;
|
||||
Row: RowType;
|
||||
DataCell: DataCellType;
|
||||
HeaderCell: HeaderCellType;
|
||||
}
|
||||
|
||||
const Table = forwardRef(({ className, size = "medium", ...rest }, ref) => (
|
||||
<table
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navds-table", `navds-table--${size}`, className)}
|
||||
/>
|
||||
)) as TableType;
|
||||
|
||||
Table.Header = Header;
|
||||
Table.Body = Body;
|
||||
Table.Row = Row;
|
||||
Table.HeaderCell = HeaderCell;
|
||||
Table.DataCell = DataCell;
|
||||
|
||||
export default Table;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Table } from "./Table";
|
||||
export * from "./Table";
|
||||
@@ -0,0 +1,139 @@
|
||||
import React from "react";
|
||||
import { Table } from "../index";
|
||||
import { Alert, Link } from "@navikt/ds-react";
|
||||
|
||||
export default {
|
||||
title: "ds-react/table",
|
||||
component: Table,
|
||||
};
|
||||
|
||||
export const All = () => {
|
||||
return (
|
||||
<>
|
||||
<h1>Table</h1>
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>ID</Table.HeaderCell>
|
||||
<Table.HeaderCell>Fornavn</Table.HeaderCell>
|
||||
<Table.HeaderCell>Etternavn</Table.HeaderCell>
|
||||
<Table.HeaderCell>Rolle</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>1</Table.HeaderCell>
|
||||
<Table.DataCell>Jean-Luc</Table.DataCell>
|
||||
<Table.DataCell>Picard</Table.DataCell>
|
||||
<Table.DataCell>Kaptein</Table.DataCell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>2</Table.HeaderCell>
|
||||
<Table.DataCell>William</Table.DataCell>
|
||||
<Table.DataCell>Riker</Table.DataCell>
|
||||
<Table.DataCell>Kommandør</Table.DataCell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>3</Table.HeaderCell>
|
||||
<Table.DataCell>Geordi</Table.DataCell>
|
||||
<Table.DataCell>La Forge</Table.DataCell>
|
||||
<Table.DataCell>Sjefsingeniør</Table.DataCell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
<h2>Small Table</h2>
|
||||
<Table size="small">
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>ID</Table.HeaderCell>
|
||||
<Table.HeaderCell>Fornavn</Table.HeaderCell>
|
||||
<Table.HeaderCell>Etternavn</Table.HeaderCell>
|
||||
<Table.HeaderCell>Rolle</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>1</Table.HeaderCell>
|
||||
<Table.DataCell>Jean-Luc</Table.DataCell>
|
||||
<Table.DataCell>Picard</Table.DataCell>
|
||||
<Table.DataCell>Kaptein</Table.DataCell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>2</Table.HeaderCell>
|
||||
<Table.DataCell>William</Table.DataCell>
|
||||
<Table.DataCell>Riker</Table.DataCell>
|
||||
<Table.DataCell>Kommandør</Table.DataCell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>3</Table.HeaderCell>
|
||||
<Table.DataCell>Geordi</Table.DataCell>
|
||||
<Table.DataCell>La Forge</Table.DataCell>
|
||||
<Table.DataCell>Sjefsingeniør</Table.DataCell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
<h2>Table with divs</h2>
|
||||
<Alert variant="warning">
|
||||
Obs! Hvis man skal bygge tabeller uten å bruke vanlig {"<tabell> "}
|
||||
-markup er det svært viktig at man supplerer elementene med{" "}
|
||||
<Link href="https://www.w3.org/TR/wai-aria-practices-1.1/examples/table/table.html">
|
||||
riktige
|
||||
</Link>{" "}
|
||||
role-attributter og display-stiler for å bevare den semantiske verdien i
|
||||
tabellene. Vi anbefaler fortsatt å ikke ta i bruk denne metoden hvis
|
||||
mulig, da nettleseren ikke kan tolke tabellen like bra uten riktig
|
||||
markup.
|
||||
</Alert>
|
||||
<div className="navds-table navds-table--zebra" role="table">
|
||||
<div className="navds-table__header" role="rowgroup">
|
||||
<div className="navds-table__row" role="row">
|
||||
<div className="navds-table__cell" role="columnheader">
|
||||
ID
|
||||
</div>
|
||||
<div className="navds-table__cell" role="columnheader">
|
||||
Fornavn
|
||||
</div>
|
||||
<div className="navds-table__cell" role="columnheader">
|
||||
Etternavn
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="navds-table__body" role="rowgroup">
|
||||
<div className="navds-table__row" role="row">
|
||||
<div className="navds-table__cell" role="cell">
|
||||
Jean-Luc
|
||||
</div>
|
||||
<div className="navds-table__cell" role="cell">
|
||||
Picard
|
||||
</div>
|
||||
<div className="navds-table__cell" role="cell">
|
||||
Kaptein
|
||||
</div>
|
||||
</div>
|
||||
<div className="navds-table__row" role="row">
|
||||
<div className="navds-table__cell" role="cell">
|
||||
William
|
||||
</div>
|
||||
<div className="navds-table__cell" role="cell">
|
||||
Riker
|
||||
</div>
|
||||
<div className="navds-table__cell" role="cell">
|
||||
Kommandør
|
||||
</div>
|
||||
</div>
|
||||
<div className="navds-table__row" role="row">
|
||||
<div className="navds-table__cell" role="cell">
|
||||
Geordi
|
||||
</div>
|
||||
<div className="navds-table__cell" role="cell">
|
||||
La Forge
|
||||
</div>
|
||||
<div className="navds-table__cell" role="cell">
|
||||
Sjefsingeniør
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
.navdsi-divider {
|
||||
margin: var(--navds-spacing-3) 0;
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--navds-color-gray-40);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
.navdsi-dropdown__menu {
|
||||
overflow: hidden;
|
||||
padding: var(--navds-spacing-4) 0;
|
||||
color: var(--navds-color-darkgray);
|
||||
width: 27ch;
|
||||
max-height: 616px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.navdsi-dropdown__menu > :not(.navdsi-divider):not(.navdsi-dropdown__list) {
|
||||
margin: 0 var(--navds-spacing-4) var(--navds-spacing-3);
|
||||
}
|
||||
|
||||
.navdsi-dropdown__list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.navdsi-dropdown__list-item {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.navdsi-dropdown__list-heading {
|
||||
margin: 0 var(--navds-spacing-4) var(--navds-spacing-4);
|
||||
}
|
||||
|
||||
.navdsi-dropdown__item {
|
||||
border: none;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
background: transparent;
|
||||
color: var(--navds-color-text-link);
|
||||
font: inherit;
|
||||
text-decoration: none;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--navds-spacing-2);
|
||||
padding: var(--navds-spacing-1) var(--navds-spacing-4);
|
||||
}
|
||||
|
||||
.navdsi-dropdown__item:hover {
|
||||
background-color: var(--navds-color-blue-10);
|
||||
}
|
||||
|
||||
.navdsi-dropdown__item:active {
|
||||
background-color: var(--navds-color-blue-20);
|
||||
}
|
||||
|
||||
.navdsi-dropdown__item:focus {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 2px var(--navds-color-blue-80);
|
||||
}
|
||||
@@ -2,63 +2,81 @@
|
||||
--navdsi-header-color-background: var(--navds-color-darkgray);
|
||||
--navdsi-header-color-border: var(--navds-color-gray-40);
|
||||
--navdsi-header-color-text: var(--navds-color-text-inverse);
|
||||
--navdsi-header-focus: inset 0 0 0 2px var(--navds-color-blue-10);
|
||||
}
|
||||
|
||||
/**************************
|
||||
* .navdsi-header *
|
||||
**************************/
|
||||
|
||||
.navdsi-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-self: stretch;
|
||||
background: var(--navdsi-header-color-background);
|
||||
color: var(--navdsi-header-color-text);
|
||||
max-width: 100vw;
|
||||
min-height: 50px;
|
||||
min-height: var(--navds-spacing-12);
|
||||
}
|
||||
|
||||
.navdsi-header__column {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/**************************
|
||||
* .navdsi-header__title *
|
||||
**************************/
|
||||
|
||||
.navdsi-header__title {
|
||||
padding: 0 var(--navds-spacing-6);
|
||||
border: none;
|
||||
overflow: visible;
|
||||
background: transparent;
|
||||
font: inherit;
|
||||
line-height: normal;
|
||||
text-align: left;
|
||||
padding: 0 var(--navds-spacing-5) 0 var(--navds-spacing-6);
|
||||
border-right: 1px solid var(--navdsi-header-color-border);
|
||||
display: flex;
|
||||
align-self: stretch;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
margin: 0;
|
||||
color: var(--navdsi-header-color-text);
|
||||
font-size: var(--navds-font-size-l);
|
||||
font-weight: var(--navds-font-weight-bold);
|
||||
line-height: var(--navds-font-line-height-l);
|
||||
}
|
||||
|
||||
.navdsi-header__title:focus {
|
||||
box-shadow: inset var(--navds-shadow-focus-on-dark);
|
||||
outline: none;
|
||||
button.navdsi-header__title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/**************************
|
||||
* .navdsi-header__user *
|
||||
**************************/
|
||||
|
||||
.navdsi-header__user {
|
||||
color: var(--navdsi-header-color-text);
|
||||
padding: 0 var(--navds-spacing-6);
|
||||
margin-left: auto;
|
||||
padding: 0 var(--navds-spacing-5);
|
||||
border-left: 1px solid var(--navdsi-header-color-border);
|
||||
display: flex;
|
||||
align-self: stretch;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.navdsi-header__name.navds-body-short {
|
||||
margin-right: var(--navds-spacing-4);
|
||||
.navdsi-header__button {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0 var(--navds-spacing-3);
|
||||
overflow: visible;
|
||||
background: transparent;
|
||||
font: inherit;
|
||||
line-height: normal;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-self: center;
|
||||
gap: var(--navds-spacing-2);
|
||||
border-left: 1px solid var(--navdsi-header-color-border);
|
||||
color: var(--navdsi-header-color-text);
|
||||
}
|
||||
|
||||
a.navdsi-header__title:hover,
|
||||
button.navdsi-header__title:hover,
|
||||
.navdsi-header__button:hover {
|
||||
background-color: var(--navds-color-gray-80);
|
||||
}
|
||||
|
||||
.navdsi-header__title:focus,
|
||||
.navdsi-header__button:focus {
|
||||
box-shadow: var(--navdsi-header-focus);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a.navdsi-header__title:active,
|
||||
button.navdsi-header__title:active,
|
||||
.navdsi-header__button:active {
|
||||
background-color: var(--navds-color-gray-60);
|
||||
}
|
||||
|
||||
.navdsi-header__user-button {
|
||||
padding-left: var(--navds-spacing-5);
|
||||
gap: var(--navds-spacing-4);
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
@import "divider.css";
|
||||
@import "dropdown.css";
|
||||
@import "header.css";
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css-internal",
|
||||
"version": "0.2.0",
|
||||
"version": "0.5.0",
|
||||
"private": false,
|
||||
"description": "Css for NAV internal Designsystem components",
|
||||
"author": "NAV Designsystem team",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react-internal",
|
||||
"version": "0.2.1",
|
||||
"version": "0.5.1",
|
||||
"private": false,
|
||||
"description": "NAV internal designsystem react components",
|
||||
"author": "NAV Designsystem team",
|
||||
@@ -33,7 +33,8 @@
|
||||
"watch": "tsc --watch -p tsconfig-esm.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-react": "^0.10.2",
|
||||
"@navikt/ds-icons": "^0.5.4",
|
||||
"@navikt/ds-react": "^0.10.3",
|
||||
"classnames": "^2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface DividerProps extends React.HTMLAttributes<HTMLHRElement> {}
|
||||
|
||||
const Divider = forwardRef<HTMLHRElement, DividerProps>(
|
||||
({ className, ...rest }, ref) => (
|
||||
<hr {...rest} ref={ref} className={cl("navdsi-divider", className)} />
|
||||
)
|
||||
);
|
||||
|
||||
export default Divider;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Divider } from "./Divider";
|
||||
export * from "./Divider";
|
||||
@@ -0,0 +1,40 @@
|
||||
import React, { createContext, useState } from "react";
|
||||
import Toggle, { ToggleType } from "./Toggle";
|
||||
import Menu, { MenuType } from "./Menu";
|
||||
|
||||
export interface DropdownType extends React.FC {
|
||||
Toggle: ToggleType;
|
||||
Menu: MenuType;
|
||||
}
|
||||
|
||||
export interface DropdownContextType {
|
||||
readonly isOpen: boolean;
|
||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
readonly anchorEl: Element | null;
|
||||
setAnchorEl: React.Dispatch<React.SetStateAction<Element | null>>;
|
||||
}
|
||||
|
||||
export const DropdownContext = createContext<DropdownContextType | null>(null);
|
||||
|
||||
const Dropdown = (({ children }) => {
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
const [anchorEl, setAnchorEl] = useState<Element | null>(null);
|
||||
|
||||
return (
|
||||
<DropdownContext.Provider
|
||||
value={{
|
||||
isOpen,
|
||||
setIsOpen,
|
||||
anchorEl,
|
||||
setAnchorEl,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DropdownContext.Provider>
|
||||
);
|
||||
}) as DropdownType;
|
||||
|
||||
Dropdown.Toggle = Toggle;
|
||||
Dropdown.Menu = Menu;
|
||||
|
||||
export default Dropdown;
|
||||
@@ -0,0 +1,28 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface HeadingProps extends React.HTMLAttributes<HTMLDetailsElement> {
|
||||
/**
|
||||
* Heading
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type HeadingType = React.ForwardRefExoticComponent<
|
||||
HeadingProps & React.RefAttributes<HTMLElement>
|
||||
>;
|
||||
|
||||
const Heading: HeadingType = forwardRef(({ className, ...rest }, ref) => (
|
||||
<dt
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navdsi-dropdown__list-heading",
|
||||
"navds-heading",
|
||||
"navds-heading--xsmall",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
));
|
||||
|
||||
export default Heading;
|
||||
@@ -0,0 +1,31 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
|
||||
export interface ItemProps extends React.ButtonHTMLAttributes<HTMLElement> {
|
||||
/**
|
||||
* Menu item content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ItemType = OverridableComponent<ItemProps, HTMLButtonElement>;
|
||||
|
||||
const Item: ItemType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => (
|
||||
<dd className="navdsi-dropdown__list-item">
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navdsi-dropdown__item",
|
||||
"navds-body-short",
|
||||
"navds-body-short--small",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
</dd>
|
||||
)
|
||||
);
|
||||
|
||||
export default Item;
|
||||
@@ -0,0 +1,31 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import Heading, { HeadingType } from "./Heading";
|
||||
import Item, { ItemType } from "./Item";
|
||||
|
||||
export interface GroupedListProps
|
||||
extends React.HTMLAttributes<HTMLDListElement> {
|
||||
/**
|
||||
* Menu list content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface GroupedListType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
GroupedListProps & React.RefAttributes<HTMLDListElement>
|
||||
> {
|
||||
Heading: HeadingType;
|
||||
Item: ItemType;
|
||||
}
|
||||
|
||||
const DescriptionList = forwardRef(({ className, children, ...rest }, ref) => (
|
||||
<dl {...rest} ref={ref} className={cl("navdsi-dropdown__list", className)}>
|
||||
{children}
|
||||
</dl>
|
||||
)) as GroupedListType;
|
||||
|
||||
DescriptionList.Heading = Heading;
|
||||
DescriptionList.Item = Item;
|
||||
|
||||
export default DescriptionList;
|
||||
@@ -0,0 +1,32 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
|
||||
export interface ItemProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Menu item content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ItemType = OverridableComponent<ItemProps, HTMLButtonElement>;
|
||||
|
||||
const Item: ItemType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => (
|
||||
<li className="navdsi-dropdown__list-item">
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navdsi-dropdown__item",
|
||||
"navds-body-short",
|
||||
"navds-body-short--small",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
);
|
||||
|
||||
export default Item;
|
||||
@@ -0,0 +1,27 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import Item, { ItemType } from "./Item";
|
||||
|
||||
export interface ListProps extends React.HTMLAttributes<HTMLUListElement> {
|
||||
/**
|
||||
* Menu list content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface ListType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
ListProps & React.RefAttributes<HTMLUListElement>
|
||||
> {
|
||||
Item: ItemType;
|
||||
}
|
||||
|
||||
const List = forwardRef(({ className, children, ...rest }, ref) => (
|
||||
<ul {...rest} ref={ref} className={cl("navdsi-dropdown__list", className)}>
|
||||
{children}
|
||||
</ul>
|
||||
)) as ListType;
|
||||
|
||||
List.Item = Item;
|
||||
|
||||
export default List;
|
||||
@@ -0,0 +1,53 @@
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import cl from "classnames";
|
||||
import { Popover } from "@navikt/ds-react";
|
||||
import List, { ListType } from "./List";
|
||||
import GroupedList, { GroupedListType } from "./GroupedList";
|
||||
import { DropdownContext } from "../Dropdown";
|
||||
|
||||
interface MenuProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* Dropdown content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface MenuType<Props = MenuProps>
|
||||
extends React.ForwardRefExoticComponent<
|
||||
Props & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
List: ListType;
|
||||
GroupedList: GroupedListType;
|
||||
}
|
||||
|
||||
const Menu = forwardRef<HTMLDivElement, MenuProps>(
|
||||
({ className, ...rest }, ref) => {
|
||||
const context = useContext(DropdownContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn("Dropdown.Menu has to be wrapped in <Dropdown />");
|
||||
return null;
|
||||
}
|
||||
|
||||
const { isOpen, anchorEl, setIsOpen } = context;
|
||||
|
||||
return (
|
||||
<Popover
|
||||
{...rest}
|
||||
ref={ref}
|
||||
placement="bottom-end"
|
||||
arrow={false}
|
||||
className={cl("navdsi-dropdown__menu", className)}
|
||||
offset={-4}
|
||||
anchorEl={anchorEl}
|
||||
open={isOpen}
|
||||
onClose={() => setIsOpen(false)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
) as MenuType;
|
||||
|
||||
Menu.List = List;
|
||||
Menu.GroupedList = GroupedList;
|
||||
|
||||
export default Menu;
|
||||
@@ -0,0 +1,42 @@
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import cl from "classnames";
|
||||
import { DropdownContext } from ".";
|
||||
|
||||
export interface ToggleProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Button content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ToggleType = React.ForwardRefExoticComponent<
|
||||
ToggleProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
|
||||
const Toggle: ToggleType = forwardRef(({ className, ...rest }, ref) => {
|
||||
const context = useContext(DropdownContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn("Dropdown.Toggle has to be wrapped in <Dropdown />");
|
||||
return null;
|
||||
}
|
||||
|
||||
const { setAnchorEl, setIsOpen, isOpen } = context;
|
||||
|
||||
return (
|
||||
<button
|
||||
{...rest}
|
||||
ref={ref}
|
||||
onClick={(e) => {
|
||||
setAnchorEl(e.currentTarget);
|
||||
setIsOpen((isOpen) => !isOpen);
|
||||
}}
|
||||
aria-expanded={isOpen}
|
||||
aria-haspopup="menu"
|
||||
className={cl("navdsi-dropdown__toggle", className)}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export default Toggle;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Dropdown } from "./Dropdown";
|
||||
export * from "./Dropdown";
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from "react";
|
||||
import { Heading } from "@navikt/ds-react";
|
||||
import { Dropdown } from "..";
|
||||
import { Divider } from "../..";
|
||||
|
||||
export default {
|
||||
title: "ds-react-internal/dropdown",
|
||||
component: Dropdown,
|
||||
};
|
||||
|
||||
export const All = () => (
|
||||
<>
|
||||
<Heading level="1" size="xlarge">
|
||||
Dropdown menu
|
||||
</Heading>
|
||||
<Dropdown>
|
||||
<Dropdown.Toggle>Toggle</Dropdown.Toggle>
|
||||
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu.GroupedList>
|
||||
<Dropdown.Menu.GroupedList.Heading>
|
||||
Systemer og oppslagsverk
|
||||
</Dropdown.Menu.GroupedList.Heading>
|
||||
<Dropdown.Menu.GroupedList.Item>Gosys</Dropdown.Menu.GroupedList.Item>
|
||||
</Dropdown.Menu.GroupedList>
|
||||
<Divider />
|
||||
<Dropdown.Menu.List>
|
||||
<Dropdown.Menu.List.Item>Gosys</Dropdown.Menu.List.Item>
|
||||
<Dropdown.Menu.List.Item>Psys</Dropdown.Menu.List.Item>
|
||||
</Dropdown.Menu.List>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</>
|
||||
);
|
||||
@@ -1,32 +1,34 @@
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import HeaderTitle, { HeaderTitleType } from "./HeaderTitle";
|
||||
import HeaderUser, { HeaderUserType } from "./HeaderUser";
|
||||
import HeaderButton, { HeaderButtonType } from "./HeaderButton";
|
||||
import HeaderUserButton, { HeaderUserButtonType } from "./HeaderUserButton";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface HeaderProps extends HTMLAttributes<HTMLElement> {
|
||||
/**
|
||||
* Component content
|
||||
* Header content
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
interface HeaderComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
HeaderProps & React.RefAttributes<HTMLDivElement>
|
||||
HeaderProps & React.RefAttributes<HTMLElement>
|
||||
> {
|
||||
Title: HeaderTitleType;
|
||||
User: HeaderUserType;
|
||||
Button: HeaderButtonType;
|
||||
UserButton: HeaderUserButtonType;
|
||||
}
|
||||
|
||||
const Header = forwardRef<HTMLElement, HeaderProps>(
|
||||
({ children, className, ...rest }, ref) => (
|
||||
<header ref={ref} className={cl("navdsi-header", className)} {...rest}>
|
||||
{children}
|
||||
</header>
|
||||
)
|
||||
) as HeaderComponent;
|
||||
const Header = forwardRef(({ className, ...rest }, ref) => (
|
||||
<header {...rest} ref={ref} className={cl("navdsi-header", className)} />
|
||||
)) as HeaderComponent;
|
||||
|
||||
Header.Title = HeaderTitle;
|
||||
Header.User = HeaderUser;
|
||||
Header.Button = HeaderButton;
|
||||
Header.UserButton = HeaderUserButton;
|
||||
|
||||
export default Header;
|
||||
@@ -0,0 +1,28 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
|
||||
export interface HeaderButtonProps
|
||||
extends React.AnchorHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Application Button
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type HeaderButtonType = OverridableComponent<
|
||||
HeaderButtonProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
|
||||
const HeaderButton: HeaderButtonType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navdsi-header__button", className)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
||||
export default HeaderButton;
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { Heading, OverridableComponent } from "@navikt/ds-react";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
|
||||
export interface HeaderTitleProps
|
||||
extends React.HTMLAttributes<HTMLHeadingElement> {
|
||||
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
||||
/**
|
||||
* Application title
|
||||
*/
|
||||
@@ -16,16 +16,20 @@ export type HeaderTitleType = OverridableComponent<
|
||||
>;
|
||||
|
||||
const HeaderTitle: HeaderTitleType = forwardRef(
|
||||
({ as = "h1", children, className, ...rest }, ref) => (
|
||||
<Heading
|
||||
({ as: Component = "a", children, className, ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
size="xsmall"
|
||||
as={as}
|
||||
className={cl("navdsi-header__title", className)}
|
||||
className={cl(
|
||||
"navdsi-header__title",
|
||||
"navds-heading",
|
||||
`navds-heading--xsmall`,
|
||||
className
|
||||
)}
|
||||
>
|
||||
<span>{children}</span>
|
||||
</Heading>
|
||||
</Component>
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@ import { BodyShort, Detail } from "@navikt/ds-react";
|
||||
|
||||
export interface HeaderUserProps extends HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* user name
|
||||
* User name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* user ident
|
||||
* User description
|
||||
*/
|
||||
ident: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export type HeaderUserType = React.ForwardRefExoticComponent<
|
||||
@@ -18,12 +18,18 @@ export type HeaderUserType = React.ForwardRefExoticComponent<
|
||||
>;
|
||||
|
||||
const HeaderUser = forwardRef<HTMLDivElement, HeaderUserProps>(
|
||||
({ className, name, ident, ...rest }, ref) => (
|
||||
({ className, name, description, ...rest }, ref) => (
|
||||
<div {...rest} ref={ref} className={cl("navdsi-header__user", className)}>
|
||||
<BodyShort size="small" className="navdsi-header__name">
|
||||
{name}
|
||||
</BodyShort>
|
||||
<Detail size="small">{ident}</Detail>
|
||||
<span>
|
||||
<BodyShort size="small" as="div">
|
||||
{name}
|
||||
</BodyShort>
|
||||
{description && (
|
||||
<Detail size="small" as="div">
|
||||
{description}
|
||||
</Detail>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
import { BodyShort, Detail } from "@navikt/ds-react";
|
||||
import { Expand } from "@navikt/ds-icons";
|
||||
import HeaderButton from "./HeaderButton";
|
||||
|
||||
export interface HeaderUserButtonProps
|
||||
extends React.AnchorHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* User name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* User description
|
||||
*/
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export type HeaderUserButtonType = OverridableComponent<
|
||||
HeaderUserButtonProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
|
||||
const HeaderUserButton: HeaderUserButtonType = forwardRef(
|
||||
({ as, name, description, className, ...rest }, ref) => (
|
||||
<HeaderButton
|
||||
{...rest}
|
||||
as={as}
|
||||
ref={ref}
|
||||
className={cl("navdsi-header__user-button", className)}
|
||||
>
|
||||
<div>
|
||||
<BodyShort size="small" as="div">
|
||||
{name}
|
||||
</BodyShort>
|
||||
{description && (
|
||||
<Detail size="small" as="div">
|
||||
{description}
|
||||
</Detail>
|
||||
)}
|
||||
</div>
|
||||
<Expand />
|
||||
</HeaderButton>
|
||||
)
|
||||
);
|
||||
|
||||
export default HeaderUserButton;
|
||||
@@ -1,6 +1,2 @@
|
||||
export { default as Header } from "./Header";
|
||||
export * from "./Header";
|
||||
export { default as HeaderTitle } from "./HeaderTitle";
|
||||
export * from "./HeaderTitle";
|
||||
export { default as HeaderUser } from "./HeaderUser";
|
||||
export * from "./HeaderUser";
|
||||
@@ -1,67 +0,0 @@
|
||||
import { Meta, Canvas } from "@storybook/addon-docs";
|
||||
import { Header, HeaderTitle, HeaderUser } from "../../index.ts";
|
||||
|
||||
<Meta title="ds-react-internal/header/intro" />
|
||||
|
||||
# Hvordan ta i bruk Header
|
||||
|
||||
Denne header-komponenten vil forgå en del endringer og er for det meste nå
|
||||
bare en enkel wrapper med lit enkel styling. Bruk på egen risiko
|
||||
|
||||
```jsx
|
||||
<Header>
|
||||
<Header.Title>NAV Sykepenger</Header.Title>
|
||||
<Header.User name="Kong Harald" ident="D123456" />
|
||||
</Header>
|
||||
```
|
||||
|
||||
<Canvas>
|
||||
<Header>
|
||||
<Header.Title>NAV Sykepenger</Header.Title>
|
||||
<Header.User name="Kong Harald" ident="D123456" />
|
||||
</Header>
|
||||
</Canvas>
|
||||
|
||||
## Uten innhold (wrapper)
|
||||
|
||||
```jsx
|
||||
<Header></Header>
|
||||
```
|
||||
|
||||
<Canvas>
|
||||
<Header />
|
||||
</Canvas>
|
||||
|
||||
## Tittel, men ikke heading (h-element)
|
||||
|
||||
```jsx
|
||||
<Header>
|
||||
<Header.Title>Tittel</Header.Title>
|
||||
</Header>
|
||||
```
|
||||
|
||||
<Canvas>
|
||||
<Header>
|
||||
<Header.Title as="span">Tittel</Header.Title>
|
||||
</Header>
|
||||
</Canvas>
|
||||
|
||||
## Heading med link
|
||||
|
||||
Focus-stylingen her er bare placeholder for nå
|
||||
|
||||
```jsx
|
||||
<Header>
|
||||
<Header.Title as="a" href="/#home">
|
||||
Tittel med lenke
|
||||
</Header.Title>
|
||||
</Header>
|
||||
```
|
||||
|
||||
<Canvas>
|
||||
<Header>
|
||||
<Header.Title as="a" href="/#home">
|
||||
Tittel med lenke
|
||||
</Header.Title>
|
||||
</Header>
|
||||
</Canvas>
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from "react";
|
||||
import { HashRouter as Router, Link } from "react-router-dom";
|
||||
import { BodyLong, BodyShort, Detail, Heading } from "@navikt/ds-react";
|
||||
import { Header } from "..";
|
||||
import { Expand, System, ExternalLink } from "@navikt/ds-icons";
|
||||
import { Divider, Dropdown } from "../..";
|
||||
|
||||
export default {
|
||||
title: "ds-react-internal/header",
|
||||
@@ -8,45 +10,148 @@ export default {
|
||||
};
|
||||
|
||||
export const All = () => (
|
||||
<div>
|
||||
<>
|
||||
<Heading level="1" size="xlarge">
|
||||
Header for interne flater
|
||||
</Heading>
|
||||
|
||||
<Heading level="2" size="medium">
|
||||
Title
|
||||
</Heading>
|
||||
<Header>
|
||||
<Header.Title>NAV Sykepenger</Header.Title>
|
||||
<Header.User name="Kong Harald" ident="D123456" />
|
||||
<Header.Title href="/#home">Tittel med lenke</Header.Title>
|
||||
</Header>
|
||||
|
||||
<h1>Uten innhold</h1>
|
||||
<Header />
|
||||
|
||||
<h1>Title</h1>
|
||||
<Heading level="2" size="medium">
|
||||
Title as h1
|
||||
</Heading>
|
||||
<Header>
|
||||
<Header.Title>Tittel</Header.Title>
|
||||
<Header.Title as="h1">Tittel</Header.Title>
|
||||
</Header>
|
||||
|
||||
<h1>Title as span</h1>
|
||||
<Heading level="2" size="medium">
|
||||
User
|
||||
</Heading>
|
||||
<Header>
|
||||
<Header.Title as="span">Tittel</Header.Title>
|
||||
<Header.Title href="/#home">NAV Sykepenger</Header.Title>
|
||||
<Header.User name="Kong Harald" style={{ marginLeft: "auto" }} />
|
||||
</Header>
|
||||
|
||||
<h1>Title as link</h1>
|
||||
<Heading level="2" size="medium">
|
||||
User with description
|
||||
</Heading>
|
||||
<Header>
|
||||
<Header.Title as="a" href="/#home">
|
||||
Tittel med lenke
|
||||
</Header.Title>
|
||||
<Header.Title href="/#home">NAV Sykepenger</Header.Title>
|
||||
<Dropdown>
|
||||
<Header.Button as={Dropdown.Toggle} style={{ marginLeft: "auto" }}>
|
||||
<System
|
||||
style={{ fontSize: "1.5rem" }}
|
||||
title="Systemer og oppslagsverk"
|
||||
/>
|
||||
</Header.Button>
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu.List>
|
||||
<Dropdown.Menu.List.Item>
|
||||
<span>A.Inntekt</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Dropdown.Menu.List.Item>
|
||||
<Dropdown.Menu.List.Item>
|
||||
<span>Aa-registeret</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Dropdown.Menu.List.Item>
|
||||
<Dropdown.Menu.List.Item>
|
||||
<span>Gosys</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Dropdown.Menu.List.Item>
|
||||
</Dropdown.Menu.List>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
<Header.User name="Kong Harald" description="D123456" />
|
||||
</Header>
|
||||
|
||||
<h1>Title as react-router link</h1>
|
||||
<Router>
|
||||
<Header>
|
||||
<Header.Title as={Link} to="/home">
|
||||
Tittel med lenke
|
||||
</Header.Title>
|
||||
</Header>
|
||||
</Router>
|
||||
<Heading level="2" size="medium">
|
||||
Systems and user menu
|
||||
</Heading>
|
||||
<Full />
|
||||
|
||||
<h1>Title + User</h1>
|
||||
<Header>
|
||||
<Header.Title>NAV Sykepenger</Header.Title>
|
||||
<Header.User name="Kong Harald" ident="D123456" />
|
||||
</Header>
|
||||
</div>
|
||||
<Heading level="2" size="medium">
|
||||
Initials
|
||||
</Heading>
|
||||
<Initials />
|
||||
</>
|
||||
);
|
||||
|
||||
const Full = () => (
|
||||
<Header>
|
||||
<Header.Title href="/#home">NAV Sykepenger</Header.Title>
|
||||
|
||||
<Dropdown>
|
||||
<Header.Button as={Dropdown.Toggle} style={{ marginLeft: "auto" }}>
|
||||
<System
|
||||
style={{ fontSize: "1.5rem" }}
|
||||
title="Systemer og oppslagsverk"
|
||||
/>
|
||||
</Header.Button>
|
||||
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu.GroupedList>
|
||||
<Dropdown.Menu.GroupedList.Heading>
|
||||
Systemer og oppslagsverk
|
||||
</Dropdown.Menu.GroupedList.Heading>
|
||||
<Dropdown.Menu.GroupedList.Item>
|
||||
A.Inntekt
|
||||
</Dropdown.Menu.GroupedList.Item>
|
||||
</Dropdown.Menu.GroupedList>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown>
|
||||
<Header.UserButton
|
||||
as={Dropdown.Toggle}
|
||||
name="Kong Harald"
|
||||
description="Enhet: Skien"
|
||||
/>
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu.List>
|
||||
<Dropdown.Menu.List.Item onClick={() => console.log("logg ut")}>
|
||||
Logg ut
|
||||
</Dropdown.Menu.List.Item>
|
||||
</Dropdown.Menu.List>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</Header>
|
||||
);
|
||||
|
||||
const Initials = () => (
|
||||
<Header>
|
||||
<Header.Title href="/#home">NAV Sykepenger</Header.Title>
|
||||
<Dropdown>
|
||||
<Header.Button as={Dropdown.Toggle} style={{ marginLeft: "auto" }}>
|
||||
<BodyShort size="small" title="Kong Harald">
|
||||
KH
|
||||
</BodyShort>
|
||||
<Expand />
|
||||
</Header.Button>
|
||||
<Dropdown.Menu>
|
||||
<div>
|
||||
<BodyLong size="small" as="div">
|
||||
Kong Harald 16px
|
||||
</BodyLong>
|
||||
<Detail size="small" as="div">
|
||||
<div>Ident nr 14px</div>
|
||||
<div>Enhet: Skien</div>
|
||||
</Detail>
|
||||
</div>
|
||||
<Divider />
|
||||
<Dropdown.Menu.List>
|
||||
<Dropdown.Menu.List.Item as="a" href="/#settings">
|
||||
Innstillinger
|
||||
</Dropdown.Menu.List.Item>
|
||||
<Dropdown.Menu.List.Item onClick={() => console.log("logg ut")}>
|
||||
Logg ut
|
||||
</Dropdown.Menu.List.Item>
|
||||
</Dropdown.Menu.List>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</Header>
|
||||
);
|
||||
@@ -1 +1,3 @@
|
||||
export * from "./divider";
|
||||
export * from "./dropdown";
|
||||
export * from "./header";
|
||||
@@ -19,6 +19,16 @@ yarn storybook
|
||||
|
||||
[http://localhost:6006](http://localhost:6006) (port auto-incrementeres hvis den allerede er i bruk av en annen server)
|
||||
|
||||
### Yarn install med Mac M1 chip
|
||||
|
||||
For at `yarn install` skal funke på Mac med M1 chip krever sharp-pakken at du har "libvps" installert globalt. Libvps krever også gcc og xcode build tools CLI. Dette kan installeres med følgende kommandoer:
|
||||
|
||||
```sh
|
||||
xcode-select --install
|
||||
brew install gcc
|
||||
brew reinstall vips
|
||||
```
|
||||
|
||||
## Utviklingsmiljø
|
||||
|
||||
Vi tar nå i bruk storybook [https://storybook.js.org/](https://storybook.js.org/) som utviklermiljø.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
## Innhold
|
||||
|
||||
Dette repoet inneholder følgende:
|
||||
Repoet inneholder følgende:
|
||||
|
||||
- [Alle felleskomponenter](https://github.com/navikt/nav-frontend-moduler/tree/master/packages/) i NAVs frontend-rammeverk forvaltet av designsystemet
|
||||
- [Felleskomponenter V2 (WIP)](https://github.com/navikt/nav-frontend-moduler/tree/master/@navikt/) oppdaterte og scopede pakker for en bedre brukeropplevelse
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
"version": "independent",
|
||||
"command": {
|
||||
"publish": {
|
||||
"registry": "http://registry.npmjs.org/",
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"npmClient": "npm",
|
||||
"ignoreChanges": ["*.md", "*.mdx", "*.story.tsx", "*.stories.tsx"],
|
||||
"message": "Lerna versionbump [ci skip]"
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/* eslint-disable strict */
|
||||
|
||||
"use strict";
|
||||
|
||||
const gulp = require("gulp");
|
||||
const through = require("through2");
|
||||
const newer = require("gulp-newer");
|
||||
const plumber = require("gulp-plumber");
|
||||
const gutil = require("gulp-util");
|
||||
const path = require("path");
|
||||
const chalk = require("chalk");
|
||||
const cssfont64 = require("gulp-cssfont64-formatter");
|
||||
const configureSvgIcon = require("react-svg-icon-generator-fork").default;
|
||||
|
||||
const fonts = "./packages/node_modules/*/assets/**/*.woff";
|
||||
const dest = "../../packages";
|
||||
|
||||
let assetsEx;
|
||||
let srcFragment;
|
||||
|
||||
if (path.win32 === path) {
|
||||
assetsEx = /(packages\\[^/]+)\\assets\\/;
|
||||
srcFragment = "$1\\src\\";
|
||||
} else {
|
||||
assetsEx = new RegExp("(packages/[^/]+)/assets/");
|
||||
srcFragment = "$1/src/";
|
||||
}
|
||||
|
||||
function mapSrcToDest(filepath) {
|
||||
return filepath.replace(assetsEx, srcFragment);
|
||||
}
|
||||
|
||||
function fixErrorHandling() {
|
||||
return plumber({
|
||||
errorHandler: (err) => gutil.log(err.stack),
|
||||
});
|
||||
}
|
||||
|
||||
function onlyNewFiles(map) {
|
||||
return newer({ map });
|
||||
}
|
||||
|
||||
function logCompiling() {
|
||||
return through.obj((file, enc, callback) => {
|
||||
gutil.log("Compiling", `'${chalk.cyan(file.path)}'...`);
|
||||
callback(null, file);
|
||||
});
|
||||
}
|
||||
|
||||
function renameUsingMapper(mapper) {
|
||||
return through.obj((file, enc, callback) => {
|
||||
file._path = file.path; // eslint-disable-line no-underscore-dangle, no-param-reassign
|
||||
file.path = mapper(file.path); // eslint-disable-line no-param-reassign
|
||||
|
||||
callback(null, file);
|
||||
});
|
||||
}
|
||||
|
||||
function cssFontfile(filename, mimetype, file64, format) {
|
||||
const fontFamiliy = "Source Sans Pro"; // all fonts at this point is Source sans pro
|
||||
const fontWeight = filename.replace(/\D/g, "") || "400"; // 400 is called regular
|
||||
const fontStyle = filename.indexOf("italic") >= 0 ? "italic" : "normal";
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
return `@font-face { font-family: '${fontFamiliy}'; font-weight: ${fontWeight}; font-style: ${fontStyle}; src: url(data:${mimetype};base64,${file64}) format("${format}");}`;
|
||||
}
|
||||
|
||||
function buildCssfonts() {
|
||||
return gulp
|
||||
.src(fonts)
|
||||
.pipe(fixErrorHandling())
|
||||
.pipe(onlyNewFiles(mapSrcToDest))
|
||||
.pipe(logCompiling())
|
||||
.pipe(cssfont64({ formatter: cssFontfile, extention: "less" }))
|
||||
.pipe(renameUsingMapper(mapSrcToDest))
|
||||
.pipe(gulp.dest(dest));
|
||||
}
|
||||
|
||||
configureSvgIcon({
|
||||
destination: path.join(
|
||||
__dirname,
|
||||
"packages",
|
||||
"node_modules",
|
||||
"nav-frontend-ikoner-assets",
|
||||
"src",
|
||||
"index.js"
|
||||
),
|
||||
svgDir: path.join(
|
||||
__dirname,
|
||||
"packages",
|
||||
"node_modules",
|
||||
"nav-frontend-ikoner-assets",
|
||||
"assets"
|
||||
),
|
||||
keepFillColor: true,
|
||||
});
|
||||
|
||||
gulp.task("default", gulp.series("build"));
|
||||
gulp.task("buildicons", gulp.series("svg-icon"));
|
||||
gulp.task("buildfonts", gulp.series(buildCssfonts));
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"allowJs": false,
|
||||
"declaration": true,
|
||||
"noImplicitAny": false,
|
||||
"strictNullChecks": true,
|
||||
"removeComments": false,
|
||||
"preserveConstEnums": true,
|
||||
"sourceMap": true,
|
||||
"jsx": "react",
|
||||
"lib": ["DOM", "es2015", "es2016", "es2017"]
|
||||
},
|
||||
"include": ["../../packages/**/src/*"],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"**/*-spec.js",
|
||||
"**/*-test.js",
|
||||
"**/*.less",
|
||||
"documentation"
|
||||
]
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "independent",
|
||||
"command": {
|
||||
"publish": {
|
||||
"registry": "http://registry.npmjs.org/",
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"npmClient": "npm",
|
||||
"ignoreChanges": ["*.md", "*.mdx", "*.story.tsx", "*.stories.tsx"],
|
||||
"message": "Lerna versionbump [ci skip]"
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
const glob = require("glob");
|
||||
const fs = require("fs");
|
||||
const inquirer = require("inquirer");
|
||||
const semver = require("semver");
|
||||
|
||||
function readfile(file) {
|
||||
return JSON.parse(fs.readFileSync(file, "utf-8"));
|
||||
}
|
||||
|
||||
function getModules() {
|
||||
return new Promise((resolve, reject) => {
|
||||
glob("./packages/node_modules/**/package.json", {}, (err, files) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
const filesdata = files.map((file) => ({
|
||||
location: file,
|
||||
pkg: readfile(file),
|
||||
}));
|
||||
|
||||
resolve(filesdata);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function bumpVersions(bump) {
|
||||
return (modules) => {
|
||||
modules.forEach((module) => {
|
||||
module.pkg.version = semver.inc(module.pkg.version, bump); // eslint-disable-line no-param-reassign
|
||||
});
|
||||
return modules;
|
||||
};
|
||||
}
|
||||
|
||||
function saveToDisk(modules) {
|
||||
modules.forEach((module) => {
|
||||
const location = module.location;
|
||||
const pkg = module.pkg;
|
||||
|
||||
const content = `${JSON.stringify(pkg, null, 2)}\n`;
|
||||
|
||||
console.log("Bumped", pkg.name, pkg.version); // eslint-disable-line no-console
|
||||
fs.writeFileSync(location, content, "utf-8");
|
||||
});
|
||||
}
|
||||
|
||||
inquirer
|
||||
.prompt([
|
||||
{
|
||||
type: "list",
|
||||
name: "bump",
|
||||
message: "Bump?",
|
||||
choices: ["patch", "minor", "major"],
|
||||
},
|
||||
])
|
||||
.then((answers) => {
|
||||
getModules()
|
||||
.then(bumpVersions(answers.bump))
|
||||
.then(saveToDisk)
|
||||
.catch((error) => {
|
||||
console.log("error", error); // eslint-disable-line no-console
|
||||
});
|
||||
});
|
||||
@@ -1,85 +0,0 @@
|
||||
const glob = require("glob");
|
||||
const fs = require("fs");
|
||||
const extend = require("extend");
|
||||
const utils = require("./utils");
|
||||
const globalPackage = require("../../package.json");
|
||||
|
||||
const globalDeps = extend(
|
||||
{},
|
||||
globalPackage.devDependencies,
|
||||
globalPackage.dependencies
|
||||
);
|
||||
|
||||
function getModules() {
|
||||
return new Promise((resolve, reject) => {
|
||||
glob("./packages/**/package.json", {}, (err, files) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(files.filter((file) => file.indexOf("node_modules") === -1));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function fixDependencies(pkg, section) {
|
||||
if (!pkg[section]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
pkg[section] = utils
|
||||
.entries(pkg[section])
|
||||
.map((entry) => {
|
||||
const depName = entry.key;
|
||||
|
||||
if (!globalDeps[depName]) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
return { key: depName, value: globalDeps[depName] };
|
||||
})
|
||||
.reduce((deps, entry) => extend(deps, { [entry.key]: entry.value }), {});
|
||||
}
|
||||
|
||||
function addModuleVersions(files) {
|
||||
files.forEach((file) => {
|
||||
const pkg = JSON.parse(fs.readFileSync(file, "utf-8"));
|
||||
globalDeps[pkg.name] = `^${pkg.version}`;
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
function injectGlobalDependencies(files) {
|
||||
return files.map((file) => {
|
||||
const pkg = JSON.parse(fs.readFileSync(file, "utf-8"));
|
||||
|
||||
fixDependencies(pkg, "dependencies");
|
||||
fixDependencies(pkg, "devDependencies");
|
||||
fixDependencies(pkg, "peerDependencies");
|
||||
|
||||
return {
|
||||
location: file,
|
||||
pkg,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function saveToDisk(modules) {
|
||||
modules.forEach((module) => {
|
||||
const location = module.location;
|
||||
const pkg = module.pkg;
|
||||
|
||||
const content = `${JSON.stringify(pkg, null, 2)}\n`;
|
||||
|
||||
fs.writeFileSync(location, content, "utf-8");
|
||||
});
|
||||
}
|
||||
|
||||
getModules()
|
||||
.then(addModuleVersions)
|
||||
.then(injectGlobalDependencies)
|
||||
.then(saveToDisk)
|
||||
.catch((error) => {
|
||||
console.log("error", error); // eslint-disable-line no-console
|
||||
});
|
||||
@@ -1,54 +0,0 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const glob = require("glob");
|
||||
const markdownMagic = require("markdown-magic");
|
||||
const mustache = require("mustache");
|
||||
const dfs = require("depth-first").default;
|
||||
|
||||
mustache.tags = ["<%", "%>"];
|
||||
const disclaimerMD = fs.readFileSync(
|
||||
path.join(__dirname, "DISCLAIMER.md"),
|
||||
"utf-8"
|
||||
);
|
||||
|
||||
function createConfig(moduleName, edges) {
|
||||
return {
|
||||
transforms: {
|
||||
DISCLAIMER() {
|
||||
const renderdata = { name: moduleName };
|
||||
return mustache.render(disclaimerMD, renderdata);
|
||||
},
|
||||
INSTALL() {
|
||||
const dependencies = dfs(edges, moduleName).sort().join(" ");
|
||||
return [
|
||||
"### Installering:",
|
||||
"```",
|
||||
`npm install ${dependencies} --save`,
|
||||
"```",
|
||||
].join("\n");
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
glob("./packages/**/package.json", { dot: true }, (err, files) => {
|
||||
const pkgs = files.map((file) => JSON.parse(fs.readFileSync(file, "utf-8")));
|
||||
|
||||
const edges = pkgs
|
||||
.map((pkg) => [pkg.name, Object.keys(pkg.peerDependencies || {})])
|
||||
.reduce(
|
||||
(arr, [pkgName, pkgDependencies]) => [
|
||||
...arr,
|
||||
...pkgDependencies.map((dependency) => [pkgName, dependency]),
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
pkgs.forEach((pkg) => {
|
||||
const pkgName = pkg.name;
|
||||
const config = createConfig(pkgName, edges);
|
||||
const MD = path.join(__dirname, "../..", "packages", pkgName, "README.md");
|
||||
// eslint-disable-next-line no-console
|
||||
markdownMagic(MD, config, (error) => error && console.log("err", error));
|
||||
});
|
||||
});
|
||||
@@ -1,65 +0,0 @@
|
||||
/* eslint-disable strict */
|
||||
|
||||
"use strict";
|
||||
|
||||
const extend = require("extend");
|
||||
|
||||
function capitalize(str) {
|
||||
return str && str[0].toUpperCase() + str.slice(1);
|
||||
}
|
||||
function camelcase(str) {
|
||||
return str && str.split(/\W/).map(capitalize).join("");
|
||||
}
|
||||
function kebabcase(str) {
|
||||
return str && str.split(/\W/).join("-");
|
||||
}
|
||||
function entries(obj) {
|
||||
return Object.keys(obj).map((key) => ({ key, value: obj[key] }));
|
||||
}
|
||||
function allCompleted(promises) {
|
||||
return new Promise((resolve, _reject) => {
|
||||
let unresolvedPromises = promises.length;
|
||||
const result = new Array(promises.length);
|
||||
promises.forEach((promise, index) =>
|
||||
promise
|
||||
.then((res) => {
|
||||
result[index] = res;
|
||||
unresolvedPromises -= 1;
|
||||
})
|
||||
.catch((res) => {
|
||||
result[index] = res;
|
||||
unresolvedPromises -= 1;
|
||||
})
|
||||
.then(() => {
|
||||
if (unresolvedPromises === 0) {
|
||||
resolve(result);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
function parsetag(tagstring) {
|
||||
const regex = /^(.+)[-@]((?:\d+\.?){3})$/;
|
||||
const match = regex.exec(tagstring);
|
||||
if (!match) {
|
||||
throw new Error(`Tag did not conform to expected format: ${tagstring}`);
|
||||
}
|
||||
|
||||
return { name: match[1], version: match[2] };
|
||||
}
|
||||
function allDependencies(pkg) {
|
||||
const dependencies = pkg.dependencies || {};
|
||||
const peerDependencies = pkg.peerDependencies || {};
|
||||
const devDependencies = pkg.devDependencies || {};
|
||||
|
||||
return extend({}, devDependencies, peerDependencies, dependencies);
|
||||
}
|
||||
module.exports = {
|
||||
capitalize,
|
||||
camelcase,
|
||||
kebabcase,
|
||||
entries,
|
||||
allCompleted,
|
||||
parsetag,
|
||||
allDependencies,
|
||||
};
|
||||
@@ -1,148 +0,0 @@
|
||||
/* eslint-disable strict, no-console */
|
||||
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const glob = require("glob");
|
||||
const chalk = require("chalk");
|
||||
const extend = require("extend");
|
||||
const semver = require("semver");
|
||||
|
||||
semver.clean = (version, loose) => {
|
||||
// Monkeypatch
|
||||
// var s = semver.parse(version.trim().replace(/^[=v]+]/, ''), loose); // Originalkode
|
||||
const s = semver.parse(version.trim().replace(/^[=v^~]+/, ""), loose);
|
||||
return s ? s.version : null;
|
||||
};
|
||||
|
||||
let hasError = false;
|
||||
const pkgGlob = "./packages/node_modules/**/package.json";
|
||||
|
||||
function objectIntersection(obj1, obj2) {
|
||||
return Object.keys(obj1).filter({}.hasOwnProperty.bind(obj2));
|
||||
}
|
||||
|
||||
function verifySameValue(obj1, obj2, errorMessage) {
|
||||
return (key) => {
|
||||
if (
|
||||
obj1[key] !== obj2[key] &&
|
||||
!semver.satisfies(semver.clean(obj1[key]), obj2[key])
|
||||
) {
|
||||
console.log(
|
||||
`${chalk.red("ERROR::")} ${errorMessage(key, obj1[key], obj2[key])}`
|
||||
);
|
||||
hasError = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const internalMismatch = (key, val1, val2) =>
|
||||
`Found internal mismatch for ${key}. ${val1} !== ${val2}`;
|
||||
const globalMismatch = (key, val1, val2) =>
|
||||
`Found global mismatch for ${key}. ${val1} !== ${val2}`;
|
||||
const interMismatch = (key, val1, val2) =>
|
||||
`Found inter-dependency mismatch for ${key}. ${val1} !== ${val2}`;
|
||||
|
||||
function verifyRelaxedVersions(dependencies) {
|
||||
return Object.keys(dependencies)
|
||||
.map((dependency) => [dependency, dependencies[dependency]])
|
||||
.forEach((dependency) => {
|
||||
const name = dependency[0];
|
||||
const version = dependency[1];
|
||||
|
||||
if (version[0] !== "^") {
|
||||
console.log(
|
||||
`${chalk.red(
|
||||
"ERROR::"
|
||||
)} Found non-relaxed version-range for ${name}:${version}`
|
||||
);
|
||||
hasError = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function analyzeDependenciesOf(pkg, depMap) {
|
||||
if (!depMap) {
|
||||
depMap = {}; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
// Check that dependencies in pkg use same version in all dependency-sections
|
||||
const dependencies = pkg.dependencies || {};
|
||||
const peerDependencies = pkg.peerDependencies || {};
|
||||
const devDependencies = pkg.devDependencies || {};
|
||||
|
||||
objectIntersection(dependencies, peerDependencies).forEach(
|
||||
verifySameValue(dependencies, peerDependencies, internalMismatch)
|
||||
); // eslint-disable-line max-len
|
||||
objectIntersection(dependencies, devDependencies).forEach(
|
||||
verifySameValue(dependencies, devDependencies, internalMismatch)
|
||||
); // eslint-disable-line max-len
|
||||
objectIntersection(devDependencies, peerDependencies).forEach(
|
||||
verifySameValue(devDependencies, peerDependencies, internalMismatch)
|
||||
); // eslint-disable-line max-len
|
||||
|
||||
objectIntersection(dependencies, depMap).forEach(
|
||||
verifySameValue(dependencies, depMap, interMismatch)
|
||||
);
|
||||
objectIntersection(devDependencies, depMap).forEach(
|
||||
verifySameValue(devDependencies, depMap, interMismatch)
|
||||
);
|
||||
objectIntersection(depMap, peerDependencies).forEach(
|
||||
verifySameValue(depMap, peerDependencies, interMismatch)
|
||||
);
|
||||
|
||||
verifyRelaxedVersions(peerDependencies);
|
||||
|
||||
return {
|
||||
name: pkg.name,
|
||||
version: pkg.version,
|
||||
dependencies: extend({}, dependencies, peerDependencies, devDependencies),
|
||||
};
|
||||
}
|
||||
|
||||
console.log(`Checking package: ${chalk.cyan("./package.json")}`);
|
||||
const globalPkg = analyzeDependenciesOf(
|
||||
JSON.parse(fs.readFileSync("./package.json"))
|
||||
);
|
||||
console.log("");
|
||||
|
||||
glob(pkgGlob, { dot: true }, (err, files) => {
|
||||
const pkgs = files.map((file) => ({
|
||||
file,
|
||||
content: JSON.parse(fs.readFileSync(file, "utf-8")),
|
||||
}));
|
||||
const depMap = pkgs.reduce(
|
||||
(map, data) => extend(map, { [data.content.name]: data.content.version }),
|
||||
{}
|
||||
);
|
||||
|
||||
pkgs.forEach((data) => {
|
||||
console.log(`Checking package: ${chalk.cyan(data.file)}`);
|
||||
|
||||
// Name check
|
||||
const pkgName = data.content.name;
|
||||
if (data.file.indexOf(pkgName) === -1) {
|
||||
console.log(
|
||||
`${chalk.red("ERROR:")} Found name mismatch in ${
|
||||
data.file
|
||||
}. Packagename was: ${pkgName}`
|
||||
);
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
const pkg = analyzeDependenciesOf(data.content, depMap);
|
||||
|
||||
Object.keys(pkg.dependencies)
|
||||
.filter((key) => !key.startsWith("nav-frontend-"))
|
||||
.forEach(
|
||||
verifySameValue(
|
||||
pkg.dependencies,
|
||||
globalPkg.dependencies,
|
||||
globalMismatch
|
||||
)
|
||||
);
|
||||
|
||||
console.log("");
|
||||
});
|
||||
|
||||
hasError && process.exit(1); // eslint-disable-line no-unused-expressions
|
||||
});
|
||||
Reference in new issue
Block a user