Compare commits

...
Author SHA1 Message Date
Ken bcfd6747d9 📝 Changeset versions 2023-01-31 11:09:43 +01:00
Ken 122bbf0090 🐛 Date-fns import feilet fra ESM 2023-01-31 11:08:45 +01:00
Ken b60d047b95 Merge branch 'next' 2023-01-31 10:57:00 +01:00
github-actions[bot]andgithub-actions[bot] 98dbc155fe Version Packages (#1774)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-31 10:55:24 +01:00
Ken 87f194c1dc 📝 Changeset 2023-01-31 10:49:41 +01:00
Ken 7f73315264 🐛 useRangepicker edgecase ved valg av start etter slutt 2023-01-31 10:48:42 +01:00
Ken 1399f6f084 Merge branch 'next' of https://github.com/navikt/Designsystemet into next 2023-01-30 13:10:56 +01:00
Kai Erik SchierenandKen 1cf90c1753 Feature/suggestion box (#1773)
* 🎨 SuggestionBlock

* ✨ SuggestionBlock for grunnleggende/komponentsider

* 🎨 Flyttet options ut til eget object

* 🎨 optional chain suggestion block

* 🎨 add issue url to new icon

* 🎨 add urls for updates requests

* 🎨 add labels to links

* 🎨 add cml label to href

* 🎨 url to new and beta

* 🎨 add fitting labels to hrefs

* fix reference 🐛

* 💄 Oppdatert ikoner/heading for beta og Ny

---------

Co-authored-by: Ken <ken.aleksander@gmail.com>
2023-01-30 13:02:20 +01:00
Ken c027c2e464 ♿ role=img på ikoner fra sanity 2023-01-30 12:35:13 +01:00
Ken 92dd582d68 🐛 Bedre error-handling for feilede lenker 2023-01-30 11:34:18 +01:00
Ken bb302bbbd6 Merge branch 'master' of https://github.com/navikt/Designsystemet 2023-01-30 10:55:58 +01:00
Ken 55005c80f3 🐛 Fiket sanity-preview av Accordion 2023-01-30 09:58:02 +01:00
Ken 27e6423b54 Update README.md 2023-01-30 09:32:53 +01:00
Ken 21a842d419 🎨 Tilbakemeldingsvisning på 'forsiden' i sanity 2023-01-27 15:27:15 +01:00
github-actions[bot]andgithub-actions[bot] e7a62a9082 Version Packages (#1772)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-27 13:20:54 +01:00
Ken 494566e604 🐛 Monthpicker oppdaterte ikke år riktig (#1771) 2023-01-27 12:33:17 +01:00
Kai Erik Schieren 1c492fda56 🎨 add labels (#1770) 2023-01-27 11:53:01 +01:00
github-actions[bot]andgithub-actions[bot] 9691ac4713 Version Packages (#1768)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-27 11:51:25 +01:00
Ken 7174bbe7bf 🐛 Fikset visning av tema-grupperinger i sanity 2023-01-27 11:47:05 +01:00
Ken 62f36da5e7 📝 Changeset 2023-01-27 10:23:41 +01:00
Ken 9ec5133ba2 💄 +4px horisontal padding small textfield (team-aksel/issues/89) 2023-01-27 10:23:01 +01:00
Ken 0a7906187f 🔥 Linting 2023-01-27 10:17:56 +01:00
Ken 28f2a3f532 ♿ Aria-live polite på tilbakemeldinger 2023-01-27 10:16:54 +01:00
Ken f5d404b925 🐛 Fikset proptabell-feil med dl-lister 2023-01-27 10:00:06 +01:00
Ken 05955acaf7 ♿ Fikset tabindex scrolltop, skiplink 2023-01-27 09:51:05 +01:00
Ken 55362f3ea7 🎨 Fikset team-aksel#145 issue god-praksis forfatter og dato 2023-01-27 09:42:20 +01:00
Ken 28f8f7a408 🐛 System-theme light fungerte ikke i Sanity 2023-01-27 09:34:38 +01:00
Ken 6778e902f3 ♿ Fikset heading-nivå for artikkelkort på landingssider god-praksis 2023-01-26 16:04:36 +01:00
Ken 92566d5750 Merge branch 'master' of https://github.com/navikt/Designsystemet 2023-01-26 15:38:11 +01:00
Kai Erik Schieren 6911913748 ✨ cmp label (#1765) 2023-01-26 13:49:40 +01:00
Kai Erik Schieren 7f3e96ae01 🎨 add labels to issue templates (#1764) 2023-01-26 12:55:42 +01:00
Ken 19791c0339 Merge branch 'master' into next 2023-01-26 12:17:03 +01:00
Kai Erik Schieren 6a00fca823 Issue templates (#1763)
* ✨ new component issue template

* ✨ add templates for feeback icon + cmp
2023-01-26 09:40:54 +01:00
Ole Jørgen Bakken f5d3ed8eee Endret til textarea i svaralternativet (#1762) 2023-01-25 14:56:07 +01:00
Ole Jørgen Bakken 5c00b91dfb Legger til en issue form for nye ikoner (#1761) 2023-01-25 14:53:13 +01:00
Ken 5b82182fda 🔥 Fjernet gamle sanity-felt 2023-01-25 09:26:55 +01:00
Ken 6246c1d311 📝 Readmes 2023-01-25 09:18:46 +01:00
Ken 04ad4d09b2 ⬆️ Oppdatert sanity 2023-01-24 16:02:07 +01:00
Ken 65ddd4bd18 Merge branch 'master' into next 2023-01-24 15:47:30 +01:00
github-actions[bot]andgithub-actions[bot] 8bb5b8f7b9 Version Packages (#1760)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-24 11:40:38 +01:00
Ken dcf5cfc06b 🐛 Fikset typefeil introdusert i v2.0.6 for ikoner og loader (#1759) 2023-01-24 11:35:28 +01:00
Ken ff97e7f3f8 📝 Readmes 2023-01-24 09:50:21 +01:00
Ken 9e1165de0a 🎨 Oppdatert backup-token bruk 2023-01-24 09:47:25 +01:00
Ken 812573ac43 🎨 Visning av antall god-praksis tema på forside 2023-01-23 10:13:06 +01:00
Ken 5f340eba49 🎨 Bedre feilmelding SEO-tab 2023-01-23 08:50:07 +01:00
Ken 703e7e3ab5 Merge branch 'master' of https://github.com/navikt/Designsystemet 2023-01-20 14:05:28 +01:00
github-actions[bot]andgithub-actions[bot] b42101f6f1 Version Packages (#1757)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-20 14:04:04 +01:00
Ken 8b0c4d8f59 🐛 Fikset oppretting av ny profilside Sanity 2023-01-20 13:54:51 +01:00
6ab84e581f [FEATURE] Timeline interne-flater (#1665)
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
Co-authored-by: Kai Erik Schieren <kai.schieren@soprasteria.com>
Co-authored-by: Kai Erik Schieren <111572054+kschieren@users.noreply.github.com>
2023-01-20 13:50:52 +01:00
Ken 42f3a298a2 🔥 Lint 2023-01-20 13:14:47 +01:00
Ken e49922d3fe ✨ Copy-knapp for tokens 2023-01-20 13:05:44 +01:00
Ken fc06e8f7b4 🎨 Default å tillate 2-siffer år (yy) 2023-01-20 12:41:51 +01:00
Ken 0273b42fb4 Revert "🎨 År med 2 tall er standard i datepicker nå"
This reverts commit aebb22bf1b.
2023-01-20 12:40:43 +01:00
Ken 0873fe6520 📝 changeset 2023-01-20 12:39:37 +01:00
Ken fdcf502a64 ♿ Aria-labels for sanity riktekst-editor 2023-01-20 12:34:46 +01:00
Ken aebb22bf1b 🎨 År med 2 tall er standard i datepicker nå 2023-01-20 12:32:38 +01:00
Ken 4529e64c6e ✨ Støtte for 'yy'-format i datepicker/monthpicker (#1755)
* 🎨 Støtte for 2-digit år

* 🎨 Props for toggling av twoDigitYear

* ✅ Tester for parsing av twoDigitYears

* 🎨 twoDigitYear demo

* 📝 Docs
2023-01-20 08:53:58 +01:00
Ken 01395e65ba 🎨 Utfaset gammel sanity-løsning 2023-01-19 21:45:29 +01:00
Ken 21dd0450e7 ⬆️ Yarn.lock 2023-01-19 21:15:04 +01:00
github-actions[bot]andgithub-actions[bot] ffac16cb05 Version Packages (#1756)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-19 15:53:44 +01:00
Ken 98177d0cd3 📝 changeset 2023-01-19 15:19:46 +01:00
Ken 2c5be718e6 🎨 Fikset hjelp ønskes modul 2023-01-19 10:00:56 +01:00
github-actions[bot]andgithub-actions[bot] 019d92dd7b Version Packages (#1754)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-18 15:24:10 +01:00
Ken 5b72afbb93 Merge branch 'master' of https://github.com/navikt/Designsystemet 2023-01-18 15:14:13 +01:00
Ken 56348cdddf ♿ Aria-labels for sanity riktekst-editor 2023-01-18 15:13:58 +01:00
github-actions[bot]andgithub-actions[bot] 973d79ee99 Version Packages (#1753)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-18 14:56:36 +01:00
Ken 5bfb912531 🎨 Bedre error-handling på akselartikkel templates 2023-01-18 14:55:45 +01:00
Ken 27e3dfee07 📝 Changeset 2023-01-18 13:08:38 +01:00
KenandKenAJoh 20b2bf6f89 Ikonsynk Figma (#1752)
Co-authored-by: KenAJoh <KenAJoh@users.noreply.github.com>
2023-01-18 13:07:48 +01:00
Ken 4b870986c8 🐛 Fikset intentbutton for feddbackløsning 2023-01-18 12:44:48 +01:00
github-actions[bot]andgithub-actions[bot] 8fcf079359 Version Packages (#1751)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-17 14:55:06 +01:00
Ken 54f8b07956 📝 changeset 2023-01-17 14:13:50 +01:00
KenandKenAJoh 9bc251e694 Ikonsynk Figma (#1750)
Co-authored-by: KenAJoh <KenAJoh@users.noreply.github.com>
2023-01-17 14:13:10 +01:00
github-actions[bot]andgithub-actions[bot] e2a9d027dc Version Packages (#1749)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-17 10:32:23 +01:00
Ken 22dfd8e603 :sparkled: Prop for posisjonering av toptekst i Chat (#1748)
* :sparkled: Prop for posisjonering av toptekst i Chat

* 📝 changeset

* 📝 Docs

* 📝 Demo

* 🎨 fliptoptext -> toptextPosition
2023-01-17 10:26:14 +01:00
Ken 53d1947311 📝 Tekstendringer sanity profilside 2023-01-17 09:39:38 +01:00
Ken d4e7c47772 🎨 Sanity feedback preview 2023-01-17 07:37:20 +01:00
Ken e191dffdf8 🔥 Fjernet dårlige editor-navn 2023-01-16 09:12:05 +01:00
Ken 7e0ee60d47 🔥 Fjernet dårlige editor-navn 2023-01-16 08:57:11 +01:00
github-actions[bot]andgithub-actions[bot] 4ecaeb9d04 Version Packages (#1746)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-13 16:03:31 +01:00
Ken 8e5c554431 ⬆️ Bump @floating-ui/react 2023-01-13 15:56:12 +01:00
Ken 727be0a98b 🔥 Fjernet snowfall fra forside 2023-01-13 15:15:47 +01:00
github-actions[bot]andgithub-actions[bot] 4c2e44ced1 Version Packages (#1745)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-13 15:07:11 +01:00
Ken 2fd1dd443f 🔥 Fjernet ubrukt kode forside 2023-01-13 14:41:06 +01:00
Ken a6c3391237 📝 changeset 2023-01-13 14:38:45 +01:00
KenandKenAJoh 5ede88a188 Ikonsynk Figma (#1739)
Co-authored-by: KenAJoh <KenAJoh@users.noreply.github.com>
2023-01-13 14:38:05 +01:00
Ken 2785593d20 ⬆️ Yarn lock update 2023-01-13 12:38:54 +01:00
Ken a37c743547 🐛 Bedre logging av temavisninger 2023-01-12 09:36:02 +01:00
Ken 6f0e18c3cf 🐛 E2E tester feilet grunnet aria-hidden 2023-01-12 09:18:10 +01:00
Ken bdfaa54e81 ♿ Gjemte til-toppen knapp for skjermleser 2023-01-12 08:27:03 +01:00
Ken 595796af6c 📝 Oppdatert grunnleggnde config 2023-01-12 06:50:16 +01:00
Ken f51d43c06a Revert "✨ Ny tokenvisning"
This reverts commit ff2515fabb.
2023-01-10 10:44:41 +01:00
Ken 8c81ae46e0 Revert "💄 Copytoken med tooltip"
This reverts commit 21da657eb0.
2023-01-10 10:43:50 +01:00
Ken c85b34e86f 🐛 Fikset henting av sider for testing i e2e! 2023-01-10 10:41:17 +01:00
Ken fc46b5a97b 🔍 Sitemap har nå lastmod-attr 2023-01-10 09:50:10 +01:00
Ken c7fcf57fdf :map: Google search-index ignorerer priority i sitemap 2023-01-10 08:28:21 +01:00
Ken 560d8bd1e8 🔍 Bedre robots.txt 2023-01-10 08:21:32 +01:00
Ken 7a53de186e 📝 1 Artikler -> 1 Artikkel 2023-01-09 13:48:57 +01:00
Ken 4feb798b25 🐛 God-praksis feilet ved visning av god-praksis sider 2023-01-09 12:53:54 +01:00
Ken c713b469f0 🔥 Fjernet ubrukt import Temaview 2023-01-09 12:40:42 +01:00
Ken 676392a5c4 🐛 Nye tema uten sider brakk sanity 2023-01-09 12:39:02 +01:00
Ken c049e08555 🎨 Sanity config refactor 2023-01-09 11:51:33 +01:00
github-actions[bot]andgithub-actions[bot] d8c898db8c Version Packages (#1738)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-09 11:05:24 +01:00
Ken 8a1ef5e7e2 🐛 Radio fikk ikke error-farge grunnet indeterminate (#1737) 2023-01-09 10:59:01 +01:00
Ken d64da78d8b Merge branch 'master' into next 2023-01-09 09:05:25 +01:00
Lars Hansen 293594235a #aksel til #Aksel 2023-01-05 15:28:57 +01:00
Lars Hansen a54d97591e Merge remote-tracking branch 'origin/master' 2023-01-05 15:28:09 +01:00
Lars Hansen dc2e7fb766 endre lenke fra #aksel og #designsystem til #aksel-designsystemet 2023-01-05 15:23:32 +01:00
Ken 53df42df22 📝 Fikset lenker til #aksel slack etter arkivering 2023-01-05 14:53:36 +01:00
Ken 21da657eb0 💄 Copytoken med tooltip 2023-01-05 11:03:20 +01:00
Ken 52d2d5f41d Merge branch 'tokens/refactor-v2' into next 2023-01-03 14:18:30 +01:00
Ken ff2515fabb ✨ Ny tokenvisning 2023-01-03 13:31:05 +01:00
Ken 5b9840524c ✅ Fikset date-test 2023-01-03 10:16:36 +01:00
Ken 0d6ddfd95e 🐛 Profilvisning sanity 2023-01-03 10:05:38 +01:00
Ken 0394e819ba ⚰️ Fjernet trello og algolia-integrasjon 2023-01-03 09:50:46 +01:00
Ken 23066e9503 ⬆️ Oppdatert aksel til å bruke clsx 2022-12-25 14:19:25 +01:00
Ken 67fc9ad560 🐛 La til kode-lenker igjen 2022-12-22 21:49:44 +01:00
Ken 8fe5c88eba 🐛 Preview låste seg på komponentsider 2022-12-22 17:11:43 +01:00
Ken 1fbcf78745 🎨 Hue-tilpassning i header på komponentsider 2022-12-22 16:35:13 +01:00
Ken 83dc3236e8 🎨 resolver dokument-ref for alle artikkel-sider 2022-12-22 16:12:57 +01:00
Ken 7503c7fa7f ✨ Feedback integrert på artikkelsider i sanity
🎨 Feedback-dokument

🎨 Sender nå feedback til sanity

🎨 Preview for feedback
2022-12-22 15:08:53 +01:00
Ken e668181690 ✨ Intro-lenker komponentsider 2022-12-21 21:07:05 +01:00
Ken 353dff3da5 🎨 localstorage for animasjons-stopp 2022-12-21 19:02:11 +01:00
Ken a11993a155 🔥 2022-12-21 15:23:06 +01:00
Ken 7b53b7670f ♿ play/pause knapp forside 2022-12-21 15:18:08 +01:00
Ken 0aaa0c4e10 📝 Klarspråk 2022-12-21 14:45:11 +01:00
Ken ea5e1f768c 🎨 Feedback-dokument 2022-12-21 14:31:49 +01:00
Ken e6b16e9b31 🐛 Fikset imports i script 2022-12-21 14:24:43 +01:00
Ken 1029d42163 Merge branch 'next' 2022-12-21 13:52:59 +01:00
Ken fba5140d8b 🚚 Flyttet scripts 2022-12-21 13:52:14 +01:00
Kai Erik Schieren fe72f32dbb ✨ moved backup (#1735) 2022-12-21 13:46:13 +01:00
Ken 6a0890b42b 💄 Kube på god-praksis forside 2022-12-21 13:13:24 +01:00
Ken 320f45a775 💄 Bedre beta-visning på komponentoversikt 2022-12-21 12:44:12 +01:00
Ken 3feb2283a4 🐛 Fikset kode-eksempler resizing 2022-12-21 12:16:59 +01:00
Ken c3b416a3cb 🎨 Deprecated-tag i sidebar sist 2022-12-21 10:10:23 +01:00
Ken 36fba1a33b 🐛 Riktig publiserings-logikk 2022-12-21 09:59:37 +01:00
Ken a9e080f892 📝 Ikonoppdatering 2022-12-20 19:16:54 +01:00
Ken 0dc8eb7a1e Ikonsynk Figma (#1730) 2022-12-20 19:15:49 +01:00
Ken 70fd78c926 🔍 Bedre scroll logging 2022-12-20 18:18:15 +01:00
Ken dbc5e7dc07 💄 Mindre gap introcards forside 2022-12-20 17:07:44 +01:00
Ken 4b0b8e4ae4 🐛 Fjernet gammel internal kategori 2022-12-20 16:33:12 +01:00
Ken 57e7e1ecc4 🐛 Forsøk på fix for flaky e2e tester 2022-12-20 16:25:17 +01:00
Ken 9534fe2540 ⚰️ fjernet limits for hva redirects kan løse 2022-12-20 16:02:23 +01:00
Ken 44683d38f1 🎨 La til ny kategori: interne 2022-12-20 16:00:42 +01:00
Ken 23c976e5d2 🐛 Fjernet sidecar fra aksel 2022-12-20 15:26:01 +01:00
Ken 9ea823d630 🐛 Fikset import 2022-12-20 15:14:36 +01:00
Ken 65c65a6637 🎨 Fikset OG-bilde grunnleggende, migrerings-script 2022-12-20 15:05:53 +01:00
ef2a2a9c49 Visuelle oppdateringer Aksel + nytt sanity-studio (#1734)
Co-authored-by: Kai Erik Schieren <kai.schieren@soprasteria.com>
Co-authored-by: Kai Erik Schieren <111572054+kschieren@users.noreply.github.com>
2022-12-20 14:00:20 +01:00
Ken 3f63fd7fb6 🐛 Backup funket ikke 2022-12-20 12:21:06 +01:00
Ken 6fe9788444 🐛 Button submittet form i table 2022-12-16 12:47:35 +01:00
Ken 10c6545885 🐛 Fikset e2e tester 2022-12-15 16:11:31 +01:00
Ken 2e76272a35 🐛 Fikset preview fra dev->prod 2022-12-15 15:44:20 +01:00
Ken 803a7a4d0f ♿ Fokusmarkering relatert innhold-cards 2022-12-15 14:18:10 +01:00
Ken d8b7e69788 📝 Datepicker i modal demo 2022-12-15 11:07:55 +01:00
Ken 097ef18910 ✨ Kan nå toggle lukking av modal med ESC 2022-12-15 10:57:03 +01:00
Ken bb081354fc ✨ Komponentvisning fra next -> prod 2022-12-15 10:10:29 +01:00
Ken edc08c6f8a 🐛 Fikset standalone-sider som fikk 404 2022-12-13 12:48:09 +01:00
Ken fc3577baf4 🐛 Fikset lenker på safari 2022-12-13 09:37:29 +01:00
Ken f02250ab75 🔧 Redirect fra /storybook til chromatic-instans 2022-12-11 21:00:00 +01:00
Ken 1af80dcc1b 🐛 ConfirmationPanel nå wrappet med divog ikke p 2022-12-06 15:00:45 +01:00
383 changed files with 14284 additions and 13109 deletions

No files matched your search

+24
View File
@@ -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
+24
View File
@@ -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 🧩", "nytt ✨", "beta 🧪"]
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
+16
View File
@@ -0,0 +1,16 @@
name: Innspill til ikon
description: Send inn innspill til ikon
title: "[Innspill til ikon]: "
labels: ["forespørsel 🥰", "nytt ✨"]
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
-3
View File
@@ -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
-3
View File
@@ -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
+3 -4
View File
@@ -22,18 +22,17 @@ jobs:
key: ${{ runner.os }}-build-${{ github.sha }}
restore-keys: |
${{ runner.os }}-build-
- name: Install dependencies
run: cd aksel.nav.no/sanity && yarn
run: cd aksel.nav.no/website && yarn
- name: Export dataset
run: cd aksel.nav.no/sanity && SANITY_TOKEN=${{secrets.SANITY_DATASET_EDITOR_TOKEN}} yarn 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"
+1 -4
View File
@@ -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:
-25
View File
@@ -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 }}
+3 -1
View File
@@ -148,4 +148,6 @@ tmp.json
/playwright/.cache/
playwright-report/
/test-results/
backup-*.tar.gz
backup-*.tar.gz
sitemap-urls.json
*.tar.gz
+34
View File
@@ -1,5 +1,39 @@
# @navikt/ds-codemod
## 2.1.5
## 2.1.4
## 2.1.3
## 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
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-codemod",
"version": "2.0.7",
"version": "2.1.5",
"description": "Aksel codemods for NAVs designsystem",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
+2 -2
View File
@@ -39,8 +39,8 @@
"build-pict": "svgr --silent --index-template index-template.js --out-dir src/pictograms pictograms"
},
"dependencies": {
"@navikt/ds-icons": "^2.0.7",
"@navikt/ds-react": "^2.0.7",
"@navikt/ds-icons": "^2.1.5",
"@navikt/ds-react": "^2.1.5",
"clsx": "^1.1.1"
},
"devDependencies": {
+46
View File
@@ -1,5 +1,51 @@
# @navikt/ds-css
## 2.1.5
## 2.1.4
## 2.1.3
## 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
+1 -1
View File
@@ -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 {
+16
View File
@@ -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);
}
+4 -12
View File
@@ -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);
}
+1 -1
View File
@@ -27,7 +27,7 @@
}
.navds-form-field--small .navds-text-field__input {
padding: 0 0.25rem;
padding: 0 0.5rem;
min-height: 32px;
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "2.0.7",
"version": "2.1.5",
"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.7",
"@navikt/ds-tokens": "^2.1.5",
"normalize.css": "^8.0.1",
"postcss": "^8.4.0",
"postcss-cli": "^9.0.0",
+1
View File
@@ -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",
+143
View File
@@ -1,5 +1,148 @@
# @navikt/ds-react
## 2.1.5
### Patch Changes
- Hotfix: ESM import fra date-fns feilet
- Updated dependencies []:
- @navikt/ds-icons@2.1.5
## 2.1.4
### Patch Changes
- [`87f194c1d`](https://github.com/navikt/Designsystemet/commit/87f194c1dc29b10a604de676b358d117e2dbf52f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset edgecase i useRangepicker der valg av startdato etter sluttdato ga feil output
- Updated dependencies []:
- @navikt/ds-icons@2.1.4
## 2.1.3
### Patch Changes
- [#1771](https://github.com/navikt/Designsystemet/pull/1771) [`494566e60`](https://github.com/navikt/Designsystemet/commit/494566e604e958363f75ebfa2adbc1669397636a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Monthpicker håndterer nå visning av År riktig
- Updated dependencies []:
- @navikt/ds-icons@2.1.3
## 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
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "2.0.7",
"version": "2.1.5",
"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.7",
"@floating-ui/react": "0.17.0",
"@navikt/ds-icons": "^2.1.5",
"@radix-ui/react-tabs": "1.0.0",
"@radix-ui/react-toggle-group": "1.0.0",
"clsx": "^1.2.1",
+22 -2
View File
@@ -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>
+13 -1
View File
@@ -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">
@@ -164,6 +164,7 @@ export const UseRangedDatepicker = () => {
UNSAFE_useRangeDatepicker({
fromDate: new Date("Aug 23 2019"),
onRangeChange: console.log,
onValidate: console.log,
});
return (
@@ -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,15 +181,29 @@ 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));
} else {
setYear(defaultSelected ?? defaultYear ?? today);
}
};
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));
};
@@ -189,12 +213,14 @@ export const useMonthpicker = (
if (month) {
setOpen(false);
inputRef.current && inputRef.current.focus();
setYear(month);
}
if (!required && !month) {
updateMonth(undefined);
updateValidation({ isValidMonth: false, isEmpty: true });
setInputValue("");
setYear(defaultYear ?? today);
return;
}
updateMonth(month);
@@ -209,7 +235,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,7 @@
import differenceInCalendarDays from "date-fns/differenceInCalendarDays";
import isBefore from "date-fns/isBefore";
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 +72,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 +203,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 +324,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 +342,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;
}
@@ -358,24 +372,26 @@ export const useRangeDatepicker = (
if (range?.from && range?.to) {
setOpen(false);
}
const prevToRange =
let prevToRange =
!selectedRange?.from && selectedRange?.to ? selectedRange?.to : range?.to;
const resetTo = isBefore(prevToRange, range?.from);
range?.from
? setFromInputValue(
formatDateForInput(range?.from, locale, "date", inputFormat)
)
: setFromInputValue("");
prevToRange
prevToRange && !resetTo
? setToInputValue(
formatDateForInput(prevToRange, locale, "date", inputFormat)
)
: setToInputValue("");
updateValidation(
{ isValidDate: !!range?.from, isEmpty: !range?.from },
{ isValidDate: !!range?.to, isEmpty: !prevToRange }
{ isValidDate: !!range?.to, isEmpty: !prevToRange || resetTo }
);
updateRange({ from: range?.from, to: prevToRange });
updateRange({ from: range?.from, to: resetTo ? undefined : prevToRange });
};
const fromChange = (
@@ -426,7 +442,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 +511,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;
@@ -134,7 +134,7 @@ export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
);
const handleSelect = (month?: Date) => {
setSelectedMonth(month);
!onMonthSelect && setSelectedMonth(month);
onMonthSelect?.(month);
month && (onClose?.() ?? setOpen(false));
};
@@ -175,7 +175,7 @@ export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
>
<RootProvider
locale={getLocaleFromString(locale)}
selected={selected}
selected={selected ?? selectedMonth}
toDate={toDate}
fromDate={fromDate}
month={selected ?? selectedMonth}
@@ -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 => {
+98 -19
View File
@@ -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 -1
View File
@@ -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;
+6 -1
View File
@@ -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,
+6
View File
@@ -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,
+1 -1
View File
@@ -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}
+1 -1
View File
@@ -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,
+34
View File
@@ -1,5 +1,39 @@
# @navikt/ds-tailwind
## 2.1.5
## 2.1.4
## 2.1.3
## 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 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tailwind",
"version": "2.0.7",
"version": "2.1.5",
"description": "Tailwind config based on @navikt/ds-tokens",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -22,7 +22,7 @@
"directory": "@navikt/core/tailwind"
},
"devDependencies": {
"@navikt/ds-tokens": "^2.0.7",
"@navikt/ds-tokens": "^2.1.5",
"@types/jest": "^29.0.0",
"color": "4.2.3",
"jest": "^29.0.0",
+39
View File
@@ -1,5 +1,44 @@
# @navikt/ds-tokens
## 2.1.5
## 2.1.4
## 2.1.3
## 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
+1 -1
View File
@@ -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 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tokens",
"version": "2.0.7",
"version": "2.1.5",
"description": "Design-tokens for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
+1 -1
View File
@@ -159,7 +159,7 @@
"danger": {
"subtle": {
"hover": { "value": "{a.red.50.value}" },
"hover": { "value": "{a.red.100.value}" },
"@": { "value": "{a.red.50.value}" }
},
"hover": {
+54
View File
@@ -1,5 +1,59 @@
# @navikt/ds-icons
## 2.1.5
## 2.1.4
## 2.1.3
## 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
+20
View File
@@ -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"));
});
+26 -14
View File
@@ -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",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-icons",
"version": "2.0.7",
"version": "2.1.5",
"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"
},
+3 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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

+2 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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

+2 -1
View File
@@ -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 -1
View File
@@ -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

+3
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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

+13
View File
@@ -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

+39
View File
@@ -1,5 +1,44 @@
# @navikt/ds-css-internal
## 2.1.5
## 2.1.4
## 2.1.3
## 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
+1
View File
@@ -1,3 +1,4 @@
@import "copy-to-clipboard.css";
@import "dropdown.css";
@import "header.css";
@import "timeline.css";
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css-internal",
"version": "2.0.7",
"version": "2.1.5",
"description": "CSS for NAV internal Designsystem-components",
"author": "Aksel | NAV designsystem team",
"keywords": [
+281
View File
@@ -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;
}
+28
View File
@@ -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"
}
}
+141
View File
@@ -1,5 +1,146 @@
# @navikt/ds-react-internal
## 2.1.5
### Patch Changes
- Updated dependencies []:
- @navikt/ds-react@2.1.5
- @navikt/ds-icons@2.1.5
## 2.1.4
### Patch Changes
- Updated dependencies [[`87f194c1d`](https://github.com/navikt/Designsystemet/commit/87f194c1dc29b10a604de676b358d117e2dbf52f)]:
- @navikt/ds-react@2.1.4
- @navikt/ds-icons@2.1.4
## 2.1.3
### Patch Changes
- Updated dependencies [[`494566e60`](https://github.com/navikt/Designsystemet/commit/494566e604e958363f75ebfa2adbc1669397636a)]:
- @navikt/ds-react@2.1.3
- @navikt/ds-icons@2.1.3
## 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
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react-internal",
"version": "2.0.7",
"version": "2.1.5",
"description": "Aksel react components for internal UIs in NAV",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -35,8 +35,8 @@
"watch": "tsc --watch -p tsconfig.esm.json"
},
"dependencies": {
"@navikt/ds-icons": "^2.0.7",
"@navikt/ds-react": "^2.0.7",
"@navikt/ds-icons": "^2.1.5",
"@navikt/ds-react": "^2.1.5",
"clsx": "^1.1.1",
"copy-to-clipboard": "^3.3.1"
},
+1
View File
@@ -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;
};
@@ -0,0 +1,65 @@
import React from "react";
export type PeriodStatus =
| "success"
| "warning"
| "danger"
| "info"
| "neutral";
export type Percentage = number;
export interface Positioned {
horizontalPosition: number;
direction: "left" | "right";
}
export interface Period {
id: string;
label?: string;
start: Date;
endInclusive: Date;
status?: PeriodStatus;
onSelectPeriod?: () => void;
icon?: React.ReactNode;
children?: React.ReactNode;
end: Date;
isActive?: boolean;
statusLabel?: string;
}
export interface PositionedPeriod extends Period, Positioned {
width: number;
active?: boolean;
cropped?: "left" | "right" | "both";
disabled?: boolean;
className?: string;
hoverLabel?: React.ReactNode;
infoPin?: boolean;
start: Date;
}
export interface Spatial {
width: number;
}
export interface AxisLabel extends Positioned, Spatial {
label: string;
date: Date;
}
export interface InternalSimpleTimeline {
id: string;
periods: PositionedPeriod[];
}
export interface SimplePeriod {
/**
* Startdato for perioden, mao. periodens høyre kant.
*/
start: Date;
/**
* Sluttdato for perioden, mao. periodens venstre kant.
*/
end: Date;
}
Loaded 100 of 383 files, more files were not shown because too many files have changed in this diff. Show more