Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9691ac4713 | ||
|
|
7174bbe7bf | ||
|
|
62f36da5e7 | ||
|
|
9ec5133ba2 | ||
|
|
0a7906187f | ||
|
|
28f2a3f532 | ||
|
|
f5d404b925 | ||
|
|
05955acaf7 | ||
|
|
55362f3ea7 | ||
|
|
28f8f7a408 | ||
|
|
6778e902f3 | ||
|
|
92566d5750 | ||
|
|
6911913748 | ||
|
|
7f3e96ae01 | ||
|
|
19791c0339 | ||
|
|
6a00fca823 | ||
|
|
f5d3ed8eee | ||
|
|
5c00b91dfb | ||
|
|
5b82182fda | ||
|
|
6246c1d311 | ||
|
|
04ad4d09b2 | ||
|
|
65ddd4bd18 | ||
|
|
8bb5b8f7b9 | ||
|
|
dcf5cfc06b | ||
|
|
ff97e7f3f8 | ||
|
|
9e1165de0a | ||
|
|
812573ac43 | ||
|
|
5f340eba49 | ||
|
|
703e7e3ab5 | ||
|
|
b42101f6f1 | ||
|
|
8b0c4d8f59 | ||
|
|
6ab84e581f | ||
|
|
42f3a298a2 | ||
|
|
e49922d3fe | ||
|
|
fc06e8f7b4 | ||
|
|
0273b42fb4 | ||
|
|
0873fe6520 | ||
|
|
fdcf502a64 | ||
|
|
aebb22bf1b | ||
|
|
4529e64c6e | ||
|
|
01395e65ba | ||
|
|
21dd0450e7 | ||
|
|
ffac16cb05 | ||
|
|
98177d0cd3 | ||
|
|
2c5be718e6 | ||
|
|
019d92dd7b | ||
|
|
5b72afbb93 | ||
|
|
56348cdddf | ||
|
|
973d79ee99 | ||
|
|
5bfb912531 | ||
|
|
27e3dfee07 | ||
|
|
20b2bf6f89 | ||
|
|
4b870986c8 | ||
|
|
8fcf079359 | ||
|
|
54f8b07956 | ||
|
|
9bc251e694 | ||
|
|
e2a9d027dc | ||
|
|
22dfd8e603 | ||
|
|
53d1947311 | ||
|
|
d4e7c47772 | ||
|
|
e191dffdf8 | ||
|
|
7e0ee60d47 | ||
|
|
4ecaeb9d04 | ||
|
|
8e5c554431 | ||
|
|
727be0a98b | ||
|
|
4c2e44ced1 | ||
|
|
2fd1dd443f | ||
|
|
a6c3391237 | ||
|
|
5ede88a188 | ||
|
|
2785593d20 | ||
|
|
a37c743547 | ||
|
|
6f0e18c3cf | ||
|
|
bdfaa54e81 | ||
|
|
595796af6c | ||
|
|
f51d43c06a | ||
|
|
8c81ae46e0 | ||
|
|
c85b34e86f | ||
|
|
fc46b5a97b | ||
|
|
c7fcf57fdf | ||
|
|
560d8bd1e8 | ||
|
|
7a53de186e | ||
|
|
4feb798b25 | ||
|
|
c713b469f0 | ||
|
|
676392a5c4 | ||
|
|
c049e08555 | ||
|
|
d8c898db8c | ||
|
|
8a1ef5e7e2 | ||
|
|
d64da78d8b | ||
|
|
293594235a | ||
|
|
a54d97591e | ||
|
|
dc2e7fb766 | ||
|
|
53df42df22 | ||
|
|
21da657eb0 | ||
|
|
52d2d5f41d | ||
|
|
ff2515fabb | ||
|
|
5b9840524c | ||
|
|
0d6ddfd95e | ||
|
|
0394e819ba | ||
|
|
23066e9503 | ||
|
|
67fc9ad560 | ||
|
|
8fe5c88eba | ||
|
|
1fbcf78745 | ||
|
|
83dc3236e8 | ||
|
|
7503c7fa7f | ||
|
|
e668181690 | ||
|
|
353dff3da5 | ||
|
|
a11993a155 | ||
|
|
7b53b7670f | ||
|
|
0aaa0c4e10 | ||
|
|
ea5e1f768c | ||
|
|
e6b16e9b31 | ||
|
|
1029d42163 | ||
|
|
fba5140d8b | ||
|
|
fe72f32dbb | ||
|
|
6a0890b42b | ||
|
|
320f45a775 | ||
|
|
3feb2283a4 | ||
|
|
c3b416a3cb | ||
|
|
36fba1a33b | ||
|
|
a9e080f892 | ||
|
|
0dc8eb7a1e | ||
|
|
70fd78c926 | ||
|
|
dbc5e7dc07 | ||
|
|
4b0b8e4ae4 | ||
|
|
57e7e1ecc4 | ||
|
|
9534fe2540 | ||
|
|
44683d38f1 | ||
|
|
23c976e5d2 | ||
|
|
9ea823d630 | ||
|
|
65c65a6637 | ||
|
|
ef2a2a9c49 | ||
|
|
3f63fd7fb6 | ||
|
|
6fe9788444 | ||
|
|
10c6545885 | ||
|
|
2e76272a35 | ||
|
|
803a7a4d0f | ||
|
|
d8b7e69788 | ||
|
|
097ef18910 | ||
|
|
bb081354fc | ||
|
|
edc08c6f8a | ||
|
|
fc3577baf4 | ||
|
|
f02250ab75 | ||
|
|
1af80dcc1b | ||
|
|
373f40d968 | ||
|
|
75609e1b09 | ||
|
|
ea9bb63d0a | ||
|
|
a148b08eb5 | ||
|
|
1ca7e746e1 | ||
|
|
535ed17d36 | ||
|
|
8df1bc26a0 | ||
|
|
1b15ab146a | ||
|
|
0868b7d716 | ||
|
|
618d8d3de1 | ||
|
|
e9831b4e2a | ||
|
|
b0aa3ce0e7 | ||
|
|
4fa62f5d64 | ||
|
|
350e929bd2 | ||
|
|
64d178ea36 | ||
|
|
cb3decf3bd | ||
|
|
d66d009fe8 | ||
|
|
5974a77140 | ||
|
|
68b4444bb1 | ||
|
|
fc7d16b64b | ||
|
|
08a893c29a | ||
|
|
8d181e7a92 | ||
|
|
ab1c0849f4 | ||
|
|
96098e532f | ||
|
|
0b14ef50e9 | ||
|
|
262f8bf5d2 | ||
|
|
f18a2dde8f | ||
|
|
2e48c97b50 | ||
|
|
8bf2b8f322 | ||
|
|
ceb7b231b5 | ||
|
|
f7f304b33d | ||
|
|
151484afd3 | ||
|
|
7ae6969b35 | ||
|
|
65cfd8b459 | ||
|
|
3c9405b718 | ||
|
|
48b347e814 | ||
|
|
59de2d7992 | ||
|
|
0166c17985 | ||
|
|
57b1de13a9 | ||
|
|
52104b0f23 | ||
|
|
564a6b4b90 | ||
|
|
d43a4bfbdb | ||
|
|
1e647bffc6 | ||
|
|
986c43ead3 | ||
|
|
ea4fffdeba | ||
|
|
c14e9c346b | ||
|
|
d3dd96d2d4 | ||
|
|
b5fd3dd734 | ||
|
|
6979811e67 | ||
|
|
82ab82889d | ||
|
|
0b978693d6 | ||
|
|
feabc168d7 | ||
|
|
759c12eeef | ||
|
|
e3bc4f99a0 | ||
|
|
8c31007854 | ||
|
|
cf80626256 | ||
|
|
cbcfecbe72 | ||
|
|
a1ae58d041 | ||
|
|
a6cf7c1f25 | ||
|
|
a31a969863 | ||
|
|
19504b0d32 | ||
|
|
920a037b47 | ||
|
|
568f55e4be | ||
|
|
53cbedf041 | ||
|
|
cb356c23dc | ||
|
|
8f76acc776 | ||
|
|
d0269a84c0 | ||
|
|
e36206197d | ||
|
|
5e6bb7e016 | ||
|
|
15ed6b0f2f | ||
|
|
16142657ec | ||
|
|
a5b50f4cef | ||
|
|
796b7ac49f | ||
|
|
9bafc3e218 | ||
|
|
72c04454e5 | ||
|
|
dc4ad88427 | ||
|
|
00ecf7c67c | ||
|
|
83f8127570 | ||
|
|
b6017ea5cf | ||
|
|
b96036d14a | ||
|
|
d0fafb41b3 | ||
|
|
ddf8f65499 | ||
|
|
31aa6243ef | ||
|
|
afca0f481a | ||
|
|
2ffc2c22dc | ||
|
|
d8100c1589 | ||
|
|
a4cce95171 | ||
|
|
01ab8e5741 | ||
|
|
dd1a961dd2 | ||
|
|
11520ce468 | ||
|
|
20c8f9204b | ||
|
|
0074bfd5fb | ||
|
|
a0504f4e57 | ||
|
|
7bcac33423 | ||
|
|
a6feaea201 | ||
|
|
9c6cf8c811 | ||
|
|
592e0ccae9 | ||
|
|
f2f44ad2d7 | ||
|
|
322077fff8 | ||
|
|
5eaf729cc4 | ||
|
|
f285477a6c | ||
|
|
16f693cee9 | ||
|
|
2a7198e02b | ||
|
|
98b4f4e76a | ||
|
|
cf397f2522 | ||
|
|
7f1305c639 | ||
|
|
5964775a8e | ||
|
|
f1ea4ee1e0 | ||
|
|
cc24357a9e | ||
|
|
53406e54a9 | ||
|
|
39faa2b945 | ||
|
|
02e5978664 | ||
|
|
fa20f601df | ||
|
|
132ee94235 | ||
|
|
fa5aa175ab | ||
|
|
cf8833c885 | ||
|
|
a37f42b28a | ||
|
|
b8e797bc92 | ||
|
|
c248cb2a57 | ||
|
|
2a748c7903 | ||
|
|
2f2cbc16ca | ||
|
|
c0b8928ece | ||
|
|
50fe0e785b | ||
|
|
b2d31aed46 | ||
|
|
9fdf2cd4df | ||
|
|
02aa151153 | ||
|
|
a472fc4793 | ||
|
|
fdab54742f |
No files matched your search
@@ -0,0 +1,24 @@
|
||||
name: Ny komponent
|
||||
description: Send et ønske om en eller flere nye komponenter
|
||||
title: "[Ny komponent]: "
|
||||
labels: ["nytt ✨", "forespørsel 🥰", "komponenter 🧩"]
|
||||
assignees:
|
||||
- olejorgenbakken
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Takk for at du bidrar inn i Aksel!
|
||||
- type: input
|
||||
id: title
|
||||
attributes:
|
||||
label: Navn på komponent
|
||||
description: Hva er navnet på komponenten du ønsker deg?
|
||||
placeholder: eks. datepicker
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: examples
|
||||
attributes:
|
||||
label: Eksempel på komponenten
|
||||
description: Send en lenke til eksempler på komponenten
|
||||
@@ -0,0 +1,24 @@
|
||||
name: Nytt ikon
|
||||
description: Send et ønske om et eller flere nye ikoner
|
||||
title: "[Nytt ikon]: "
|
||||
labels: ["nytt ✨", "ikoner 🖼", "forespørsel 🥰"]
|
||||
assignees:
|
||||
- olejorgenbakken
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Takk for at du bidrar inn i Aksel!
|
||||
- type: input
|
||||
id: title
|
||||
attributes:
|
||||
label: Navn på ikonet
|
||||
description: Hva er navnet på ikonet du ønsker deg?
|
||||
placeholder: eks. send
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: examples
|
||||
attributes:
|
||||
label: Eksempel på ikonet
|
||||
description: Send en lenke til eksempler på ikonet
|
||||
@@ -0,0 +1,16 @@
|
||||
name: Innspill til komponent
|
||||
description: Send inn innspill til komponent
|
||||
title: "[Innspill til komponent]: "
|
||||
labels: ["forespørsel 🥰", "komponenter 🧩"]
|
||||
assignees:
|
||||
- olejorgenbakken
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Takk for at du bidrar inn i Aksel!
|
||||
- type: textarea
|
||||
id: feeback
|
||||
attributes:
|
||||
label: Tilbakemelding
|
||||
description: Beskriv hvilke tilbakemeldinger du har til komponenten
|
||||
@@ -0,0 +1,16 @@
|
||||
name: Innspill til ikon
|
||||
description: Send inn innspill til ikon
|
||||
title: "[Innspill til ikon]: "
|
||||
labels: ["forespørsel 🥰"]
|
||||
assignees:
|
||||
- olejorgenbakken
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Takk for at du bidrar inn i Aksel!
|
||||
- type: textarea
|
||||
id: feeback
|
||||
attributes:
|
||||
label: Tilbakemelding
|
||||
description: Beskriv hvilke tilbakemeldinger du har til ikonet
|
||||
@@ -22,9 +22,6 @@ jobs:
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ADMIN=${{ secrets.ALGOLIA_ADMIN }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ID=${{ secrets.ALGOLIA_ID}}" >> aksel.nav.no/website/.env
|
||||
echo "TRELLO_TOKEN=${{ secrets.TRELLO_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PREVIEW_TOKEN=${{ secrets.SANITY_PREVIEW_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PRIVATE_NO_DRAFTS=${{ secrets.SANITY_PRIVATE_NO_DRAFTS }}" >> aksel.nav.no/website/.env
|
||||
|
||||
@@ -21,9 +21,6 @@ jobs:
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ADMIN=${{ secrets.ALGOLIA_ADMIN }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ID=${{ secrets.ALGOLIA_ID}}" >> aksel.nav.no/website/.env
|
||||
echo "TRELLO_TOKEN=${{ secrets.TRELLO_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PREVIEW_TOKEN=${{ secrets.SANITY_PREVIEW_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PRIVATE_NO_DRAFTS=${{ secrets.SANITY_PRIVATE_NO_DRAFTS }}" >> aksel.nav.no/website/.env
|
||||
|
||||
@@ -22,18 +22,17 @@ jobs:
|
||||
key: ${{ runner.os }}-build-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-build-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
run: cd aksel.nav.no/website && yarn
|
||||
|
||||
- name: Export dataset
|
||||
run: SANITY_TOKEN=${{secrets.SANITY_DATASET_EDITOR_TOKEN}} yarn workspace aksel.nav.no sanity:backup
|
||||
run: cd aksel.nav.no/website && SANITY_PREVIEW_TOKEN=${{secrets.SANITY_DATASET_EDITOR_TOKEN}} yarn backup
|
||||
- name: Upload GCP bucket
|
||||
uses: "google-github-actions/auth@v0"
|
||||
with:
|
||||
credentials_json: "${{ secrets.gcp_credentials_prod }}"
|
||||
- uses: "google-github-actions/upload-cloud-storage@v0"
|
||||
with:
|
||||
path: ./aksel.nav.no/sanity
|
||||
path: ./aksel.nav.no/website
|
||||
destination: "aksel-website-prod/backups"
|
||||
glob: "**/backup-*.tar.gz"
|
||||
glob: "backup-*.tar.gz"
|
||||
@@ -21,9 +21,6 @@ jobs:
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ADMIN=${{ secrets.ALGOLIA_ADMIN }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ID=${{ secrets.ALGOLIA_ID}}" >> aksel.nav.no/website/.env
|
||||
echo "TRELLO_TOKEN=${{ secrets.TRELLO_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PREVIEW_TOKEN=${{ secrets.SANITY_PREVIEW_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PRIVATE_NO_DRAFTS=${{ secrets.SANITY_PRIVATE_NO_DRAFTS }}" >> aksel.nav.no/website/.env
|
||||
@@ -47,7 +44,7 @@ jobs:
|
||||
- name: Install Playwright Browsers
|
||||
run: npx playwright install --with-deps
|
||||
- name: Run Playwright tests
|
||||
run: yarn workspace website e2e
|
||||
run: yarn workspace website e2e:full
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
|
||||
@@ -20,9 +20,8 @@ jobs:
|
||||
- uses: "actions/checkout@v3"
|
||||
|
||||
- id: upload
|
||||
uses: nais/frontend-plattform-cdn-upload-action@main
|
||||
uses: navikt/frontend/actions/cdn-upload/v1@main
|
||||
with:
|
||||
cdn-environment: cdn.nav.no
|
||||
cdn-team-name: aksel
|
||||
source: ./fonts
|
||||
destination: "" # uploads folder to team root
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
name: Indexing search
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# 01.00 & 12.00 every day
|
||||
- cron: "00 01,12 * * *"
|
||||
|
||||
jobs:
|
||||
searchcrawl:
|
||||
name: Search-indexing aksel.nav.no
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
APPLICATION_ID: ${{ secrets.ALGOLIA_ID}}
|
||||
API_KEY: ${{ secrets.ALGOLIA_ADMIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Read crawler.json
|
||||
id: algolia_config
|
||||
run: echo "::set-output name=config::$(cat ./aksel.nav.no/crawler.json | jq -r tostring)"
|
||||
- name: Push indices to Algolia
|
||||
uses: signcl/docsearch-scraper-action@master
|
||||
env:
|
||||
APPLICATION_ID: ${{ secrets.ALGOLIA_ID}}
|
||||
API_KEY: ${{ secrets.ALGOLIA_ADMIN }}
|
||||
CONFIG: ${{ steps.algolia_config.outputs.config }}
|
||||
@@ -148,3 +148,6 @@ tmp.json
|
||||
/playwright/.cache/
|
||||
playwright-report/
|
||||
/test-results/
|
||||
backup-*.tar.gz
|
||||
sitemap-urls.json
|
||||
*.tar.gz
|
||||
@@ -1,5 +1,37 @@
|
||||
# @navikt/ds-codemod
|
||||
|
||||
## 2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
## 2.0.4
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-codemod",
|
||||
"version": "2.0.5",
|
||||
"version": "2.1.2",
|
||||
"description": "Aksel codemods for NAVs designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
"build-pict": "svgr --silent --index-template index-template.js --out-dir src/pictograms pictograms"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-icons": "^2.0.5",
|
||||
"@navikt/ds-react": "^2.0.5",
|
||||
"@navikt/ds-icons": "^2.1.2",
|
||||
"@navikt/ds-react": "^2.1.2",
|
||||
"clsx": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -51,7 +51,6 @@
|
||||
"@rollup/plugin-commonjs": "23.0.2",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@svgr/cli": "6.2.1",
|
||||
"@types/node": "^17.0.35",
|
||||
"concurrently": "7.2.1",
|
||||
"copyfiles": "2.4.1",
|
||||
"postcss-combine-duplicated-selectors": "10.0.3",
|
||||
|
||||
@@ -1,5 +1,49 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`62f36da5e`](https://github.com/navikt/Designsystemet/commit/62f36da5e74fc7f53414d42b310c3b57597795bc) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Small textfield har nå 8px horisontal padding (4px før)
|
||||
|
||||
## 2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1748](https://github.com/navikt/Designsystemet/pull/1748) [`22dfd8e60`](https://github.com/navikt/Designsystemet/commit/22dfd8e60315c421749394d35e41f412a00a7593) Thanks [@KenAJoh](https://github.com/KenAJoh)! - toptextPosition prop i Chat for horisontal plassering av navn og dato.
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1737](https://github.com/navikt/Designsystemet/pull/1737) [`8a1ef5e7e`](https://github.com/navikt/Designsystemet/commit/8a1ef5e7e2c066cb80c13e14329e1585e2c427f8) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset default visuell error-state for radio
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-bottom: 2px solid var(--a-border-strong);
|
||||
border-bottom: 2px solid var(--ac-accordion-header-border, var(--a-border-strong));
|
||||
}
|
||||
|
||||
.navds-accordion__header:focus {
|
||||
|
||||
@@ -77,6 +77,22 @@
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.navds-chat--top-text-left .navds-chat__top-text {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.navds-chat--top-text-right .navds-chat__top-text {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.navds-chat--left .navds-chat__top-text--right {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.navds-chat--right .navds-chat__top-text--left {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.navds-chat__name {
|
||||
font-weight: var(--a-font-weight-bold);
|
||||
}
|
||||
@@ -143,27 +143,21 @@
|
||||
.navds-checkbox--error
|
||||
> .navds-checkbox__input:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--error
|
||||
> .navds-radio__input:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-radio__label::before {
|
||||
.navds-radio--error > .navds-radio__input:not(:hover):not(:disabled):not(:checked) + .navds-radio__label::before {
|
||||
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger));
|
||||
}
|
||||
|
||||
.navds-checkbox--error
|
||||
> .navds-checkbox__input:focus:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--error
|
||||
> .navds-radio__input:focus:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-radio__label::before {
|
||||
.navds-radio--error > .navds-radio__input:focus:not(:hover):not(:disabled):not(:checked) + .navds-radio__label::before {
|
||||
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
.navds-checkbox--error
|
||||
> .navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--error
|
||||
> .navds-radio__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus)
|
||||
+ .navds-radio__label::before {
|
||||
.navds-radio--error > .navds-radio__input:hover:not(:disabled):not(:checked):not(:focus) + .navds-radio__label::before {
|
||||
background-color: var(--ac-radio-checkbox-error-hover-bg, var(--a-surface-danger-subtle));
|
||||
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger));
|
||||
}
|
||||
@@ -171,9 +165,7 @@
|
||||
.navds-checkbox--error
|
||||
> .navds-checkbox__input:focus:hover:not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--error
|
||||
> .navds-radio__input:focus:hover:not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-radio__label::before {
|
||||
.navds-radio--error > .navds-radio__input:focus:hover:not(:disabled):not(:checked) + .navds-radio__label::before {
|
||||
background-color: var(--ac-radio-checkbox-error-hover-bg, var(--a-surface-danger-subtle));
|
||||
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
.navds-form-field--small .navds-text-field__input {
|
||||
padding: 0 0.25rem;
|
||||
padding: 0 0.5rem;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "2.0.5",
|
||||
"version": "2.1.2",
|
||||
"description": "CSS for NAV Designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -20,7 +20,7 @@
|
||||
"watch": "postcss --watch --use postcss-import -o dist/index.css index.css"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^2.0.5",
|
||||
"@navikt/ds-tokens": "^2.1.2",
|
||||
"normalize.css": "^8.0.1",
|
||||
"postcss": "^8.4.0",
|
||||
"postcss-cli": "^9.0.0",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"--ac-alert-success-bg": "--a-surface-success-subtle"
|
||||
},
|
||||
"accordion": {
|
||||
"--ac-accordion-header-border": "--a-border-strong",
|
||||
"--ac-accordion-header-text-hover": "--a-text-action-on-action-subtle",
|
||||
"--ac-accordion-header-border-hover": "--a-border-strong",
|
||||
"--ac-accordion-item-bg-open": "--a-surface-action-subtle",
|
||||
|
||||
@@ -1,5 +1,139 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1759](https://github.com/navikt/Designsystemet/pull/1759) [`dcf5cfc06`](https://github.com/navikt/Designsystemet/commit/dcf5cfc06b751341559ef30085bd974820531e57) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset @types/react v18 feil introdusert i v2.0.6
|
||||
|
||||
- Updated dependencies [[`dcf5cfc06`](https://github.com/navikt/Designsystemet/commit/dcf5cfc06b751341559ef30085bd974820531e57)]:
|
||||
- @navikt/ds-icons@2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [`0873fe652`](https://github.com/navikt/Designsystemet/commit/0873fe6520e817e462197c162b49c05826da4838) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Datepicker/Monthpicker støtter nå år med 2 siffer i input
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.1.0
|
||||
|
||||
## 2.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`98177d0cd`](https://github.com/navikt/Designsystemet/commit/98177d0cd3802029dcf398ce93c1767d3b0860c5) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Bedre typer for ref i datepicker
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`27e3dfee0`](https://github.com/navikt/Designsystemet/commit/27e3dfee07e135893e9f62cd32f80ed83a3510de)]:
|
||||
- @navikt/ds-icons@2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`54f8b0795`](https://github.com/navikt/Designsystemet/commit/54f8b07956bbfb7de51f6682a5fc64903bfd1bdf)]:
|
||||
- @navikt/ds-icons@2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1748](https://github.com/navikt/Designsystemet/pull/1748) [`22dfd8e60`](https://github.com/navikt/Designsystemet/commit/22dfd8e60315c421749394d35e41f412a00a7593) Thanks [@KenAJoh](https://github.com/KenAJoh)! - toptextPosition prop i Chat for horisontal plassering av navn og dato.
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`8e5c55443`](https://github.com/navikt/Designsystemet/commit/8e5c554431c98b1b658c5054c0b3cf08b8a65e52) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Bumpet @floating-ui/react
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a6c339123`](https://github.com/navikt/Designsystemet/commit/a6c3391237f13394063e4c004ac9efb1875fc944)]:
|
||||
- @navikt/ds-icons@2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Button submittet form i table
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ShouldCloseOnEsc i Modal
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Confirmationpanel wrappet med div
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :bug: Fikset keyboard-click i monthpicker
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- DateInput hadde duplikat className satt
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "2.0.5",
|
||||
"version": "2.1.2",
|
||||
"description": "Aksel react-components for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -36,8 +36,8 @@
|
||||
"test": "TZ=UTC jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom-interactions": "0.9.2",
|
||||
"@navikt/ds-icons": "^2.0.5",
|
||||
"@floating-ui/react": "0.17.0",
|
||||
"@navikt/ds-icons": "^2.1.2",
|
||||
"@radix-ui/react-tabs": "1.0.0",
|
||||
"@radix-ui/react-toggle-group": "1.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
@@ -52,7 +52,6 @@
|
||||
"@testing-library/user-event": "^14.2.0",
|
||||
"@types/faker": "5.5.8",
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/node": "^17.0.35",
|
||||
"@types/react-modal": "^3.13.1",
|
||||
"concurrently": "7.2.1",
|
||||
"copyfiles": "^2.4.1",
|
||||
|
||||
@@ -19,6 +19,10 @@ export interface BubbleProps extends HTMLAttributes<HTMLDivElement> {
|
||||
* Background color on bubble
|
||||
*/
|
||||
backgroundColor?: string;
|
||||
/**
|
||||
* Overrides hoizontal position of toptext
|
||||
*/
|
||||
toptextPosition?: "left" | "right";
|
||||
}
|
||||
|
||||
export type BubbleType = React.ForwardRefExoticComponent<
|
||||
@@ -26,7 +30,18 @@ export type BubbleType = React.ForwardRefExoticComponent<
|
||||
>;
|
||||
|
||||
const Bubble: BubbleType = forwardRef(
|
||||
({ children, className, name, timestamp, backgroundColor, ...rest }, ref) => {
|
||||
(
|
||||
{
|
||||
children,
|
||||
className,
|
||||
name,
|
||||
timestamp,
|
||||
backgroundColor,
|
||||
toptextPosition,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
@@ -35,7 +50,12 @@ const Bubble: BubbleType = forwardRef(
|
||||
{...rest}
|
||||
>
|
||||
{(timestamp || name) && (
|
||||
<div className="navds-chat__top-text">
|
||||
<div
|
||||
className={cl(
|
||||
`navds-chat__top-text`,
|
||||
toptextPosition && `navds-chat__top-text--${toptextPosition}`
|
||||
)}
|
||||
>
|
||||
{name && <Detail className="navds-chat__name">{name}</Detail>}
|
||||
{timestamp && (
|
||||
<Detail className="navds-chat__timestamp">{timestamp}</Detail>
|
||||
|
||||
@@ -33,6 +33,11 @@ export interface ChatProps extends HTMLAttributes<HTMLDivElement> {
|
||||
* @default "left"
|
||||
*/
|
||||
position?: "left" | "right";
|
||||
/**
|
||||
* Hoizontal position of toptext
|
||||
* @default Same as chat
|
||||
*/
|
||||
toptextPosition?: "left" | "right";
|
||||
}
|
||||
|
||||
interface ChatComponent
|
||||
@@ -53,6 +58,7 @@ export const Chat = forwardRef<HTMLDivElement, ChatProps>(
|
||||
position = "left",
|
||||
avatarBgColor,
|
||||
backgroundColor,
|
||||
toptextPosition,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
@@ -60,7 +66,13 @@ export const Chat = forwardRef<HTMLDivElement, ChatProps>(
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cl("navds-chat", className, `navds-chat--${position}`)}
|
||||
className={cl(
|
||||
"navds-chat",
|
||||
className,
|
||||
`navds-chat--${position} navds-chat--top-text-${
|
||||
toptextPosition ?? position
|
||||
}`
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<BodyShort
|
||||
|
||||
@@ -116,6 +116,57 @@ export const Position = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const ToptextPosition = () => {
|
||||
return (
|
||||
<div className="colgap">
|
||||
<Chat
|
||||
avatar="ON"
|
||||
name="Ola Normann"
|
||||
timestamp="01.01.21 14:00"
|
||||
backgroundColor="rgba(255, 249, 240, 1)"
|
||||
avatarBgColor="rgba(255, 236, 204, 1)"
|
||||
toptextPosition="right"
|
||||
>
|
||||
<Chat.Bubble>
|
||||
Adipisicing laborum est eu laborum est sit in commodo enim sint
|
||||
laboris labore nisi ut.
|
||||
</Chat.Bubble>
|
||||
</Chat>
|
||||
<Chat
|
||||
avatar="KH"
|
||||
name="Kari Høyli"
|
||||
timestamp="01.01.21 14:32"
|
||||
position="right"
|
||||
backgroundColor="rgba(230, 240, 255, 1)"
|
||||
avatarBgColor="rgba(204, 225, 255, 1)"
|
||||
toptextPosition="left"
|
||||
>
|
||||
<Chat.Bubble>
|
||||
Reprehenderit pariatur officia exercitation laboris.
|
||||
</Chat.Bubble>
|
||||
<Chat.Bubble>
|
||||
Enim velit deserunt do quis. Eu fugiat magna esse dolore ad sunt sit
|
||||
est dolore incididunt. Occaecat cupidatat magna.
|
||||
</Chat.Bubble>
|
||||
</Chat>
|
||||
<Chat
|
||||
avatar="ON"
|
||||
name="Ola Normann"
|
||||
timestamp="01.01.21 15:00"
|
||||
backgroundColor="rgba(255, 249, 240, 1)"
|
||||
avatarBgColor="rgba(255, 236, 204, 1)"
|
||||
>
|
||||
<Chat.Bubble toptextPosition="right">
|
||||
Exercitation irure Lorem cupidatat culpa anim cillum esse ullamco qui
|
||||
dolore laborum et Lorem. Labore sunt duis id Lorem voluptate commodo
|
||||
ea esse. Dolore esse aliqua proident ea ad commodo ut dolore voluptate
|
||||
labore sunt aute.
|
||||
</Chat.Bubble>
|
||||
</Chat>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Avatar = () => {
|
||||
return (
|
||||
<Chat avatar={<Illustration />} timestamp="01.01.21 14:00">
|
||||
|
||||
@@ -108,7 +108,6 @@ const DateInput: DateInputType = forwardRef<HTMLInputElement, DateInputProps>(
|
||||
autoComplete="off"
|
||||
aria-controls={ariaId}
|
||||
className={cl(
|
||||
className,
|
||||
"navds-date__field-input",
|
||||
"navds-text-field__input",
|
||||
"navds-body-short",
|
||||
|
||||
@@ -49,6 +49,13 @@ export interface UseDatepickerOptions
|
||||
* validation-callback
|
||||
*/
|
||||
onValidate?: (val: DateValidationT) => void;
|
||||
/**
|
||||
* Allows input of with 'yy' year format.
|
||||
* @default true
|
||||
* @Note Decision between 20th and 21st century is based on before(todays year - 80) ? 21st : 20th.
|
||||
* In 2023 this equals to 1943 - 2042
|
||||
*/
|
||||
allowTwoDigitYear?: boolean;
|
||||
}
|
||||
|
||||
interface UseDatepickerValue {
|
||||
@@ -59,7 +66,10 @@ interface UseDatepickerValue {
|
||||
/**
|
||||
* Use: <DatePicker.Input {...inputProps}/>
|
||||
*/
|
||||
inputProps: Pick<DateInputProps, "onChange" | "onFocus" | "onBlur" | "value">;
|
||||
inputProps: Pick<
|
||||
DateInputProps,
|
||||
"onChange" | "onFocus" | "onBlur" | "value"
|
||||
> & { ref: React.RefObject<HTMLInputElement> };
|
||||
/**
|
||||
* Resets all states (callback)
|
||||
*/
|
||||
@@ -112,6 +122,7 @@ export const useDatepicker = (
|
||||
inputFormat,
|
||||
onValidate,
|
||||
defaultMonth,
|
||||
allowTwoDigitYear = true,
|
||||
} = opt;
|
||||
|
||||
const locale = getLocaleFromString(_locale);
|
||||
@@ -188,7 +199,13 @@ export const useDatepicker = (
|
||||
|
||||
const handleFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
||||
!open && setOpen(true);
|
||||
let day = parseDate(e.target.value, today, locale, "date");
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"date",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
if (isValidDate(day)) {
|
||||
setMonth(day);
|
||||
setInputValue(formatDateForInput(day, locale, "date", inputFormat));
|
||||
@@ -196,7 +213,13 @@ export const useDatepicker = (
|
||||
};
|
||||
|
||||
const handleBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
||||
let day = parseDate(e.target.value, today, locale, "date");
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"date",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
isValidDate(day) &&
|
||||
setInputValue(formatDateForInput(day, locale, "date", inputFormat));
|
||||
};
|
||||
@@ -227,7 +250,13 @@ export const useDatepicker = (
|
||||
// the calendar’s month.
|
||||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
setInputValue(e.target.value);
|
||||
const day = parseDate(e.target.value, today, locale, "date");
|
||||
const day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"date",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
|
||||
const isBefore =
|
||||
fromDate && day && differenceInCalendarDays(fromDate, day) > 0;
|
||||
|
||||
@@ -35,6 +35,13 @@ export interface UseMonthPickerOptions
|
||||
* Default shown year
|
||||
*/
|
||||
defaultYear?: Date;
|
||||
/**
|
||||
* Allows input of with 'yy' year format.
|
||||
* @default true
|
||||
* @Note Decision between 20th and 21st century is based on before(todays year - 80) ? 21st : 20th.
|
||||
* In 2023 this equals to 1943 - 2042
|
||||
*/
|
||||
allowTwoDigitYear?: boolean;
|
||||
}
|
||||
|
||||
interface UseMonthPickerValue {
|
||||
@@ -45,7 +52,9 @@ interface UseMonthPickerValue {
|
||||
/**
|
||||
* Use: <MonthPicker.Input {...inputProps} />
|
||||
*/
|
||||
inputProps: Pick<DateInputProps, "onChange" | "onFocus" | "value">;
|
||||
inputProps: Pick<DateInputProps, "onChange" | "onFocus" | "value"> & {
|
||||
ref: React.RefObject<HTMLInputElement>;
|
||||
};
|
||||
/**
|
||||
* Currently selected Date
|
||||
* Up to user to validate value and extract month
|
||||
@@ -94,6 +103,7 @@ export const useMonthpicker = (
|
||||
inputFormat,
|
||||
onValidate,
|
||||
defaultYear,
|
||||
allowTwoDigitYear = true,
|
||||
} = opt;
|
||||
|
||||
const [defaultSelected, setDefaultSelected] = useState(_defaultSelected);
|
||||
@@ -101,7 +111,7 @@ export const useMonthpicker = (
|
||||
const today = new Date();
|
||||
const locale = getLocaleFromString(_locale);
|
||||
|
||||
const inputRef = useRef<HTMLDivElement>(null);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const monthpickerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Initialize states
|
||||
@@ -171,7 +181,13 @@ export const useMonthpicker = (
|
||||
|
||||
const handleFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
||||
!open && setOpen(true);
|
||||
let day = parseDate(e.target.value, today, locale, "month");
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"month",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
if (isValidDate(day)) {
|
||||
setYear(day);
|
||||
setInputValue(formatDateForInput(day, locale, "month", inputFormat));
|
||||
@@ -179,7 +195,13 @@ export const useMonthpicker = (
|
||||
};
|
||||
|
||||
const handleBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
||||
let day = parseDate(e.target.value, today, locale, "month");
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"month",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
isValidDate(day) &&
|
||||
setInputValue(formatDateForInput(day, locale, "month", inputFormat));
|
||||
};
|
||||
@@ -209,7 +231,13 @@ export const useMonthpicker = (
|
||||
// the calendar’s month.
|
||||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
setInputValue(e.target.value);
|
||||
const month = parseDate(e.target.value, today, locale, "month");
|
||||
const month = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"month",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
|
||||
const isBefore =
|
||||
fromDate &&
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import differenceInCalendarDays from "date-fns/differenceInCalendarDays";
|
||||
import isWeekend from "date-fns/isWeekend";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { DateRange, isMatch } from "react-day-picker";
|
||||
import { DateInputProps } from "../DateInput";
|
||||
import { DatePickerProps } from "../datepicker/DatePicker";
|
||||
@@ -71,14 +71,14 @@ interface UseRangeDatepickerValue {
|
||||
fromInputProps: Pick<
|
||||
DateInputProps,
|
||||
"onChange" | "onFocus" | "onBlur" | "value"
|
||||
>;
|
||||
> & { ref: React.RefObject<HTMLInputElement> };
|
||||
/**
|
||||
* Use: <DatePicker.Input label="to" {...toInputProps}/>
|
||||
*/
|
||||
toInputProps: Pick<
|
||||
DateInputProps,
|
||||
"onChange" | "onFocus" | "onBlur" | "value"
|
||||
>;
|
||||
> & { ref: React.RefObject<HTMLInputElement> };
|
||||
/**
|
||||
* Resets all states (callback)
|
||||
*/
|
||||
@@ -202,12 +202,13 @@ export const useRangeDatepicker = (
|
||||
inputFormat,
|
||||
onValidate,
|
||||
defaultMonth,
|
||||
allowTwoDigitYear = true,
|
||||
} = opt;
|
||||
|
||||
const locale = getLocaleFromString(_locale);
|
||||
|
||||
const inputRefTo = useRef<HTMLDivElement>(null);
|
||||
const inputRefFrom = useRef<HTMLDivElement>(null);
|
||||
const inputRefTo = useRef<HTMLInputElement>(null);
|
||||
const inputRefFrom = useRef<HTMLInputElement>(null);
|
||||
const datePickerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const [defaultSelected, setDefaultSelected] = useState(_defaultSelected);
|
||||
@@ -322,7 +323,13 @@ export const useRangeDatepicker = (
|
||||
|
||||
const handleFocus = (e, src: RangeT) => {
|
||||
!open && setOpen(true);
|
||||
let day = parseDate(e.target.value, today, locale, "date");
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"date",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
if (isValidDate(day)) {
|
||||
setMonth(day);
|
||||
src === RANGE.FROM
|
||||
@@ -334,7 +341,13 @@ export const useRangeDatepicker = (
|
||||
};
|
||||
|
||||
const handleBlur = (e, src: RangeT) => {
|
||||
let day = parseDate(e.target.value, today, locale, "date");
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"date",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
if (!isValidDate(day)) {
|
||||
return;
|
||||
}
|
||||
@@ -426,7 +439,13 @@ export const useRangeDatepicker = (
|
||||
}
|
||||
|
||||
if (toInputValue && !selectedRange?.to) {
|
||||
const toDay = parseDate(toInputValue, today, locale, "date");
|
||||
const toDay = parseDate(
|
||||
toInputValue,
|
||||
today,
|
||||
locale,
|
||||
"date",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
if (validateDay(toDay)) {
|
||||
updateRange({ from: day, to: toDay });
|
||||
setMonth(day);
|
||||
@@ -489,7 +508,13 @@ export const useRangeDatepicker = (
|
||||
|
||||
/* live-update datepicker based on changes in inputfields */
|
||||
const handleChange = (e, src: RangeT) => {
|
||||
const day = parseDate(e.target.value, today, locale, "date");
|
||||
const day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
locale,
|
||||
"date",
|
||||
allowTwoDigitYear
|
||||
);
|
||||
const isBefore = fromDate && differenceInCalendarDays(fromDate, day) > 0;
|
||||
const isAfter = toDate && differenceInCalendarDays(day, toDate) > 0;
|
||||
|
||||
|
||||
@@ -74,7 +74,6 @@ export const MonthButton = ({
|
||||
: -1
|
||||
}
|
||||
onKeyDown={(e) => {
|
||||
e.preventDefault();
|
||||
const next = nextEnabled(
|
||||
months,
|
||||
e.key,
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("Returns if year is at start or end of range", () => {
|
||||
expect(hasNextYear(new Date(), years, 1)).toBeTruthy();
|
||||
});
|
||||
test("Should have previous year (true)", () => {
|
||||
expect(hasNextYear(new Date("Aug 3 2023"), years, -1)).toBeTruthy();
|
||||
expect(hasNextYear(new Date("Aug 3 2024"), years, -1)).toBeTruthy();
|
||||
});
|
||||
test("Should not have next year (false)", () => {
|
||||
expect(hasNextYear(new Date("Aug 3 2029"), years, 1)).toBeFalsy();
|
||||
|
||||
@@ -2,7 +2,9 @@ import { parseDate } from "../parse-date";
|
||||
import nb from "date-fns/locale/nb";
|
||||
import { formatDateForInput } from "../format-date";
|
||||
|
||||
const parse = (inp: string) => parseDate(inp, new Date(), nb, "date");
|
||||
const parse = (inp: string) => parseDate(inp, new Date(), nb, "date", false);
|
||||
const parseTwoDigit = (inp: string) =>
|
||||
parseDate(inp, new Date(), nb, "date", true);
|
||||
|
||||
describe("Format date to correct output", () => {
|
||||
test("formatDateForInput", () => {
|
||||
@@ -19,4 +21,12 @@ describe("Format date to correct output", () => {
|
||||
"15.05.2022"
|
||||
);
|
||||
});
|
||||
test("formatDateForInput with twoDigitYears", () => {
|
||||
expect(formatDateForInput(parseTwoDigit("15/05/22"), nb, "date")).toEqual(
|
||||
"15.05.2022"
|
||||
);
|
||||
expect(formatDateForInput(parseTwoDigit("1/5/95"), nb, "date")).toEqual(
|
||||
"01.05.1995"
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -4,11 +4,14 @@ import nb from "date-fns/locale/nb";
|
||||
import getMonth from "date-fns/getMonth";
|
||||
|
||||
const check = (inp: string) =>
|
||||
expect(isValidDate(parseDate(inp, new Date(), nb, "date")));
|
||||
expect(isValidDate(parseDate(inp, new Date(), nb, "date", false)));
|
||||
|
||||
const parse = (inp: string) => parseDate(inp, new Date(), nb, "date");
|
||||
const checkTwoDigit = (inp: string) =>
|
||||
expect(isValidDate(parseDate(inp, new Date(), nb, "date", true)));
|
||||
|
||||
describe("Parse date-inputs", () => {
|
||||
const parse = (inp: string) => parseDate(inp, new Date(), nb, "date", false);
|
||||
|
||||
describe("Parse date-inputs with 4-digit years", () => {
|
||||
test("No spaces", () => {
|
||||
check("11052022").toBeTruthy();
|
||||
check("15052022").toBeTruthy();
|
||||
@@ -34,6 +37,44 @@ describe("Parse date-inputs", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Parse date-inputs with 2-digit years", () => {
|
||||
test("No spaces", () => {
|
||||
checkTwoDigit("110522").toBeTruthy();
|
||||
checkTwoDigit("150522").toBeTruthy();
|
||||
});
|
||||
|
||||
test(". divider", () => {
|
||||
checkTwoDigit("1.5.22").toBeTruthy();
|
||||
checkTwoDigit("11.05.22").toBeTruthy();
|
||||
});
|
||||
|
||||
test("/ divider", () => {
|
||||
checkTwoDigit("1/5/22").toBeTruthy();
|
||||
checkTwoDigit("10/5/22").toBeTruthy();
|
||||
checkTwoDigit("1/05/22").toBeTruthy();
|
||||
checkTwoDigit("10/05/22").toBeTruthy();
|
||||
});
|
||||
|
||||
test("- divider", () => {
|
||||
checkTwoDigit("1-5-22").toBeTruthy();
|
||||
checkTwoDigit("10-5-22").toBeTruthy();
|
||||
checkTwoDigit("1-05-22").toBeTruthy();
|
||||
checkTwoDigit("10-05-22").toBeTruthy();
|
||||
});
|
||||
|
||||
test("Dissallow 1 and 3 digit years", () => {
|
||||
checkTwoDigit("11052").toBeFalsy();
|
||||
checkTwoDigit("1105222").toBeFalsy();
|
||||
checkTwoDigit("1105999").toBeFalsy();
|
||||
});
|
||||
|
||||
test("Dissallow date before year 1000", () => {
|
||||
checkTwoDigit("11050999").toBeFalsy();
|
||||
checkTwoDigit("11050010").toBeFalsy();
|
||||
checkTwoDigit("11051000").toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Parse date-inputs to correct month", () => {
|
||||
test("No spaces", () => {
|
||||
expect(getMonth(parse("11052022"))).toEqual(4);
|
||||
|
||||
@@ -10,7 +10,7 @@ export const dateIsInCurrentMonth = (
|
||||
|
||||
/** @private */
|
||||
export function isValidDate(day: Date): boolean {
|
||||
return !isNaN(day.getTime());
|
||||
return day && !isNaN(day?.getTime()) && day.getFullYear() > 999;
|
||||
}
|
||||
|
||||
export const hasNextYear = (year: Date, years: Date[], val: any): boolean => {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import parse from "date-fns/parse";
|
||||
import isBefore from "date-fns/isBefore";
|
||||
import sub from "date-fns/sub";
|
||||
import { isValidDate } from ".";
|
||||
|
||||
export const INPUT_DATE_STRING_FORMAT_DATE = "dd.MM.yyyy";
|
||||
@@ -22,7 +24,60 @@ const ALLOWED_INPUT_FORMATS_MONTH = [
|
||||
...ALLOWED_INPUT_FORMATS_DATE,
|
||||
];
|
||||
|
||||
const isTwoDigitYear = (dateString, today, locale, formats) => {
|
||||
export const parseDate = (
|
||||
date: string,
|
||||
today: Date,
|
||||
locale: Locale,
|
||||
type: "date" | "month",
|
||||
allowTwoDigitYear: boolean
|
||||
): Date => {
|
||||
let parsed;
|
||||
const ALLOWED_FORMATS =
|
||||
type === "date" ? ALLOWED_INPUT_FORMATS_DATE : ALLOWED_INPUT_FORMATS_MONTH;
|
||||
|
||||
if (allowTwoDigitYear) {
|
||||
for (const format of ALLOWED_FORMATS) {
|
||||
parsed = parse(date, format, today, { locale });
|
||||
if (
|
||||
isValidDate(parsed) &&
|
||||
!isTwoDigitYear(date, today, locale, ALLOWED_FORMATS)
|
||||
) {
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
for (const format of [
|
||||
...ALLOWED_FORMATS.map((x) => x.replace("yyyy", "yy")),
|
||||
]) {
|
||||
parsed = parse(date, format, today, { locale });
|
||||
if (
|
||||
isValidDate(parsed) &&
|
||||
isTwoDigitYear(date, today, locale, ALLOWED_FORMATS)
|
||||
) {
|
||||
const convertedDate = assignCenturyToDate(date, format, today, locale);
|
||||
|
||||
if (isValidDate(new Date(convertedDate))) {
|
||||
return new Date(convertedDate);
|
||||
} else {
|
||||
return new Date("Invalid date");
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Date("Invalid date");
|
||||
} else {
|
||||
for (const format of ALLOWED_FORMATS) {
|
||||
parsed = parse(date, format, today, { locale });
|
||||
if (
|
||||
isValidDate(parsed) &&
|
||||
!isTwoDigitYear(date, today, locale, ALLOWED_FORMATS)
|
||||
) {
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
return new Date("Invalid date");
|
||||
}
|
||||
};
|
||||
|
||||
function isTwoDigitYear(dateString, today, locale, formats) {
|
||||
let parsed;
|
||||
const newFormat = formats.map((x) => x.replace("yyyy", "yy"));
|
||||
for (const format of newFormat) {
|
||||
@@ -32,25 +87,49 @@ const isTwoDigitYear = (dateString, today, locale, formats) => {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
export const parseDate = (
|
||||
date: string,
|
||||
function assignCenturyToDate(
|
||||
dateStr: string,
|
||||
format: string,
|
||||
today: Date,
|
||||
locale: Locale,
|
||||
type: "date" | "month"
|
||||
): Date => {
|
||||
let parsed;
|
||||
const ALLOWED_FORMATS =
|
||||
type === "date" ? ALLOWED_INPUT_FORMATS_DATE : ALLOWED_INPUT_FORMATS_MONTH;
|
||||
for (const format of ALLOWED_FORMATS) {
|
||||
parsed = parse(date, format, today, { locale });
|
||||
if (
|
||||
isValidDate(parsed) &&
|
||||
!isTwoDigitYear(date, today, locale, ALLOWED_FORMATS)
|
||||
) {
|
||||
return parsed;
|
||||
}
|
||||
locale: Locale
|
||||
) {
|
||||
const date20Century = parse(
|
||||
appendCenturyToTwoYearDigitDateString(dateStr, "19"),
|
||||
format.replace("yy", "yyyy"),
|
||||
today,
|
||||
{ locale }
|
||||
);
|
||||
|
||||
const date21Century = parse(
|
||||
appendCenturyToTwoYearDigitDateString(dateStr, "20"),
|
||||
format.replace("yy", "yyyy"),
|
||||
today,
|
||||
{ locale }
|
||||
);
|
||||
|
||||
if (isValidDate(date20Century) && isValidDate(date21Century)) {
|
||||
return isBefore(
|
||||
date20Century,
|
||||
sub(new Date(), {
|
||||
years: 80,
|
||||
})
|
||||
)
|
||||
? date21Century
|
||||
: date20Century;
|
||||
}
|
||||
|
||||
return new Date("Invalid date");
|
||||
};
|
||||
}
|
||||
|
||||
function appendCenturyToTwoYearDigitDateString(
|
||||
dateString: string,
|
||||
century: "19" | "20"
|
||||
) {
|
||||
const twoDigitYear = dateString.slice(-2);
|
||||
return `${dateString.slice(
|
||||
0,
|
||||
dateString.length - 2
|
||||
)}${century}${twoDigitYear}`;
|
||||
}
|
||||
@@ -51,6 +51,7 @@ export const ConfirmationPanel = forwardRef<
|
||||
size={props.size}
|
||||
className="navds-confirmation-panel__content"
|
||||
id={`confirmation-panel-${id}`}
|
||||
as="div"
|
||||
>
|
||||
{children}
|
||||
</BodyLong>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import { BodyShort, Detail, omit } from "../..";
|
||||
import { FormFieldProps } from "../useFormField";
|
||||
import { useRadio } from "./useRadio";
|
||||
|
||||
@@ -23,7 +23,7 @@ export const Default = (props) => {
|
||||
value={props.controlled ? state : undefined}
|
||||
onChange={props.controlled ? setState : undefined}
|
||||
hideLegend={props.hideLegend}
|
||||
error={props.errorGroup ? "Errormelding" : undefined}
|
||||
error={props.error ? "Errormelding" : undefined}
|
||||
size={props?.size}
|
||||
>
|
||||
<Radio value="radio1">{props.children || "Apple"}</Radio>
|
||||
@@ -41,6 +41,7 @@ export const Default = (props) => {
|
||||
|
||||
Default.args = {
|
||||
controlled: false,
|
||||
error: false,
|
||||
size: "medium",
|
||||
legend: "Legend-tekst",
|
||||
radioDescription: false,
|
||||
|
||||
@@ -6,11 +6,15 @@ interface SVGRProps {
|
||||
titleId?: string;
|
||||
}
|
||||
|
||||
export const DefaultIllustration = ({
|
||||
export type DefaultIllustrationType = React.FunctionComponent<
|
||||
SVGProps<SVGSVGElement> & SVGRProps
|
||||
>;
|
||||
|
||||
export const DefaultIllustration: DefaultIllustrationType = ({
|
||||
title,
|
||||
titleId: _titleId,
|
||||
...props
|
||||
}: SVGProps<SVGSVGElement> & SVGRProps) => {
|
||||
}) => {
|
||||
let titleId: string | undefined = useId();
|
||||
titleId = title ? (_titleId ? _titleId : "title-" + titleId) : undefined;
|
||||
|
||||
|
||||
@@ -33,7 +33,12 @@ export interface LoaderProps extends SVGProps<SVGSVGElement> {
|
||||
variant?: "neutral" | "interaction" | "inverted";
|
||||
}
|
||||
|
||||
export const Loader = forwardRef<SVGSVGElement, LoaderProps>(
|
||||
/* Workaround for @types/react v17/v18 feil */
|
||||
export type LoaderType = React.ForwardRefExoticComponent<
|
||||
LoaderProps & React.RefAttributes<SVGSVGElement>
|
||||
>;
|
||||
|
||||
export const Loader: LoaderType = forwardRef<SVGSVGElement, LoaderProps>(
|
||||
(
|
||||
{
|
||||
children,
|
||||
|
||||
@@ -36,6 +36,10 @@ export interface ModalProps {
|
||||
* @default true
|
||||
*/
|
||||
closeButton?: boolean;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
shouldCloseOnEsc?: boolean;
|
||||
/**
|
||||
* Allows custom styling of ReactModal, in accordance with their typing
|
||||
*/
|
||||
@@ -75,6 +79,7 @@ export const Modal = forwardRef<ReactModal, ModalProps>(
|
||||
className,
|
||||
overlayClassName,
|
||||
shouldCloseOnOverlayClick = true,
|
||||
shouldCloseOnEsc = true,
|
||||
closeButton = true,
|
||||
"aria-describedby": ariaDescribedBy,
|
||||
"aria-labelledby": ariaLabelledBy,
|
||||
@@ -123,6 +128,7 @@ export const Modal = forwardRef<ReactModal, ModalProps>(
|
||||
className={cl("navds-modal", className)}
|
||||
overlayClassName={cl("navds-modal__overlay", overlayClassName)}
|
||||
shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}
|
||||
shouldCloseOnEsc={shouldCloseOnEsc}
|
||||
onRequestClose={(e) => onModalCloseRequest(e)}
|
||||
aria={{
|
||||
describedby: ariaDescribedBy,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
useDismiss,
|
||||
useFloating,
|
||||
useInteractions,
|
||||
} from "@floating-ui/react-dom-interactions";
|
||||
} from "@floating-ui/react";
|
||||
import cl from "clsx";
|
||||
import React, {
|
||||
forwardRef,
|
||||
|
||||
@@ -44,6 +44,7 @@ export const ColumnHeader: ColumnHeaderType = forwardRef(
|
||||
>
|
||||
{sortable ? (
|
||||
<button
|
||||
type="button"
|
||||
className="navds-table__sort-button"
|
||||
onClick={
|
||||
sortable && sortKey
|
||||
|
||||
@@ -85,6 +85,7 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
|
||||
>
|
||||
{!expansionDisabled && (
|
||||
<button
|
||||
type="button"
|
||||
className="navds-table__toggle-expand-button"
|
||||
aria-controls={id}
|
||||
aria-expanded={isOpen}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
useFocus,
|
||||
useHover,
|
||||
useInteractions,
|
||||
} from "@floating-ui/react-dom-interactions";
|
||||
} from "@floating-ui/react";
|
||||
import cl from "clsx";
|
||||
import React, {
|
||||
cloneElement,
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
# @navikt/ds-tailwind
|
||||
|
||||
## 2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
## 2.0.4
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tailwind",
|
||||
"version": "2.0.5",
|
||||
"version": "2.1.2",
|
||||
"description": "Tailwind config based on @navikt/ds-tokens",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -22,9 +22,8 @@
|
||||
"directory": "@navikt/core/tailwind"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^2.0.5",
|
||||
"@navikt/ds-tokens": "^2.1.2",
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/node": "^17.0.35",
|
||||
"color": "4.2.3",
|
||||
"jest": "^29.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
# @navikt/ds-tokens
|
||||
|
||||
## 2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1665](https://github.com/navikt/Designsystemet/pull/1665) [`6ab84e581`](https://github.com/navikt/Designsystemet/commit/6ab84e581f8d3e850bcec340608354335506a051) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Ny Timeline-komponent for interne-flater
|
||||
:bug: Fikset feil danger-hover token
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
## 2.0.4
|
||||
|
||||
@@ -240,7 +240,7 @@
|
||||
{ "name": "--a-surface-danger-subtle", "value": "rgba(255, 230, 230, 1)" },
|
||||
{
|
||||
"name": "--a-surface-danger-subtle-hover",
|
||||
"value": "rgba(255, 230, 230, 1)"
|
||||
"value": "rgba(255, 184, 184, 1)"
|
||||
},
|
||||
{ "name": "--a-surface-danger", "value": "rgba(195, 0, 0, 1)" },
|
||||
{ "name": "--a-surface-danger-hover", "value": "rgba(173, 0, 0, 1)" },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tokens",
|
||||
"version": "2.0.5",
|
||||
"version": "2.1.2",
|
||||
"description": "Design-tokens for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -31,7 +31,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/node": "^17.0.35",
|
||||
"color": "4.2.3",
|
||||
"jest": "^29.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
|
||||
"danger": {
|
||||
"subtle": {
|
||||
"hover": { "value": "{a.red.50.value}" },
|
||||
"hover": { "value": "{a.red.100.value}" },
|
||||
"@": { "value": "{a.red.50.value}" }
|
||||
},
|
||||
"hover": {
|
||||
|
||||
@@ -1,5 +1,57 @@
|
||||
# @navikt/ds-icons
|
||||
|
||||
## 2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1759](https://github.com/navikt/Designsystemet/pull/1759) [`dcf5cfc06`](https://github.com/navikt/Designsystemet/commit/dcf5cfc06b751341559ef30085bd974820531e57) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset @types/react v18 feil introdusert i v2.0.6
|
||||
|
||||
## 2.1.0
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`27e3dfee0`](https://github.com/navikt/Designsystemet/commit/27e3dfee07e135893e9f62cd32f80ed83a3510de) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Translate og Paragraph ikon
|
||||
|
||||
## 2.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`54f8b0795`](https://github.com/navikt/Designsystemet/commit/54f8b07956bbfb7de51f6682a5fc64903bfd1bdf) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert ikoner med feile farger
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`a6c339123`](https://github.com/navikt/Designsystemet/commit/a6c3391237f13394063e4c004ac9efb1875fc944) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Ikonjusteringer sirkleikoner
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Oppdatert svg-path i ikoner
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
## 2.0.4
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Fikser https://github.com/navikt/Designsystemet/issues/1758
|
||||
*/
|
||||
|
||||
const fs = require("fs");
|
||||
|
||||
const files = fs.readdirSync(`./esm`).filter((x) => x.endsWith(".d.ts"));
|
||||
|
||||
files.forEach((file) => {
|
||||
let data = fs.readFileSync(`./esm/${file}`).toString().split("\n");
|
||||
|
||||
data = data.map((x) => {
|
||||
return x.includes("React.ForwardRefExoticComponent")
|
||||
? x.split(":")[0] +
|
||||
`: React.ForwardRefExoticComponent<React.SVGProps<SVGSVGElement> & SVGRProps & React.RefAttributes<SVGSVGElement>>;`
|
||||
: x;
|
||||
});
|
||||
|
||||
fs.writeFileSync(`./esm/${file}`, data.join("\n"));
|
||||
});
|
||||
@@ -867,13 +867,13 @@
|
||||
"name": "Eu",
|
||||
"description": "",
|
||||
"created_at": "2022-02-08T11:45:47.104Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "EuFilled",
|
||||
"description": "",
|
||||
"created_at": "2022-02-08T11:45:47.109Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Expand",
|
||||
@@ -1479,13 +1479,13 @@
|
||||
"name": "Law",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:42.819Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "LawFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.330Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Left",
|
||||
@@ -1551,37 +1551,37 @@
|
||||
"name": "Locked",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:43.027Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "LockedFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.325Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Login",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:43.087Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "LoginFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.531Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Logout",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:42.931Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "LogoutFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.609Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Male",
|
||||
@@ -1811,6 +1811,12 @@
|
||||
"created_at": "2021-12-15T15:16:55.869Z",
|
||||
"pageName": "People"
|
||||
},
|
||||
{
|
||||
"name": "Paragraph",
|
||||
"description": "",
|
||||
"created_at": "2023-01-17T13:24:22.989Z",
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Parking",
|
||||
"description": "",
|
||||
@@ -1827,13 +1833,13 @@
|
||||
"name": "Passport",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:43.078Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "PassportFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.757Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "PensionBag",
|
||||
@@ -2615,6 +2621,12 @@
|
||||
"created_at": "2021-01-28T14:00:38.585Z",
|
||||
"pageName": "Buildings"
|
||||
},
|
||||
{
|
||||
"name": "Translate",
|
||||
"description": "",
|
||||
"created_at": "2023-01-18T10:52:22.311Z",
|
||||
"pageName": "Interface"
|
||||
},
|
||||
{
|
||||
"name": "Truck",
|
||||
"description": "",
|
||||
@@ -2643,13 +2655,13 @@
|
||||
"name": "Unlocked",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:42.823Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "UnlockedFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.317Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Up",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-icons",
|
||||
"version": "2.0.5",
|
||||
"version": "2.1.2",
|
||||
"description": "Aksel icons for NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"repository": {
|
||||
@@ -32,7 +32,7 @@
|
||||
"create-package-json-pointers-to-esm": "node ../../scripts/createPackageJsonsWithESMPointers.js",
|
||||
"create-icons": "svgr --silent --out-dir src svg",
|
||||
"clean": "rimraf src cjs esm",
|
||||
"build": "copyfiles util/* src && yarn create-icons && concurrently \"tsc\" \"tsc -p tsconfig.esm.json\" && yarn create-package-json-pointers-to-esm",
|
||||
"build": "copyfiles util/* src && yarn create-icons && concurrently \"tsc\" \"tsc -p tsconfig.esm.json\" && node cleanTypes.js && yarn create-package-json-pointers-to-esm",
|
||||
"update": "ts-node figma/index.ts dotenv/config",
|
||||
"test": "jest"
|
||||
},
|
||||
@@ -49,7 +49,6 @@
|
||||
"@svgr/cli": "6.2.1",
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/lodash.startcase": "^4.4.6",
|
||||
"@types/node": "^17.0.35",
|
||||
"@types/rimraf": "3.0.2",
|
||||
"axios": "^0.21.3",
|
||||
"concurrently": "7.2.1",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM13 6V11H18V13H13V18H11V13H6V11H11V6H13Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 2.5C6.64137 2.5 2.5 6.64137 2.5 11.75C2.5 16.8586 6.64137 21 11.75 21C16.8586 21 21 16.8586 21 11.75C21 6.64137 16.8586 2.5 11.75 2.5ZM1 11.75C1 5.81294 5.81294 1 11.75 1C17.6871 1 22.5 5.81294 22.5 11.75C22.5 17.6871 17.6871 22.5 11.75 22.5C5.81294 22.5 1 17.6871 1 11.75Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17 12.75H7V11.25H17V12.75Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.25 17L11.25 7L12.75 7L12.75 17H11.25Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 655 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0ZM13 6V11H18V13H13V18H11V13H6V11H11V6H13Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 1C5.81294 1 1 5.81294 1 11.75C1 17.6871 5.81294 22.5 11.75 22.5C17.6871 22.5 22.5 17.6871 22.5 11.75C22.5 5.81294 17.6871 1 11.75 1ZM11.25 12.75V17H12.75V12.75H17V11.25H12.75V7H11.25V11.25H7V12.75H11.25Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 381 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.70711 4.7071C8.09763 4.31657 8.09763 3.68341 7.70711 3.29289C7.31658 2.90236 6.68342 2.90236 6.29289 3.29289L2.29289 7.29289C2.10535 7.48042 2 7.73478 2 8C2 8.26521 2.10535 8.51957 2.29289 8.7071L6.29289 12.7071C6.68342 13.0976 7.31658 13.0976 7.70711 12.7071C8.09763 12.3166 8.09763 11.6834 7.70711 11.2929L5.41421 8.99999H15C17.7614 8.99999 20 11.2386 20 14C20 16.7614 17.7614 19 15 19H13.7879C13.2356 19 12.7879 19.4477 12.7879 20C12.7879 20.5523 13.2356 21 13.7879 21H15C18.866 21 22 17.866 22 14C22 10.134 18.866 6.99999 15 6.99999H5.41421L7.70711 4.7071Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.70708 4.7071L8.41418 3.99999L6.99997 2.58578L6.29286 3.29288L2.29286 7.29289L1.58575 7.99999L2.29286 8.7071L6.29286 12.7071L6.99997 13.4142L8.41418 12L7.70708 11.2929L5.41418 8.99999H15C17.7614 8.99999 20 11.2386 20 14C20 16.7614 17.7614 19 15 19H13.7878H12.7878V21H13.7878H15C18.866 21 22 17.866 22 14C22 10.134 18.866 6.99999 15 6.99999H5.41418L7.70708 4.7071Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 734 B After Width: | Height: | Size: 536 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 0C0.895431 0 0 0.89543 0 2V22C0 23.1046 0.89543 24 2 24H22C23.1046 24 24 23.1046 24 22V2C24 0.895431 23.1046 0 22 0H2ZM7.70711 3.29289C8.09763 3.68342 8.09763 4.31658 7.70711 4.70711L5.41422 7H15C18.866 7 22 10.134 22 14C22 17.866 18.866 21 15 21H13.7879C13.2356 21 12.7879 20.5523 12.7879 20C12.7879 19.4477 13.2356 19 13.7879 19H15C17.7614 19 20 16.7614 20 14C20 11.2386 17.7614 9 15 9H5.41421L7.70711 11.2929C8.09763 11.6834 8.09763 12.3166 7.70711 12.7071C7.31659 13.0976 6.68342 13.0976 6.2929 12.7071L2.29289 8.70711C2.10536 8.51957 2 8.26522 2 8C2 7.73479 2.10536 7.48043 2.29289 7.2929L6.2929 3.29289C6.68342 2.90237 7.31659 2.90237 7.70711 3.29289Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.41418 3.99999L6.99997 2.58578L1.58575 7.99999L6.99997 13.4142L8.41418 12L5.41418 8.99999H15C17.7614 8.99999 20 11.2386 20 14C20 16.7614 17.7614 19 15 19H12.7878V21H15C18.866 21 22 17.866 22 14C22 10.134 18.866 6.99999 15 6.99999H5.41418L8.41418 3.99999Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 831 B After Width: | Height: | Size: 427 B |
@@ -1,3 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 12C2 6.81465 5.94668 2.5511 11 2.04938V12.4142L18.3288 19.743C16.6044 21.1544 14.4017 22 12 22C6.47715 22 2 17.5228 2 12ZM19.7488 21.163C17.6587 22.9321 14.9533 24 12 24C5.37258 24 0 18.6274 0 12C0 5.70934 4.84047 0.549225 11 0.0410738V0H12H13V0.0410738C19.1595 0.549225 24 5.70934 24 12C24 14.9533 22.9321 17.6587 21.163 19.7488L21.1924 19.7782L20.4853 20.4853L19.7782 21.1924L19.7488 21.163ZM19.743 18.3288C21.1543 16.6044 22 14.4017 22 12C22 6.81465 18.0533 2.5511 13 2.04938V11.5858L19.743 18.3288Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.75C6.89137 2.75 2.75 6.89137 2.75 12C2.75 17.1086 6.89137 21.25 12 21.25C17.1086 21.25 21.25 17.1086 21.25 12C21.25 6.89137 17.1086 2.75 12 2.75ZM1.25 12C1.25 6.06294 6.06294 1.25 12 1.25C17.9371 1.25 22.75 6.06294 22.75 12C22.75 17.9371 17.9371 22.75 12 22.75C6.06294 22.75 1.25 17.9371 1.25 12Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.25 2.5H12.75V12.1729L19.5103 18.4504L18.4897 19.5496L11.25 12.8271V2.5Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 676 B After Width: | Height: | Size: 616 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 12V0.0410767C4.84047 0.549228 0 5.70934 0 12C0 18.6274 5.37258 24 12 24C14.9922 24 17.7286 22.9048 19.8303 21.0935L11 12ZM24 12C24 12.9017 23.9005 13.7803 23.712 14.6252C23.297 16.4847 22.4505 18.1814 21.2831 19.6048L13 11V0.0410767C18.2766 0.476386 22.5852 4.32557 23.712 9.37485C23.9005 10.2198 24 11.0983 24 12Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.25 1.27576C5.66285 1.6608 1.25 6.31506 1.25 12C1.25 17.9371 6.06294 22.75 12 22.75C14.5711 22.75 16.9313 21.8474 18.7812 20.3418L11.25 12.8107V1.27576ZM19.8766 19.3159C21.6596 17.3972 22.75 14.8259 22.75 12C22.75 6.31506 18.3372 1.6608 12.75 1.27576V12.1893L19.8766 19.3159Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 489 B After Width: | Height: | Size: 449 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 17V18H5V17H3ZM20 10L20.7071 10.7071L21.4142 10L20.7071 9.29289L20 10ZM16.7071 5.29289L16 4.58579L14.5858 6L15.2929 6.70711L16.7071 5.29289ZM15.2929 13.2929L14.5858 14L16 15.4142L16.7071 14.7071L15.2929 13.2929ZM5 17V14H3V17H5ZM8 11H20V9H8V11ZM20.7071 9.29289L16.7071 5.29289L15.2929 6.70711L19.2929 10.7071L20.7071 9.29289ZM19.2929 9.29289L15.2929 13.2929L16.7071 14.7071L20.7071 10.7071L19.2929 9.29289ZM5 14C5 12.3431 6.34315 11 8 11V9C5.23858 9 3 11.2386 3 14H5Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 4.58579L21.4142 10L16 15.4142L14.5858 14L17.5858 11H8C6.34315 11 5 12.3431 5 14V18H3V14C3 11.2386 5.23858 9 8 9H17.5858L14.5858 6.00001L16 4.58579Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 322 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 17V18H5V17H3ZM20 10L20.7071 10.7071L21.4142 10L20.7071 9.29289L20 10ZM16.7071 5.29289L16 4.58579L14.5858 6L15.2929 6.70711L16.7071 5.29289ZM15.2929 13.2929L14.5858 14L16 15.4142L16.7071 14.7071L15.2929 13.2929ZM5 17V14H3V17H5ZM8 11H20V9H8V11ZM20.7071 9.29289L16.7071 5.29289L15.2929 6.70711L19.2929 10.7071L20.7071 9.29289ZM19.2929 9.29289L15.2929 13.2929L16.7071 14.7071L20.7071 10.7071L19.2929 9.29289ZM5 14C5 12.3431 6.34315 11 8 11V9C5.23858 9 3 11.2386 3 14H5Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 4.58578L21.4142 10L16 15.4142L14.5858 14L17.5858 11H8C6.34315 11 5 12.3431 5 14V18H3V14C3 11.2386 5.23858 9 8 9H17.5858L14.5858 6L16 4.58578Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 316 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 0C0.447715 0 0 0.447716 0 1V23C0 23.5523 0.447716 24 1 24H23C23.5523 24 24 23.5523 24 23V1C24 0.447715 23.5523 0 23 0H1ZM12.2928 10.2929L17.5857 5L13 5V3H21V11H19V6.41412L13.707 11.7071L12.2928 10.2929ZM5 17.5859V13H3V21H11V19H6.4143L11.7072 13.7071L10.293 12.2929L5 17.5859Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.5857 5L12.2928 10.2929L13.707 11.7071L19 6.41412V11H21V3H13V5L17.5857 5ZM5 13V17.5859L10.293 12.2929L11.7072 13.7071L6.4143 19H11V21H3V13H5Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 315 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 0C0.447715 0 0 0.447716 0 1V23C0 23.5523 0.447716 24 1 24H23C23.5523 24 24 23.5523 24 23V1C24 0.447715 23.5523 0 23 0H1ZM21.7068 3.70709L16.414 8.99998H20.9999V11H12.9999V2.99998H14.9999V7.5856L20.2926 2.29288L21.7068 3.70709ZM2.29272 20.2929L7.58562 15L2.99991 15L2.99991 13L10.9999 13L10.9999 21H8.99991V16.4141L3.70694 21.7071L2.29272 20.2929Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.414 8.99998L21.7068 3.70709L20.2926 2.29288L14.9999 7.5856V2.99998H12.9999V11H20.9999V8.99998H16.414ZM7.58562 15L2.29272 20.2929L3.70694 21.7071L8.99991 16.4141L8.99991 21H10.9999L10.9999 13L2.99991 13L2.99991 15L7.58562 15Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 399 B |
@@ -1,3 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM18 11H6V13H18V11Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 2.5C6.64137 2.5 2.5 6.64137 2.5 11.75C2.5 16.8586 6.64137 21 11.75 21C16.8586 21 21 16.8586 21 11.75C21 6.64137 16.8586 2.5 11.75 2.5ZM1 11.75C1 5.81294 5.81294 1 11.75 1C17.6871 1 22.5 5.81294 22.5 11.75C22.5 17.6871 17.6871 22.5 11.75 22.5C5.81294 22.5 1 17.6871 1 11.75Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17 12.75H7V11.25H17V12.75Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 413 B After Width: | Height: | Size: 546 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C18.6274 24 24 18.6274 24 12ZM18 11H6V13H18V11Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 1C5.81294 1 1 5.81294 1 11.75C1 17.6871 5.81294 22.5 11.75 22.5C17.6871 22.5 22.5 17.6871 22.5 11.75C22.5 5.81294 17.6871 1 11.75 1ZM7 12.75H17V11.25H7V12.75Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 302 B After Width: | Height: | Size: 336 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C9.79085 2 7.99999 3.79086 7.99999 6C7.99999 6.66187 8.16311 7.29714 8.45828 7.85918C6.00646 9.12956 5.6173 13.1739 8.76271 14.4845L12.7692 16.1538C13.5145 16.4644 14 17.1926 14 18C14 19.1046 13.1046 20 12 20C10.8954 20 9.99999 19.1046 9.99999 18H7.99999C7.99999 20.2091 9.79085 22 12 22C14.2091 22 16 20.2091 16 18C16 17.3381 15.8369 16.7029 15.5417 16.1408C17.9935 14.8704 18.3827 10.8261 15.2373 9.51554L11.2308 7.84615C10.4855 7.53561 9.99999 6.8074 9.99999 6C9.99999 4.89543 10.8954 4 12 4C13.1046 4 14 4.89543 14 6H16C16 3.79086 14.2091 2 12 2ZM13.9738 14.5208C15.6075 14.4232 16.1245 12.0519 14.4681 11.3617L10.4615 9.69231C10.311 9.62957 10.1657 9.55832 10.0262 9.47924C8.39252 9.57681 7.87544 11.9481 9.53194 12.6383L13.5385 14.3077C13.689 14.3704 13.8343 14.4417 13.9738 14.5208Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 965 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.70711 3.7071C10.0976 3.31658 10.0976 2.68341 9.70711 2.29289C9.31658 1.90237 8.68342 1.90237 8.29289 2.29289L5.29289 5.29289C5.10535 5.48043 5 5.73478 5 6C5 6.26522 5.10535 6.51957 5.29289 6.70711L8.29289 9.7071C8.68342 10.0976 9.31658 10.0976 9.70711 9.7071C10.0976 9.31658 10.0976 8.68341 9.70711 8.29289L8.41421 7H17C18.6569 7 20 8.34314 20 10V12C20 12.5523 20.4477 13 21 13C21.5523 13 22 12.5523 22 12V10C22 7.23857 19.7614 5 17 5H8.41421L9.70711 3.7071ZM14.2929 20.2929C13.9024 20.6834 13.9024 21.3166 14.2929 21.7071C14.6834 22.0976 15.3166 22.0976 15.7071 21.7071L18.7071 18.7071C18.8946 18.5196 19 18.2652 19 18C19 17.7348 18.8946 17.4804 18.7071 17.2929L15.7071 14.2929C15.3166 13.9024 14.6834 13.9024 14.2929 14.2929C13.9024 14.6834 13.9024 15.3166 14.2929 15.7071L15.5858 17L7 17C5.34314 17 4 15.6568 4 14L4 12C4 11.4477 3.55228 11 3 11C2.44771 11 2 11.4477 2 12V14C2 16.7614 4.23858 19 7 19H15.5858L14.2929 20.2929Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.70711 3.7071L10.4142 2.99999L9 1.58578L8.29289 2.29289L5.29289 5.29289L4.58578 6L5.29289 6.7071L8.29289 9.7071L9 10.4142L10.4142 8.99999L9.70711 8.29289L8.41421 6.99999H17C18.6569 6.99999 20 8.34314 20 9.99999V12V13H22V12V9.99999C22 7.23857 19.7614 4.99999 17 4.99999H8.41421L9.70711 3.7071ZM14.2929 20.2929L13.5858 21L15 22.4142L15.7071 21.7071L18.7071 18.7071L19.4142 18L18.7071 17.2929L15.7071 14.2929L15 13.5858L13.5858 15L14.2929 15.7071L15.5858 17L7 17C5.34314 17 4 15.6568 4 14L4 12L4 11H2V12V14C2 16.7614 4.23858 19 7 19H15.5858L14.2929 20.2929Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 727 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 0C0.895431 0 0 0.89543 0 2V22C0 23.1046 0.89543 24 2 24H22C23.1046 24 24 23.1046 24 22V2C24 0.895431 23.1046 0 22 0H2ZM9.70711 2.29289C10.0976 2.68342 10.0976 3.31658 9.70711 3.70711L8.41421 5H17C19.7614 5 22 7.23858 22 10V12C22 12.5523 21.5523 13 21 13C20.4477 13 20 12.5523 20 12V10C20 8.34315 18.6569 7 17 7H8.41421L9.70711 8.29289C10.0976 8.68342 10.0976 9.31658 9.70711 9.70711C9.31658 10.0976 8.68342 10.0976 8.29289 9.70711L5.29289 6.70711C5.10535 6.51957 5 6.26522 5 6C5 5.73479 5.10535 5.48043 5.29289 5.2929L8.29289 2.29289C8.68342 1.90237 9.31658 1.90237 9.70711 2.29289ZM14.2929 21.7071C13.9024 21.3166 13.9024 20.6834 14.2929 20.2929L15.5858 19H7C4.23858 19 2 16.7614 2 14V12C2 11.4477 2.44771 11 3 11C3.55228 11 4 11.4477 4 12V14C4 15.6569 5.34314 17 7 17H15.5858L14.2929 15.7071C13.9024 15.3166 13.9024 14.6834 14.2929 14.2929C14.6834 13.9024 15.3166 13.9024 15.7071 14.2929L18.7071 17.2929C18.8946 17.4804 19 17.7348 19 18C19 18.2652 18.8946 18.5196 18.7071 18.7071L15.7071 21.7071C15.3166 22.0976 14.6834 22.0976 14.2929 21.7071Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.70711 3.7071L10.4142 2.99999L9 1.58578L8.29289 2.29289L5.29289 5.29289L4.58578 6L5.29289 6.7071L8.29289 9.7071L9 10.4142L10.4142 8.99999L9.70711 8.29289L8.41421 6.99999H17C18.6569 6.99999 20 8.34314 20 9.99999V12V13H22V12V9.99999C22 7.23857 19.7614 4.99999 17 4.99999H8.41421L9.70711 3.7071ZM14.2929 20.2929L13.5858 21L15 22.4142L15.7071 21.7071L18.7071 18.7071L19.4142 18L18.7071 17.2929L15.7071 14.2929L15 13.5858L13.5858 15L14.2929 15.7071L15.5858 17L7 17C5.34314 17 4 15.6568 4 14L4 12L4 11H2V12V14C2 16.7614 4.23858 19 7 19H15.5858L14.2929 20.2929Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 727 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.70817 6C8.11909 4.75448 9.9715 4 12 4C16.4183 4 20 7.58172 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12H2C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C9.27396 2 6.80296 3.09136 5 4.85869L5 2H3L3 8H9V6H6.70817Z" fill="#262626"/>
|
||||
<path d="M6.70817 6C8.11909 4.75448 9.9715 4 12 4C16.4183 4 20 7.58172 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12H2C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C9.27396 2 6.80296 3.09136 5 4.85869L5 2H3L3 8H9V6H6.70817Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 434 B After Width: | Height: | Size: 394 B |
@@ -0,0 +1,13 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.5 19.5L15.5 10.5L19.5 19.5" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13 17H18" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<mask id="mask0_6814_1365" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="4" width="15" height="17">
|
||||
<path d="M9.90083 18.7893L13.9008 9.78926C14.1817 9.15728 14.8084 8.75 15.5 8.75C16.1193 8.75 16.6865 9.07657 17.0001 9.59861V4H2.00005V21H10.5983C9.85068 20.5519 9.53784 19.606 9.90083 18.7893Z" fill="black"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_6814_1365)">
|
||||
<path d="M4 7.5H16" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 7.5V5.5" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13.5 7.5L13.4116 7.78744C12.2005 11.7232 9.30115 14.9162 5.5 16.5" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.5 7.5L6.58844 7.78744C7.79946 11.7232 10.6989 14.9162 14.5 16.5" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -1,5 +1,42 @@
|
||||
# @navikt/ds-css-internal
|
||||
|
||||
## 2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1665](https://github.com/navikt/Designsystemet/pull/1665) [`6ab84e581`](https://github.com/navikt/Designsystemet/commit/6ab84e581f8d3e850bcec340608354335506a051) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Ny Timeline-komponent for interne-flater
|
||||
:bug: Fikset feil danger-hover token
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
## 2.0.4
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@import "copy-to-clipboard.css";
|
||||
@import "dropdown.css";
|
||||
@import "header.css";
|
||||
@import "timeline.css";
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css-internal",
|
||||
"version": "2.0.5",
|
||||
"version": "2.1.2",
|
||||
"description": "CSS for NAV internal Designsystem-components",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
.navdsi-timeline {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
width: 100%;
|
||||
min-width: fit-content;
|
||||
}
|
||||
|
||||
.navdsi-timeline__axislabels {
|
||||
position: relative;
|
||||
height: 1rem;
|
||||
box-sizing: content-box;
|
||||
grid-column: 2;
|
||||
margin-bottom: var(--a-spacing-4);
|
||||
margin-left: var(--a-spacing-8);
|
||||
}
|
||||
|
||||
.navdsi-timeline__row-label {
|
||||
white-space: nowrap;
|
||||
width: auto;
|
||||
margin-right: var(--a-spacing-4);
|
||||
grid-column: 1;
|
||||
height: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navdsi-timeline__axislabels-label {
|
||||
position: absolute;
|
||||
color: var(--ac-timeline-axislabel-text, var(--a-text-subtle));
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.navdsi-timeline__row {
|
||||
display: flex;
|
||||
background: var(--ac-timeline-row-bg, var(--a-surface-subtle));
|
||||
margin: 0 0 var(--a-spacing-8);
|
||||
padding-left: var(--a-spacing-8);
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.navdsi-timeline__row--active {
|
||||
background: var(--ac-timeline-row-active-bg, var(--a-surface-selected));
|
||||
}
|
||||
|
||||
.navdsi-timeline__row:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.navdsi-timeline__row-periods {
|
||||
height: 1.5rem;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.navdsi-timeline__row-periods > li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.navdsi-timeline__period {
|
||||
height: 100%;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 2;
|
||||
border: none;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--inner {
|
||||
margin: 0 var(--a-spacing-1) 0 var(--a-spacing-2);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: clip;
|
||||
text-align: left;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
/* .navdsi-timeline__period > * {
|
||||
flex-shrink: 0;
|
||||
} */
|
||||
|
||||
.navdsi-timeline__period--clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--success {
|
||||
background: var(--ac-timeline-period-success-bg, var(--a-surface-success-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-success-border, var(--a-border-success));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--success.navdsi-timeline__period--clickable:hover {
|
||||
background: var(--a-surface-success-subtle-hover);
|
||||
background: var(--ac-timeline-period-success-bg-hover, var(--a-surface-success-subtle-hover));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--warning {
|
||||
background: var(--ac-timeline-period-warning-bg, var(--a-surface-warning-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-warning-border, var(--a-border-warning));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--warning.navdsi-timeline__period--clickable:hover {
|
||||
background: var(--ac-timeline-period-warning-bg-hover, var(--a-surface-warning-subtle-hover));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--danger {
|
||||
background: var(--ac-timeline-period-danger-bg, var(--a-surface-danger-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-danger-border, var(--a-border-danger));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--danger.navdsi-timeline__period--clickable:hover {
|
||||
background: var(--ac-timeline-period-danger-bg-hover, var(--a-surface-danger-subtle-hover));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--info {
|
||||
background: var(--ac-timeline-period-info-bg, var(--a-surface-info-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-info-border, var(--a-border-info));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--info.navdsi-timeline__period--clickable:hover {
|
||||
background: var(--ac-timeline-period-info-bg-hover, var(--a-surface-info-subtle-hover));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--neutral {
|
||||
background: var(--ac-timeline-period-neutral-bg, var(--a-bg-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-period-neutral-border, var(--a-border-default));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--neutral.navdsi-timeline__period--clickable:hover {
|
||||
background: var(--ac-timeline-period-neutral-bg-hover, var(--a-gray-200));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--connected-both {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--connected-right {
|
||||
border-bottom-right-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--connected-left {
|
||||
border-bottom-left-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--selected {
|
||||
box-shadow: inset 0 0 0 2px var(--ac-timeline-period-selected-border, var(--a-border-action-selected));
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.navdsi-timeline__pin-wrapper {
|
||||
position: absolute;
|
||||
grid-column: 2;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
isolation: isolate;
|
||||
|
||||
--navdsc-timeline-pin-size: 0.9rem;
|
||||
}
|
||||
|
||||
.navdsi-timeline__pin-button {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background: var(--a-surface-default);
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-pin-bg, var(--a-surface-danger)),
|
||||
0 0 0 4px var(--ac-timeline-pin-bg, var(--a-surface-danger)), 0 0 0 5px var(--a-surface-default);
|
||||
z-index: 2;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
padding: 3.5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navdsi-timeline__pin-button::before {
|
||||
content: "";
|
||||
inset: 0;
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
left: calc(-12.5px + 3.5px);
|
||||
top: calc(-12.5px + 3.5px);
|
||||
}
|
||||
|
||||
.navdsi-timeline__pin-button:focus {
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-pin-bg, var(--a-surface-danger)),
|
||||
0 0 0 3px var(--ac-timeline-pin-bg, var(--a-surface-danger)), 0 0 0 4px var(--a-surface-default),
|
||||
0 0 0 6px var(--a-border-focus);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.navdsi-timeline__pin-button:hover {
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)),
|
||||
0 0 0 4px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)), 0 0 0 5px var(--a-surface-default);
|
||||
}
|
||||
|
||||
.navdsi-timeline__pin-button:hover:focus {
|
||||
box-shadow: inset 0 0 0 1px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)),
|
||||
0 0 0 3px var(--ac-timeline-pin-bg-hover, var(--a-surface-danger-hover)), 0 0 0 4px var(--a-surface-default),
|
||||
0 0 0 6px var(--a-border-focus);
|
||||
}
|
||||
|
||||
.navdsi-timeline__pin-wrapper::before {
|
||||
content: "";
|
||||
top: var(--navdsc-timeline-pin-size);
|
||||
height: calc(94% - var(--navdsc-timeline-pin-size));
|
||||
width: 1px;
|
||||
margin: 0 auto;
|
||||
background: var(--a-surface-inverted);
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom {
|
||||
margin-top: var(--a-spacing-6);
|
||||
float: right;
|
||||
display: flex;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom-button {
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
padding: 6px 9px 6px 8px;
|
||||
border: 1px solid var(--ac-timeline-zoom-border, var(--a-border-default));
|
||||
border-width: 1px 0 1px 1px;
|
||||
background: var(--ac-timeline-zoom-bg, var(--a-surface-default));
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom li:first-child .navdsi-timeline__zoom-button {
|
||||
border-radius: var(--a-border-radius-medium) 0 0 var(--a-border-radius-medium);
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom li:last-child .navdsi-timeline__zoom-button {
|
||||
border-width: 1px;
|
||||
border-radius: 0 var(--a-border-radius-medium) var(--a-border-radius-medium) 0;
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom li:only-child .navdsi-timeline__zoom-button {
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom-button:not([aria-pressed="true"]):hover {
|
||||
background: var(--ac-timeline-zoom-hover, var(--a-surface-action-subtle-hover));
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom-button[aria-pressed="true"] {
|
||||
background: var(--ac-timeline-zoom-selected-bg, var(--a-surface-inverted));
|
||||
color: var(--ac-timeline-zoom-selected-text, var(--a-text-on-inverted));
|
||||
}
|
||||
|
||||
.navdsi-timeline__period:focus {
|
||||
outline: none;
|
||||
z-index: 4;
|
||||
box-shadow: 0 0 0 2px var(--a-border-focus);
|
||||
}
|
||||
|
||||
.navdsi-timeline__period--selected:focus {
|
||||
box-shadow: inset 0 0 0 2px var(--ac-timeline-period-selected-border, var(--a-border-action-selected)),
|
||||
0 0 0 2px var(--a-border-focus);
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom li:focus-within {
|
||||
z-index: var(--a-z-index-focus);
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom-button:focus {
|
||||
box-shadow: 0 0 0 1px var(--a-surface-default), 0 0 0 3px var(--a-border-focus);
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.navdsi-timeline__zoom li:not(:last-child) .navdsi-timeline__zoom-button:focus {
|
||||
margin-right: 2px;
|
||||
padding-right: 6px;
|
||||
}
|
||||
@@ -16,5 +16,33 @@
|
||||
"--ac-header-text": "--a-text-on-inverted",
|
||||
"--ac-header-hover-bg": "--a-surface-inverted-hover",
|
||||
"--ac-header-active-bg": "--a-surface-inverted-active"
|
||||
},
|
||||
"timeline": {
|
||||
"--ac-timeline-row-bg": "--a-surface-subtle",
|
||||
"--ac-timeline-row-active-bg": "--a-surface-selected",
|
||||
"--ac-timeline-period-success-bg": "--a-surface-success-subtle",
|
||||
"--ac-timeline-period-success-border": "--a-border-success",
|
||||
"--ac-timeline-period-success-bg-hover": "--a-surface-success-subtle-hover",
|
||||
"--ac-timeline-period-warning-bg": "--a-surface-warning-subtle",
|
||||
"--ac-timeline-period-warning-border": "--a-border-warning",
|
||||
"--ac-timeline-period-warning-bg-hover": "--a-surface-warning-subtle-hover",
|
||||
"--ac-timeline-period-danger-bg": "--a-surface-danger-subtle",
|
||||
"--ac-timeline-period-danger-border": "--a-border-danger",
|
||||
"--ac-timeline-period-danger-bg-hover": "--a-surface-danger-subtle-hover",
|
||||
"--ac-timeline-period-info-bg": "--a-surface-info-subtle",
|
||||
"--ac-timeline-period-info-border": "--a-border-info",
|
||||
"--ac-timeline-period-info-bg-hover": "--a-surface-info-subtle-hover",
|
||||
"--ac-timeline-period-neutral-bg": "--a-bg-subtle",
|
||||
"--ac-timeline-period-neutral-border": "--a-border-default",
|
||||
"--ac-timeline-period-neutral-bg-hover": "--a-gray-200",
|
||||
"--ac-timeline-period-selected-border": "--a-border-action-selected",
|
||||
"--ac-timeline-pin-bg": "--a-surface-danger",
|
||||
"--ac-timeline-pin-bg-hover": "--a-surface-danger-hover",
|
||||
"--ac-timeline-zoom-border": "--a-border-default",
|
||||
"--ac-timeline-zoom-bg": "--a-surface-default",
|
||||
"--ac-timeline-zoom-hover": "--a-surface-action-subtle-hover",
|
||||
"--ac-timeline-zoom-selected-bg": "--a-surface-inverted",
|
||||
"--ac-timeline-zoom-selected-text": "--a-text-on-inverted",
|
||||
"--ac-timeline-axislabel-text": "--a-text-subtle"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,138 @@
|
||||
# @navikt/ds-react-internal
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.1.2
|
||||
- @navikt/ds-icons@2.1.2
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`dcf5cfc06`](https://github.com/navikt/Designsystemet/commit/dcf5cfc06b751341559ef30085bd974820531e57)]:
|
||||
- @navikt/ds-react@2.1.1
|
||||
- @navikt/ds-icons@2.1.1
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1665](https://github.com/navikt/Designsystemet/pull/1665) [`6ab84e581`](https://github.com/navikt/Designsystemet/commit/6ab84e581f8d3e850bcec340608354335506a051) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Ny Timeline-komponent for interne-flater
|
||||
:bug: Fikset feil danger-hover token
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0873fe652`](https://github.com/navikt/Designsystemet/commit/0873fe6520e817e462197c162b49c05826da4838)]:
|
||||
- @navikt/ds-react@2.1.0
|
||||
- @navikt/ds-icons@2.1.0
|
||||
|
||||
## 2.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`98177d0cd`](https://github.com/navikt/Designsystemet/commit/98177d0cd3802029dcf398ce93c1767d3b0860c5)]:
|
||||
- @navikt/ds-react@2.0.18
|
||||
- @navikt/ds-icons@2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`27e3dfee0`](https://github.com/navikt/Designsystemet/commit/27e3dfee07e135893e9f62cd32f80ed83a3510de)]:
|
||||
- @navikt/ds-icons@2.0.17
|
||||
- @navikt/ds-react@2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`54f8b0795`](https://github.com/navikt/Designsystemet/commit/54f8b07956bbfb7de51f6682a5fc64903bfd1bdf)]:
|
||||
- @navikt/ds-icons@2.0.16
|
||||
- @navikt/ds-react@2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`22dfd8e60`](https://github.com/navikt/Designsystemet/commit/22dfd8e60315c421749394d35e41f412a00a7593)]:
|
||||
- @navikt/ds-react@2.0.15
|
||||
- @navikt/ds-icons@2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8e5c55443`](https://github.com/navikt/Designsystemet/commit/8e5c554431c98b1b658c5054c0b3cf08b8a65e52)]:
|
||||
- @navikt/ds-react@2.0.14
|
||||
- @navikt/ds-icons@2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a6c339123`](https://github.com/navikt/Designsystemet/commit/a6c3391237f13394063e4c004ac9efb1875fc944)]:
|
||||
- @navikt/ds-icons@2.0.13
|
||||
- @navikt/ds-react@2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.0.12
|
||||
- @navikt/ds-icons@2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.11
|
||||
- @navikt/ds-react@2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.0.10
|
||||
- @navikt/ds-icons@2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.0.9
|
||||
- @navikt/ds-icons@2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.0.8
|
||||
- @navikt/ds-icons@2.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.0.7
|
||||
- @navikt/ds-icons@2.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.0.6
|
||||
- @navikt/ds-icons@2.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react-internal",
|
||||
"version": "2.0.5",
|
||||
"version": "2.1.2",
|
||||
"description": "Aksel react components for internal UIs in NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -35,13 +35,12 @@
|
||||
"watch": "tsc --watch -p tsconfig.esm.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-icons": "^2.0.5",
|
||||
"@navikt/ds-react": "^2.0.5",
|
||||
"@navikt/ds-icons": "^2.1.2",
|
||||
"@navikt/ds-react": "^2.1.2",
|
||||
"clsx": "^1.1.1",
|
||||
"copy-to-clipboard": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^17.0.35",
|
||||
"concurrently": "7.2.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-node": "10.9.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./copy-to-clipboard";
|
||||
export * from "./dropdown";
|
||||
export * from "./header";
|
||||
export * from "./timeline";
|
||||
@@ -0,0 +1,142 @@
|
||||
import { Detail } from "@navikt/ds-react";
|
||||
import {
|
||||
addDays,
|
||||
addMonths,
|
||||
addYears,
|
||||
differenceInDays,
|
||||
differenceInMonths,
|
||||
differenceInYears,
|
||||
endOfMonth,
|
||||
endOfYear,
|
||||
format,
|
||||
startOfDay,
|
||||
startOfMonth,
|
||||
startOfYear,
|
||||
subDays,
|
||||
} from "date-fns";
|
||||
import React from "react";
|
||||
import { useTimelineContext } from "./hooks/useTimelineContext";
|
||||
import { isVisible } from "./utils";
|
||||
import { horizontalPositionAndWidth } from "./utils/calc";
|
||||
import { AxisLabel } from "./utils/types.external";
|
||||
|
||||
export const dayLabels = (
|
||||
start: Date,
|
||||
end: Date,
|
||||
totalDays: number,
|
||||
direction: "left" | "right"
|
||||
): AxisLabel[] => {
|
||||
const increment = Math.ceil(totalDays / 10);
|
||||
const lastDay = startOfDay(end);
|
||||
return new Array(totalDays)
|
||||
.fill(lastDay)
|
||||
.map((thisDay, i) => {
|
||||
if (i % increment !== 0) return null;
|
||||
const day: Date = subDays(thisDay, i);
|
||||
const { horizontalPosition, width } = horizontalPositionAndWidth(
|
||||
day,
|
||||
addDays(day, 1),
|
||||
start,
|
||||
end
|
||||
);
|
||||
return {
|
||||
direction: direction,
|
||||
horizontalPosition: horizontalPosition,
|
||||
label: format(day, "MM.dd"),
|
||||
date: day,
|
||||
width: width,
|
||||
};
|
||||
})
|
||||
.filter((label) => label !== null) as AxisLabel[];
|
||||
};
|
||||
|
||||
export const monthLabels = (
|
||||
start: Date,
|
||||
end: Date,
|
||||
direction: "left" | "right"
|
||||
): AxisLabel[] => {
|
||||
const startMonth = startOfMonth(start);
|
||||
const endMonth = endOfMonth(end);
|
||||
const numberOfMonths = differenceInMonths(endMonth, startMonth) + 1;
|
||||
return new Array(numberOfMonths).fill(startMonth).map((thisMonth, i) => {
|
||||
const month: Date = addMonths(thisMonth, i);
|
||||
const { horizontalPosition, width } = horizontalPositionAndWidth(
|
||||
month,
|
||||
addMonths(month, 1),
|
||||
start,
|
||||
end
|
||||
);
|
||||
return {
|
||||
direction: direction,
|
||||
horizontalPosition: horizontalPosition,
|
||||
label: format(month, "MMM yy"),
|
||||
date: month,
|
||||
width: width,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const yearLabels = (
|
||||
start: Date,
|
||||
end: Date,
|
||||
direction: "left" | "right"
|
||||
): AxisLabel[] => {
|
||||
const firstYear = startOfYear(start);
|
||||
const lastYear = endOfYear(end);
|
||||
const yearCount = differenceInYears(lastYear, start) + 1;
|
||||
return new Array(yearCount).fill(firstYear).map((thisYear, i) => {
|
||||
const year: Date = addYears(thisYear, i);
|
||||
const { horizontalPosition, width } = horizontalPositionAndWidth(
|
||||
year,
|
||||
addYears(year, 1),
|
||||
start,
|
||||
end
|
||||
);
|
||||
return {
|
||||
direction: direction,
|
||||
horizontalPosition: horizontalPosition,
|
||||
label: year.getFullYear().toString(),
|
||||
date: year,
|
||||
width: width,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const axisLabels = (
|
||||
start: Date,
|
||||
end: Date,
|
||||
direction: "left" | "right"
|
||||
): AxisLabel[] => {
|
||||
const totalDays = differenceInDays(end, start);
|
||||
if (totalDays < 40) {
|
||||
return dayLabels(start, end, totalDays, direction);
|
||||
} else if (totalDays < 370) {
|
||||
return monthLabels(start, end, direction);
|
||||
} else {
|
||||
return yearLabels(start, end, direction);
|
||||
}
|
||||
};
|
||||
|
||||
export const AxisLabels = () => {
|
||||
const { endDate, startDate, direction } = useTimelineContext();
|
||||
const labels = axisLabels(startDate, endDate, direction).filter(isVisible);
|
||||
|
||||
return (
|
||||
<div className="navdsi-timeline__axislabels" aria-hidden="true">
|
||||
{labels.map((etikett) => (
|
||||
<Detail
|
||||
className="navdsi-timeline__axislabels-label"
|
||||
as="div"
|
||||
key={etikett.label}
|
||||
style={{
|
||||
justifyContent: direction === "left" ? "flex-start" : "flex-end",
|
||||
[direction]: `${etikett.horizontalPosition}%`,
|
||||
width: `${etikett.width}%`,
|
||||
}}
|
||||
>
|
||||
{etikett.label}
|
||||
</Detail>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import { mergeRefs, Popover } from "@navikt/ds-react";
|
||||
import { format } from "date-fns";
|
||||
import React, { forwardRef, useMemo, useRef, useState } from "react";
|
||||
import { useTimelineContext } from "./hooks/useTimelineContext";
|
||||
import { position } from "./utils/calc";
|
||||
import { TimelineComponentTypes } from "./utils/types.internal";
|
||||
|
||||
export interface TimelinePinProps {
|
||||
/**
|
||||
* Date position for the pin.
|
||||
*/
|
||||
date: Date;
|
||||
/**
|
||||
* Content in Pin Popover.
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface PinType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
TimelinePinProps & React.RefAttributes<HTMLButtonElement>
|
||||
> {
|
||||
componentType: TimelineComponentTypes;
|
||||
}
|
||||
|
||||
export const Pin = forwardRef<HTMLButtonElement, TimelinePinProps>(
|
||||
({ date, children, ...rest }, ref) => {
|
||||
const { startDate, endDate, direction } = useTimelineContext();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const buttonRef = useRef<HTMLButtonElement | null>(null);
|
||||
const mergedRef = useMemo(() => mergeRefs([buttonRef, ref]), [ref]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="navdsi-timeline__pin-wrapper"
|
||||
style={{ [direction]: `${position(date, startDate, endDate)}%` }}
|
||||
>
|
||||
<button
|
||||
{...rest}
|
||||
ref={mergedRef}
|
||||
className="navdsi-timeline__pin-button"
|
||||
onClick={() => setOpen(!open)}
|
||||
aria-label={`pin:${format(date, "dd.MM.yyyy")}`}
|
||||
aria-expanded={open}
|
||||
/>
|
||||
</div>
|
||||
{children && (
|
||||
<Popover
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
anchorEl={buttonRef.current}
|
||||
offset={18}
|
||||
>
|
||||
<Popover.Content>{children}</Popover.Content>
|
||||
</Popover>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
) as PinType;
|
||||
|
||||
Pin.componentType = "pin";
|
||||
|
||||
export default Pin;
|
||||
@@ -0,0 +1,209 @@
|
||||
import { endOfDay, isSameDay, startOfDay } from "date-fns";
|
||||
import React, { forwardRef, useMemo, useRef, useState } from "react";
|
||||
import { AxisLabels } from "./AxisLabels";
|
||||
import { RowContext } from "./hooks/useRowContext";
|
||||
import { TimelineContext } from "./hooks/useTimelineContext";
|
||||
import {
|
||||
useEarliestDate,
|
||||
useLatestDate,
|
||||
useTimelineRows,
|
||||
} from "./hooks/useTimelineRows";
|
||||
import Period, { PeriodType } from "./period";
|
||||
import Pin, { PinType } from "./Pin";
|
||||
import TimelineRow, { TimelineRowType } from "./TimelineRow";
|
||||
import { parseRows } from "./utils/timeline";
|
||||
import Zoom, { ZoomType } from "./zoom";
|
||||
|
||||
export interface TimelineProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* Decides startingpoint in timeline.
|
||||
* Defaults to earliest date among the timeline periods.
|
||||
*/
|
||||
startDate?: Date;
|
||||
/**
|
||||
* Decides end-date for timeline.
|
||||
* Defaults to the latest date among the timeline periods.
|
||||
*/
|
||||
endDate?: Date;
|
||||
/**
|
||||
* Decides direction which periods are sorted/displayed. "left" ascends from earliest date on left.
|
||||
* @default "left"
|
||||
*/
|
||||
direction?: "left" | "right";
|
||||
}
|
||||
|
||||
interface TimelineComponent
|
||||
extends React.ForwardRefExoticComponent<TimelineProps> {
|
||||
/**
|
||||
* Built-in timeline row
|
||||
*/
|
||||
Row: TimelineRowType;
|
||||
/**
|
||||
* Built-in row period
|
||||
*/
|
||||
Period: PeriodType;
|
||||
/**
|
||||
* Built-in timeline pin
|
||||
*/
|
||||
Pin: PinType;
|
||||
/**
|
||||
* Built-in timeline zoom-component
|
||||
*/
|
||||
Zoom: ZoomType;
|
||||
}
|
||||
|
||||
export const Timeline = forwardRef<HTMLDivElement, TimelineProps>(
|
||||
({ children, startDate, endDate, direction = "left", ...rest }, ref) => {
|
||||
const isMultipleRows = Array.isArray(children);
|
||||
|
||||
const firstFocusabled = useRef<
|
||||
{ ref: HTMLButtonElement | null; id: number }[]
|
||||
>([]);
|
||||
|
||||
if (!isMultipleRows) {
|
||||
children = [children];
|
||||
}
|
||||
const rowChildren = React.Children.toArray(children).filter(
|
||||
(c: any) => c?.type?.componentType === "row"
|
||||
);
|
||||
|
||||
const pins = React.Children.toArray(children).filter(
|
||||
(c: any) => c?.type?.componentType === "pin"
|
||||
);
|
||||
|
||||
const zoomComponent = React.Children.toArray(children).find(
|
||||
(c: any) => c?.type?.componentType === "zoom"
|
||||
);
|
||||
|
||||
const rowsRaw = useMemo(() => {
|
||||
return parseRows(rowChildren);
|
||||
}, [rowChildren]);
|
||||
|
||||
const rows = rowsRaw.map((r) => {
|
||||
if (r?.periods) {
|
||||
return r.periods;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
const initialStartDate = startOfDay(useEarliestDate({ startDate, rows }));
|
||||
const [start, setStart] = useState(initialStartDate);
|
||||
const [activeRow, setActiveRow] = useState<number | null>(null);
|
||||
const [endInclusive, setEndInclusive] = useState(
|
||||
endOfDay(useLatestDate({ endDate, rows }))
|
||||
);
|
||||
|
||||
const initialEndDate = endOfDay(useLatestDate({ endDate, rows }));
|
||||
const processedRows = useTimelineRows(
|
||||
rowsRaw,
|
||||
start,
|
||||
endInclusive,
|
||||
direction
|
||||
);
|
||||
|
||||
const handleZoomChange = (zoomStart: Date) => {
|
||||
if (direction === "left") {
|
||||
if (isSameDay(zoomStart, start)) {
|
||||
setStart(initialStartDate);
|
||||
return;
|
||||
}
|
||||
setStart(zoomStart);
|
||||
} else {
|
||||
if (isSameDay(zoomStart, endInclusive)) {
|
||||
setEndInclusive(initialEndDate);
|
||||
return;
|
||||
}
|
||||
setEndInclusive(zoomStart);
|
||||
}
|
||||
};
|
||||
|
||||
const handleActiveRowChange = (key: string) => {
|
||||
if (activeRow !== null && key === "ArrowDown") {
|
||||
for (let i = activeRow + 1; i < processedRows.length; i++) {
|
||||
const row = processedRows[i];
|
||||
if (row.periods.find((p) => !!p.children || !!p.onSelectPeriod)) {
|
||||
setActiveRow(i);
|
||||
firstFocusabled.current.find((x) => x.id === i)?.ref?.focus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (activeRow !== null && key === "ArrowUp") {
|
||||
for (let i = activeRow - 1; i >= 0; i--) {
|
||||
const row = processedRows[i];
|
||||
if (row.periods.find((p) => !!p.children || !!p.onSelectPeriod)) {
|
||||
setActiveRow(i);
|
||||
firstFocusabled.current.find((x) => x.id === i)?.ref?.focus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const addFocusable = (ref: HTMLButtonElement | null, id: number) => {
|
||||
let items = firstFocusabled.current;
|
||||
items = items.filter((x) => x.id !== id);
|
||||
items.push({ ref, id });
|
||||
firstFocusabled.current = items;
|
||||
};
|
||||
|
||||
return (
|
||||
<TimelineContext.Provider
|
||||
value={{
|
||||
startDate: start,
|
||||
endDate: endInclusive,
|
||||
direction: direction,
|
||||
setStart: (d) => handleZoomChange(d),
|
||||
setEndInclusive: (d) => setEndInclusive(d),
|
||||
activeRow: activeRow,
|
||||
setActiveRow: (key) => handleActiveRowChange(key),
|
||||
initiate: (i) => setActiveRow(i),
|
||||
addFocusable,
|
||||
}}
|
||||
>
|
||||
<div {...rest} ref={ref}>
|
||||
<div className="navdsi-timeline">
|
||||
<AxisLabels />
|
||||
|
||||
{pins.map((pin) => {
|
||||
return pin;
|
||||
})}
|
||||
|
||||
{processedRows.map((row, i) => {
|
||||
return (
|
||||
<RowContext.Provider
|
||||
key={`row-${row.id}`}
|
||||
value={{
|
||||
periods: row.periods,
|
||||
id: row.id,
|
||||
active: activeRow === i,
|
||||
index: i,
|
||||
}}
|
||||
>
|
||||
<TimelineRow
|
||||
{...row?.restProps}
|
||||
ref={row?.ref}
|
||||
label={row.label}
|
||||
icon={row.icon}
|
||||
headingTag={row.headingTag}
|
||||
/>
|
||||
</RowContext.Provider>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{zoomComponent && zoomComponent}
|
||||
</div>
|
||||
</TimelineContext.Provider>
|
||||
);
|
||||
}
|
||||
) as TimelineComponent;
|
||||
|
||||
Timeline.Row = TimelineRow;
|
||||
Timeline.Period = Period;
|
||||
Timeline.Pin = Pin;
|
||||
Timeline.Zoom = Zoom;
|
||||
|
||||
export default Timeline;
|
||||
@@ -0,0 +1,122 @@
|
||||
import { BodyShort } from "@navikt/ds-react";
|
||||
import { format } from "date-fns";
|
||||
import React, { forwardRef } from "react";
|
||||
import { PeriodContext } from "./hooks/usePeriodContext";
|
||||
import { useRowContext } from "./hooks/useRowContext";
|
||||
import { useTimelineContext } from "./hooks/useTimelineContext";
|
||||
import Period from "./period";
|
||||
import {
|
||||
PositionedPeriod,
|
||||
TimelineComponentTypes,
|
||||
} from "./utils/types.internal";
|
||||
import cl from "clsx";
|
||||
|
||||
export interface TimelineRowProps
|
||||
extends React.HTMLAttributes<HTMLOListElement> {
|
||||
/**
|
||||
* Label for the timeline row
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Heading level for the label e.g h2, h3...
|
||||
* @default "h3"
|
||||
*/
|
||||
headingTag?: "h2" | "h3" | "h4" | "h5" | "h6";
|
||||
/**
|
||||
* Icon next to label
|
||||
*/
|
||||
icon?: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface TimelineRowType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
TimelineRowProps & React.RefAttributes<HTMLOListElement>
|
||||
> {
|
||||
componentType: TimelineComponentTypes;
|
||||
}
|
||||
|
||||
export const TimelineRow = forwardRef<HTMLOListElement, TimelineRowProps>(
|
||||
({ label, headingTag = "h3", icon, ...rest }, ref) => {
|
||||
const { periods, id, active } = useRowContext();
|
||||
const { setActiveRow } = useTimelineContext();
|
||||
|
||||
const latest = periods.reduce((a, b) => {
|
||||
return a.end > b.end ? a : b;
|
||||
}, {} as PositionedPeriod);
|
||||
|
||||
const earliest = periods.reduce((a, b) => {
|
||||
return a.end < b.end ? a : b;
|
||||
}, {} as PositionedPeriod);
|
||||
|
||||
const firstFocusable = periods.find(
|
||||
(p) => !!p.children || !!p.onSelectPeriod
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{label && (
|
||||
<BodyShort
|
||||
as={headingTag}
|
||||
id={`timeline-row-${id}`}
|
||||
className="navdsi-timeline__row-label"
|
||||
size="small"
|
||||
>
|
||||
{icon}
|
||||
{label}
|
||||
</BodyShort>
|
||||
)}
|
||||
<div
|
||||
className={cl("navdsi-timeline__row", {
|
||||
"navdsi-timeline__row--active": active,
|
||||
})}
|
||||
>
|
||||
<ol
|
||||
{...rest}
|
||||
ref={ref}
|
||||
aria-label={
|
||||
periods.length === 0
|
||||
? "Ingen perioder"
|
||||
: `${format(earliest.start, "dd.MM.yyyy")} til ${format(
|
||||
latest.end,
|
||||
"dd.MM.yyyy"
|
||||
)}`
|
||||
}
|
||||
className="navdsi-timeline__row-periods"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
||||
e.preventDefault();
|
||||
setActiveRow(e.key);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{periods &&
|
||||
periods.map((period) => {
|
||||
return (
|
||||
<li key={`period-${period.id}`}>
|
||||
<PeriodContext.Provider
|
||||
value={{
|
||||
periodId: period.id,
|
||||
firstFocus: firstFocusable?.id === period.id,
|
||||
restProps: period?.restProps,
|
||||
}}
|
||||
>
|
||||
<Period
|
||||
start={period.start}
|
||||
end={period.endInclusive}
|
||||
icon={period.icon}
|
||||
ref={period?.ref}
|
||||
/>
|
||||
</PeriodContext.Provider>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ol>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
) as TimelineRowType;
|
||||
|
||||
TimelineRow.componentType = "row";
|
||||
|
||||
export default TimelineRow;
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createContext, useContext } from "react";
|
||||
|
||||
interface PeriodContextProps {
|
||||
periodId: String;
|
||||
firstFocus: boolean;
|
||||
restProps?: any;
|
||||
}
|
||||
|
||||
export const PeriodContext = createContext<PeriodContextProps>({
|
||||
periodId: "",
|
||||
firstFocus: false,
|
||||
});
|
||||
|
||||
export const usePeriodContext = () => {
|
||||
const context = useContext(PeriodContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn("usePeriodContext must be used with PeriodContext");
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
import { createContext, useContext } from "react";
|
||||
import { PositionedPeriod } from "../utils/types.internal";
|
||||
|
||||
interface RowContextProps {
|
||||
periods: PositionedPeriod[];
|
||||
id: string;
|
||||
active: boolean;
|
||||
index: number;
|
||||
}
|
||||
|
||||
export const RowContext = createContext<RowContextProps>({
|
||||
periods: [],
|
||||
id: "",
|
||||
active: false,
|
||||
index: 0,
|
||||
});
|
||||
|
||||
export const useRowContext = () => {
|
||||
const context = useContext(RowContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn("useRowContext must be used with RowContext");
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import { createContext, useContext } from "react";
|
||||
|
||||
interface TimelineContextProps {
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
direction: "left" | "right";
|
||||
setStart: (d: Date) => void;
|
||||
setEndInclusive: (d: Date) => void;
|
||||
activeRow: number | null;
|
||||
setActiveRow: (i: string) => void;
|
||||
initiate: (i: number) => void;
|
||||
addFocusable: (ref: HTMLButtonElement | null, id: number) => void;
|
||||
}
|
||||
|
||||
export const TimelineContext = createContext<TimelineContextProps>({
|
||||
startDate: new Date(),
|
||||
endDate: new Date(),
|
||||
direction: "left",
|
||||
setStart: () => null,
|
||||
setEndInclusive: () => null,
|
||||
activeRow: 0,
|
||||
setActiveRow: () => null,
|
||||
initiate: () => null,
|
||||
addFocusable: () => null,
|
||||
});
|
||||
|
||||
export const useTimelineContext = () => {
|
||||
const context = useContext(TimelineContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn(
|
||||
"useTimelineContext must be used with TimelineContext (<Timeline />)"
|
||||
);
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
@@ -0,0 +1,161 @@
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { addDays, endOfDay, isAfter, startOfDay, subDays } from "date-fns";
|
||||
|
||||
import { lastPeriod } from "../utils/sort";
|
||||
import { Period } from "../utils/types.external";
|
||||
import {
|
||||
InternalSimpleTimeline,
|
||||
PositionedPeriod,
|
||||
} from "../utils/types.internal";
|
||||
|
||||
import { horizontalPositionAndWidth } from "../utils/calc";
|
||||
import { invisiblePeriods, withinADay } from "../utils/filter";
|
||||
|
||||
const spatialPeriod = (
|
||||
period: Period,
|
||||
timelineStart: Date,
|
||||
timelineEndInclusive: Date,
|
||||
direction: "left" | "right" = "left",
|
||||
i: number,
|
||||
periods: PositionedPeriod[],
|
||||
rowIndex: number
|
||||
): PositionedPeriod => {
|
||||
const start = period.start;
|
||||
const endInclusive = period.end;
|
||||
|
||||
const rightOverlap =
|
||||
i < periods.length - 1 && !isAfter(periods[i + 1].start, endInclusive);
|
||||
|
||||
const { horizontalPosition, width } = horizontalPositionAndWidth(
|
||||
startOfDay(start),
|
||||
endOfDay(
|
||||
rightOverlap ? startOfDay(subDays(periods[i + 1].start, 1)) : endInclusive
|
||||
),
|
||||
timelineStart,
|
||||
timelineEndInclusive
|
||||
);
|
||||
|
||||
return {
|
||||
id: `r-${rowIndex}-p-${i}`,
|
||||
start: start,
|
||||
endInclusive: endInclusive,
|
||||
horizontalPosition: horizontalPosition,
|
||||
direction: direction,
|
||||
width: width,
|
||||
end: endInclusive,
|
||||
status: period.status,
|
||||
onSelectPeriod: period.onSelectPeriod,
|
||||
icon: period.icon,
|
||||
children: period.children,
|
||||
isActive: period.isActive,
|
||||
statusLabel: period.statusLabel,
|
||||
};
|
||||
};
|
||||
|
||||
const adjustedEdges = (
|
||||
period: PositionedPeriod,
|
||||
i: number,
|
||||
allPeriods: PositionedPeriod[]
|
||||
): PositionedPeriod => {
|
||||
const left =
|
||||
i > 0 && withinADay(period.start, allPeriods[i - 1].endInclusive);
|
||||
const right =
|
||||
i < allPeriods.length - 1 &&
|
||||
withinADay(allPeriods[i + 1].start, period.endInclusive);
|
||||
|
||||
return left && right
|
||||
? { ...period, cropped: "both" }
|
||||
: left
|
||||
? { ...period, cropped: "left" }
|
||||
: right
|
||||
? { ...period, cropped: "right" }
|
||||
: period;
|
||||
};
|
||||
|
||||
const trimmedPeriods = (period: PositionedPeriod) => {
|
||||
let { horizontalPosition, width, cropped } = period;
|
||||
if (horizontalPosition + width > 100) {
|
||||
width = 100 - horizontalPosition;
|
||||
cropped = cropped === "left" || cropped === "both" ? "both" : "right";
|
||||
}
|
||||
if (horizontalPosition < 0 && horizontalPosition + width > 0) {
|
||||
width = horizontalPosition + width;
|
||||
horizontalPosition = 0;
|
||||
cropped = cropped === "right" || cropped === "both" ? "both" : "left";
|
||||
}
|
||||
|
||||
return {
|
||||
...period,
|
||||
width: width,
|
||||
horizontalPosition: horizontalPosition,
|
||||
cropped: cropped,
|
||||
};
|
||||
};
|
||||
|
||||
export const useTimelineRows = (
|
||||
rows: any,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
direction: "left" | "right"
|
||||
): InternalSimpleTimeline[] =>
|
||||
useMemo(
|
||||
() =>
|
||||
rows.map((periods: InternalSimpleTimeline, i: number) => {
|
||||
const rowIndex = i;
|
||||
const timelinePeriods = periods.periods
|
||||
.sort((a: Period, b: Period) => a.start.valueOf() - b.start.valueOf())
|
||||
.map((period: Period & { restProps?: any; ref?: any }, i) => ({
|
||||
...spatialPeriod(
|
||||
period,
|
||||
startDate,
|
||||
endDate,
|
||||
direction,
|
||||
i,
|
||||
periods.periods,
|
||||
rowIndex
|
||||
),
|
||||
restProps: period?.restProps,
|
||||
ref: period?.ref,
|
||||
}))
|
||||
.sort(lastPeriod)
|
||||
.map(adjustedEdges)
|
||||
.map(trimmedPeriods)
|
||||
.filter(invisiblePeriods);
|
||||
return {
|
||||
id: `tl-row-${rowIndex}`,
|
||||
label: periods.label,
|
||||
headingTag: periods.headingTag || "h3",
|
||||
icon: periods.icon,
|
||||
periods:
|
||||
direction === "left" ? timelinePeriods : timelinePeriods.reverse(),
|
||||
restProps: periods?.restProps,
|
||||
ref: periods?.ref,
|
||||
};
|
||||
}),
|
||||
[rows, startDate, endDate, direction]
|
||||
);
|
||||
|
||||
const earliestDate = (earliest: Date, period: Period) =>
|
||||
period.start < earliest ? period.start : earliest;
|
||||
|
||||
const earliestFomDate = (rader: Period[][]) =>
|
||||
rader.flat().reduce(earliestDate, new Date());
|
||||
|
||||
export const useEarliestDate = ({ startDate, rows }: any) =>
|
||||
useMemo(
|
||||
() => (startDate ? startDate : earliestFomDate(rows)),
|
||||
[startDate, rows]
|
||||
);
|
||||
|
||||
const latestDate = (latest: Date, period: Period) =>
|
||||
period.end > latest ? period.end : latest;
|
||||
|
||||
const latestTomDate = (rows: Period[][]) =>
|
||||
rows.flat().reduce(latestDate, new Date(0));
|
||||
|
||||
export const useLatestDate = ({ endDate, rows }: any) =>
|
||||
useMemo(
|
||||
() => (endDate ? endDate : addDays(latestTomDate(rows), 1)),
|
||||
[endDate, rows]
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
export { default as Timeline } from "./Timeline";
|
||||
export type { TimelineProps } from "./Timeline";
|
||||
export type { TimelineRowProps } from "./TimelineRow";
|
||||
export type { TimelinePinProps } from "./Pin";
|
||||
export type { TimelinePeriodProps } from "./period";
|
||||
export type { TimelineZoomButtonProps } from "./zoom/ZoomButton";
|
||||
@@ -0,0 +1,91 @@
|
||||
import { mergeRefs, Popover } from "@navikt/ds-react";
|
||||
import cl from "clsx";
|
||||
import React, { useMemo, useRef, useState } from "react";
|
||||
import { usePeriodContext } from "../hooks/usePeriodContext";
|
||||
import { useRowContext } from "../hooks/useRowContext";
|
||||
import { useTimelineContext } from "../hooks/useTimelineContext";
|
||||
import { ariaLabel, getConditionalClasses } from "../utils/period";
|
||||
import { PeriodProps } from "./index";
|
||||
|
||||
interface TimelineClickablePeriodProps extends PeriodProps {
|
||||
onSelectPeriod?: () => void;
|
||||
isActive?: boolean;
|
||||
periodRef: React.ForwardedRef<HTMLButtonElement>;
|
||||
}
|
||||
|
||||
const ClickablePeriod = React.memo(
|
||||
({
|
||||
onSelectPeriod,
|
||||
start,
|
||||
end,
|
||||
status,
|
||||
cropped,
|
||||
direction,
|
||||
left,
|
||||
width,
|
||||
icon,
|
||||
children,
|
||||
isActive,
|
||||
statusLabel,
|
||||
restProps,
|
||||
periodRef,
|
||||
}: TimelineClickablePeriodProps) => {
|
||||
const buttonRef = useRef<HTMLButtonElement | null>(null);
|
||||
const [selected, setSelected] = useState(false);
|
||||
const { index } = useRowContext();
|
||||
const { firstFocus } = usePeriodContext();
|
||||
const { initiate, addFocusable } = useTimelineContext();
|
||||
|
||||
const mergedRef = useMemo(
|
||||
() => mergeRefs([buttonRef, periodRef]),
|
||||
[periodRef]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
{...restProps}
|
||||
ref={(r) => {
|
||||
firstFocus && addFocusable(r, index);
|
||||
mergedRef(r);
|
||||
}}
|
||||
onClick={() => {
|
||||
children && setSelected((x) => !x);
|
||||
onSelectPeriod?.();
|
||||
}}
|
||||
aria-label={ariaLabel(start, end, status, statusLabel)}
|
||||
className={cl(
|
||||
"navdsi-timeline__period--clickable",
|
||||
getConditionalClasses(cropped, direction, status),
|
||||
restProps?.className,
|
||||
{
|
||||
"navdsi-timeline__period--selected": isActive,
|
||||
}
|
||||
)}
|
||||
style={{
|
||||
width: `${width}%`,
|
||||
[direction]: `${left}%`,
|
||||
}}
|
||||
aria-expanded={children ? selected : undefined}
|
||||
onFocus={() => {
|
||||
initiate(index);
|
||||
}}
|
||||
>
|
||||
<div className="navdsi-timeline__period--inner">{icon}</div>
|
||||
</button>
|
||||
{children && (
|
||||
<Popover
|
||||
open={selected}
|
||||
onClose={() => setSelected(false)}
|
||||
anchorEl={buttonRef.current}
|
||||
strategy="fixed"
|
||||
>
|
||||
<Popover.Content>{children}</Popover.Content>
|
||||
</Popover>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default ClickablePeriod;
|
||||
@@ -0,0 +1,44 @@
|
||||
import React from "react";
|
||||
import { ariaLabel, getConditionalClasses } from "../utils/period";
|
||||
import { PeriodProps } from "./index";
|
||||
import cl from "clsx";
|
||||
|
||||
interface TimelineNonClickablePeriodProps extends PeriodProps {
|
||||
periodRef?: React.ForwardedRef<HTMLDivElement>;
|
||||
}
|
||||
|
||||
const NonClickablePeriod = ({
|
||||
start,
|
||||
end,
|
||||
status,
|
||||
cropped,
|
||||
direction,
|
||||
left,
|
||||
width,
|
||||
icon,
|
||||
statusLabel,
|
||||
restProps,
|
||||
periodRef,
|
||||
}: TimelineNonClickablePeriodProps) => {
|
||||
return (
|
||||
<div
|
||||
ref={periodRef}
|
||||
{...restProps}
|
||||
className={cl(
|
||||
getConditionalClasses(cropped, direction, status),
|
||||
restProps?.classname
|
||||
)}
|
||||
style={{
|
||||
width: `${width}%`,
|
||||
[direction]: `${left}%`,
|
||||
}}
|
||||
>
|
||||
<div className="navdsi-timeline__period--inner">
|
||||
{icon}
|
||||
<p className="sr-only">{ariaLabel(start, end, status, statusLabel)}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NonClickablePeriod;
|
||||
@@ -0,0 +1,130 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import { usePeriodContext } from "../hooks/usePeriodContext";
|
||||
import { useRowContext } from "../hooks/useRowContext";
|
||||
import { TimelineComponentTypes } from "../utils/types.internal";
|
||||
import ClickablePeriod from "./ClickablePeriod";
|
||||
import NonClickablePeriod from "./NonClickablePeriod";
|
||||
|
||||
export interface TimelinePeriodProps
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* Period start date.
|
||||
*/
|
||||
start: Date;
|
||||
/**
|
||||
* Period end date.
|
||||
*/
|
||||
end: Date;
|
||||
/**
|
||||
* Icon for easier visual identification.
|
||||
*/
|
||||
icon?: React.ReactNode;
|
||||
/**
|
||||
* Period status.
|
||||
* @default "neutral"
|
||||
*/
|
||||
status?: "success" | "warning" | "danger" | "info" | "neutral";
|
||||
/**
|
||||
* Status label for screen-readers
|
||||
* e.g "Sykemeldt", "foreldrepermisjon"
|
||||
*/
|
||||
statusLabel?: string;
|
||||
/**
|
||||
* Callback when selecting a period.
|
||||
*/
|
||||
onSelectPeriod?: () => void;
|
||||
/**
|
||||
* Content displayed in Popover on click.
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
/**
|
||||
* Visual active inidcation on period
|
||||
* @note Make sure only one period is active at a time
|
||||
*/
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
export interface PeriodProps {
|
||||
start: Date;
|
||||
end: Date;
|
||||
status: string;
|
||||
cropped: string;
|
||||
direction: string;
|
||||
width: Number;
|
||||
left: Number;
|
||||
icon?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
statusLabel?: string;
|
||||
restProps?: any;
|
||||
}
|
||||
|
||||
export interface PeriodType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
TimelinePeriodProps &
|
||||
React.RefAttributes<HTMLDivElement | HTMLButtonElement>
|
||||
> {
|
||||
componentType: TimelineComponentTypes;
|
||||
}
|
||||
|
||||
export const Period = forwardRef<HTMLDivElement, TimelinePeriodProps>(
|
||||
({ icon }, ref) => {
|
||||
const { periods } = useRowContext();
|
||||
const { periodId, restProps } = usePeriodContext();
|
||||
|
||||
const period = periods.find((p) => p.id === periodId);
|
||||
|
||||
if (!period) {
|
||||
return <></>;
|
||||
}
|
||||
const {
|
||||
start,
|
||||
endInclusive,
|
||||
width,
|
||||
horizontalPosition,
|
||||
status = "neutral",
|
||||
onSelectPeriod,
|
||||
cropped,
|
||||
direction,
|
||||
children,
|
||||
isActive,
|
||||
statusLabel,
|
||||
} = period;
|
||||
|
||||
return onSelectPeriod || children ? (
|
||||
<ClickablePeriod
|
||||
periodRef={ref as React.ForwardedRef<HTMLButtonElement>}
|
||||
start={start}
|
||||
end={endInclusive}
|
||||
status={status}
|
||||
onSelectPeriod={onSelectPeriod}
|
||||
cropped={cropped || ""}
|
||||
direction={direction}
|
||||
width={width}
|
||||
left={horizontalPosition}
|
||||
icon={icon}
|
||||
children={children}
|
||||
isActive={isActive}
|
||||
statusLabel={statusLabel}
|
||||
restProps={restProps}
|
||||
/>
|
||||
) : (
|
||||
<NonClickablePeriod
|
||||
periodRef={ref}
|
||||
start={start}
|
||||
end={endInclusive}
|
||||
status={status}
|
||||
cropped={cropped || ""}
|
||||
direction={direction}
|
||||
width={width}
|
||||
left={horizontalPosition}
|
||||
icon={icon}
|
||||
statusLabel={statusLabel}
|
||||
restProps={restProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
) as PeriodType;
|
||||
|
||||
Period.componentType = "period";
|
||||
|
||||
export default Period;
|
||||
@@ -0,0 +1,326 @@
|
||||
import { SuccessFilled } from "@navikt/ds-icons";
|
||||
import { useState } from "@storybook/addons";
|
||||
import { Meta } from "@storybook/react";
|
||||
import * as React from "react";
|
||||
import Timeline from "./Timeline";
|
||||
|
||||
export default {
|
||||
title: "ds-react-internal/Timeline",
|
||||
component: Timeline,
|
||||
argTypes: {},
|
||||
} as Meta;
|
||||
|
||||
const DummyLabel = () => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: "239px",
|
||||
margin: 0,
|
||||
textAlign: "left",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
<p>Periode: 15.07.2019 - 25.07.2019</p>
|
||||
<p>Utbetalt: 12 345,00 kr</p>
|
||||
<p style={{ color: "red" }}>Dager igjen: 0</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const row1 = [
|
||||
{
|
||||
id: "1",
|
||||
start: new Date("Jan 1 2022"),
|
||||
end: new Date("Jan 31 2022"),
|
||||
status: "success",
|
||||
icon: <SuccessFilled aria-hidden />,
|
||||
statusLabel: "Sykemeldt",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
start: new Date("Feb 1 2022"),
|
||||
end: new Date("Mar 15 2022"),
|
||||
status: "danger",
|
||||
onSelectPeriod: () => console.log("PERIOD SELECTED!"),
|
||||
statusLabel: "Sykemeldt",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
start: new Date("May 2 2022"),
|
||||
end: new Date("May 25 2022"),
|
||||
status: "success",
|
||||
icon: <SuccessFilled aria-hidden />,
|
||||
statusLabel: "Sykemeldt",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
start: new Date("Mar 1 2022"),
|
||||
end: new Date("Mar 31 2022"),
|
||||
status: "success",
|
||||
onSelectPeriod: () => console.log("PERIOD SELECTED!"),
|
||||
icon: <SuccessFilled aria-hidden />,
|
||||
label: "test",
|
||||
statusLabel: "Sykemeldt",
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
start: new Date("Jul 1 2022"),
|
||||
end: new Date("Jul 31 2022"),
|
||||
status: "warning",
|
||||
icon: <SuccessFilled aria-hidden />,
|
||||
onSelectPeriod: () => console.log("PERIOD SELECTED!"),
|
||||
statusLabel: "Sykemeldt",
|
||||
},
|
||||
{
|
||||
id: "6",
|
||||
start: new Date("Aug 1 2022"),
|
||||
end: new Date("Aug 30 2022"),
|
||||
status: "warning",
|
||||
icon: <SuccessFilled aria-hidden />,
|
||||
statusLabel: "Sykemeldt",
|
||||
},
|
||||
];
|
||||
|
||||
const row2 = [
|
||||
{
|
||||
id: "7",
|
||||
start: new Date("May 13 2022"),
|
||||
end: new Date("May 25 2022"),
|
||||
status: "warning",
|
||||
onSelectPeriod: () => console.log("PERIOD SELECTED!"),
|
||||
icon: <SuccessFilled aria-hidden />,
|
||||
children: <DummyLabel />,
|
||||
},
|
||||
{
|
||||
id: "8",
|
||||
start: new Date("Feb 1 2022"),
|
||||
end: new Date("May 2 2022"),
|
||||
status: "neutral",
|
||||
onSelectPeriod: () => console.log("PERIOD SELECTED!"),
|
||||
icon: <SuccessFilled aria-hidden />,
|
||||
children: <DummyLabel />,
|
||||
},
|
||||
];
|
||||
|
||||
export const Default = () => {
|
||||
return (
|
||||
<div style={{ width: "80vw" }}>
|
||||
<Timeline>
|
||||
<Timeline.Row label="Row 1" icon={<SuccessFilled aria-hidden />}>
|
||||
{row1.map((p: any, i) => {
|
||||
return (
|
||||
<Timeline.Period
|
||||
key={p.id}
|
||||
start={p.start}
|
||||
end={p.end}
|
||||
status={p.status}
|
||||
icon={p.icon}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Timeline.Row>
|
||||
<Timeline.Row label="Row 2" icon={<SuccessFilled aria-hidden />}>
|
||||
{row2.map((p: any, i) => {
|
||||
return (
|
||||
<Timeline.Period
|
||||
key={p.id}
|
||||
start={p.start}
|
||||
end={p.end}
|
||||
status={p.status}
|
||||
icon={p.icon}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Timeline.Row>
|
||||
</Timeline>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const WithPins = () => {
|
||||
return (
|
||||
<div style={{ width: "80vw" }}>
|
||||
<Timeline>
|
||||
<Timeline.Pin date={new Date("Apr 15 2022")}>Pin 1</Timeline.Pin>
|
||||
<Timeline.Pin date={new Date("Jun 12 2022")}>Pin 2</Timeline.Pin>
|
||||
<Timeline.Pin date={new Date("Jul 28 2022")}>Pin 3</Timeline.Pin>
|
||||
<Timeline.Row label="Row 1" icon={<SuccessFilled aria-hidden />}>
|
||||
{row1.map((p: any, i) => {
|
||||
return (
|
||||
<Timeline.Period
|
||||
key={p.id}
|
||||
start={p.start}
|
||||
end={p.end}
|
||||
status={p.status}
|
||||
icon={p.icon}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Timeline.Row>
|
||||
<Timeline.Row label="Row 2" icon={<SuccessFilled aria-hidden />}>
|
||||
{row2.map((p: any, i) => {
|
||||
return (
|
||||
<Timeline.Period
|
||||
key={p.id}
|
||||
start={p.start}
|
||||
end={p.end}
|
||||
status={p.status}
|
||||
icon={p.icon}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Timeline.Row>
|
||||
</Timeline>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const WithZoom = () => {
|
||||
return (
|
||||
<div style={{ width: "80vw" }}>
|
||||
<Timeline>
|
||||
<Timeline.Row label="Row 1" icon={<SuccessFilled aria-hidden />}>
|
||||
{row1.map((p: any, i) => {
|
||||
return (
|
||||
<Timeline.Period
|
||||
key={p.id}
|
||||
start={p.start}
|
||||
end={p.end}
|
||||
status={p.status}
|
||||
icon={p.icon}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Timeline.Row>
|
||||
<Timeline.Row label="Row 2" icon={<SuccessFilled aria-hidden />}>
|
||||
{row2.map((p: any, i) => {
|
||||
return (
|
||||
<Timeline.Period
|
||||
key={p.id}
|
||||
start={p.start}
|
||||
end={p.end}
|
||||
status={p.status}
|
||||
icon={p.icon}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Timeline.Row>
|
||||
<Timeline.Zoom>
|
||||
<Timeline.Zoom.Button label="3 mnd" interval="month" count={3} />
|
||||
<Timeline.Zoom.Button label="7 mnd" interval="month" count={7} />
|
||||
<Timeline.Zoom.Button label="9 mnd" interval="month" count={9} />
|
||||
</Timeline.Zoom>
|
||||
</Timeline>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const ActivePeriod = () => {
|
||||
const [activePeriod, setActivePeriod] = useState(row1[0]);
|
||||
|
||||
return (
|
||||
<div style={{ width: "80vw" }}>
|
||||
<Timeline>
|
||||
<Timeline.Pin date={new Date("Apr 15 2022")}>Pin 1</Timeline.Pin>
|
||||
<Timeline.Pin date={new Date("Jun 12 2022")}>Pin 2</Timeline.Pin>
|
||||
<Timeline.Pin date={new Date("Jul 28 2022")}>Pin 3</Timeline.Pin>
|
||||
<Timeline.Row label="Rad 1" icon={<SuccessFilled aria-hidden />}>
|
||||
{row1.map((p: any, i) => {
|
||||
return (
|
||||
<Timeline.Period
|
||||
key={p.id}
|
||||
start={p.start}
|
||||
end={p.end}
|
||||
status={p.status}
|
||||
onSelectPeriod={() => {
|
||||
setActivePeriod(p);
|
||||
p?.onSelectPeriod?.();
|
||||
}}
|
||||
icon={p.icon}
|
||||
isActive={activePeriod.id === p.id}
|
||||
statusLabel={p.statusLabel}
|
||||
>
|
||||
{p.children}
|
||||
</Timeline.Period>
|
||||
);
|
||||
})}
|
||||
</Timeline.Row>
|
||||
<Timeline.Row label="Rad 2">
|
||||
{row2.map((p: any, i) => {
|
||||
return (
|
||||
<Timeline.Period
|
||||
key={p.id}
|
||||
start={p.start}
|
||||
end={p.end}
|
||||
status={p.status}
|
||||
onSelectPeriod={() => {
|
||||
setActivePeriod(p);
|
||||
p?.onSelectPeriod?.();
|
||||
}}
|
||||
icon={p.icon}
|
||||
isActive={activePeriod.id === p.id}
|
||||
statusLabel={p.statusLabel}
|
||||
>
|
||||
{p.children}
|
||||
</Timeline.Period>
|
||||
);
|
||||
})}
|
||||
</Timeline.Row>
|
||||
<Timeline.Row label="Rad 3">
|
||||
<Timeline.Period
|
||||
start={new Date("Jan 1 2022")}
|
||||
end={new Date("Aug 20 2022")}
|
||||
status="info"
|
||||
icon={<SuccessFilled aria-hidden />}
|
||||
/>
|
||||
</Timeline.Row>
|
||||
</Timeline>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const WithDayLabels = () => {
|
||||
return (
|
||||
<div style={{ width: "80vw" }}>
|
||||
<Timeline>
|
||||
<Timeline.Row label="Row 1" icon={<SuccessFilled aria-hidden />}>
|
||||
<Timeline.Period
|
||||
start={new Date("Feb 4 2022")}
|
||||
end={new Date("Feb 13 2022")}
|
||||
status="success"
|
||||
/>
|
||||
</Timeline.Row>
|
||||
<Timeline.Row label="Row 2" icon={<SuccessFilled aria-hidden />}>
|
||||
<Timeline.Period
|
||||
start={new Date("Feb 17 2022")}
|
||||
end={new Date("Feb 22 2022")}
|
||||
status="warning"
|
||||
/>
|
||||
</Timeline.Row>
|
||||
</Timeline>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const WithYearLabels = () => {
|
||||
return (
|
||||
<div style={{ width: "80vw" }}>
|
||||
<Timeline>
|
||||
<Timeline.Row label="Row 1" icon={<SuccessFilled aria-hidden />}>
|
||||
<Timeline.Period
|
||||
start={new Date("Feb 4 2022")}
|
||||
end={new Date("Feb 13 2028")}
|
||||
status="success"
|
||||
/>
|
||||
</Timeline.Row>
|
||||
<Timeline.Row label="Row 2" icon={<SuccessFilled aria-hidden />}>
|
||||
<Timeline.Period
|
||||
start={new Date("Feb 17 2024")}
|
||||
end={new Date("Feb 22 2031")}
|
||||
status="warning"
|
||||
/>
|
||||
</Timeline.Row>
|
||||
</Timeline>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
import { differenceInMilliseconds } from "date-fns";
|
||||
|
||||
export const position = (date: Date, start: Date, endInclusive: Date) => {
|
||||
const diff = differenceInMilliseconds(endInclusive, start);
|
||||
return (differenceInMilliseconds(date, start) / diff) * 100;
|
||||
};
|
||||
|
||||
export const horizontalPositionAndWidth = (
|
||||
start: Date,
|
||||
endInclusive: Date,
|
||||
timelineStart: Date,
|
||||
timelineEndInclusive: Date
|
||||
) => {
|
||||
const horizontalPosition = position(
|
||||
start,
|
||||
timelineStart,
|
||||
timelineEndInclusive
|
||||
);
|
||||
const width =
|
||||
position(endInclusive, timelineStart, timelineEndInclusive) -
|
||||
horizontalPosition;
|
||||
return {
|
||||
horizontalPosition: horizontalPosition,
|
||||
width: width,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
import { differenceInDays } from "date-fns";
|
||||
import { PeriodProps } from "../period";
|
||||
import { Spatial } from "./types.internal";
|
||||
|
||||
export interface Positioned {
|
||||
horizontalPosition: number;
|
||||
direction: "left" | "right";
|
||||
}
|
||||
|
||||
export const isVisible = ({ horizontalPosition }: Positioned): boolean =>
|
||||
horizontalPosition <= 98 && horizontalPosition >= 0;
|
||||
|
||||
export const getFirstDate = (periods: any) => {
|
||||
return periods.sort(
|
||||
(a: PeriodProps, b: PeriodProps) => a.start.getTime() - b.start.getTime()
|
||||
)[0].start;
|
||||
};
|
||||
|
||||
export const getLastDate = (periods: any) => {
|
||||
return periods.sort(
|
||||
(a: PeriodProps, b: PeriodProps) => a.end.getTime() - b.end.getTime()
|
||||
)[periods.length - 1].end;
|
||||
};
|
||||
|
||||
export const withinADay = (date1: Date, date2: Date): boolean =>
|
||||
differenceInDays(date1, date2) <= 1;
|
||||
|
||||
export const invisiblePeriods = ({
|
||||
horizontalPosition,
|
||||
width,
|
||||
}: Positioned & Spatial) =>
|
||||
horizontalPosition >= 0 && horizontalPosition <= 100 && width > 0;
|
||||
@@ -0,0 +1 @@
|
||||
export { getFirstDate, getLastDate, isVisible, Positioned } from "./filter";
|
||||
@@ -0,0 +1,48 @@
|
||||
import cl from "clsx";
|
||||
import { format } from "date-fns";
|
||||
|
||||
export const getConditionalClasses = (
|
||||
cropped: string,
|
||||
direction: string,
|
||||
status: string
|
||||
) => {
|
||||
return cl(`navdsi-timeline__period navdsi-timeline__period--${status}`, {
|
||||
"navdsi-timeline__period--connected-both": cropped === "both",
|
||||
"navdsi-timeline__period--connected-right":
|
||||
(cropped === "right" && direction === "left") ||
|
||||
(cropped === "left" && direction === "right"),
|
||||
"navdsi-timeline__period--connected-left":
|
||||
(cropped === "left" && direction === "left") ||
|
||||
(cropped === "right" && direction === "right"),
|
||||
});
|
||||
};
|
||||
|
||||
const translateStatus = (status: string): string => {
|
||||
switch (status) {
|
||||
case "success":
|
||||
return "Suksess";
|
||||
case "warning":
|
||||
return "Advarsel";
|
||||
case "danger":
|
||||
return "Fare";
|
||||
case "info":
|
||||
return "Info";
|
||||
case "neutral":
|
||||
return "Nøytral";
|
||||
default:
|
||||
return status;
|
||||
}
|
||||
};
|
||||
|
||||
export const ariaLabel = (
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
status: string,
|
||||
statusLabel?: string
|
||||
): string => {
|
||||
const start = format(startDate, "dd.MM.yyyy");
|
||||
const end = format(endDate, "dd.MM.yyyy");
|
||||
return `${
|
||||
statusLabel ? statusLabel : translateStatus(status)
|
||||
} fra ${start} til ${end}`;
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import { differenceInMilliseconds } from "date-fns";
|
||||
import { Period, PositionedPeriod } from "./types.internal";
|
||||
|
||||
export const lastDate = (a: Date, b: Date): number =>
|
||||
differenceInMilliseconds(a, b);
|
||||
|
||||
export const lastPeriod = (a: PositionedPeriod, b: PositionedPeriod): number =>
|
||||
a.horizontalPosition - b.horizontalPosition;
|
||||
|
||||
export const lastSinglePeriod = (a: Period, b: Period): number =>
|
||||
differenceInMilliseconds(b.endInclusive, a.endInclusive);
|
||||
@@ -0,0 +1,83 @@
|
||||
import { omit } from "@navikt/ds-react";
|
||||
import React, { ReactNode } from "react";
|
||||
import { Period } from "./types.external";
|
||||
|
||||
type ParsedChild = {
|
||||
label?: string;
|
||||
icon?: React.ReactNode;
|
||||
headingTag: string;
|
||||
periods: Omit<Period, "id" | "endInclusive">[];
|
||||
restProps: any;
|
||||
ref: any;
|
||||
};
|
||||
|
||||
export const parseRows = (rowChildren: ReactNode[]) => {
|
||||
let parsedChildren: ParsedChild[] = [];
|
||||
rowChildren?.forEach((r: React.ReactNode) => {
|
||||
let periods = [];
|
||||
if (React.isValidElement(r) && r?.props?.children) {
|
||||
if (Array.isArray(r.props.children)) {
|
||||
for (let i = 0; i < r.props.children.length; i++) {
|
||||
const p = r.props.children[i];
|
||||
|
||||
periods.push({
|
||||
start: p?.props?.start,
|
||||
end: p?.props?.end,
|
||||
status: p?.props?.status || "neutral",
|
||||
onSelectPeriod: p.props?.onSelectPeriod,
|
||||
label: r.props.label,
|
||||
icon: p.props.icon,
|
||||
children: p.props.children,
|
||||
isActive: p.props.isActive,
|
||||
statusLabel: p.props.statusLabel,
|
||||
restProps: omit(p.props, [
|
||||
"start",
|
||||
"end",
|
||||
"status",
|
||||
"onSelectPeriod",
|
||||
"label",
|
||||
"icon",
|
||||
"children",
|
||||
"isActive",
|
||||
"statusLabel",
|
||||
]),
|
||||
ref: p?.ref,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
periods.push({
|
||||
start: r.props.children.props.start,
|
||||
end: r.props.children.props.end,
|
||||
status: r.props.children.props?.status || "neutral",
|
||||
onSelectPeriod: r.props.children.props?.onSelectPeriod,
|
||||
label: r.props.label,
|
||||
icon: r.props.children.props?.icon,
|
||||
children: r.props.children.props?.children,
|
||||
statusLabel: r.props.children.props?.statusLabel,
|
||||
restProps: omit(r.props.children.props, [
|
||||
"start",
|
||||
"end",
|
||||
"status",
|
||||
"onSelectPeriod",
|
||||
"label",
|
||||
"icon",
|
||||
"children",
|
||||
"isActive",
|
||||
"statusLabel",
|
||||
]),
|
||||
ref: r.props?.children?.ref,
|
||||
});
|
||||
}
|
||||
parsedChildren.push({
|
||||
label: r.props.label,
|
||||
icon: r.props.icon,
|
||||
headingTag: r.props.headingTag,
|
||||
periods: periods,
|
||||
restProps: omit(r.props, ["label", "icon", "headingTag"]),
|
||||
ref: (r as any)?.ref,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return parsedChildren;
|
||||
};
|
||||