mirror of
https://github.com/navikt/aksel.git
synced 2026-10-14 09:42:02 +00:00
Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6385c4686e | ||
|
|
30068dca3f | ||
|
|
3aa04d2375 | ||
|
|
91343563c9 | ||
|
|
d5c8112339 | ||
|
|
e6cc9d1b4f | ||
|
|
db8c38a094 | ||
|
|
35041e64eb | ||
|
|
690422d824 | ||
|
|
b54bebd308 | ||
|
|
8db194170c | ||
|
|
7b42f536aa | ||
|
|
b2f796d681 | ||
|
|
17d92c9ed5 | ||
|
|
7bae5dce88 | ||
|
|
6aca0a4b6a | ||
|
|
4f7fde22a3 | ||
|
|
0dad69a8df | ||
|
|
c028f36e2b | ||
|
|
988fb36619 | ||
|
|
f61cd88627 |
No files matched your search
@@ -1,5 +1,11 @@
|
||||
# @navikt/aksel-icons
|
||||
|
||||
## 4.1.2
|
||||
|
||||
## 4.1.1
|
||||
|
||||
## 4.1.0
|
||||
|
||||
## 4.0.0
|
||||
|
||||
## 3.4.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel-icons",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.2",
|
||||
"author": "Aksel | NAV",
|
||||
"homepage": "https://aksel.nav.no/ikoner",
|
||||
"repository": {
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @navikt/aksel-stylelint
|
||||
|
||||
## 4.1.2
|
||||
|
||||
## 4.1.1
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2035](https://github.com/navikt/aksel/pull/2035) [`7b42f536a`](https://github.com/navikt/aksel/commit/7b42f536aa90c1b5dbe2b19f1bbe292701546420) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Oppdatert Chips
|
||||
|
||||
- Toggle Chips har nå varianter: neutral og action
|
||||
- Toggle Chips har nå en ny prop: `checkmark` som slår av/på checkmark ved selected-state
|
||||
|
||||
## 4.0.0
|
||||
|
||||
## 3.4.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel-stylelint",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.2",
|
||||
"author": "Aksel | NAV",
|
||||
"homepage": "https://aksel.nav.no/grunnleggende/kode/stylelint",
|
||||
"repository": {
|
||||
@@ -35,8 +35,8 @@
|
||||
"dev": "yarn watch:lint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-css": "^4.0.0",
|
||||
"@navikt/ds-tokens": "^4.0.0",
|
||||
"@navikt/ds-css": "^4.1.2",
|
||||
"@navikt/ds-tokens": "^4.1.2",
|
||||
"@types/jest": "^29.0.0",
|
||||
"concurrently": "7.2.1",
|
||||
"copyfiles": "2.4.1",
|
||||
|
||||
@@ -20,4 +20,9 @@ export const deprecations: DeprecatedList = [
|
||||
"Class were moved to '@navikt/ds-css' and renamed with 'navds'-prefix in v4.0.0. Docs: https://aksel.nav.no/grunnleggende/kode/endringslogg#h728704adeb59.",
|
||||
deprecatePrefix: true,
|
||||
},
|
||||
{
|
||||
classes: ["navds-chips--icon-left"],
|
||||
message:
|
||||
"In v4.1.0 Chips. Toggle no longer handles special alignment for checkmark-icon, thus removing this class",
|
||||
},
|
||||
];
|
||||
@@ -1,5 +1,26 @@
|
||||
# @navikt/aksel
|
||||
|
||||
## 4.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@4.1.2
|
||||
|
||||
## 4.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`91343563c`](https://github.com/navikt/aksel/commit/91343563c916a554d8ade5401c28ab4c3b3e26af)]:
|
||||
- @navikt/ds-css@4.1.1
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7b42f536a`](https://github.com/navikt/aksel/commit/7b42f536aa90c1b5dbe2b19f1bbe292701546420), [`c028f36e2`](https://github.com/navikt/aksel/commit/c028f36e2bc58223ebf8b655980dde7eafb30add), [`b2f796d68`](https://github.com/navikt/aksel/commit/b2f796d681f1c1d76d26d1fd743268c8c618a854), [`db8c38a09`](https://github.com/navikt/aksel/commit/db8c38a094cd183db54aebecb62d5b223920a040)]:
|
||||
- @navikt/ds-css@4.1.0
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.2",
|
||||
"description": "Aksel command line interface. Handles css-imports, codemods and more",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
|
||||
"dependencies": {
|
||||
"@navikt/ds-css": "4.0.0",
|
||||
"@navikt/ds-css": "4.1.2",
|
||||
"axios": "1.3.6",
|
||||
"chalk": "4.1.0",
|
||||
"clipboardy": "^2.3.0",
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 4.1.2
|
||||
|
||||
## 4.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`91343563c`](https://github.com/navikt/aksel/commit/91343563c916a554d8ade5401c28ab4c3b3e26af) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset markering av tekst i skeleton.
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2035](https://github.com/navikt/aksel/pull/2035) [`7b42f536a`](https://github.com/navikt/aksel/commit/7b42f536aa90c1b5dbe2b19f1bbe292701546420) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Oppdatert Chips
|
||||
|
||||
- Toggle Chips har nå varianter: neutral og action
|
||||
- Toggle Chips har nå en ny prop: `checkmark` som slår av/på checkmark ved selected-state
|
||||
|
||||
- [#2036](https://github.com/navikt/aksel/pull/2036) [`b2f796d68`](https://github.com/navikt/aksel/commit/b2f796d681f1c1d76d26d1fd743268c8c618a854) Thanks [@KenAJoh](https://github.com/KenAJoh)! - - Oppdatert text-subtle og icon-subtle tokens til 700-skala (tidligere 600).
|
||||
|
||||
- Icon-subtle bruker nå grayalpha.
|
||||
- Alle description-felter på fieldsets har nå text-subtle som farge.
|
||||
|
||||
- [#1821](https://github.com/navikt/aksel/pull/1821) [`db8c38a09`](https://github.com/navikt/aksel/commit/db8c38a094cd183db54aebecb62d5b223920a040) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Ny komponent Skeleton!
|
||||
|
||||
- varianter: text, circle, rounded og rectangle
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2027](https://github.com/navikt/aksel/pull/2027) [`c028f36e2`](https://github.com/navikt/aksel/commit/c028f36e2bc58223ebf8b655980dde7eafb30add) Thanks [@JulianNymark](https://github.com/JulianNymark)! - :sparkles: La til `indent`-prop på Accordion
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -141,11 +141,16 @@
|
||||
/*************************
|
||||
* Content *
|
||||
*************************/
|
||||
|
||||
.navds-accordion__content {
|
||||
padding: 0 var(--a-spacing-3) var(--a-spacing-5) var(--a-spacing-11);
|
||||
padding: 0 var(--a-spacing-3) var(--a-spacing-5);
|
||||
animation: fadeAccordionContent 250ms ease;
|
||||
}
|
||||
|
||||
.navds-accordion--indent > :where(.navds-accordion__item) > :where(.navds-accordion__content) {
|
||||
padding: 0 var(--a-spacing-3) var(--a-spacing-5) var(--a-spacing-11);
|
||||
}
|
||||
|
||||
.navds-accordion__content--closed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
+27
-22
@@ -20,7 +20,7 @@
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--a-spacing-05);
|
||||
gap: var(--a-spacing-1);
|
||||
margin: 0;
|
||||
padding: 0 var(--a-spacing-3);
|
||||
text-decoration: none;
|
||||
@@ -34,14 +34,14 @@
|
||||
}
|
||||
|
||||
.navds-chips__toggle {
|
||||
box-shadow: inset 0 0 0 1px var(--ac-chip-toggle-border, var(--a-border-default));
|
||||
background-color: var(--ac-chip-toggle-bg, var(--a-surface-neutral-subtle));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-chip-toggle-border, var(--a-border-subtle));
|
||||
background-color: var(--ac-chip-toggle-bg, var(--a-surface-action-subtle));
|
||||
color: var(--ac-chip-toggle-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-chips__toggle:hover {
|
||||
box-shadow: inset 0 0 0 1px var(--ac-chip-toggle-hover-border, var(--a-border-strong));
|
||||
background-color: var(--ac-chip-toggle-hover-bg, var(--a-surface-neutral-subtle-hover));
|
||||
box-shadow: inset 0 0 0 1px var(--ac-chip-toggle-hover-border, var(--a-border-subtle-hover));
|
||||
background-color: var(--ac-chip-toggle-hover-bg, var(--a-surface-action-subtle-hover));
|
||||
}
|
||||
|
||||
.navds-chips__toggle[aria-pressed="true"] {
|
||||
@@ -54,6 +54,28 @@
|
||||
background-color: var(--ac-chip-toggle-pressed-hover-bg, var(--a-surface-action-selected-hover));
|
||||
}
|
||||
|
||||
/* Toggle variant neutral */
|
||||
.navds-chips__toggle--neutral {
|
||||
box-shadow: inset 0 0 0 1px var(--ac-chip-toggle-neutral-border, var(--a-border-subtle));
|
||||
background-color: var(--ac-chip-toggle-neutral-bg, var(--a-surface-neutral-subtle));
|
||||
color: var(--ac-chip-toggle-neutral-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-chips__toggle--neutral:hover {
|
||||
box-shadow: inset 0 0 0 1px var(--ac-chip-toggle-neutral-hover-border, var(--a-border-subtle-hover));
|
||||
background-color: var(--ac-chip-toggle-neutral-hover-bg, var(--a-surface-neutral-subtle-hover));
|
||||
}
|
||||
|
||||
.navds-chips__toggle--neutral[aria-pressed="true"] {
|
||||
box-shadow: none;
|
||||
background-color: var(--ac-chip-toggle-neutral-pressed-bg, var(--a-surface-neutral-selected));
|
||||
color: var(--ac-chip-toggle-neutral-pressed-text, var(--a-text-on-neutral));
|
||||
}
|
||||
|
||||
.navds-chips__toggle--neutral[aria-pressed="true"]:hover {
|
||||
background-color: var(--ac-chip-toggle-neutral-pressed-hover-bg, var(--a-surface-neutral-selected));
|
||||
}
|
||||
|
||||
.navds-chips__toggle:focus-visible {
|
||||
box-shadow: 0 0 0 2px var(--ac-chip-toggle-focus, var(--a-border-focus));
|
||||
}
|
||||
@@ -99,19 +121,6 @@
|
||||
border-radius: var(--a-border-radius-full);
|
||||
}
|
||||
|
||||
.navds-chips__toggle-icon {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
border-radius: var(--a-border-radius-full);
|
||||
}
|
||||
|
||||
.navds-chips--small .navds-chips__toggle-icon {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
.navds-chips--small .navds-chips__removable-icon {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
@@ -161,7 +170,3 @@
|
||||
.navds-chips--small .navds-chips--icon-right {
|
||||
padding-right: var(--a-spacing-05);
|
||||
}
|
||||
|
||||
.navds-chips--small .navds-chips--icon-left {
|
||||
padding-left: 0.375rem;
|
||||
}
|
||||
@@ -127,6 +127,7 @@ const StyleMappings = {
|
||||
{ component: "ReadMore", main: "read-more.css", dependencies: [typoCss] },
|
||||
{ component: "Search", main: formCss, dependencies: [typoCss] },
|
||||
{ component: "Select", main: formCss, dependencies: [typoCss] },
|
||||
{ component: "Skeleton", main: "skeleton.css", dependencies: [] },
|
||||
{ component: "Stepper", main: "stepper.css", dependencies: [typoCss] },
|
||||
{ component: "Switch", main: formCss, dependencies: [typoCss] },
|
||||
{ component: "Table", main: "table.css", dependencies: [typoCss] },
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
[data-theme="dark"] {
|
||||
--ac-form-description: var(--a-text-on-inverted);
|
||||
}
|
||||
|
||||
.navds-fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -9,6 +13,10 @@
|
||||
margin-top: var(--a-spacing-2);
|
||||
}
|
||||
|
||||
.navds-fieldset__description {
|
||||
color: var(--ac-form-description, var(--a-text-subtle));
|
||||
}
|
||||
|
||||
.navds-fieldset > .navds-fieldset__description:not(:empty) {
|
||||
margin-top: 0.125rem;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
[data-theme="dark"] {
|
||||
--ac-form-description: var(--a-text-on-inverted);
|
||||
}
|
||||
|
||||
.navds-form-field {
|
||||
display: grid;
|
||||
justify-items: start;
|
||||
@@ -6,6 +10,7 @@
|
||||
|
||||
.navds-form-field__description {
|
||||
margin-top: -6px;
|
||||
color: var(--ac-form-description, var(--a-text-subtle));
|
||||
}
|
||||
|
||||
.navds-form-field .navds-error-message,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
@import "panel.css";
|
||||
@import "link-panel.css";
|
||||
@import "read-more.css";
|
||||
@import "skeleton.css";
|
||||
@import "stepper.css";
|
||||
@import "table.css";
|
||||
@import "tabs.css";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.2",
|
||||
"description": "CSS for NAV Designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -27,7 +27,7 @@
|
||||
"css:get-version": "node config/get-version.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^4.0.0",
|
||||
"@navikt/ds-tokens": "^4.1.2",
|
||||
"cssnano": "6.0.0",
|
||||
"fast-glob": "3.2.11",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
.navds-skeleton {
|
||||
display: block;
|
||||
background-color: var(--ac-skeleton-bg, var(--a-surface-neutral-moderate));
|
||||
height: 1.3em;
|
||||
animation: akselSkeletonAnimation 0.8s linear infinite alternate;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.navds-skeleton--has-children {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.navds-skeleton--has-children > * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.navds-skeleton--has-children.navds-skeleton--no-height {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.navds-skeleton--has-children.navds-skeleton--no-width {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.navds-skeleton--text {
|
||||
height: auto;
|
||||
transform-origin: 0 55%;
|
||||
transform: scale(1, 0.6);
|
||||
border-radius: var(--a-border-radius-medium);
|
||||
}
|
||||
|
||||
.navds-skeleton--text:empty::before {
|
||||
content: "\00a0";
|
||||
}
|
||||
|
||||
.navds-skeleton--circle {
|
||||
border-radius: var(--a-border-radius-full);
|
||||
}
|
||||
|
||||
.navds-skeleton--rectangle {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.navds-skeleton--rounded {
|
||||
border-radius: var(--a-border-radius-xlarge);
|
||||
}
|
||||
|
||||
@keyframes akselSkeletonAnimation {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
@@ -86,14 +86,22 @@
|
||||
"--ac-chat-top-text": "--a-text-default"
|
||||
},
|
||||
"chips": {
|
||||
"--ac-chip-toggle-border": "--a-border-default",
|
||||
"--ac-chip-toggle-bg": "--a-surface-neutral-subtle",
|
||||
"--ac-chip-toggle-border": "--a-border-subtle",
|
||||
"--ac-chip-toggle-bg": "--a-surface-action-subtle",
|
||||
"--ac-chip-toggle-text": "--a-text-default",
|
||||
"--ac-chip-toggle-hover-border": "--a-border-strong",
|
||||
"--ac-chip-toggle-hover-bg": "--a-surface-neutral-subtle-hover",
|
||||
"--ac-chip-toggle-hover-border": "--a-border-subtle-hover",
|
||||
"--ac-chip-toggle-hover-bg": "--a-surface-action-subtle-hover",
|
||||
"--ac-chip-toggle-pressed-bg": "--a-surface-action-selected",
|
||||
"--ac-chip-toggle-pressed-text": "--a-text-on-action",
|
||||
"--ac-chip-toggle-pressed-hover-bg": "--a-surface-action-selected-hover",
|
||||
"--ac-chip-toggle-neutral-border": "--a-border-subtle",
|
||||
"--ac-chip-toggle-neutral-bg": "--a-surface-neutral-subtle",
|
||||
"--ac-chip-toggle-neutral-text": "--a-text-default",
|
||||
"--ac-chip-toggle-neutral-hover-border": "--a-border-subtle-hover",
|
||||
"--ac-chip-toggle-neutral-hover-bg": "--a-surface-neutral-subtle-hover",
|
||||
"--ac-chip-toggle-neutral-pressed-bg": "--a-surface-neutral-selected",
|
||||
"--ac-chip-toggle-neutral-pressed-text": "--a-text-on-neutral",
|
||||
"--ac-chip-toggle-neutral-pressed-hover-bg": "--a-surface-neutral-selected",
|
||||
"--ac-chip-toggle-focus": "--a-border-focus",
|
||||
"--ac-chip-removable-action-bg": "--a-surface-action-selected",
|
||||
"--ac-chip-removable-action-text": "--a-text-on-action",
|
||||
@@ -206,6 +214,9 @@
|
||||
"--ac-read-more-active-bg": "--a-surface-active",
|
||||
"--ac-read-more-line": "--a-border-divider"
|
||||
},
|
||||
"skeleton": {
|
||||
"--ac-skeleton-bg": "--a-surface-neutral-moderate"
|
||||
},
|
||||
"stepper": {
|
||||
"--ac-stepper-text": "--a-surface-action",
|
||||
"--ac-stepper-line": "--a-border-default",
|
||||
@@ -349,6 +360,10 @@
|
||||
"--ac-radio-checkbox-error-border": "--a-border-danger",
|
||||
"--ac-radio-checkbox-error-hover-bg": "--a-surface-danger-subtle"
|
||||
},
|
||||
"forms": {
|
||||
"--ac-form-description": "--a-text-subtle",
|
||||
"--ac-form-subdescription": "--a-text-subtle"
|
||||
},
|
||||
"search": {
|
||||
"--ac-search-button-border": "--a-border-default",
|
||||
"--ac-search-button-border-hover": "--a-border-action",
|
||||
|
||||
@@ -1,5 +1,43 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 4.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`30068dca3`](https://github.com/navikt/aksel/commit/30068dca3fcdf4bf7bbfbfb3d09baa9fee003962) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Jsdoc for Skeleton-komponent
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@4.1.2
|
||||
|
||||
## 4.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@4.1.1
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2035](https://github.com/navikt/aksel/pull/2035) [`7b42f536a`](https://github.com/navikt/aksel/commit/7b42f536aa90c1b5dbe2b19f1bbe292701546420) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Oppdatert Chips
|
||||
|
||||
- Toggle Chips har nå varianter: neutral og action
|
||||
- Toggle Chips har nå en ny prop: `checkmark` som slår av/på checkmark ved selected-state
|
||||
|
||||
- [#1821](https://github.com/navikt/aksel/pull/1821) [`db8c38a09`](https://github.com/navikt/aksel/commit/db8c38a094cd183db54aebecb62d5b223920a040) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Ny komponent Skeleton!
|
||||
|
||||
- varianter: text, circle, rounded og rectangle
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2034](https://github.com/navikt/aksel/pull/2034) [`17d92c9ed`](https://github.com/navikt/aksel/commit/17d92c9ed5f82a80f99a1512989744343edf60b3) Thanks [@JulianNymark](https://github.com/JulianNymark)! - Add JSDoc typings
|
||||
|
||||
- [#2027](https://github.com/navikt/aksel/pull/2027) [`c028f36e2`](https://github.com/navikt/aksel/commit/c028f36e2bc58223ebf8b655980dde7eafb30add) Thanks [@JulianNymark](https://github.com/JulianNymark)! - :sparkles: La til `indent`-prop på Accordion
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@4.1.0
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.2",
|
||||
"description": "Aksel react-components for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "0.24.1",
|
||||
"@navikt/aksel-icons": "^4.0.0",
|
||||
"@navikt/aksel-icons": "^4.1.2",
|
||||
"@radix-ui/react-tabs": "1.0.0",
|
||||
"@radix-ui/react-toggle-group": "1.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
|
||||
@@ -1,17 +1,32 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
import AccordionItem, { AccordionItemType } from "./AccordionItem";
|
||||
import AccordionContent, { AccordionContentType } from "./AccordionContent";
|
||||
import AccordionHeader, { AccordionHeaderType } from "./AccordionHeader";
|
||||
import AccordionItem, { AccordionItemProps } from "./AccordionItem";
|
||||
import AccordionContent, { AccordionContentProps } from "./AccordionContent";
|
||||
import AccordionHeader, { AccordionHeaderProps } from "./AccordionHeader";
|
||||
import { AccordionContext } from "./AccordionContext";
|
||||
|
||||
interface AccordionComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
AccordionProps & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
Item: AccordionItemType;
|
||||
Header: AccordionHeaderType;
|
||||
Content: AccordionContentType;
|
||||
/**
|
||||
* @see 🏷️ {@link AccordionItemProps}
|
||||
*/
|
||||
Item: React.ForwardRefExoticComponent<
|
||||
AccordionItemProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
/**
|
||||
* @see 🏷️ {@link AccordionHeaderProps}
|
||||
*/
|
||||
Header: React.ForwardRefExoticComponent<
|
||||
AccordionHeaderProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
/**
|
||||
* @see 🏷️ {@link AccordionContentProps}
|
||||
*/
|
||||
Content: React.ForwardRefExoticComponent<
|
||||
AccordionContentProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
}
|
||||
|
||||
export interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
@@ -27,12 +42,37 @@ export interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
* @default "medium"
|
||||
*/
|
||||
size?: "large" | "medium" | "small";
|
||||
/**
|
||||
* Whether to indent content or not
|
||||
* @default true
|
||||
*/
|
||||
indent?: boolean;
|
||||
/**
|
||||
* Instances of Accordion.Item
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays collapsible content sections.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/accordion)
|
||||
* @see 🏷️ {@link AccordionProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Accordion>
|
||||
* <Accordion.Item>
|
||||
* <Accordion.Header>Section 1</Accordion.Header>
|
||||
* <Accordion.Content>Content 1</Accordion.Content>
|
||||
* </Accordion.Item>
|
||||
* <Accordion.Item>
|
||||
* <Accordion.Header>Section 2</Accordion.Header>
|
||||
* <Accordion.Content>Content 2</Accordion.Content>
|
||||
* </Accordion.Item>
|
||||
* </Accordion>
|
||||
* ```
|
||||
*/
|
||||
export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
|
||||
(
|
||||
{
|
||||
@@ -40,6 +80,7 @@ export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
|
||||
variant = "default",
|
||||
headingSize = "small",
|
||||
size = "medium",
|
||||
indent = true,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
@@ -57,7 +98,8 @@ export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
|
||||
className={cl(
|
||||
"navds-accordion",
|
||||
className,
|
||||
`navds-accordion--${size}`
|
||||
`navds-accordion--${size}`,
|
||||
{ "navds-accordion--indent": indent }
|
||||
)}
|
||||
ref={ref}
|
||||
/>
|
||||
|
||||
@@ -11,11 +11,7 @@ export interface AccordionContentProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type AccordionContentType = React.ForwardRefExoticComponent<
|
||||
AccordionContentProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
const AccordionContent: AccordionContentType = forwardRef(
|
||||
const AccordionContent = forwardRef<HTMLDivElement, AccordionContentProps>(
|
||||
({ children, className, ...rest }, ref) => {
|
||||
const context = useContext(AccordionItemContext);
|
||||
|
||||
|
||||
@@ -13,11 +13,7 @@ export interface AccordionHeaderProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type AccordionHeaderType = React.ForwardRefExoticComponent<
|
||||
AccordionHeaderProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
|
||||
const AccordionHeader: AccordionHeaderType = forwardRef(
|
||||
const AccordionHeader = forwardRef<HTMLButtonElement, AccordionHeaderProps>(
|
||||
({ children, className, onClick, ...rest }, ref) => {
|
||||
const itemContext = useContext(AccordionItemContext);
|
||||
const accordionContext = useContext(AccordionContext);
|
||||
|
||||
@@ -27,10 +27,6 @@ export interface AccordionItemProps
|
||||
defaultOpen?: boolean;
|
||||
}
|
||||
|
||||
export type AccordionItemType = React.ForwardRefExoticComponent<
|
||||
AccordionItemProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
export interface AccordionItemContextProps {
|
||||
open: boolean;
|
||||
toggleOpen: () => void;
|
||||
@@ -39,7 +35,7 @@ export interface AccordionItemContextProps {
|
||||
export const AccordionItemContext =
|
||||
createContext<AccordionItemContextProps | null>(null);
|
||||
|
||||
const AccordionItem: AccordionItemType = forwardRef(
|
||||
const AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(
|
||||
(
|
||||
{ children, className, open, defaultOpen = false, onClick, id, ...rest },
|
||||
ref
|
||||
|
||||
@@ -114,11 +114,12 @@ export const Default = {
|
||||
},
|
||||
|
||||
args: {
|
||||
controlled: "false",
|
||||
controlled: false,
|
||||
nItems: 2,
|
||||
variant: "default",
|
||||
headingSize: "medium",
|
||||
size: "medium",
|
||||
indent: true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -137,7 +138,7 @@ export const DefaultOpen = {
|
||||
|
||||
args: {
|
||||
openItems: [1, 2],
|
||||
controlled: "false",
|
||||
controlled: false,
|
||||
nItems: 5,
|
||||
variant: "neutral",
|
||||
headingSize: "large",
|
||||
@@ -251,6 +252,7 @@ export const WithTable = {
|
||||
args: {
|
||||
variant: "default",
|
||||
headingSize: "large",
|
||||
indent: false,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -53,6 +53,15 @@ export interface AlertContextProps {
|
||||
size: "medium" | "small";
|
||||
}
|
||||
|
||||
/**
|
||||
* A component for displaying alerts
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/alert)
|
||||
* @see 🏷️ {@link AlertProps}
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Alert variant="error">Dette er en feilmelding</Alert>
|
||||
* ```
|
||||
*/
|
||||
export const Alert = forwardRef<HTMLDivElement, AlertProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -47,6 +47,16 @@ export interface ButtonProps
|
||||
iconPosition?: "left" | "right";
|
||||
}
|
||||
|
||||
/**
|
||||
* A button component
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/button)
|
||||
* @see 🏷️ {@link ButtonProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Button>Klikk meg</Button>
|
||||
* ```
|
||||
*/
|
||||
export const Button: OverridableComponent<ButtonProps, HTMLButtonElement> =
|
||||
forwardRef(
|
||||
(
|
||||
|
||||
@@ -25,11 +25,7 @@ export interface BubbleProps extends HTMLAttributes<HTMLDivElement> {
|
||||
toptextPosition?: "left" | "right";
|
||||
}
|
||||
|
||||
export type BubbleType = React.ForwardRefExoticComponent<
|
||||
BubbleProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
const Bubble: BubbleType = forwardRef(
|
||||
const Bubble = forwardRef<HTMLDivElement, BubbleProps>(
|
||||
(
|
||||
{
|
||||
children,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import cl from "clsx";
|
||||
import Bubble, { BubbleType } from "./Bubble";
|
||||
import Bubble, { BubbleProps } from "./Bubble";
|
||||
import { BodyLong, BodyShort } from "../typography";
|
||||
|
||||
export interface ChatProps extends HTMLAttributes<HTMLDivElement> {
|
||||
@@ -44,9 +44,30 @@ interface ChatComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
ChatProps & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
Bubble: BubbleType;
|
||||
/**
|
||||
* @see 🏷️ {@link BubbleProps}
|
||||
*/
|
||||
Bubble: React.ForwardRefExoticComponent<
|
||||
BubbleProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component for displaying chat messages.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/chat)
|
||||
* @see 🏷️ {@link ChatProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Chat>
|
||||
* <Chat.Bubble avatar="A" name="Alice">Hello!</Chat.Bubble>
|
||||
* </Chat>
|
||||
* <Chat>
|
||||
* <Chat.Bubble avatar="B" name="Bob">Hi there!</Chat.Bubble>
|
||||
* </Chat>
|
||||
* ```
|
||||
*/
|
||||
export const Chat = forwardRef<HTMLDivElement, ChatProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import ToggleChips, { ToggleChipsType } from "./Toggle";
|
||||
import RemovableChips, { RemovableChipsType } from "./Removable";
|
||||
import ToggleChips, { ToggleChipsProps } from "./Toggle";
|
||||
import RemovableChips, { RemovableChipsProps } from "./Removable";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
|
||||
export interface ChipsProps extends HTMLAttributes<HTMLUListElement> {
|
||||
children: React.ReactNode;
|
||||
@@ -16,10 +17,47 @@ interface ChipsComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
ChipsProps & React.RefAttributes<HTMLUListElement>
|
||||
> {
|
||||
Toggle: ToggleChipsType;
|
||||
Removable: RemovableChipsType;
|
||||
/**
|
||||
* Toggle between selected-states.
|
||||
* @see 🏷️ {@link ToggleChipsProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Toggle: OverridableComponent<ToggleChipsProps, HTMLButtonElement>;
|
||||
/**
|
||||
* Remove filter or the likes on click
|
||||
* @see 🏷️ {@link RemovableChipsProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Removable: OverridableComponent<RemovableChipsProps, HTMLButtonElement>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a list of items as chips.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/chips)
|
||||
* @see 🏷️ {@link ChipsProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
<Chips size="small">
|
||||
{options.map((c) => (
|
||||
<Chips.Toggle
|
||||
selected={selected.includes(c)}
|
||||
key={c}
|
||||
onClick={() =>
|
||||
setSelected(
|
||||
selected.includes(c)
|
||||
? selected.filter((x) => x !== c)
|
||||
: [...selected, c]
|
||||
)
|
||||
}
|
||||
>
|
||||
{c}
|
||||
</Chips.Toggle>
|
||||
))}
|
||||
</Chips>
|
||||
* ```
|
||||
*/
|
||||
export const Chips: ChipsComponent = forwardRef<HTMLUListElement, ChipsProps>(
|
||||
({ className, size = "medium", children, ...rest }, ref) => {
|
||||
return (
|
||||
|
||||
@@ -22,9 +22,6 @@ export interface RemovableChipsProps
|
||||
onDelete?: () => void;
|
||||
}
|
||||
|
||||
export interface RemovableChipsType
|
||||
extends OverridableComponent<RemovableChipsProps, HTMLButtonElement> {}
|
||||
|
||||
export const RemovableChips: OverridableComponent<
|
||||
RemovableChipsProps,
|
||||
HTMLButtonElement
|
||||
@@ -63,6 +60,6 @@ export const RemovableChips: OverridableComponent<
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
) as RemovableChipsType;
|
||||
);
|
||||
|
||||
export default RemovableChips;
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CheckmarkIcon } from "@navikt/aksel-icons";
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef } from "react";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
@@ -10,27 +9,64 @@ export interface ToggleChipsProps
|
||||
* Toggles aria-pressed and visual-changes
|
||||
*/
|
||||
selected?: boolean;
|
||||
/**
|
||||
* Chip-variants
|
||||
* @default "action"
|
||||
*/
|
||||
variant?: "action" | "neutral";
|
||||
/**
|
||||
* Toggles display of checkmark on selected
|
||||
* @default true
|
||||
*/
|
||||
checkmark?: boolean;
|
||||
}
|
||||
|
||||
export interface ToggleChipsType
|
||||
extends OverridableComponent<ToggleChipsProps, HTMLButtonElement> {}
|
||||
|
||||
export const ToggleChips: ToggleChipsType = forwardRef(
|
||||
export const ToggleChips: OverridableComponent<
|
||||
ToggleChipsProps,
|
||||
HTMLButtonElement
|
||||
> = forwardRef(
|
||||
(
|
||||
{ className, children, selected, as: Component = "button", ...rest },
|
||||
{
|
||||
className,
|
||||
children,
|
||||
selected,
|
||||
variant = "action",
|
||||
checkmark = true,
|
||||
as: Component = "button",
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navds-chips__chip navds-chips__toggle", className, {
|
||||
"navds-chips--icon-left": selected,
|
||||
})}
|
||||
className={cl(
|
||||
"navds-chips__chip navds-chips__toggle",
|
||||
className,
|
||||
`navds-chips__toggle--${variant}`
|
||||
)}
|
||||
aria-pressed={selected}
|
||||
>
|
||||
{selected && (
|
||||
<CheckmarkIcon aria-hidden className="navds-chips__toggle-icon" />
|
||||
{selected && checkmark && (
|
||||
<svg
|
||||
aria-hidden
|
||||
className="navds-chips__toggle-icon"
|
||||
width="10"
|
||||
height="8"
|
||||
viewBox="0 0 10 8"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable={false}
|
||||
role="img"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M9.51894 0.45851C9.81799 0.745107 9.8281 1.21987 9.5415 1.51893L3.7915 7.51893C3.51247 7.81009 3.05315 7.82848 2.75174 7.56056L0.501735 5.56056C0.192148 5.28537 0.164263 4.81132 0.439451 4.50173C0.71464 4.19214 1.18869 4.16426 1.49828 4.43944L3.20835 5.95951L8.45852 0.481072C8.74511 0.182015 9.21988 0.171913 9.51894 0.45851Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
<span className="navds-chips__chip-text">{children}</span>
|
||||
</Component>
|
||||
|
||||
@@ -66,25 +66,78 @@ export const Default = {
|
||||
};
|
||||
|
||||
export const Toggle = () => {
|
||||
const [selected, setSelected] = useState<number[]>([]);
|
||||
const [selected, setSelected] = useState<number[]>([2, 4]);
|
||||
return (
|
||||
<Chips>
|
||||
{options.map((c, y) => (
|
||||
<Chips.Toggle
|
||||
selected={selected.includes(y)}
|
||||
onClick={() =>
|
||||
setSelected(
|
||||
selected.includes(y)
|
||||
? selected.filter((x) => x !== y)
|
||||
: [...selected, y]
|
||||
)
|
||||
}
|
||||
key={y}
|
||||
>
|
||||
{c}
|
||||
</Chips.Toggle>
|
||||
))}
|
||||
</Chips>
|
||||
<div className="colgap">
|
||||
<Chips>
|
||||
{options.map((c, y) => (
|
||||
<Chips.Toggle
|
||||
selected={selected.includes(y)}
|
||||
onClick={() =>
|
||||
setSelected(
|
||||
selected.includes(y)
|
||||
? selected.filter((x) => x !== y)
|
||||
: [...selected, y]
|
||||
)
|
||||
}
|
||||
key={y}
|
||||
>
|
||||
{c}
|
||||
</Chips.Toggle>
|
||||
))}
|
||||
</Chips>
|
||||
<Chips>
|
||||
{options.map((c, y) => (
|
||||
<Chips.Toggle
|
||||
variant="neutral"
|
||||
selected={selected.includes(y)}
|
||||
onClick={() =>
|
||||
setSelected(
|
||||
selected.includes(y)
|
||||
? selected.filter((x) => x !== y)
|
||||
: [...selected, y]
|
||||
)
|
||||
}
|
||||
key={y}
|
||||
>
|
||||
{c}
|
||||
</Chips.Toggle>
|
||||
))}
|
||||
</Chips>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const ToggleNoCheckmark = () => {
|
||||
const [selected, setSelected] = useState<number>(2);
|
||||
return (
|
||||
<div className="colgap">
|
||||
<Chips>
|
||||
{options.map((c, y) => (
|
||||
<Chips.Toggle
|
||||
selected={selected === y}
|
||||
checkmark={false}
|
||||
onClick={() => setSelected(y)}
|
||||
key={y}
|
||||
>
|
||||
{c}
|
||||
</Chips.Toggle>
|
||||
))}
|
||||
</Chips>
|
||||
<Chips>
|
||||
{options.map((c, y) => (
|
||||
<Chips.Toggle
|
||||
variant="neutral"
|
||||
selected={selected === y}
|
||||
checkmark={false}
|
||||
onClick={() => setSelected(y)}
|
||||
key={y}
|
||||
>
|
||||
{c}
|
||||
</Chips.Toggle>
|
||||
))}
|
||||
</Chips>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -108,7 +161,7 @@ export const Removable = () => {
|
||||
};
|
||||
|
||||
export const Regular = () => {
|
||||
const [selected, setSelected] = useState<number[]>([]);
|
||||
const [selected, setSelected] = useState<number[]>([2]);
|
||||
return (
|
||||
<div className="colgap">
|
||||
<Chips>
|
||||
@@ -138,7 +191,7 @@ export const Regular = () => {
|
||||
};
|
||||
|
||||
export const Small = () => {
|
||||
const [selected, setSelected] = useState<number[]>([]);
|
||||
const [selected, setSelected] = useState<number[]>([2, 4]);
|
||||
return (
|
||||
<div className="colgap">
|
||||
<Chips size="small">
|
||||
|
||||
@@ -65,6 +65,17 @@ export interface CopyButtonProps
|
||||
activeTitle?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A button component that copies text to the clipboard when clicked.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/copybutton)
|
||||
* @see 🏷️ {@link CopyButtonProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
<CopyButton copyText="3.14" />
|
||||
* ```
|
||||
*/
|
||||
export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -28,131 +28,121 @@ export interface DateInputProps
|
||||
variant?: "datepicker" | "monthpicker";
|
||||
}
|
||||
|
||||
export type DateInputType = React.ForwardRefExoticComponent<
|
||||
DateInputProps & React.RefAttributes<HTMLInputElement>
|
||||
>;
|
||||
const DateInput = forwardRef<HTMLInputElement, DateInputProps>((props, ref) => {
|
||||
const {
|
||||
className,
|
||||
hideLabel = false,
|
||||
label,
|
||||
description,
|
||||
variant = "datepicker",
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const DateInput: DateInputType = forwardRef<HTMLInputElement, DateInputProps>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
className,
|
||||
hideLabel = false,
|
||||
label,
|
||||
description,
|
||||
variant = "datepicker",
|
||||
...rest
|
||||
} = props;
|
||||
const isDatepickerVariant = variant === "datepicker";
|
||||
|
||||
const isDatepickerVariant = variant === "datepicker";
|
||||
const conditionalVariables = {
|
||||
prefix: isDatepickerVariant ? "datepicker-input" : "monthpicker-input",
|
||||
iconTitle: {
|
||||
open: isDatepickerVariant ? "Åpne datovelger" : "Åpne månedsvelger",
|
||||
close: isDatepickerVariant ? "Lukk datovelger" : "Lukk månedsvelger",
|
||||
},
|
||||
};
|
||||
|
||||
const conditionalVariables = {
|
||||
prefix: isDatepickerVariant ? "datepicker-input" : "monthpicker-input",
|
||||
iconTitle: {
|
||||
open: isDatepickerVariant ? "Åpne datovelger" : "Åpne månedsvelger",
|
||||
close: isDatepickerVariant ? "Lukk datovelger" : "Lukk månedsvelger",
|
||||
},
|
||||
};
|
||||
const { onOpen, ariaId, open } = useDateInputContext();
|
||||
|
||||
const { onOpen, ariaId, open } = useDateInputContext();
|
||||
const {
|
||||
inputProps,
|
||||
size = "medium",
|
||||
inputDescriptionId,
|
||||
errorId,
|
||||
showErrorMsg,
|
||||
hasError,
|
||||
} = useFormField(props, conditionalVariables.prefix);
|
||||
|
||||
const {
|
||||
inputProps,
|
||||
size = "medium",
|
||||
inputDescriptionId,
|
||||
errorId,
|
||||
showErrorMsg,
|
||||
hasError,
|
||||
} = useFormField(props, conditionalVariables.prefix);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cl(
|
||||
className,
|
||||
"navds-form-field",
|
||||
`navds-form-field--${size}`,
|
||||
"navds-date__field",
|
||||
{
|
||||
"navds-text-field--error": hasError,
|
||||
"navds-date__field--error": hasError,
|
||||
"navds-form-field--disabled": !!inputProps.disabled,
|
||||
"navds-text-field--disabled": !!inputProps.disabled,
|
||||
}
|
||||
)}
|
||||
return (
|
||||
<div
|
||||
className={cl(
|
||||
className,
|
||||
"navds-form-field",
|
||||
`navds-form-field--${size}`,
|
||||
"navds-date__field",
|
||||
{
|
||||
"navds-text-field--error": hasError,
|
||||
"navds-date__field--error": hasError,
|
||||
"navds-form-field--disabled": !!inputProps.disabled,
|
||||
"navds-text-field--disabled": !!inputProps.disabled,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Label
|
||||
htmlFor={inputProps.id}
|
||||
size={size}
|
||||
className={cl("navds-form-field__label", {
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
>
|
||||
<Label
|
||||
htmlFor={inputProps.id}
|
||||
size={size}
|
||||
className={cl("navds-form-field__label", {
|
||||
{label}
|
||||
</Label>
|
||||
{!!description && (
|
||||
<BodyShort
|
||||
as="div"
|
||||
className={cl("navds-form-field__description", {
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
id={inputDescriptionId}
|
||||
size={size}
|
||||
>
|
||||
{label}
|
||||
</Label>
|
||||
{!!description && (
|
||||
<BodyShort
|
||||
as="div"
|
||||
className={cl("navds-form-field__description", {
|
||||
"navds-sr-only": hideLabel,
|
||||
})}
|
||||
id={inputDescriptionId}
|
||||
size={size}
|
||||
>
|
||||
{description}
|
||||
</BodyShort>
|
||||
)}
|
||||
<div className="navds-date__field-wrapper">
|
||||
<input
|
||||
ref={ref}
|
||||
{...omit(rest, ["error", "errorId", "size"])}
|
||||
{...inputProps}
|
||||
autoComplete="off"
|
||||
aria-controls={ariaId}
|
||||
className={cl(
|
||||
"navds-date__field-input",
|
||||
"navds-text-field__input",
|
||||
"navds-body-short",
|
||||
`navds-body-${size}`
|
||||
)}
|
||||
size={14}
|
||||
/>
|
||||
<button
|
||||
disabled={inputProps.disabled}
|
||||
tabIndex={open ? -1 : 0}
|
||||
onClick={() => onOpen()}
|
||||
type="button"
|
||||
className="navds-date__field-button"
|
||||
>
|
||||
<CalendarIcon
|
||||
pointerEvents="none"
|
||||
title={
|
||||
open
|
||||
? conditionalVariables.iconTitle.close
|
||||
: conditionalVariables.iconTitle.open
|
||||
}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="navds-form-field__error"
|
||||
id={errorId}
|
||||
aria-relevant="additions removals"
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && (
|
||||
<ErrorMessage size={size}>{props.error}</ErrorMessage>
|
||||
{description}
|
||||
</BodyShort>
|
||||
)}
|
||||
<div className="navds-date__field-wrapper">
|
||||
<input
|
||||
ref={ref}
|
||||
{...omit(rest, ["error", "errorId", "size"])}
|
||||
{...inputProps}
|
||||
autoComplete="off"
|
||||
aria-controls={ariaId}
|
||||
className={cl(
|
||||
"navds-date__field-input",
|
||||
"navds-text-field__input",
|
||||
"navds-body-short",
|
||||
`navds-body-${size}`
|
||||
)}
|
||||
</div>
|
||||
size={14}
|
||||
/>
|
||||
<button
|
||||
disabled={inputProps.disabled}
|
||||
tabIndex={open ? -1 : 0}
|
||||
onClick={() => onOpen()}
|
||||
type="button"
|
||||
className="navds-date__field-button"
|
||||
>
|
||||
<CalendarIcon
|
||||
pointerEvents="none"
|
||||
title={
|
||||
open
|
||||
? conditionalVariables.iconTitle.close
|
||||
: conditionalVariables.iconTitle.open
|
||||
}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
<div
|
||||
className="navds-form-field__error"
|
||||
id={errorId}
|
||||
aria-relevant="additions removals"
|
||||
aria-live="polite"
|
||||
>
|
||||
{showErrorMsg && <ErrorMessage size={size}>{props.error}</ErrorMessage>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const DatePickerInput = forwardRef<HTMLInputElement, DateInputProps>(
|
||||
(props, ref) => <DateInput {...props} ref={ref} />
|
||||
);
|
||||
|
||||
export const DatePickerInput: DateInputType = forwardRef<
|
||||
HTMLInputElement,
|
||||
DateInputProps
|
||||
>((props, ref) => <DateInput {...props} ref={ref} />);
|
||||
|
||||
export const MonthPickerInput: DateInputType = forwardRef<
|
||||
HTMLInputElement,
|
||||
DateInputProps
|
||||
>((props, ref) => <DateInput {...props} variant="monthpicker" ref={ref} />);
|
||||
export const MonthPickerInput = forwardRef<HTMLInputElement, DateInputProps>(
|
||||
(props, ref) => <DateInput {...props} variant="monthpicker" ref={ref} />
|
||||
);
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
SelectSingleEventHandler,
|
||||
} from "react-day-picker";
|
||||
import { omit, Popover, useId } from "../..";
|
||||
import { DateInputType, DatePickerInput } from "../DateInput";
|
||||
import { DateInputProps, DatePickerInput } from "../DateInput";
|
||||
import { DateContext } from "../context";
|
||||
import { getLocaleFromString, labels } from "../utils";
|
||||
import { Caption, DropdownCaption } from "./caption";
|
||||
@@ -120,10 +120,48 @@ export type DatePickerProps = DatePickerDefaultProps & ConditionalModeProps;
|
||||
|
||||
interface DatePickerComponent
|
||||
extends React.ForwardRefExoticComponent<DatePickerProps> {
|
||||
/**
|
||||
* @example
|
||||
* ```jsx
|
||||
* <DatePicker.Standalone
|
||||
* dropdownCaption
|
||||
* fromDate={new Date("2020-10-01")}
|
||||
* toDate={new Date("2024-10-01")}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
Standalone: DatePickerStandaloneType;
|
||||
Input: DateInputType;
|
||||
/**
|
||||
* Custom TextField for DatePicker
|
||||
* @see 🏷️ {@link DateInputProps}
|
||||
*/
|
||||
Input: React.ForwardRefExoticComponent<
|
||||
DateInputProps & React.RefAttributes<HTMLInputElement>
|
||||
>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that allows users to select a date from a calendar.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/datepicker)
|
||||
* @see 🏷️ {@link DatePickerProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* const { inputProps, datepickerProps } = useMonthpicker({
|
||||
* onMonthChange: console.log,
|
||||
* });
|
||||
*
|
||||
* return (
|
||||
* <DatePicker {...datepickerProps} dropdownCaption>
|
||||
* <DatePicker.Input
|
||||
* {...inputProps}
|
||||
* label="Velg dato"
|
||||
* />
|
||||
* </DatePicker>
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -113,6 +113,19 @@ const getValidationMessage = (val = {}): DateValidationT => ({
|
||||
...val,
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @see 🏷️ {@link UseDatepickerOptions}
|
||||
* @see 🏷️ {@link UseDatepickerValue}
|
||||
* @see 🏷️ {@link DateValidationT}
|
||||
* @example
|
||||
* const { datepickerProps, inputProps } = useDatepicker({
|
||||
* fromDate: new Date("Aug 23 2019"),
|
||||
* toDate: new Date("Feb 23 2024"),
|
||||
* onDateChange: console.log,
|
||||
* onValidate: console.log,
|
||||
* });
|
||||
*/
|
||||
export const useDatepicker = (
|
||||
opt: UseDatepickerOptions = {}
|
||||
): UseDatepickerValue => {
|
||||
|
||||
@@ -110,6 +110,19 @@ const getIsAfter = (opt: { toDate?: Date; date?: Date }) =>
|
||||
(opt.toDate.getFullYear() === opt.date.getFullYear() &&
|
||||
opt.toDate.getMonth() < opt.date.getMonth()));
|
||||
|
||||
/**
|
||||
*
|
||||
* @see 🏷️ {@link UseMonthPickerOptions}
|
||||
* @see 🏷️ {@link UseMonthPickerValue}
|
||||
* @see 🏷️ {@link MonthValidationT}
|
||||
* @example
|
||||
* const { monthpickerProps, inputProps } = useMonthpicker({
|
||||
* fromDate: new Date("Aug 23 2019"),
|
||||
* toDate: new Date("Feb 23 2024"),
|
||||
* onMonthChange: console.log,
|
||||
* onValidate: console.log,
|
||||
* });
|
||||
*/
|
||||
export const useMonthpicker = (
|
||||
opt: UseMonthPickerOptions = {}
|
||||
): UseMonthPickerValue => {
|
||||
|
||||
@@ -102,7 +102,7 @@ const RANGE = {
|
||||
TO: "TO",
|
||||
} as const;
|
||||
|
||||
type RangeT = typeof RANGE[keyof typeof RANGE];
|
||||
type RangeT = (typeof RANGE)[keyof typeof RANGE];
|
||||
|
||||
const fromValidation = (day: Date, opt?: UseRangeDatepickerOptions) => {
|
||||
const isBefore =
|
||||
@@ -190,6 +190,18 @@ const initialValidation = (
|
||||
return getValidationMessage({ ...fromVal }, { ...toVal });
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @see 🏷️ {@link UseRangeDatepickerOptions}
|
||||
* @see 🏷️ {@link UseRangeDatepickerValue}
|
||||
* @see 🏷️ {@link RangeValidationT}
|
||||
* @example
|
||||
* const { datepickerProps, fromInputProps, toInputProps } = useRangeDatepicker({
|
||||
* fromDate: new Date("Aug 23 2019"),
|
||||
* onRangeChange: console.log,
|
||||
* onValidate: console.log,
|
||||
* });
|
||||
*/
|
||||
export const useRangeDatepicker = (
|
||||
opt: UseRangeDatepickerOptions = {}
|
||||
): UseRangeDatepickerValue => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import cl from "clsx";
|
||||
import React, { forwardRef, useRef, useState } from "react";
|
||||
import { RootProvider } from "react-day-picker";
|
||||
import { Popover, useId } from "../..";
|
||||
import { DateInputType, MonthPickerInput } from "../DateInput";
|
||||
import { DateInputProps, MonthPickerInput } from "../DateInput";
|
||||
import { DateContext, SharedMonthProvider } from "../context";
|
||||
import { getLocaleFromString, Matcher } from "../utils";
|
||||
import MonthCaption from "./MonthCaption";
|
||||
@@ -91,15 +91,47 @@ export interface MonthPickerProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
interface MonthPickerComponent
|
||||
extends React.ForwardRefExoticComponent<MonthPickerProps> {
|
||||
/**
|
||||
* Variant without popover
|
||||
* @example
|
||||
* ```jsx
|
||||
* <MonthPicker.Standalone
|
||||
* dropdownCaption
|
||||
* fromDate={new Date("1 Oct 2020")}
|
||||
* toDate={new Date("1 Oct 2024")}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
Standalone: MonthPickerStandaloneType;
|
||||
/**
|
||||
* Built-in Inputfield
|
||||
* Custom TextField for MonthPicker
|
||||
* @see 🏷️ {@link DateInputProps}
|
||||
*/
|
||||
Input: DateInputType;
|
||||
Input: React.ForwardRefExoticComponent<
|
||||
DateInputProps & React.RefAttributes<HTMLInputElement>
|
||||
>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a month picker.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/monthpicker)
|
||||
* @see 🏷️ {@link MonthPickerProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* const { inputProps, monthpickerProps } = useMonthpicker({
|
||||
* onMonthChange: console.log,
|
||||
* });
|
||||
*
|
||||
* return (
|
||||
* <MonthPicker {...monthpickerProps} dropdownCaption>
|
||||
* <MonthPicker.Input
|
||||
* {...inputProps}
|
||||
* label="Velg måned"
|
||||
* />
|
||||
* </MonthPicker>
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { createContext, useState } from "react";
|
||||
import Toggle, { ToggleType } from "./Toggle";
|
||||
import Toggle, { ToggleProps } from "./Toggle";
|
||||
import Menu, { MenuType } from "./Menu";
|
||||
|
||||
export interface DropdownProps {
|
||||
@@ -24,7 +24,15 @@ export interface DropdownProps {
|
||||
}
|
||||
|
||||
export interface DropdownType extends React.FC<DropdownProps> {
|
||||
Toggle: ToggleType;
|
||||
/**
|
||||
* @see 🏷️ {@link ToggleProps}
|
||||
*/
|
||||
Toggle: React.ForwardRefExoticComponent<
|
||||
ToggleProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
/**
|
||||
* @see 🏷️ {@link MenuType}
|
||||
*/
|
||||
Menu: MenuType;
|
||||
}
|
||||
|
||||
@@ -38,6 +46,37 @@ export interface DropdownContextType {
|
||||
|
||||
export const DropdownContext = createContext<DropdownContextType | null>(null);
|
||||
|
||||
/**
|
||||
* A component that displays a dropdown menu when the user clicks on its toggle button.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/dropdown)
|
||||
* @see 🏷️ {@link DropdownProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Dropdown>
|
||||
* <Button as={Dropdown.Toggle}>Toggle</Button>
|
||||
* <Dropdown.Menu>
|
||||
* <Dropdown.Menu.GroupedList>
|
||||
* <Dropdown.Menu.GroupedList.Heading>
|
||||
* Systemer og oppslagsverk
|
||||
* </Dropdown.Menu.GroupedList.Heading>
|
||||
* <Dropdown.Menu.GroupedList.Item>
|
||||
* Gosys
|
||||
* </Dropdown.Menu.GroupedList.Item>
|
||||
* <Dropdown.Menu.GroupedList.Item>
|
||||
* Infotrygd
|
||||
* </Dropdown.Menu.GroupedList.Item>
|
||||
* </Dropdown.Menu.GroupedList>
|
||||
* <Dropdown.Menu.Divider />
|
||||
* <Dropdown.Menu.List>
|
||||
* <Dropdown.Menu.List.Item>Gosys</Dropdown.Menu.List.Item>
|
||||
* <Dropdown.Menu.List.Item>Infotrygd</Dropdown.Menu.List.Item>
|
||||
* </Dropdown.Menu.List>
|
||||
* </Dropdown.Menu>
|
||||
* </Dropdown>
|
||||
* ```
|
||||
*/
|
||||
export const Dropdown = (({
|
||||
children,
|
||||
onSelect,
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "clsx";
|
||||
|
||||
export type DividerType = React.ForwardRefExoticComponent<
|
||||
React.HTMLAttributes<HTMLHRElement> & React.RefAttributes<HTMLHRElement>
|
||||
>;
|
||||
|
||||
export const Divider: DividerType = forwardRef(
|
||||
({ className, ...rest }, ref) => (
|
||||
<hr
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navds-dropdown__divider", className)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
export const Divider = forwardRef<
|
||||
HTMLHRElement,
|
||||
React.HTMLAttributes<HTMLHRElement>
|
||||
>(({ className, ...rest }, ref) => (
|
||||
<hr
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navds-dropdown__divider", className)}
|
||||
/>
|
||||
));
|
||||
|
||||
export default Divider;
|
||||
@@ -9,23 +9,20 @@ export interface GroupedHeadingProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type GroupedHeadingType = React.ForwardRefExoticComponent<
|
||||
GroupedHeadingProps & React.RefAttributes<HTMLElement>
|
||||
>;
|
||||
|
||||
export const GroupedHeading: GroupedHeadingType = forwardRef(
|
||||
({ className, ...rest }, ref) => (
|
||||
<dt
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-dropdown__list-heading",
|
||||
"navds-heading",
|
||||
"navds-heading--xsmall",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
export const GroupedHeading = forwardRef<
|
||||
HTMLDetailsElement,
|
||||
GroupedHeadingProps
|
||||
>(({ className, ...rest }, ref) => (
|
||||
<dt
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-dropdown__list-heading",
|
||||
"navds-heading",
|
||||
"navds-heading--xsmall",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
));
|
||||
|
||||
export default GroupedHeading;
|
||||
@@ -11,35 +11,31 @@ export interface GroupedItemProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type GroupedItemType = OverridableComponent<
|
||||
export const GroupedItem: OverridableComponent<
|
||||
GroupedItemProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
> = forwardRef(({ as: Component = "button", className, ...rest }, ref) => {
|
||||
const context = useContext(DropdownContext);
|
||||
|
||||
export const GroupedItem: GroupedItemType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => {
|
||||
const context = useContext(DropdownContext);
|
||||
|
||||
return (
|
||||
<dd className="navds-dropdown__list-item">
|
||||
<Component
|
||||
{...rest}
|
||||
value={rest.children}
|
||||
onClick={(event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
context?.onSelect?.(event);
|
||||
rest?.onClick?.(event);
|
||||
}}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-dropdown__item",
|
||||
"navds-body-short",
|
||||
"navds-body-short--small",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
</dd>
|
||||
);
|
||||
}
|
||||
);
|
||||
return (
|
||||
<dd className="navds-dropdown__list-item">
|
||||
<Component
|
||||
{...rest}
|
||||
value={rest.children}
|
||||
onClick={(event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
context?.onSelect?.(event);
|
||||
rest?.onClick?.(event);
|
||||
}}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-dropdown__item",
|
||||
"navds-body-short",
|
||||
"navds-body-short--small",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
</dd>
|
||||
);
|
||||
});
|
||||
|
||||
export default GroupedItem;
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "clsx";
|
||||
import GroupedHeading, { GroupedHeadingType } from "./Heading";
|
||||
import GroupedItem, { GroupedItemType } from "./Item";
|
||||
import React, { forwardRef } from "react";
|
||||
import { OverridableComponent } from "../../../util/OverridableComponent";
|
||||
import GroupedHeading, { GroupedHeadingProps } from "./Heading";
|
||||
import GroupedItem, { GroupedItemProps } from "./Item";
|
||||
|
||||
export interface GroupedListProps
|
||||
extends React.HTMLAttributes<HTMLDListElement> {
|
||||
@@ -15,8 +16,17 @@ export interface GroupedListType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
GroupedListProps & React.RefAttributes<HTMLDListElement>
|
||||
> {
|
||||
Heading: GroupedHeadingType;
|
||||
Item: GroupedItemType;
|
||||
/**
|
||||
* @see 🏷️ {@link GroupedHeadingProps}
|
||||
*/
|
||||
Heading: React.ForwardRefExoticComponent<
|
||||
GroupedHeadingProps & React.RefAttributes<HTMLDetailsElement>
|
||||
>;
|
||||
/**
|
||||
* @see 🏷️ {@link GroupedItemProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Item: OverridableComponent<GroupedItemProps, HTMLButtonElement>;
|
||||
}
|
||||
|
||||
export const DescriptionList = forwardRef(
|
||||
|
||||
@@ -10,13 +10,8 @@ export interface ListItemProps extends React.ButtonHTMLAttributes<HTMLElement> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ListItemType = OverridableComponent<
|
||||
ListItemProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
|
||||
export const ListItem: ListItemType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => {
|
||||
export const ListItem: OverridableComponent<ListItemProps, HTMLButtonElement> =
|
||||
forwardRef(({ as: Component = "button", className, ...rest }, ref) => {
|
||||
const context = useContext(DropdownContext);
|
||||
|
||||
return (
|
||||
@@ -38,7 +33,6 @@ export const ListItem: ListItemType = forwardRef(
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
export default ListItem;
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "clsx";
|
||||
import ListItem, { ListItemType } from "./Item";
|
||||
import React, { forwardRef } from "react";
|
||||
import { OverridableComponent } from "../../../util/OverridableComponent";
|
||||
import ListItem, { ListItemProps } from "./Item";
|
||||
|
||||
export interface ListProps extends React.HTMLAttributes<HTMLUListElement> {
|
||||
/**
|
||||
@@ -13,7 +14,11 @@ export interface ListType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
ListProps & React.RefAttributes<HTMLUListElement>
|
||||
> {
|
||||
Item: ListItemType;
|
||||
/**
|
||||
* @see 🏷️ {@link ListItemProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Item: OverridableComponent<ListItemProps, HTMLButtonElement>;
|
||||
}
|
||||
|
||||
export const List = forwardRef(({ className, children, ...rest }, ref) => (
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Popover } from "../../popover";
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import { Popover } from "../../popover";
|
||||
import { DropdownContext } from "../Dropdown";
|
||||
import Divider, { DividerType } from "./Divider";
|
||||
import Divider from "./Divider";
|
||||
import GroupedList, { GroupedListType } from "./GroupedList";
|
||||
import List, { ListType } from "./List";
|
||||
|
||||
@@ -43,9 +43,20 @@ export interface MenuType<Props = MenuProps>
|
||||
extends React.ForwardRefExoticComponent<
|
||||
Props & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
/**
|
||||
* @see 🏷️ {@link ListType}
|
||||
*/
|
||||
List: ListType;
|
||||
/**
|
||||
* @see 🏷️ {@link GroupedListType}
|
||||
*/
|
||||
GroupedList: GroupedListType;
|
||||
Divider: DividerType;
|
||||
/**
|
||||
* @see 🏷️ {@link React.HTMLAttributes<HTMLHRElement>}
|
||||
*/
|
||||
Divider: React.ForwardRefExoticComponent<
|
||||
React.HTMLAttributes<HTMLHRElement> & React.RefAttributes<HTMLHRElement>
|
||||
>;
|
||||
}
|
||||
|
||||
export const Menu = forwardRef<HTMLDivElement, MenuProps>(
|
||||
|
||||
@@ -10,11 +10,7 @@ export interface ToggleProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ToggleType = React.ForwardRefExoticComponent<
|
||||
ToggleProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
|
||||
export const Toggle: ToggleType = forwardRef(
|
||||
export const Toggle = forwardRef<HTMLButtonElement, ToggleProps>(
|
||||
({ className, onClick, ...rest }, ref) => {
|
||||
const context = useContext(DropdownContext);
|
||||
|
||||
|
||||
@@ -1,28 +1,48 @@
|
||||
import cl from "clsx";
|
||||
import React, { createContext, forwardRef, useRef, useState } from "react";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
import ExpansionCardContent, {
|
||||
ExpansionCardContentType,
|
||||
ExpansionCardContentProps,
|
||||
} from "./ExpansionCardContent";
|
||||
import {
|
||||
ExpansionCardDescription,
|
||||
ExpansionCardDescriptionType,
|
||||
ExpansionCardDescriptionProps,
|
||||
} from "./ExpansionCardDescription";
|
||||
import ExpansionCardHeader, {
|
||||
ExpansionCardHeaderType,
|
||||
ExpansionCardHeaderProps,
|
||||
} from "./ExpansionCardHeader";
|
||||
import {
|
||||
ExpansionCardTitle,
|
||||
ExpansionCardTitleType,
|
||||
ExpansionCardTitleProps,
|
||||
} from "./ExpansionCardTitle";
|
||||
|
||||
interface ExpansionCardComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
ExpansionCardProps & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
Header: ExpansionCardHeaderType;
|
||||
Title: ExpansionCardTitleType;
|
||||
Description: ExpansionCardDescriptionType;
|
||||
Content: ExpansionCardContentType;
|
||||
/**
|
||||
* @see 🏷️ {@link ExpansionCardHeaderProps}
|
||||
*/
|
||||
Header: React.ForwardRefExoticComponent<
|
||||
ExpansionCardHeaderProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
/**
|
||||
* @see 🏷️ {@link ExpansionCardTitleProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Title: OverridableComponent<ExpansionCardTitleProps, HTMLHeadingElement>;
|
||||
/**
|
||||
* @see 🏷️ {@link ExpansionCardDescriptionProps}
|
||||
*/
|
||||
Description: React.ForwardRefExoticComponent<
|
||||
ExpansionCardDescriptionProps & React.RefAttributes<HTMLParagraphElement>
|
||||
>;
|
||||
/**
|
||||
* @see 🏷️ {@link ExpansionCardContentProps}
|
||||
*/
|
||||
Content: React.ForwardRefExoticComponent<
|
||||
ExpansionCardContentProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
}
|
||||
|
||||
interface ExpansionCardCommonProps
|
||||
@@ -77,6 +97,24 @@ export const ExpansionCardContext = createContext<ExpansionCardContextProps>({
|
||||
export type ExpansionCardProps = ExpansionCardCommonProps &
|
||||
ExpansionCardConditionalProps;
|
||||
|
||||
/**
|
||||
* A component that displays an expandable card.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/expansioncard)
|
||||
* @see 🏷️ {@link ExpansionCardProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <ExpansionCard aria-label="default-demo">
|
||||
* <ExpansionCard.Header>
|
||||
* <ExpansionCard.Title>Utbetaling av sykepenger</ExpansionCard.Title>
|
||||
* </ExpansionCard.Header>
|
||||
* <ExpansionCard.Content>
|
||||
* <Innhold />
|
||||
* </ExpansionCard.Content>
|
||||
* </ExpansionCard>
|
||||
* ```
|
||||
*/
|
||||
export const ExpansionCard = forwardRef<HTMLDivElement, ExpansionCardProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -8,36 +8,33 @@ export interface ExpansionCardContentProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ExpansionCardContentType = React.ForwardRefExoticComponent<
|
||||
ExpansionCardContentProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
const ExpansionCardContent = forwardRef<
|
||||
HTMLDivElement,
|
||||
ExpansionCardContentProps
|
||||
>(({ children, className, ...rest }, ref) => {
|
||||
const panelContext = useContext(ExpansionCardContext);
|
||||
|
||||
const ExpansionCardContent: ExpansionCardContentType = forwardRef(
|
||||
({ children, className, ...rest }, ref) => {
|
||||
const panelContext = useContext(ExpansionCardContext);
|
||||
|
||||
if (panelContext === null) {
|
||||
console.error(
|
||||
"<ExpansionCard.Content> has to be used within an <ExpansionCard>"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<BodyLong
|
||||
{...rest}
|
||||
ref={ref}
|
||||
as="div"
|
||||
className={cl("navds-expansioncard__content", className, {
|
||||
"navds-expansioncard__content--closed": !panelContext.open,
|
||||
})}
|
||||
aria-hidden={!panelContext.open}
|
||||
size={panelContext.size}
|
||||
>
|
||||
<div className="navds-expansioncard__content-inner">{children}</div>
|
||||
</BodyLong>
|
||||
if (panelContext === null) {
|
||||
console.error(
|
||||
"<ExpansionCard.Content> has to be used within an <ExpansionCard>"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<BodyLong
|
||||
{...rest}
|
||||
ref={ref}
|
||||
as="div"
|
||||
className={cl("navds-expansioncard__content", className, {
|
||||
"navds-expansioncard__content--closed": !panelContext.open,
|
||||
})}
|
||||
aria-hidden={!panelContext.open}
|
||||
size={panelContext.size}
|
||||
>
|
||||
<div className="navds-expansioncard__content-inner">{children}</div>
|
||||
</BodyLong>
|
||||
);
|
||||
});
|
||||
|
||||
export default ExpansionCardContent;
|
||||
@@ -3,33 +3,31 @@ import cl from "clsx";
|
||||
import { BodyLong } from "../typography/BodyLong";
|
||||
import { ExpansionCardContext } from "./ExpansionCard";
|
||||
|
||||
interface ExpansionCardDescriptionProps
|
||||
export interface ExpansionCardDescriptionProps
|
||||
extends React.HTMLAttributes<HTMLParagraphElement> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ExpansionCardDescriptionType = React.ForwardRefExoticComponent<
|
||||
ExpansionCardDescriptionProps & React.RefAttributes<HTMLParagraphElement>
|
||||
>;
|
||||
export const ExpansionCardDescription = forwardRef<
|
||||
HTMLParagraphElement,
|
||||
ExpansionCardDescriptionProps
|
||||
>(({ className, ...rest }, ref) => {
|
||||
const panelContext = useContext(ExpansionCardContext);
|
||||
|
||||
export const ExpansionCardDescription: ExpansionCardDescriptionType =
|
||||
forwardRef(({ className, ...rest }, ref) => {
|
||||
const panelContext = useContext(ExpansionCardContext);
|
||||
|
||||
if (panelContext === null) {
|
||||
console.error(
|
||||
"<ExpansionCard.Description> has to be used within an <ExpansionCard>"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<BodyLong
|
||||
{...rest}
|
||||
as="p"
|
||||
ref={ref}
|
||||
className={cl("navds-link-panel__description", className)}
|
||||
size={panelContext.size}
|
||||
/>
|
||||
if (panelContext === null) {
|
||||
console.error(
|
||||
"<ExpansionCard.Description> has to be used within an <ExpansionCard>"
|
||||
);
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<BodyLong
|
||||
{...rest}
|
||||
as="p"
|
||||
ref={ref}
|
||||
className={cl("navds-link-panel__description", className)}
|
||||
size={panelContext.size}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@@ -8,43 +8,40 @@ export interface ExpansionCardHeaderProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ExpansionCardHeaderType = React.ForwardRefExoticComponent<
|
||||
ExpansionCardHeaderProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
const ExpansionCardHeader = forwardRef<
|
||||
HTMLDivElement,
|
||||
ExpansionCardHeaderProps
|
||||
>(({ children, className, ...rest }, ref) => {
|
||||
const panelContext = useContext(ExpansionCardContext);
|
||||
|
||||
const ExpansionCardHeader: ExpansionCardHeaderType = forwardRef(
|
||||
({ children, className, ...rest }, ref) => {
|
||||
const panelContext = useContext(ExpansionCardContext);
|
||||
|
||||
if (panelContext === null) {
|
||||
console.error(
|
||||
"<ExpansionCard.Header> has to be used within an <ExpansionCard>"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
{...rest}
|
||||
className={cl("navds-expansioncard__header", className)}
|
||||
>
|
||||
<div className="navds-expansioncard__header-content">{children}</div>
|
||||
|
||||
<button
|
||||
className="navds-expansioncard__header-button"
|
||||
onClick={() => panelContext.toggleOpen()}
|
||||
type="button"
|
||||
aria-expanded={panelContext.open}
|
||||
>
|
||||
<ChevronDownIcon
|
||||
className="navds-expansioncard__header-chevron"
|
||||
title="Vis mer"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
if (panelContext === null) {
|
||||
console.error(
|
||||
"<ExpansionCard.Header> has to be used within an <ExpansionCard>"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
{...rest}
|
||||
className={cl("navds-expansioncard__header", className)}
|
||||
>
|
||||
<div className="navds-expansioncard__header-content">{children}</div>
|
||||
|
||||
<button
|
||||
className="navds-expansioncard__header-button"
|
||||
onClick={() => panelContext.toggleOpen()}
|
||||
type="button"
|
||||
aria-expanded={panelContext.open}
|
||||
>
|
||||
<ChevronDownIcon
|
||||
className="navds-expansioncard__header-chevron"
|
||||
title="Vis mer"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default ExpansionCardHeader;
|
||||
@@ -2,7 +2,7 @@ import React, { forwardRef } from "react";
|
||||
import cl from "clsx";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
|
||||
interface ExpansionCardTitleProps
|
||||
export interface ExpansionCardTitleProps
|
||||
extends React.HTMLAttributes<HTMLHeadingElement> {
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
@@ -12,12 +12,10 @@ interface ExpansionCardTitleProps
|
||||
size?: "large" | "medium" | "small";
|
||||
}
|
||||
|
||||
export type ExpansionCardTitleType = OverridableComponent<
|
||||
export const ExpansionCardTitle: OverridableComponent<
|
||||
ExpansionCardTitleProps,
|
||||
HTMLHeadingElement
|
||||
>;
|
||||
|
||||
export const ExpansionCardTitle: ExpansionCardTitleType = forwardRef(
|
||||
> = forwardRef(
|
||||
({ className, as: Component = "h3", size = "medium", ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
|
||||
@@ -26,6 +26,24 @@ export interface ConfirmationPanelProps
|
||||
errorId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a confirmation checkbox with a label.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/confirmationpanel)
|
||||
* @see 🏷️ {@link ConfirmationPanelProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
<ConfirmationPanel
|
||||
checked={state}
|
||||
label="Ja, jeg samtykker."
|
||||
onChange={() => setState((x) => !x)}
|
||||
>
|
||||
For å komme videre må du gi oss lov til å hente inn og bruke opplysninger
|
||||
om deg.
|
||||
</ConfirmationPanel>
|
||||
* ```
|
||||
*/
|
||||
export const ConfirmationPanel = forwardRef<
|
||||
HTMLInputElement,
|
||||
ConfirmationPanelProps
|
||||
|
||||
@@ -30,6 +30,22 @@ export interface SelectProps
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a select input field.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/select)
|
||||
* @see 🏷️ {@link SelectProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Select label="Hvilket land har du bosted i.">
|
||||
* <option value="">Velg land</option>
|
||||
* <option value="norge">Norge</option>
|
||||
* <option value="sverige">Sverige</option>
|
||||
* <option value="danmark">Danmark</option>
|
||||
* </Select>
|
||||
* ```
|
||||
*/
|
||||
export const Select = forwardRef<HTMLSelectElement, SelectProps>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
|
||||
@@ -55,6 +55,17 @@ export interface SwitchProps
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a switch input field.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/switch)
|
||||
* @see 🏷️ {@link SwitchProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Switch>Slå på notifikasjoner</Switch>
|
||||
* ```
|
||||
*/
|
||||
export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
||||
(props, ref) => {
|
||||
const { inputProps, size } = useFormField(props, "switch");
|
||||
|
||||
@@ -33,6 +33,17 @@ export interface TextFieldProps
|
||||
type?: "email" | "number" | "password" | "tel" | "text" | "url";
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a text input field with a label.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/textfield)
|
||||
* @see 🏷️ {@link TextFieldProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <TextField label="Har du noen tilbakemeldinger?" />
|
||||
* ```
|
||||
*/
|
||||
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
|
||||
@@ -55,6 +55,17 @@ export interface TextareaProps
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a textarea input field with a label.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/textarea)
|
||||
* @see 🏷️ {@link TextareaProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Textarea label="Har du noen tilbakemeldinger?" />
|
||||
* ```
|
||||
*/
|
||||
export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
|
||||
@@ -35,6 +35,21 @@ export interface CheckboxGroupProps
|
||||
onChange?: (value: any[]) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that allows users to select one or more options from a list.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/checkbox)
|
||||
* @see 🏷️ {@link CheckboxProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <CheckboxGroup legend="Hvor vil du sitte?">
|
||||
* <Checkbox value="Bakerst">Bakerst</Checkbox>
|
||||
* <Checkbox value="Midterst">Midterst</Checkbox>
|
||||
* <Checkbox value="Fremst">Fremst</Checkbox>
|
||||
* </CheckboxGroup>
|
||||
* ```
|
||||
*/
|
||||
export const CheckboxGroup = forwardRef<
|
||||
HTMLFieldSetElement,
|
||||
CheckboxGroupProps
|
||||
|
||||
@@ -32,6 +32,24 @@ interface ErrorSummaryComponent
|
||||
Item: ErrorSummaryItemType;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a summary of errors.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/errorsummary)
|
||||
* @see 🏷️ {@link ErrorSummaryProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <ErrorSummary heading="Du må fikse disse feilene før du kan sende inn søknad.">
|
||||
* <ErrorSummary.Item href="#1">
|
||||
* Felt må fylles ut med alder
|
||||
* </ErrorSummary.Item>
|
||||
* <ErrorSummary.Item href="#2">
|
||||
* Tekstfeltet må ha en godkjent e-mail
|
||||
* </ErrorSummary.Item>
|
||||
* </ErrorSummary>
|
||||
* ```
|
||||
*/
|
||||
export const ErrorSummary = forwardRef<HTMLDivElement, ErrorSummaryProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -47,8 +47,8 @@ export interface RadioGroupProps
|
||||
|
||||
/**
|
||||
* Form radio group
|
||||
* @see https://aksel.nav.no/komponenter/core/radio
|
||||
* @see {@link RadioGroupProps}
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/radio)
|
||||
* @see 🏷️ {@link RadioGroupProps}
|
||||
* @example
|
||||
* <RadioGroup legend="Får du AAP nå?">
|
||||
* <Radio value="ja">Ja</Radio>
|
||||
|
||||
@@ -91,6 +91,19 @@ export const SearchContext = React.createContext<SearchContextProps | null>(
|
||||
null
|
||||
);
|
||||
|
||||
/**
|
||||
* A component that displays a search input field.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/search)
|
||||
* @see 🏷️ {@link SearchProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <form>
|
||||
* <Search label="Søk alle NAV sine sider" variant="primary" />
|
||||
* </form>
|
||||
* ```
|
||||
*/
|
||||
export const Search = forwardRef<HTMLInputElement, SearchProps>(
|
||||
(props, ref) => {
|
||||
const {
|
||||
|
||||
@@ -18,6 +18,21 @@ export interface GuidePanelProps extends HTMLAttributes<HTMLDivElement> {
|
||||
poster?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a guide panel.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/guidepanel)
|
||||
* @see 🏷️ {@link GuidePanelProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <GuidePanel>
|
||||
* Saksbehandlingstiden varierer fra kommune til kommune. Hvis det går mer
|
||||
* enn X måneder siden du søkte, skal du få brev om at saksbehandlingstiden
|
||||
* er forlenget.
|
||||
* </GuidePanel>
|
||||
* ```
|
||||
*/
|
||||
export const GuidePanel = forwardRef<HTMLDivElement, GuidePanelProps>(
|
||||
(
|
||||
{ children, className, illustration, poster = false, color, ...rest },
|
||||
|
||||
@@ -31,6 +31,19 @@ export interface HelpTextProps
|
||||
| "left-end";
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a help text button with a popover.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/helptext)
|
||||
* @see 🏷️ {@link HelpTextProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <HelpText title="Hvor kommer dette fra?">
|
||||
* Informasjonen er hentet fra X sin statistikk fra 2021
|
||||
* </HelpText>
|
||||
* ```
|
||||
*/
|
||||
export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ export * from "./panel";
|
||||
export * from "./popover";
|
||||
export * from "./provider";
|
||||
export * from "./read-more";
|
||||
export * from "./skeleton";
|
||||
export * from "./stepper";
|
||||
export * from "./table";
|
||||
export * from "./tabs";
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
import InternalHeaderButton, {
|
||||
InternalHeaderButtonProps,
|
||||
} from "./InternalHeaderButton";
|
||||
import InternalHeaderTitle, {
|
||||
InternalHeaderTitleType,
|
||||
InternalHeaderTitleProps,
|
||||
} from "./InternalHeaderTitle";
|
||||
import InternalHeaderUser, {
|
||||
InternalHeaderUserType,
|
||||
InternalHeaderUserProps,
|
||||
} from "./InternalHeaderUser";
|
||||
import InternalHeaderButton, {
|
||||
InternalHeaderButtonType,
|
||||
} from "./InternalHeaderButton";
|
||||
import InternalHeaderUserButton, {
|
||||
InternalHeaderUserButtonType,
|
||||
InternalHeaderUserButtonProps,
|
||||
} from "./InternalHeaderUserButton";
|
||||
import cl from "clsx";
|
||||
|
||||
export interface InternalHeaderProps extends HTMLAttributes<HTMLElement> {
|
||||
children: React.ReactNode;
|
||||
@@ -21,12 +22,60 @@ interface InternalHeaderComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
InternalHeaderProps & React.RefAttributes<HTMLElement>
|
||||
> {
|
||||
Title: InternalHeaderTitleType;
|
||||
User: InternalHeaderUserType;
|
||||
Button: InternalHeaderButtonType;
|
||||
UserButton: InternalHeaderUserButtonType;
|
||||
/**
|
||||
* @see 🏷️ {@link InternalHeaderTitleProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Title: OverridableComponent<InternalHeaderTitleProps, HTMLAnchorElement>;
|
||||
/**
|
||||
* @see 🏷️ {@link InternalHeaderUserProps}
|
||||
*/
|
||||
User: React.ForwardRefExoticComponent<
|
||||
InternalHeaderUserProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
/**
|
||||
* @see 🏷️ {@link InternalHeaderButtonProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Button: OverridableComponent<InternalHeaderButtonProps, HTMLButtonElement>;
|
||||
/**
|
||||
* @see 🏷️ {@link InternalHeaderUserButtonProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
UserButton: OverridableComponent<
|
||||
InternalHeaderUserButtonProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Header for internal pages and systems.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/i-header)
|
||||
* @see 🏷️ {@link InternalHeaderProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <InternalHeader>
|
||||
* <InternalHeader.Title as="h1">Sykepenger</InternalHeader.Title>
|
||||
* <InternalHeader.User name="Ola Normann" className="ml-auto" />
|
||||
* </InternalHeader>
|
||||
* ```
|
||||
* @example
|
||||
* ```jsx
|
||||
* <InternalHeader >
|
||||
* <InternalHeader.Title href="/#home">Tittel med lenke</InternalHeader.Title>
|
||||
* <Dropdown>
|
||||
* <InternalHeader.Button
|
||||
* as={Dropdown.Toggle}
|
||||
* >
|
||||
* <MenuGridIcon title="MenuGridIconer og oppslagsverk" />
|
||||
* </InternalHeader.Button>
|
||||
* <Dropdown.Menu />
|
||||
* </Dropdown>
|
||||
* </InternalHeader>
|
||||
* ```
|
||||
*/
|
||||
export const InternalHeader = forwardRef(({ className, ...rest }, ref) => (
|
||||
<header
|
||||
data-theme="dark"
|
||||
|
||||
@@ -9,20 +9,15 @@ export interface InternalHeaderButtonProps
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type InternalHeaderButtonType = OverridableComponent<
|
||||
export const InternalHeaderButton: OverridableComponent<
|
||||
InternalHeaderButtonProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
|
||||
export const InternalHeaderButton: InternalHeaderButtonType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navds-internalheader__button", className)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
> = forwardRef(({ as: Component = "button", className, ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navds-internalheader__button", className)}
|
||||
/>
|
||||
));
|
||||
|
||||
export default InternalHeaderButton;
|
||||
@@ -10,26 +10,18 @@ export interface InternalHeaderTitleProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type InternalHeaderTitleType = OverridableComponent<
|
||||
export const InternalHeaderTitle: OverridableComponent<
|
||||
InternalHeaderTitleProps,
|
||||
HTMLAnchorElement
|
||||
>;
|
||||
|
||||
export const InternalHeaderTitle: InternalHeaderTitleType = forwardRef(
|
||||
({ as: Component = "a", children, className, ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
size="xsmall"
|
||||
className={cl(
|
||||
"navds-internalheader__title",
|
||||
"navds-body-short",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<span>{children}</span>
|
||||
</Component>
|
||||
)
|
||||
);
|
||||
> = forwardRef(({ as: Component = "a", children, className, ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
size="xsmall"
|
||||
className={cl("navds-internalheader__title", "navds-body-short", className)}
|
||||
>
|
||||
<span>{children}</span>
|
||||
</Component>
|
||||
));
|
||||
|
||||
export default InternalHeaderTitle;
|
||||
@@ -14,10 +14,6 @@ export interface InternalHeaderUserProps
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export type InternalHeaderUserType = React.ForwardRefExoticComponent<
|
||||
InternalHeaderUserProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
export const InternalHeaderUser = forwardRef<
|
||||
HTMLDivElement,
|
||||
InternalHeaderUserProps
|
||||
|
||||
@@ -17,27 +17,24 @@ export interface InternalHeaderUserButtonProps
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export type InternalHeaderUserButtonType = OverridableComponent<
|
||||
export const InternalHeaderUserButton: OverridableComponent<
|
||||
InternalHeaderUserButtonProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
|
||||
export const InternalHeaderUserButton: InternalHeaderUserButtonType =
|
||||
forwardRef(({ as, name, description, className, ...rest }, ref) => (
|
||||
<InternalHeaderButton
|
||||
{...rest}
|
||||
as={as}
|
||||
ref={ref}
|
||||
className={cl("navds-internalheader__user-button", className)}
|
||||
>
|
||||
<div>
|
||||
<BodyShort size="small" as="div">
|
||||
{name}
|
||||
</BodyShort>
|
||||
{description && <Detail as="div">{description}</Detail>}
|
||||
</div>
|
||||
<ChevronDownIcon title="vis meny" />
|
||||
</InternalHeaderButton>
|
||||
));
|
||||
> = forwardRef(({ as, name, description, className, ...rest }, ref) => (
|
||||
<InternalHeaderButton
|
||||
{...rest}
|
||||
as={as}
|
||||
ref={ref}
|
||||
className={cl("navds-internalheader__user-button", className)}
|
||||
>
|
||||
<div>
|
||||
<BodyShort size="small" as="div">
|
||||
{name}
|
||||
</BodyShort>
|
||||
{description && <Detail as="div">{description}</Detail>}
|
||||
</div>
|
||||
<ChevronDownIcon title="vis meny" />
|
||||
</InternalHeaderButton>
|
||||
));
|
||||
|
||||
export default InternalHeaderUserButton;
|
||||
@@ -2,10 +2,10 @@ import React, { forwardRef } from "react";
|
||||
import { Panel, OverridableComponent } from "..";
|
||||
|
||||
import cl from "clsx";
|
||||
import { LinkPanelTitle, LinkPanelTitleType } from "./LinkPanelTitle";
|
||||
import { LinkPanelTitle, LinkPanelTitleProps } from "./LinkPanelTitle";
|
||||
import {
|
||||
LinkPanelDescription,
|
||||
LinkPanelDescriptionType,
|
||||
LinkPanelDescriptionProps,
|
||||
} from "./LinkPanelDescription";
|
||||
import { ChevronRightIcon } from "@navikt/aksel-icons";
|
||||
|
||||
@@ -24,10 +24,36 @@ export interface LinkPanelProps
|
||||
|
||||
interface LinkPanelComponentType
|
||||
extends OverridableComponent<LinkPanelProps, HTMLAnchorElement> {
|
||||
Title: LinkPanelTitleType;
|
||||
Description: LinkPanelDescriptionType;
|
||||
/**
|
||||
* @see 🏷️ {@link LinkPanelDescriptionProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Title: OverridableComponent<LinkPanelTitleProps, HTMLDivElement>;
|
||||
/**
|
||||
* @see 🏷️ {@link LinkPanelDescriptionProps}
|
||||
*/
|
||||
Description: React.ForwardRefExoticComponent<
|
||||
LinkPanelDescriptionProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a link panel.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/linkpanel)
|
||||
* @see 🏷️ {@link LinkPanelProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <LinkPanel href="#" border>
|
||||
* <LinkPanel.Title>Arbeidssøker eller permittert</LinkPanel.Title>
|
||||
* <LinkPanel.Description>
|
||||
* Om jobb, registrering, CV, dagpenger og feriepenger av dagpenger
|
||||
* </LinkPanel.Description>
|
||||
* </LinkPanel>
|
||||
* ```
|
||||
*/
|
||||
export const LinkPanelComponent: OverridableComponent<
|
||||
LinkPanelProps,
|
||||
HTMLAnchorElement
|
||||
|
||||
@@ -2,22 +2,19 @@ import React, { forwardRef } from "react";
|
||||
import cl from "clsx";
|
||||
import { BodyLong } from "..";
|
||||
|
||||
interface LinkPanelDescriptionProps
|
||||
export interface LinkPanelDescriptionProps
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type LinkPanelDescriptionType = React.ForwardRefExoticComponent<
|
||||
LinkPanelDescriptionProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
export const LinkPanelDescription: LinkPanelDescriptionType = forwardRef(
|
||||
({ className, ...rest }, ref) => (
|
||||
<BodyLong
|
||||
{...rest}
|
||||
as="div"
|
||||
ref={ref}
|
||||
className={cl("navds-link-panel__description", className)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
export const LinkPanelDescription = forwardRef<
|
||||
HTMLDivElement,
|
||||
LinkPanelDescriptionProps
|
||||
>(({ className, ...rest }, ref) => (
|
||||
<BodyLong
|
||||
{...rest}
|
||||
as="div"
|
||||
ref={ref}
|
||||
className={cl("navds-link-panel__description", className)}
|
||||
/>
|
||||
));
|
||||
@@ -2,26 +2,23 @@ import React, { forwardRef } from "react";
|
||||
import cl from "clsx";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
|
||||
interface LinkPanelTitleProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
export interface LinkPanelTitleProps
|
||||
extends React.HTMLAttributes<HTMLDivElement> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type LinkPanelTitleType = OverridableComponent<
|
||||
export const LinkPanelTitle: OverridableComponent<
|
||||
LinkPanelTitleProps,
|
||||
HTMLDivElement
|
||||
>;
|
||||
|
||||
export const LinkPanelTitle: LinkPanelTitleType = forwardRef(
|
||||
({ className, as: Component = "div", ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-link-panel__title",
|
||||
"navds-heading",
|
||||
"navds-heading--medium",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
> = forwardRef(({ className, as: Component = "div", ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-link-panel__title",
|
||||
"navds-heading",
|
||||
"navds-heading--medium",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
));
|
||||
@@ -10,6 +10,19 @@ export interface LinkProps
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a hyperlink.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/link)
|
||||
* @see 🏷️ {@link LinkProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Link href="#">lenke til ny side</Link>
|
||||
* <Link as={ReactRouter.Link} to="#">lenke til ny side</Link>
|
||||
* ```
|
||||
*/
|
||||
export const Link: OverridableComponent<LinkProps, HTMLAnchorElement> =
|
||||
forwardRef(({ as: Component = "a", className, ...rest }, ref) => (
|
||||
<Component {...rest} ref={ref} className={cl("navds-link", className)} />
|
||||
|
||||
@@ -2,7 +2,7 @@ import cl from "clsx";
|
||||
import React, { createContext, forwardRef, useContext } from "react";
|
||||
import { BodyShort, Heading } from "../typography";
|
||||
import { useId } from "../util/useId";
|
||||
import { ListItem, ListItemType } from "./ListItem";
|
||||
import { ListItem, ListItemProps } from "./ListItem";
|
||||
|
||||
export interface ListProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
children: React.ReactNode;
|
||||
@@ -28,7 +28,12 @@ export interface ListProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
|
||||
export interface ListComponent
|
||||
extends React.ForwardRefExoticComponent<ListProps> {
|
||||
Item: ListItemType;
|
||||
/**
|
||||
* @see 🏷️ {@link ListItemProps}
|
||||
*/
|
||||
Item: React.ForwardRefExoticComponent<
|
||||
ListItemProps & React.RefAttributes<HTMLLIElement>
|
||||
>;
|
||||
}
|
||||
|
||||
interface ListContextProps {
|
||||
|
||||
@@ -18,12 +18,7 @@ export interface ListItemProps extends React.HTMLAttributes<HTMLLIElement> {
|
||||
icon?: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface ListItemType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
ListItemProps & React.RefAttributes<HTMLLIElement>
|
||||
> {}
|
||||
|
||||
export const ListItem: ListItemType = forwardRef(
|
||||
export const ListItem = forwardRef<HTMLLIElement, ListItemProps>(
|
||||
({ className, children, title, icon, ...rest }, ref) => {
|
||||
const { listType, isNested } = useContext(ListContext);
|
||||
|
||||
|
||||
@@ -38,6 +38,17 @@ export type LoaderType = React.ForwardRefExoticComponent<
|
||||
LoaderProps & React.RefAttributes<SVGSVGElement>
|
||||
>;
|
||||
|
||||
/**
|
||||
* A component that displays a loading spinner.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/loader)
|
||||
* @see 🏷️ {@link LoaderProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Loader size="3xlarge" title="venter..." />
|
||||
* ```
|
||||
*/
|
||||
export const Loader: LoaderType = forwardRef<SVGSVGElement, LoaderProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -71,6 +71,33 @@ type ModalLifecycle = {
|
||||
setAppElement: (element: any) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* A component that displays a modal dialog.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/modal)
|
||||
* @see 🏷️ {@link ModalProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* const [open, setOpen] = useState(false);
|
||||
*
|
||||
* <Modal
|
||||
* open={open}
|
||||
* aria-label="Modal demo"
|
||||
* onClose={() => setOpen((x) => !x)}
|
||||
* aria-labelledby="modal-heading"
|
||||
* >
|
||||
* <Modal.Content>
|
||||
* <Heading spacing level="1" size="large" id="modal-heading">
|
||||
* Viktig info
|
||||
* </Heading>
|
||||
* <BodyLong spacing>
|
||||
* Hallo!
|
||||
* </BodyLong>
|
||||
* </Modal.Content>
|
||||
* </Modal>
|
||||
* ```
|
||||
*/
|
||||
export const Modal = forwardRef<ReactModal, ModalProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -89,6 +89,23 @@ export const getSteps = ({
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* A component that displays pagination controls.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/pagination)
|
||||
* @see 🏷️ {@link PaginationProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Pagination
|
||||
* page={pageState}
|
||||
* onPageChange={(x) => setPageState(x)}
|
||||
* count={9}
|
||||
* boundaryCount={1}
|
||||
* siblingCount={1}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export const Pagination = forwardRef<HTMLElement, PaginationProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -16,6 +16,25 @@ export interface PanelProps extends React.HTMLAttributes<HTMLElement> {
|
||||
|
||||
export type PanelType = OverridableComponent<PanelProps, HTMLElement>;
|
||||
|
||||
/**
|
||||
* A component that displays a bordered panel with heading and body.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/panel)
|
||||
* @see 🏷️ {@link PanelProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Panel border>
|
||||
* <Heading spacing level="2" size="large">
|
||||
* Søk om økonomisk sosialhjelp
|
||||
* </Heading>
|
||||
* <BodyLong>
|
||||
* Du kan søke om det du trenger økonomisk støtte til.
|
||||
* </BodyLong>
|
||||
* </Panel>
|
||||
* ```
|
||||
*/
|
||||
export const Panel: PanelType = forwardRef(
|
||||
(
|
||||
{ children, className, border = false, as: Component = "div", ...rest },
|
||||
|
||||
@@ -81,6 +81,26 @@ interface PopoverComponent
|
||||
Content: PopoverContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a popover.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/popover)
|
||||
* @see 🏷️ {@link PopoverProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Button ref={buttonRef} onClick={() => setOpenState(true)}>
|
||||
* Åpne popover
|
||||
* </Button>
|
||||
* <Popover
|
||||
* open={openState}
|
||||
* onClose={() => setOpenState(false)}
|
||||
* anchorEl={buttonRef.current}
|
||||
* >
|
||||
* <Popover.Content>Innhold her!</Popover.Content>
|
||||
* </Popover>
|
||||
* ```
|
||||
*/
|
||||
export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -23,6 +23,19 @@ export interface ProviderProps {
|
||||
|
||||
export const useProvider = () => useContext(ProviderContext);
|
||||
|
||||
/**
|
||||
* Provides added context to the component tree.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/provider)
|
||||
* @see 🏷️ {@link ProviderProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Provider rootElement={rootElement}>
|
||||
* {app}
|
||||
* </Provider>
|
||||
* ```
|
||||
*/
|
||||
export const Provider = ({ children, ...rest }: ProviderProps) => {
|
||||
return (
|
||||
<ProviderContext.Provider value={rest}>{children}</ProviderContext.Provider>
|
||||
|
||||
@@ -32,8 +32,8 @@ export interface ReadMoreProps
|
||||
|
||||
/**
|
||||
* ReadMore
|
||||
* @see https://aksel.nav.no/komponenter/core/read-more
|
||||
* @see {@link ReadMoreProps}
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/read-more)
|
||||
* @see 🏷️ {@link ReadMoreProps}
|
||||
*
|
||||
* @example
|
||||
* // Default
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "clsx";
|
||||
|
||||
export interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
children?: React.ReactNode;
|
||||
/**
|
||||
* @default text
|
||||
*/
|
||||
variant?: "circle" | "rectangle" | "rounded" | "text";
|
||||
/**
|
||||
* When not inferring height from children, you must specify height
|
||||
*/
|
||||
height?: number | string;
|
||||
/**
|
||||
* When not inferring width from children, you must specify width
|
||||
*/
|
||||
width?: number | string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple skeleton loader
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/skeleton)
|
||||
* @see 🏷️ {@link SkeletonProps}
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Skeleton variant="circle" height="5rem" width="5rem" />
|
||||
* ```
|
||||
*/
|
||||
export const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(
|
||||
(
|
||||
{ className, children, height, width, style, variant = "text", ...rest },
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-skeleton",
|
||||
className,
|
||||
`navds-skeleton--${variant}`,
|
||||
{
|
||||
"navds-skeleton--has-children": Boolean(children),
|
||||
"navds-skeleton--no-height": !height,
|
||||
"navds-skeleton--no-width": !width,
|
||||
}
|
||||
)}
|
||||
style={{ ...style, width, height }}
|
||||
aria-hidden
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default Skeleton;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Skeleton } from "./Skeleton";
|
||||
export type { SkeletonProps } from "./Skeleton";
|
||||
@@ -0,0 +1,118 @@
|
||||
import React from "react";
|
||||
import { Skeleton } from ".";
|
||||
import { Alert } from "../alert";
|
||||
import { Button } from "../button";
|
||||
import { Checkbox } from "../form";
|
||||
import { BodyLong, Heading } from "../typography";
|
||||
|
||||
export default {
|
||||
title: "ds-react/Skeleton",
|
||||
component: Skeleton,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div style={{ display: "grid", gap: "0.5rem" }}>
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
export const Default = {
|
||||
render: () => (
|
||||
<div>
|
||||
<Skeleton>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur
|
||||
voluptas sint dolore omnis quia consequatur beatae vero cum officia
|
||||
debitis. Quidem debitis omnis reprehenderit nobis rerum. Nulla, magnam?
|
||||
Saepe, eveniet? Test
|
||||
</Skeleton>
|
||||
<Skeleton>
|
||||
<Alert variant="info">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur
|
||||
voluptas sint dolore omnis quia consequatur beatae vero cum officia
|
||||
debitis. Quidem debitis omnis reprehenderit nobis rerum. Nulla,
|
||||
magnam? Saepe, eveniet?
|
||||
</Alert>
|
||||
</Skeleton>
|
||||
<Skeleton>
|
||||
<BodyLong>
|
||||
Quidem debitis omnis reprehenderit nobis rerum. Nulla, magnam? Saepe,
|
||||
eveniet?
|
||||
</BodyLong>
|
||||
<Checkbox value="test">Valg 1</Checkbox>
|
||||
<Checkbox value="tes2">Valg 2</Checkbox>
|
||||
<div style={{ display: "flex", gap: "2rem" }}>
|
||||
<Button>Send inn</Button>
|
||||
<Button>Tilbake</Button>
|
||||
</div>
|
||||
</Skeleton>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
export const Shapes = {
|
||||
render: () => (
|
||||
<>
|
||||
<Skeleton variant="text"></Skeleton>
|
||||
<Skeleton variant="circle" width={60} height={60}></Skeleton>
|
||||
<Skeleton variant="rectangle" width={200} height={40}></Skeleton>
|
||||
<Skeleton variant="rounded" width={200} height={40}></Skeleton>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
export const WrappingComponents = {
|
||||
render: () => (
|
||||
<Skeleton style={{ display: "grid", gap: "0.5rem" }}>
|
||||
<BodyLong>
|
||||
Quidem debitis omnis reprehenderit nobis rerum. Nulla, magnam? Saepe,
|
||||
eveniet?
|
||||
</BodyLong>
|
||||
<Checkbox value="test">Valg 1</Checkbox>
|
||||
<Checkbox value="tes2">Valg 2</Checkbox>
|
||||
<div style={{ display: "flex", gap: "2rem" }}>
|
||||
<Button>Send inn</Button>
|
||||
<Button>Tilbake</Button>
|
||||
</div>
|
||||
</Skeleton>
|
||||
),
|
||||
};
|
||||
|
||||
export const TextSizing = {
|
||||
render: () => (
|
||||
<div style={{ display: "grid", width: 300 }}>
|
||||
<Skeleton>
|
||||
<Heading level="1" size="xlarge">
|
||||
Placeholder
|
||||
</Heading>
|
||||
</Skeleton>
|
||||
<Skeleton>
|
||||
<BodyLong>Placeholder</BodyLong>
|
||||
</Skeleton>
|
||||
<BodyLong as={Skeleton}>Placeholder</BodyLong>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
export const NativeText = {
|
||||
render: () => (
|
||||
<div>
|
||||
<h1>
|
||||
<Skeleton>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur
|
||||
voluptas sint dolore omnis quia consequatur beatae vero cum officia
|
||||
debitis. Quidem debitis omnis reprehenderit nobis rerum. Nulla,
|
||||
magnam? Saepe, eveniet? Test
|
||||
</Skeleton>
|
||||
</h1>
|
||||
<Skeleton>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur
|
||||
voluptas sint dolore omnis quia consequatur beatae vero cum officia
|
||||
debitis. Quidem debitis omnis reprehenderit nobis rerum. Nulla,
|
||||
magnam? Saepe, eveniet? Test
|
||||
</p>
|
||||
</Skeleton>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
@@ -45,69 +45,66 @@ const CompletedIcon = () => (
|
||||
</svg>
|
||||
);
|
||||
|
||||
export interface StepperStepType
|
||||
extends OverridableComponent<StepperStepProps, HTMLAnchorElement> {}
|
||||
export const Step: OverridableComponent<StepperStepProps, HTMLAnchorElement> =
|
||||
forwardRef(
|
||||
(
|
||||
{
|
||||
className,
|
||||
children,
|
||||
as: Component = "a",
|
||||
unsafe_index = 0,
|
||||
completed = false,
|
||||
interactive,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const context = useContext(StepperContext);
|
||||
if (context === null) {
|
||||
console.error("<Stepper.Step> has to be used within <Stepper>");
|
||||
return null;
|
||||
}
|
||||
const { activeStep } = context;
|
||||
|
||||
export const StepComponent: OverridableComponent<
|
||||
StepperStepProps,
|
||||
HTMLAnchorElement
|
||||
> = forwardRef(
|
||||
(
|
||||
{
|
||||
className,
|
||||
children,
|
||||
as: Component = "a",
|
||||
unsafe_index = 0,
|
||||
completed = false,
|
||||
interactive,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const context = useContext(StepperContext);
|
||||
if (context === null) {
|
||||
console.error("<Stepper.Step> has to be used within <Stepper>");
|
||||
return null;
|
||||
}
|
||||
const { activeStep } = context;
|
||||
const isInteractive = interactive ?? context?.interactive;
|
||||
|
||||
const isInteractive = interactive ?? context?.interactive;
|
||||
const Comp = isInteractive ? Component : "div";
|
||||
|
||||
const Comp = isInteractive ? Component : "div";
|
||||
|
||||
return (
|
||||
<Comp
|
||||
{...rest}
|
||||
aria-current={activeStep === unsafe_index}
|
||||
ref={ref}
|
||||
className={cl("navds-stepper__step", className, {
|
||||
"navds-stepper__step--active": activeStep === unsafe_index,
|
||||
"navds-stepper__step--behind": activeStep > unsafe_index,
|
||||
"navds-stepper__step--non-interactive": !isInteractive,
|
||||
"navds-stepper__step--completed": completed,
|
||||
})}
|
||||
onClick={(e) => {
|
||||
isInteractive && context.onStepChange(unsafe_index + 1);
|
||||
rest?.onClick?.(e);
|
||||
}}
|
||||
>
|
||||
{completed ? (
|
||||
<span className="navds-stepper__circle navds-stepper__circle--success">
|
||||
<CompletedIcon />
|
||||
</span>
|
||||
) : (
|
||||
<Label className="navds-stepper__circle" as="span" aria-hidden="true">
|
||||
{unsafe_index + 1}
|
||||
return (
|
||||
<Comp
|
||||
{...rest}
|
||||
aria-current={activeStep === unsafe_index}
|
||||
ref={ref}
|
||||
className={cl("navds-stepper__step", className, {
|
||||
"navds-stepper__step--active": activeStep === unsafe_index,
|
||||
"navds-stepper__step--behind": activeStep > unsafe_index,
|
||||
"navds-stepper__step--non-interactive": !isInteractive,
|
||||
"navds-stepper__step--completed": completed,
|
||||
})}
|
||||
onClick={(e) => {
|
||||
isInteractive && context.onStepChange(unsafe_index + 1);
|
||||
rest?.onClick?.(e);
|
||||
}}
|
||||
>
|
||||
{completed ? (
|
||||
<span className="navds-stepper__circle navds-stepper__circle--success">
|
||||
<CompletedIcon />
|
||||
</span>
|
||||
) : (
|
||||
<Label
|
||||
className="navds-stepper__circle"
|
||||
as="span"
|
||||
aria-hidden="true"
|
||||
>
|
||||
{unsafe_index + 1}
|
||||
</Label>
|
||||
)}
|
||||
<Label as="span" className="navds-stepper__content">
|
||||
{children}
|
||||
</Label>
|
||||
)}
|
||||
<Label as="span" className="navds-stepper__content">
|
||||
{children}
|
||||
</Label>
|
||||
</Comp>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const Step = StepComponent as StepperStepType;
|
||||
</Comp>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default Step;
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { createContext, forwardRef } from "react";
|
||||
import cl from "clsx";
|
||||
import Step, { StepperStepProps, StepperStepType } from "./Step";
|
||||
import Step, { StepperStepProps } from "./Step";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
|
||||
export interface StepperProps extends React.HTMLAttributes<HTMLOListElement> {
|
||||
/**
|
||||
@@ -33,7 +34,11 @@ interface StepperComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
StepperProps & React.RefAttributes<HTMLOListElement>
|
||||
> {
|
||||
Step: StepperStepType;
|
||||
/**
|
||||
* @see 🏷️ {@link StepperStepProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Step: OverridableComponent<StepperStepProps, HTMLAnchorElement>;
|
||||
}
|
||||
|
||||
interface StepperContextProps {
|
||||
@@ -46,6 +51,30 @@ interface StepperContextProps {
|
||||
|
||||
export const StepperContext = createContext<StepperContextProps | null>(null);
|
||||
|
||||
/**
|
||||
* A component that displays a stepper with clickable steps.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/stepper)
|
||||
* @see 🏷️ {@link StepperProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <>
|
||||
* <Heading size="medium" spacing level="2" id="stepper-heading">
|
||||
* Søknadssteg
|
||||
* </Heading>
|
||||
* <Stepper
|
||||
* aria-labelledby="stepper-heading"
|
||||
* activeStep={activeStep}
|
||||
* onStepChange={(x) => setActiveStep(x)}
|
||||
* >
|
||||
* <Stepper.Step href="#">Start søknad</Stepper.Step>
|
||||
* <Stepper.Step href="#">Saksopplysninger</Stepper.Step>
|
||||
* <Stepper.Step href="#">Vedlegg</Stepper.Step>
|
||||
* </Stepper>
|
||||
* </>
|
||||
* ```
|
||||
*/
|
||||
export const Stepper: StepperComponent = forwardRef<
|
||||
HTMLOListElement,
|
||||
StepperProps
|
||||
|
||||
@@ -56,6 +56,38 @@ export interface TableContextProps {
|
||||
|
||||
export const TableContext = createContext<TableContextProps | null>(null);
|
||||
|
||||
/**
|
||||
* A component that displays a table with headers and rows.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/table)
|
||||
* @see 🏷️ {@link TableProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Table>
|
||||
* <Table.Header>
|
||||
* <Table.Row>
|
||||
* <Table.HeaderCell scope="col">Navn</Table.HeaderCell>
|
||||
* <Table.HeaderCell scope="col">Fødseslnr.</Table.HeaderCell>
|
||||
* <Table.HeaderCell scope="col">Start</Table.HeaderCell>
|
||||
* </Table.Row>
|
||||
* </Table.Header>
|
||||
* <Table.Body>
|
||||
* {data.map(({ name, fnr, start }, i) => {
|
||||
* return (
|
||||
* <Table.Row key={i + fnr}>
|
||||
* <Table.HeaderCell scope="row">{name}</Table.HeaderCell>
|
||||
* <Table.DataCell>{fnr}</Table.DataCell>
|
||||
* <Table.DataCell>
|
||||
* {format(new Date(start), "dd.MM.yyyy")}
|
||||
* </Table.DataCell>
|
||||
* </Table.Row>
|
||||
* );
|
||||
* })}
|
||||
* </Table.Body>
|
||||
* </Table>
|
||||
* ```
|
||||
*/
|
||||
export const Table = forwardRef(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -20,47 +20,46 @@ export interface TabProps
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type TabType = OverridableComponent<TabProps, HTMLButtonElement>;
|
||||
export const Tab: OverridableComponent<TabProps, HTMLButtonElement> =
|
||||
forwardRef(
|
||||
(
|
||||
{ className, as: Component = "button", label, icon, value, ...rest },
|
||||
ref
|
||||
) => {
|
||||
const context = useContext(TabsContext);
|
||||
|
||||
export const Tab: TabType = forwardRef(
|
||||
(
|
||||
{ className, as: Component = "button", label, icon, value, ...rest },
|
||||
ref
|
||||
) => {
|
||||
const context = useContext(TabsContext);
|
||||
if (!label && !icon) {
|
||||
console.error("<Tabs.Tab/> needs label/icon");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!label && !icon) {
|
||||
console.error("<Tabs.Tab/> needs label/icon");
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<RadixTabs.Trigger value={value} asChild>
|
||||
<Component
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-tabs__tab",
|
||||
`navds-tabs__tab--${context?.size ?? "medium"}`,
|
||||
`navds-tabs__tab-icon--${context?.iconPosition}`,
|
||||
className,
|
||||
{
|
||||
"navds-tabs__tab--icon-only": icon && !label,
|
||||
}
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<BodyShort
|
||||
as="span"
|
||||
className="navds-tabs__tab-inner"
|
||||
size={context?.size}
|
||||
return (
|
||||
<RadixTabs.Trigger value={value} asChild>
|
||||
<Component
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navds-tabs__tab",
|
||||
`navds-tabs__tab--${context?.size ?? "medium"}`,
|
||||
`navds-tabs__tab-icon--${context?.iconPosition}`,
|
||||
className,
|
||||
{
|
||||
"navds-tabs__tab--icon-only": icon && !label,
|
||||
}
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{icon}
|
||||
{label}
|
||||
</BodyShort>
|
||||
</Component>
|
||||
</RadixTabs.Trigger>
|
||||
);
|
||||
}
|
||||
);
|
||||
<BodyShort
|
||||
as="span"
|
||||
className="navds-tabs__tab-inner"
|
||||
size={context?.size}
|
||||
>
|
||||
{icon}
|
||||
{label}
|
||||
</BodyShort>
|
||||
</Component>
|
||||
</RadixTabs.Trigger>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default Tab;
|
||||
@@ -19,10 +19,6 @@ export interface TabListProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type TabListType = React.ForwardRefExoticComponent<
|
||||
TabListProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
export const TabList = forwardRef<HTMLDivElement, TabListProps>(
|
||||
({ className, ...rest }, ref) => {
|
||||
const context = useContext(TabsContext);
|
||||
@@ -127,6 +123,6 @@ export const TabList = forwardRef<HTMLDivElement, TabListProps>(
|
||||
</div>
|
||||
);
|
||||
}
|
||||
) as TabListType;
|
||||
);
|
||||
|
||||
export default TabList;
|
||||
@@ -13,10 +13,6 @@ export interface TabPanelProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type TabPanelType = React.ForwardRefExoticComponent<
|
||||
TabPanelProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
|
||||
const TabPanel = forwardRef<HTMLDivElement, TabPanelProps>(
|
||||
({ className, ...rest }, ref) => (
|
||||
<TabsContent
|
||||
@@ -25,6 +21,6 @@ const TabPanel = forwardRef<HTMLDivElement, TabPanelProps>(
|
||||
className={cl("navds-tabs__tabpanel", className)}
|
||||
/>
|
||||
)
|
||||
) as TabPanelType;
|
||||
);
|
||||
|
||||
export default TabPanel;
|
||||
@@ -1,9 +1,10 @@
|
||||
import * as RadixTabs from "@radix-ui/react-tabs";
|
||||
import cl from "clsx";
|
||||
import React, { createContext, forwardRef, HTMLAttributes } from "react";
|
||||
import * as RadixTabs from "@radix-ui/react-tabs";
|
||||
import Tab, { TabType } from "./Tab";
|
||||
import TabList, { TabListType } from "./TabList";
|
||||
import TabPanel, { TabPanelType } from "./TabPanel";
|
||||
import { OverridableComponent } from "../util/OverridableComponent";
|
||||
import Tab, { TabProps } from "./Tab";
|
||||
import TabList, { TabListProps } from "./TabList";
|
||||
import TabPanel, { TabPanelProps } from "./TabPanel";
|
||||
|
||||
export interface TabsProps
|
||||
extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "dir"> {
|
||||
@@ -46,9 +47,23 @@ interface TabsComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
TabsProps & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
Tab: TabType;
|
||||
List: TabListType;
|
||||
Panel: TabPanelType;
|
||||
/**
|
||||
* @see 🏷️ {@link TabProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*/
|
||||
Tab: OverridableComponent<TabProps, HTMLButtonElement>;
|
||||
/**
|
||||
* @see 🏷️ {@link TabListProps}
|
||||
*/
|
||||
List: React.ForwardRefExoticComponent<
|
||||
TabListProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
/**
|
||||
* @see 🏷️ {@link TabPanelProps}
|
||||
*/
|
||||
Panel: React.ForwardRefExoticComponent<
|
||||
TabPanelProps & React.RefAttributes<HTMLDivElement>
|
||||
>;
|
||||
}
|
||||
|
||||
interface TabsContextProps {
|
||||
@@ -59,6 +74,32 @@ interface TabsContextProps {
|
||||
|
||||
export const TabsContext = createContext<TabsContextProps | null>(null);
|
||||
|
||||
/**
|
||||
* A component that displays a set of tabs that can be used to switch between different views.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/tabs)
|
||||
* @see 🏷️ {@link TabsProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Tabs defaultValue="logg">
|
||||
* <Tabs.List>
|
||||
* <Tabs.Tab value="logg" label="Logg" />
|
||||
* <Tabs.Tab value="inbox" label="Inbox" />
|
||||
* <Tabs.Tab value="sendt" label="Sendt" />
|
||||
* </Tabs.List>
|
||||
* <Tabs.Panel value="logg" className="h-24 w-full bg-gray-50 p-4">
|
||||
* Logg-tab
|
||||
* </Tabs.Panel>
|
||||
* <Tabs.Panel value="inbox" className="h-24 w-full bg-gray-50 p-4">
|
||||
* Inbox-tab
|
||||
* </Tabs.Panel>
|
||||
* <Tabs.Panel value="sendt" className="h-24 w-full bg-gray-50 p-4">
|
||||
* Sendt-tab
|
||||
* </Tabs.Panel>
|
||||
* </Tabs>
|
||||
* ```
|
||||
*/
|
||||
export const Tabs = forwardRef<HTMLDivElement, TabsProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -38,6 +38,17 @@ export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
size?: "medium" | "small" | "xsmall";
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a small label with a text and a background color.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/tag)
|
||||
* @see 🏷️ {@link TagProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Tag variant="success">Success</Tag>
|
||||
* ```
|
||||
*/
|
||||
export const Tag = forwardRef<HTMLSpanElement, TagProps>(
|
||||
({ className, variant, size = "medium", ...rest }, ref) => (
|
||||
<BodyShort
|
||||
|
||||
@@ -38,23 +38,41 @@ export interface TimelineProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
interface TimelineComponent
|
||||
extends React.ForwardRefExoticComponent<TimelineProps> {
|
||||
/**
|
||||
* Built-in timeline row
|
||||
* @see 🏷️ {@link TimelineRowType}
|
||||
*/
|
||||
Row: TimelineRowType;
|
||||
/**
|
||||
* Built-in row period
|
||||
* @see 🏷️ {@link PeriodType}
|
||||
*/
|
||||
Period: PeriodType;
|
||||
/**
|
||||
* Built-in timeline pin
|
||||
* @see 🏷️ {@link PinType}
|
||||
*/
|
||||
Pin: PinType;
|
||||
/**
|
||||
* Built-in timeline zoom-component
|
||||
* @see 🏷️ {@link ZoomType}
|
||||
*/
|
||||
Zoom: ZoomType;
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a timeline of events. Meant for Internal systems.
|
||||
* @note Component is made for desktop enviroments and will start having issues on smaller screens.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/timeline)
|
||||
* @see 🏷️ {@link TimelineProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Timeline>
|
||||
* <Timeline.Row>
|
||||
* <Timeline.Period start={new Date("2020-01-01")} end={new Date("2020-01-31")}>
|
||||
* <p>Period 1</p>
|
||||
* </Timeline.Period>
|
||||
* <Timeline.Row>
|
||||
* </Timeline>
|
||||
* ```
|
||||
*/
|
||||
export const Timeline = forwardRef<HTMLDivElement, TimelineProps>(
|
||||
({ children, startDate, endDate, direction = "left", ...rest }, ref) => {
|
||||
const isMultipleRows = Array.isArray(children);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as RadixToggleGroup from "@radix-ui/react-toggle-group";
|
||||
import cl from "clsx";
|
||||
import React, {
|
||||
createContext,
|
||||
@@ -5,9 +6,8 @@ import React, {
|
||||
HTMLAttributes,
|
||||
useState,
|
||||
} from "react";
|
||||
import ToggleItem, { ToggleItemType } from "./ToggleItem";
|
||||
import * as RadixToggleGroup from "@radix-ui/react-toggle-group";
|
||||
import { Label, useId } from "..";
|
||||
import ToggleItem, { ToggleItemProps } from "./ToggleItem";
|
||||
|
||||
export interface ToggleGroupProps
|
||||
extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "dir"> {
|
||||
@@ -47,7 +47,12 @@ interface ToggleGroupComponent
|
||||
extends React.ForwardRefExoticComponent<
|
||||
ToggleGroupProps & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
Item: ToggleItemType;
|
||||
/**
|
||||
* @see 🏷️ {@link ToggleItemProps}
|
||||
*/
|
||||
Item: React.ForwardRefExoticComponent<
|
||||
ToggleItemProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
}
|
||||
|
||||
interface ToggleContextProps {
|
||||
@@ -58,6 +63,21 @@ export const ToggleGroupContext = createContext<ToggleContextProps | null>(
|
||||
null
|
||||
);
|
||||
|
||||
/**
|
||||
* A component that displays a group of toggle buttons.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/toggle-group)
|
||||
* @see 🏷️ {@link ToggleGroupProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <ToggleGroup defaultValue="lest" onChange={console.log} size="small">
|
||||
* <ToggleGroup.Item value="ulest">Ulest</ToggleGroup.Item>
|
||||
* <ToggleGroup.Item value="lest">Leste</ToggleGroup.Item>
|
||||
* <ToggleGroup.Item value="sendt">Sendt</ToggleGroup.Item>
|
||||
* </ToggleGroup>
|
||||
* ```
|
||||
*/
|
||||
export const ToggleGroup = forwardRef<HTMLDivElement, ToggleGroupProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -16,10 +16,6 @@ export interface ToggleItemProps
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type ToggleItemType = React.ForwardRefExoticComponent<
|
||||
ToggleItemProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
|
||||
const ToggleItem = forwardRef<HTMLButtonElement, ToggleItemProps>(
|
||||
({ className, children, ...rest }, ref) => {
|
||||
const context = useContext(ToggleGroupContext);
|
||||
@@ -40,6 +36,6 @@ const ToggleItem = forwardRef<HTMLButtonElement, ToggleItemProps>(
|
||||
</RadixToggleGroup.Item>
|
||||
);
|
||||
}
|
||||
) as ToggleItemType;
|
||||
);
|
||||
|
||||
export default ToggleItem;
|
||||
@@ -75,6 +75,19 @@ export interface TooltipProps extends HTMLAttributes<HTMLDivElement> {
|
||||
keys?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A component that displays a tooltip when the user hovers over its child element.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/tooltip)
|
||||
* @see 🏷️ {@link TooltipProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <Tooltip content="Skriv ut dokument">
|
||||
* <Button icon={<PrinterLargeIcon title="demo knapp" />} />
|
||||
* </Tooltip>
|
||||
* ```
|
||||
*/
|
||||
export const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(
|
||||
(
|
||||
{
|
||||
|
||||
@@ -19,6 +19,20 @@ export interface BodyLongProps
|
||||
spacing?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of a set of components for displaying text with consistent typography.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/typography)
|
||||
* @see 🏷️ {@link BodyLongProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <BodyLong level="1" size="xlarge">
|
||||
* Pengestøtte når du er syk
|
||||
* </BodyLong>
|
||||
* ```
|
||||
*/
|
||||
export const BodyLong: OverridableComponent<
|
||||
BodyLongProps,
|
||||
HTMLParagraphElement
|
||||
|
||||
@@ -19,6 +19,20 @@ export interface BodyShortProps
|
||||
spacing?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of a set of components for displaying text with consistent typography.
|
||||
*
|
||||
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/typography)
|
||||
* @see 🏷️ {@link BodyShortProps}
|
||||
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <BodyShort level="1" size="xlarge">
|
||||
* Pengestøtte når du er syk
|
||||
* </BodyShort>
|
||||
* ```
|
||||
*/
|
||||
export const BodyShort: OverridableComponent<
|
||||
BodyShortProps,
|
||||
HTMLParagraphElement
|
||||
|
||||
Loaded 100 of 137 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user