Compare commits

...
Author SHA1 Message Date
github-actions[bot] e91e307177 Lerna versionbump [ci skip] 2022-10-10 13:29:23 +00:00
Martin BerglundandKen 225e882eae [FIX] Fallback på font-family i body (#1647)
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2022-10-10 15:19:22 +02:00
github-actions[bot] 77c4833c42 Lerna versionbump [ci skip] 2022-10-08 16:32:06 +00:00
Ken fbced203b1 [FIX]💄 Nested-accordion arrow brakk 2022-10-08 18:22:04 +02:00
Ken fff3d22f1a [FIX]💄 For lav kontrast toptext Chat 2022-10-08 18:12:18 +02:00
Ken c5689ab543 [FIX] Comment textarea autosize 2022-10-08 18:08:54 +02:00
larseirikhansen d1edf960e6 [FIX] Textarea counter color (#1646) 2022-10-08 18:03:49 +02:00
Ken 64ec281fb2 🎨 Optional add type button (#1645) 2022-10-04 09:54:57 +02:00
github-actions[bot] 9c9174d3a6 Lerna versionbump [ci skip] 2022-09-30 11:53:13 +00:00
Ken 51dcf4f60a [FIX] 🎨 Fikset typer og story for CopyToClipboard (#1643) 2022-09-30 13:11:21 +02:00
github-actions[bot] f3929075e3 Lerna versionbump [ci skip] 2022-09-22 12:30:20 +00:00
larseirikhansen 943a39d30d [FIX] Expandale table line (#1642)
* yarn lock update
* remove expanded cell border bottom
* merge master
2022-09-22 14:20:28 +02:00
github-actions[bot] 85518226c6 Lerna versionbump [ci skip] 2022-09-22 09:11:32 +00:00
Ken 6a7f14e71c [fix] yarn lock fix 2022-09-22 10:58:39 +02:00
Andreas Nordahl 9b3efc6e1f [fix] table row hover prop to disable hover style (#1640) 2022-09-22 10:50:16 +02:00
github-actions[bot] b6d65ad805 Lerna versionbump [ci skip] 2022-09-20 07:31:42 +00:00
Andreas Nordahl 7ab5e10f57 [fix] expose colSpan prop in ExpandableRow (#1641) 2022-09-20 09:20:02 +02:00
github-actions[bot] 6f3aa4690f Lerna versionbump [ci skip] 2022-09-19 09:09:42 +00:00
Ken f4ff216e45 [fix] Definert maksbredde på HelpText (#1638) 2022-09-19 10:59:32 +02:00
github-actions[bot] 01a6f250da Lerna versionbump [ci skip] 2022-09-12 13:22:25 +00:00
KenandMartin Berglund 1ccc97d8e5 [FEATURE] Stepper med interactive, completed-option (#1626)
Co-authored-by: Martin Berglund <martin.berglund@nav.no>
2022-09-12 15:07:18 +02:00
github-actions[bot] ed2537dc58 Lerna versionbump [ci skip] 2022-09-07 07:01:21 +00:00
Ken 16b7176fe3 [FIX]Toggle-group fix for label (#1635) 2022-09-07 08:50:19 +02:00
github-actions[bot] f2eab3f636 Lerna versionbump [ci skip] 2022-09-06 09:50:14 +00:00
Ken 00747ac364 [FIX] Oppdatert typer for TextField (#1634)
* oppdatert typer for textfield

* yarn lock fix
2022-09-06 11:34:46 +02:00
github-actions[bot] ad3f7e174c Lerna versionbump [ci skip] 2022-08-29 13:29:36 +00:00
Ken 4708688b02 [FIX] Fikset onClick for Dropdown-items (#1632) 2022-08-29 15:18:31 +02:00
github-actions[bot] 940e1255f1 Lerna versionbump [ci skip] 2022-08-26 13:54:08 +00:00
larseirikhansen c8b041154e [FIX] Optional name-prop for <Chat/> (#1629) 2022-08-26 15:40:01 +02:00
github-actions[bot] 7da8246ce3 Lerna versionbump [ci skip] 2022-08-26 09:45:49 +00:00
Ken 38bccf08eb [FIX] Minsket padding-right for Select 2022-08-26 11:32:21 +02:00
Ken ed817bf04c Fikset flikker og update-bug for popover (#1627)
* Test for fix i popover

* Lerna versionbump [ci skip]

* ryddet i testkode

* ryddet i testkode 2

* yarn lock

* Lerna versionbump [ci skip]

* yarn lock
2022-08-25 14:36:48 +02:00
Ken 4f8d6f8fa1 Update README.md 2022-08-24 09:25:52 +02:00
Ken d13b7b19c9 Update README.md 2022-08-24 09:21:17 +02:00
Ken 2e7535037c Update README.md 2022-08-24 08:51:35 +02:00
github-actions[bot] 5b8290e77e Lerna versionbump [ci skip] 2022-08-23 15:43:48 +00:00
Ken a19cad1bce [feature] reversert workflow comparator for release 2022-08-23 17:32:24 +02:00
Ken 8b8e59349b [feature] Fikset workflow for publisering (#1624) 2022-08-23 16:35:10 +02:00
Kai Erik SchierenandKai Erik Schieren f87d020db2 [feature] add closeOnSelect on dropdown (#1623)
Co-authored-by: Kai Erik Schieren <kschieren@Kais-MacBook-Pro.local>
2022-08-23 16:10:20 +02:00
Ken 91cb70c5a3 Fikset fixed versjonering (#1621) 2022-08-23 15:23:00 +02:00
Kai Erik Schieren eda041ec74 Update CONTRIBUTING.md (#1622) 2022-08-23 14:05:41 +02:00
Ken d875804d2b fikset versjoner 2022-08-22 15:17:16 +02:00
github-actions[bot] 6b77a04e12 Lerna versionbump [ci skip] 2022-08-22 13:02:35 +00:00
Tanet Trimas 3f18280557 [feature] Event ved lukking av dropdown (#1620) 2022-08-22 14:48:40 +02:00
github-actions[bot] 1b9c7b90ff Lerna versionbump [ci skip] 2022-08-18 08:05:45 +00:00
Ken 1ef6ebafd4 [FIX] Update readme 2022-08-18 09:55:28 +02:00
Ken 058969c0f0 Lerna versionbump [ci skip] 2022-08-18 08:57:56 +02:00
Ken 8f43b09205 Fikset errormessage docs 2022-08-18 08:57:39 +02:00
155c556fea Designsystemet v1.0.0 (#1535)
Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
Co-authored-by: Ken <ken.aleksander@gmail.com>
Co-authored-by: Martin Berglund <martin.berglund@nav.no>
Co-authored-by: larseirikhansen <71271458+larseirikhansen@users.noreply.github.com>
2022-08-18 08:15:21 +02:00
Ken 151ec81036 Pusset opp bug-reports 2022-08-17 10:39:37 +02:00
github-actions[bot] c5d52a4c9a Lerna versionbump [ci skip]
- @navikt/ds-css@0.18.29
2022-08-17 08:25:30 +00:00
Ken 6ef57ee106 [FIX] Fikset Select issue ved bruk i Intern-header (#1616) 2022-08-17 10:12:24 +02:00
github-actions[bot] dd2167dab5 Lerna versionbump [ci skip]
- @navikt/ds-react@0.19.27
 - @navikt/ds-react-internal@0.14.28
2022-08-11 08:44:24 +00:00
larseirikhansen 0c179d92af [fix] React modal style (#1615)
* version bump

* added custom styling to react modal

* use prop 'style' to avoid breaking changes

* update modal story
2022-08-11 10:32:41 +02:00
github-actions[bot] abace10750 Lerna versionbump [ci skip]
- @navikt/ds-react@0.19.26
 - @navikt/ds-react-internal@0.14.27
2022-08-09 13:16:39 +00:00
Andreas Nordahl 03949990b1 [fix] bump radix-ui to 1.0 (#1613) 2022-08-09 15:04:23 +02:00
github-actions[bot] bdb777df0c Lerna versionbump [ci skip]
- @navikt/ds-css@0.18.28
 - @navikt/ds-tailwind@0.2.9
 - @navikt/ds-tokens@0.9.8
2022-08-09 09:13:09 +00:00
Andreas Nordahl 5d2ed071e1 [fix] update lockfile (#1611) 2022-08-09 10:59:03 +02:00
Andreas Nordahl e152c92bf4 [fix] generate types for js tokens (#1610) 2022-08-09 10:42:31 +02:00
Ken 840b4dddd3 fjernet favikon for storybook 2022-07-18 10:39:15 +02:00
github-actions[bot] 136ab3aa97 Lerna versionbump [ci skip]
- @navikt/ds-icons@0.8.20
 - @navikt/ds-react@0.19.25
 - @navikt/ds-react-internal@0.14.26
2022-07-18 08:21:56 +00:00
KenandKenAJoh 6b9ecd239a [FIX] Ikonsynk Figma (#1607)
Co-authored-by: KenAJoh <KenAJoh@users.noreply.github.com>
2022-07-18 10:11:50 +02:00
238 changed files with 5678 additions and 6082 deletions

No files matched your search

+8 -9
View File
@@ -3,14 +3,13 @@ name: Bug Report
about: Meld inn bugs eller feil
title: "[BUG]"
labels: "bug \U0001F41B"
assignees: ''
assignees: ""
---
## Hvilken av tjenestene våre gjelder det?
## Hvilken løsning gjelder det?
<!--
Sett en x i type pakke det gjelder:
Sett en x i type løsning det gjelder:
- [x] type
-->
@@ -19,9 +18,9 @@ assignees: ''
- [ ] `Ikoner`
- [ ] `Annet`
## Beskriv feilen/problemet
## Hva er feilen/problemet?
<!--
<!--
> Beskriv hva slags problem(er) som oppstår
> Hva forventet du skulle oppstå?
@@ -31,7 +30,7 @@ assignees: ''
(skriv her.)
## Steg for å reprodusere problemet
## Steg for å reprodusere problemet (valgfri)
<!--
1. Steg en
@@ -41,11 +40,11 @@ assignees: ''
(skriv her.)
## Eksempel/Tilleggsinformasjon
## Eksempel/Tilleggsinformasjon (valgfri)
<!--
Screenshots eller kodesnippets
Legg gjerne ved ekstrainfo som nettleser, desktop/mobil etc
Legg gjerne ved ekstrainfo som nettleser eller desktop/mobil hvis det er relevant.
-->
```
+3 -3
View File
@@ -78,13 +78,13 @@ jobs:
- name: Update changed packages with PATCH
if: "contains(github.event.head_commit.message, '[fix]')"
run: yarn lerna version patch --include-merged-tags --yes
run: yarn lerna version patch --force-publish --include-merged-tags --yes
- name: Update changed packages with MINOR
if: "contains(github.event.head_commit.message, '[feature]')"
run: yarn lerna version minor --include-merged-tags --yes
run: yarn lerna version minor --force-publish --include-merged-tags --yes
- name: Update changed packages with MAJOR
if: "contains(github.event.head_commit.message, '[breaking]')"
run: yarn lerna version major --include-merged-tags --yes
run: yarn lerna version major --force-publish --include-merged-tags --yes
- name: Publish to NPM registry
run: yarn lerna publish --no-verify-access from-package --yes
+5 -2
View File
@@ -2,9 +2,12 @@ name: Chromatic
on:
push:
branches: [master]
branches:
- master
pull_request:
branches: [master]
branches:
- master
- big-one-oh
jobs:
chromatic-pr:
-12
View File
@@ -1,12 +0,0 @@
import { Meta, Canvas } from "@storybook/addon-docs";
<Meta title="ds-react(deprecated)/intro" />
# Utdaterte pakker
På sikt vil komponentene under bli flyttet ut av ds-react eller erstattes av andre komponenter
- PageHeader -> @navikt/ds-react-navno
- MicroCard -> @navikt/ds-react-navno
- StepIndicator -> Horizontal `<Stepper />`
-1
View File
@@ -20,7 +20,6 @@ module.exports = {
"@storybook/addon-docs",
"@storybook/addon-a11y",
"@whitespace/storybook-addon-html",
"storybook-addon-css-user-preferences",
{
name: "@storybook/addon-storysource",
options: {
+3 -3
View File
@@ -1,12 +1,12 @@
import { addons } from "@storybook/addons";
import NavTheme from "./theme.js";
import logoUrl from "./public/logo.svg";
/* import logoUrl from "./public/logo.svg"; */
addons.setConfig({
theme: NavTheme,
});
const link = document.createElement("link");
/* const link = document.createElement("link");
link.setAttribute("rel", "shortcut icon");
link.setAttribute("href", logoUrl);
document.head.appendChild(link);
document.head.appendChild(link); */
+27 -7
View File
@@ -7,7 +7,7 @@ export const parameters = {
options: {
storySort: {
method: "",
order: ["Intro", "ds-icons", "ds-react", ["Default"]],
order: ["Intro", "ds-icons", "ds-react", ["form"], ["Default"]],
locales: "",
},
},
@@ -21,13 +21,33 @@ export const parameters = {
value: "#ffffff",
},
{
name: "Alternate",
value: "#f7f7f7",
},
{
name: "Inverted",
value: "#292929",
name: "Darkmode",
value: "#262626",
},
],
},
};
export const globalTypes = {
theme: {
name: "Theme",
description: "Global theme for components",
defaultValue: "light",
toolbar: {
icon: "circlehollow",
items: [
{ value: "light", icon: "circlehollow", title: "light" },
{ value: "dark", icon: "circle", title: "dark" },
],
showName: true,
},
},
};
export const withTheme = (StoryFn, context) => (
<div data-theme={context.parameters.theme || context.globals.theme}>
<StoryFn />
</div>
);
export const decorators = [withTheme];
+1 -1
View File
@@ -9,7 +9,7 @@ export default create({
fontCode: "monospace",
// Text colors
textColor: "#292929",
textColor: "#262626",
textInverseColor: "rgba(255,255,255,0.9)",
colorSecondary: "rgba(0, 36, 58, 1)",
+7 -1
View File
@@ -2,7 +2,7 @@ import { Meta, Canvas } from "@storybook/addon-docs";
<Meta title="Intro/Velkommen" />
# NAV designsystem-komponenter
# NAV designsystem
- [Dokumentasjon](https://aksel.nav.no/designsystem)
- [Komponenter](https://aksel.nav.no/designsystem/side/oversikt-komponenter)
@@ -21,6 +21,12 @@ yarn add @navikt/ds-react @navikt/ds-css @navikt/ds-icons
yarn add @navikt/ds-react-internal @navikt/ds-css-internal
```
### Ikonpakke
```bash
yarn add @navikt/ds-icons
```
### Bruk
```jsx
+106
View File
@@ -0,0 +1,106 @@
# NAV designsystem Codemods
Collection of Codemods for easier migration between breaking changes.
Highly inspired by both MUI and NEXT
- [NEXT](https://nextjs.org/docs/advanced-features/codemods)
- [MUI](https://github.com/mui/material-ui/tree/master/packages/mui-codemod)
## Usage
Codemod transformations runs code-transformations programmatically in your project. This helps when migrating lots of breaking changes without spending hours doing it manually.
NOTE: This codemod only supports fairly "default" usage of components. Components used with dynamic imports, styled-components, non-default imports (example `import * as DS from "@navikt/ds-react"` or `from "@navikt/ds-react/cjs"`) will not work as expected.
```javascript
npx @navikt/ds-codemod <transform> <path>
```
transform - name of transform, see available transforms below.
path - files or directory to transform
--dry Do a dry-run, no code will be edited
--print Prints the changed output for comparison
## Beta (0.19.x) -> v1.0.0
`npx @navikt/ds-codemod v1.0.0/preset src`
### preset
Combines all avaliable codemods for migrating from beta -> v1.0.0. This transform should only be ran once.
Includes these transforms
- v1.0.0/tabs
- v1.0.0/chat
- v1.0.0/pagination
### tabs
`npx @navikt/ds-codemod v1.0.0/tabs src`
```diff
<Tabs
defaultValue="logg"
onChange={(x) => console.log(x)}
- loop
+ iconPosition="left"
>
<Tabs.List
- loop
>
<Tabs.Tab
value="logg"
label="logg"
- iconPosition="left"
/>
</Tabs.List>
<Tabs.Panel value="logg">TabPanel for Logg-tab</Tabs.Panel>
</Tabs>
```
### chat
`npx @navikt/ds-codemodmod v1.0.0/chat src`
```diff
-<SpeechBubble
+<Chat
- illustration={<Illustration />}
- topText="Ola Normann 01.01.21 14:00"
- illustrationBgColor="blue"
+ avatar={<Illustration />}
+ name="Ola Normann 01.01.21 14:00"
+ avatarBgColor="blue"
backgroundColor="red"
>
- <SpeechBubble.Bubble>
+ <Chat.Bubble>
Aute minim nisi sunt mollit duis sunt nulla minim non proident.
- </SpeechBubble.Bubble>
+ </Chat.Bubble>
-</SpeechBubble>
+</Chat>
```
### pagination
`npx @navikt/ds-codemod v1.0.0/pagination src`
This codemod should only be ran once, since the size-scale will keep decreasing for each subsequent iteration.
```diff
-<Pagiation />
+<Pagiation size="small"/>
-<Pagiation size="medium"/>
+<Pagiation size="small"/>
-<Pagiation size="small"/>
+<Pagiation size="xsmall"/>
```
## License
[MIT](https://github.com/navikt/Designsystemet/blob/master/LICENCE)
+13 -1
View File
@@ -35,7 +35,7 @@ export function checkGitStatus(force) {
if (force) {
console.log(`WARNING: ${errorMessage}. Forcibly continuing.`);
} else {
console.log("Thank you for using @@navikt/ds-codemod");
console.log("Thank you for using @navikt/ds-codemod");
console.log(
chalk.yellow(
"\nBut before we continue, please stash or commit your git changes."
@@ -94,6 +94,18 @@ export function runTransform({ files, flags, transformer }) {
}
const TRANSFORMER_INQUIRER_CHOICES = [
{
name: "v1.0.0/preset: Runs all codemods for beta to v1 migration",
value: "v1.0.0/preset",
},
{
name: "v1.0.0/pagination: Fixes breaking API-changes from <Pagination /> component",
value: "v1.0.0/pagination",
},
{
name: "v1.0.0/tabs: Fixes breaking API-changes from <Tabs /> component",
value: "v1.0.0/tabs",
},
{
name: "v1.0.0/chat: Fixes breaking API-changes from <SpeechBubble /> (now <Chat/>) component",
value: "v1.0.0/chat",
+5 -3
View File
@@ -1,7 +1,6 @@
{
"name": "@navikt/ds-codemod",
"version": "1.0.2",
"private": true,
"version": "1.3.7",
"description": "NAV designsystem codemods",
"author": "NAV Designsystem team",
"license": "MIT",
@@ -11,7 +10,7 @@
"jscodeshift"
],
"files": [
"transforms/*.js",
"transforms/**/*.js",
"bin/*.js",
"lib/**/*.js",
"lib/cra-to-next/gitignore"
@@ -49,5 +48,8 @@
"sideEffects": false,
"engines": {
"node": ">=12.0.0"
},
"publishConfig": {
"access": "public"
}
}
@@ -8,8 +8,9 @@ export const Page = () => {
topText="Ola Normann 01.01.21 14:00"
backgroundColor="red"
illustrationBgColor="blue"
{...testProps}
>
<SpeechBubble.Bubble>
<SpeechBubble.Bubble {...testProps}>
Aute minim nisi sunt mollit duis sunt nulla minim non proident.
</SpeechBubble.Bubble>
<SpeechBubble.Bubble>
@@ -8,8 +8,9 @@ export const Page = () => {
name="Ola Normann 01.01.21 14:00"
backgroundColor="red"
avatarBgColor="blue"
{...testProps}
>
<Chat.Bubble>
<Chat.Bubble {...testProps}>
Aute minim nisi sunt mollit duis sunt nulla minim non proident.
</Chat.Bubble>
<Chat.Bubble>
@@ -3,9 +3,16 @@ import { Pagination, Button } from "@navikt/ds-react";
export const Demo = () => {
return (
<div>
<Pagination size="small" onPageChange={setPage} data-version="v1" />
<Pagination
size="small"
onPageChange={setPage}
data-version="v1"
{...testProps}
/>
<Pagination size="small" onPageChange={setPage} data-version="v1" />
<Pagination size="xsmall" onPageChange={setPage} data-version="v1" />
<Pagination onPageChange={setPage} />
<Pagination size="small" onPageChange={setPage} />
</div>
);
};
@@ -3,7 +3,14 @@ import { Pagination, Button } from "@navikt/ds-react";
export const Demo = () => {
return (
<div>
<Pagination
size="small"
onPageChange={setPage}
data-version="v1"
{...testProps}
/>
<Pagination size="small" onPageChange={setPage} data-version="v1" />
<Pagination size="xsmall" onPageChange={setPage} data-version="v1" />
<Pagination size="small" onPageChange={setPage} data-version="v1" />
<Pagination size="xsmall" onPageChange={setPage} data-version="v1" />
</div>
@@ -3,9 +3,9 @@ import { Pagination as DsPagination, Button } from "@navikt/ds-react";
export const Demo = () => {
return (
<div>
<DsPagination size="small" onPageChange={setPage} />
<DsPagination size="small" onPageChange={setPage} />
<DsPagination size="xsmall" onPageChange={setPage} />
<DsPagination size="small" onPageChange={setPage} data-version="v1" />
<DsPagination size="small" onPageChange={setPage} data-version="v1" />
<DsPagination size="xsmall" onPageChange={setPage} data-version="v1" />
</div>
);
};
@@ -3,9 +3,9 @@ import { Pagination, Button } from "@navikt/ds-react";
export const Demo = () => {
return (
<div>
<Pagination size="small" onPageChange={setPage} />
<Pagination size="small" onPageChange={setPage} />
<Pagination size="xsmall" onPageChange={setPage} />
<Pagination size="small" onPageChange={setPage} data-version="v1" />
<Pagination size="small" onPageChange={setPage} data-version="v1" />
<Pagination size="xsmall" onPageChange={setPage} data-version="v1" />
</div>
);
};
@@ -4,9 +4,9 @@ const TabComp = () => {
return (
/* prettier-ignore */
<div>
<Tabs defaultValue="logg" onChange={(x) => console.log(x)}>
<Tabs.List loop={false}>
<Tabs.Tab value="logg" iconPosition={props.left} label="logg" />
<Tabs defaultValue="logg" onChange={(x) => console.log(x)} {...testProps}>
<Tabs.List loop={false} {...testProps}>
<Tabs.Tab value="logg" iconPosition={props.left} label="logg" {...testProps}/>
<Tabs.Tab value="logg2" iconPosition="top" label="logg2medlangtekst" />
</Tabs.List>
<Tabs.Panel value="logg">TabPanel for Logg-tab</Tabs.Panel>
@@ -7,10 +7,11 @@ const TabComp = () => {
<Tabs
defaultValue="logg"
onChange={(x) => console.log(x)}
{...testProps}
loop={false}
iconPosition={props.left}>
<Tabs.List>
<Tabs.Tab value="logg" label="logg" />
<Tabs.List {...testProps}>
<Tabs.Tab value="logg" label="logg" {...testProps} />
<Tabs.Tab value="logg2" label="logg2medlangtekst" />
</Tabs.List>
<Tabs.Panel value="logg">TabPanel for Logg-tab</Tabs.Panel>
@@ -8,6 +8,22 @@ export default function transformer(file, api, options) {
const root = j(file.source);
function addMigrationTag(node) {
const attributes = node.openingElement.attributes;
const isMigrated = attributes.find(
(node) =>
node.type === "JSXAttribute" &&
node.name.name === "data-version" &&
node.value.value === "v1"
);
if (!isMigrated) {
attributes.push(
j.jsxAttribute(j.jsxIdentifier("data-version"), j.literal("v1"))
);
}
}
/* https://github.com/mui/material-ui/blob/master/packages/mui-codemod/src/v5.0.0/variant-prop.js */
function addExplicitStandardProp(node) {
const attributes = node.openingElement.attributes;
@@ -19,6 +35,7 @@ export default function transformer(file, api, options) {
attributes.unshift(
j.jsxAttribute(j.jsxIdentifier("size"), j.literal("small"))
);
addMigrationTag(node);
}
}
@@ -42,14 +59,20 @@ export default function transformer(file, api, options) {
const skip = !!parent.value.openingElement?.attributes.find(
(x) => x.name.name === "data-version" && x.value.value === "v1"
);
parent.value.openingElement?.attributes.forEach((x, index) => {
let didUpdate = false;
if (x.name?.name === "size" && x.type === "JSXAttribute" && !skip) {
/* addExplicitStandardProp */
if (x.value.value === "medium") {
x.value = j.literal("small");
didUpdate = true;
} else if (x.value.value === "small") {
x.value = j.literal("xsmall");
didUpdate = true;
}
didUpdate && addMigrationTag(parent.value);
}
});
addExplicitStandardProp(parent.value);
@@ -0,0 +1,15 @@
import transformTabs from "./tabs";
import transformChat from "./chat";
import transformPagination from "./pagination";
/**
* @param {import('jscodeshift').FileInfo} file
* @param {import('jscodeshift').API} api
*/
export default function transformer(file, api, options) {
file.source = transformTabs(file, api, options);
file.source = transformChat(file, api, options);
file.source = transformPagination(file, api, options);
return file.source;
}
+50
View File
@@ -0,0 +1,50 @@
# NAV designsystem styling
CSS-package containing design for @navikt/ds-react and more.
- All our tokens (Colors, border, shadows etc)
- Component-styling for `@navikt/ds-react` packages
- Normalize.css v8
- Fonts
## Installation
Install `@navikt/ds-css` with yarn
```bash
yarn add @navikt/ds-css
```
Install `@navikt/ds-css` with npm
```bash
npm install @navikt/ds-css
```
## Usage
You can import these styles once to make it accessible in your entire project. Typically you will add the following line to your root .js or .ts files.
```javascript
import "@navikt/ds-css";
function App() {
return <Component />;
}
```
But you can also import it in a .css-file like this
```css
@import "@navikt/ds-css";
```
## Learn more
- [Designsystem documentation](https://aksel.nav.no/designsystem)
- [Storybook](https://master--5f801fb2aea7820022de2936.chromatic.com/)
- [ds-react README](https://github.com/navikt/Designsystemet/blob/master/%40navikt/core/react/README.md)
## License
[MIT](https://github.com/navikt/Designsystemet/blob/master/LICENCE)
+3 -5
View File
@@ -11,10 +11,6 @@
);
}
.navds-accordion .ReactCollapse--collapse {
transition: height 250ms cubic-bezier(0.4, 0, 0.2, 1);
}
.navds-accordion__item:focus-within {
position: relative;
}
@@ -72,7 +68,9 @@
flex-shrink: 0;
}
.navds-accordion__item--open .navds-accordion__expand-icon {
.navds-accordion__item--open
> .navds-accordion__header
> .navds-accordion__expand-icon {
transform: rotateZ(180deg);
}
-6
View File
@@ -34,18 +34,12 @@
.navds-alert--small {
padding: var(--navds-spacing-2) var(--navds-spacing-4);
gap: var(--navds-spacing-3);
}
.navds-alert--full-width {
border-radius: 0;
}
.navds-alert--full-width.navds-alert--small {
padding-right: var(--navds-spacing-4);
padding-left: var(--navds-spacing-4);
}
.navds-alert > .navds-alert__icon {
flex-shrink: 0;
font-size: 1.5rem;
+1 -1
View File
@@ -34,7 +34,7 @@ html {
}
body {
font-family: var(--navds-font-family);
font-family: var(--navds-font-family, "Source Sans Pro", Arial, sans-serif);
line-height: 1.333;
font-size: 1.125rem;
}
+43 -17
View File
@@ -116,24 +116,35 @@
display: inline-flex;
cursor: pointer;
margin: 0;
text-align: center;
text-decoration: none;
border: none;
background: none;
border-radius: var(--navds-border-radius-small);
min-width: 48px;
padding: var(--navds-spacing-3);
padding: var(--navds-spacing-3) var(--navds-spacing-5);
align-items: center;
justify-content: center;
gap: var(--navds-spacing-2);
}
.navds-button--small {
padding-top: 0.375rem;
padding-bottom: 0.375rem;
min-width: 32px;
padding: 0.375rem var(--navds-spacing-3);
}
.navds-button--xsmall {
padding: 0.125rem 0.375rem;
min-width: 24px;
padding: 0.125rem var(--navds-spacing-2);
gap: var(--navds-spacing-1);
}
.navds-button--icon-only {
padding: var(--navds-spacing-3);
}
.navds-button--small.navds-button--icon-only {
padding: 0.375rem;
}
.navds-button--xsmall.navds-button--icon-only {
padding: var(--navds-spacing-1);
}
.navds-button:focus {
@@ -141,22 +152,37 @@
box-shadow: var(--navds-shadow-focus);
}
.navds-button__inner {
margin: auto;
display: flex;
align-items: center;
gap: var(--navds-spacing-2);
}
.navds-button__icon {
--navds-button-icon-adjustment: -4px;
.navds-button svg {
font-size: 1.5rem;
display: flex;
}
.navds-button--small svg,
.navds-button--xsmall svg {
.navds-button__icon:first-child {
margin-left: var(--navds-button-icon-adjustment);
}
.navds-button__icon:last-child {
margin-right: var(--navds-button-icon-adjustment);
}
.navds-button__icon:only-child {
margin: 0;
}
.navds-button--small .navds-button__icon {
--navds-button-icon-adjustment: -2px;
font-size: 1.25rem;
}
.navds-button--xsmall .navds-button__icon {
--navds-button-icon-adjustment: -2px;
font-size: 1rem;
}
/*************************
* .navds-button--primary *
*************************/
-55
View File
@@ -1,55 +0,0 @@
:root {
--navds-card-micro-color-text: var(--navds-semantic-color-text);
--navds-card-micro-color-background: var(--navds-global-color-orange-200);
--navds-card-micro-color-border: transparent;
--navds-card-micro-color-text-hover: var(--navds-semantic-color-link);
--navds-card-micro-color-background-hover: var(
--navds-semantic-color-component-background-light
);
--navds-card-micro-color-border-hover: var(
--navds-semantic-color-interaction-primary
);
--navds-card-micro-color-text-focus: var(--navds-semantic-color-link);
--navds-card-micro-color-background-focus: var(
--navds-semantic-color-component-background-light
);
--navds-card-micro-color-shadow-focus: var(--navds-semantic-color-focus);
--navds-card-micro-color-background-active: var(
--navds-semantic-color-interaction-primary
);
--navds-card-micro-color-text-active: var(
--navds-semantic-color-text-inverted
);
}
/*
MicroCard
*/
.navds-card__micro {
border-radius: var(--navds-border-radius-full);
color: var(--navds-card-micro-color-text);
display: inline-flex;
padding: var(--navds-spacing-1) var(--navds-spacing-2);
text-decoration: none;
background-color: var(--navds-card-micro-color-background);
border: 1px solid var(--navds-card-micro-color-border);
}
.navds-card__micro:hover {
background-color: var(--navds-card-micro-color-background-hover);
border-color: var(--navds-card-micro-color-border-hover);
color: var(--navds-card-micro-color-text-hover);
}
.navds-card__micro:focus {
background-color: var(--navds-card-micro-color-background-focus);
color: var(--navds-card-micro-color-text-focus);
outline: none;
box-shadow: 0 0 0 3px var(--navds-card-micro-color-shadow-focus);
}
.navds-card__micro:active {
background-color: var(--navds-card-micro-color-background-active);
color: var(--navds-card-micro-color-text-active);
}
+90
View File
@@ -0,0 +1,90 @@
:root {
--navds-chat-color-background: var(--navds-semantic-color-canvas-background);
--navds-chat-color-avatar: var(--navds-semantic-color-text);
--navds-chat-color-avatar-background: var(
--navds-semantic-color-canvas-background
);
}
.navds-chat {
display: flex;
align-items: flex-end;
gap: var(--navds-spacing-4);
padding-right: var(--navds-spacing-16);
}
.navds-chat--right {
flex-direction: row-reverse;
padding-right: 0;
padding-left: var(--navds-spacing-16);
}
.navds-chat__bubble-wrapper {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: var(--navds-spacing-3);
}
.navds-chat--right .navds-chat__bubble-wrapper {
align-items: flex-end;
}
.navds-chat__avatar {
align-items: center;
background: var(--navds-chat-color-avatar-background);
color: var(--navds-chat-color-avatar);
border-radius: var(--navds-border-radius-full);
display: flex;
flex-shrink: 0;
justify-content: center;
overflow: hidden;
height: 3rem;
width: 3rem;
}
.navds-chat__avatar svg {
align-self: center;
height: 100%;
width: 100%;
}
.navds-chat__bubble {
padding: 1rem;
box-shadow: var(--navds-shadow-small);
width: fit-content;
max-width: 37.5rem;
background-color: var(--navds-chat-color-background);
border-radius: var(--navds-border-radius-xlarge);
border-bottom-left-radius: 2px;
display: flex;
flex-direction: column;
gap: var(--navds-spacing-2);
}
.navds-chat__bubble:focus {
box-shadow: var(--navds-shadow-focus);
outline: none;
}
.navds-chat--right .navds-chat__bubble {
border-radius: var(--navds-border-radius-xlarge);
border-bottom-right-radius: 2px;
}
.navds-chat__top-text {
color: var(--navds-semantic-color-text);
display: flex;
gap: var(--navds-spacing-2);
align-items: baseline;
}
.navds-chat--right .navds-chat__top-text {
align-self: flex-end;
}
.navds-chat__name {
font-weight: var(--navds-font-weight-bold);
}
-8
View File
@@ -3,9 +3,6 @@
--navds-semantic-color-component-background-light
);
--navds-radio-checkbox-color-text: var(--navds-semantic-color-text);
--navds-radio-checkbox-color-description: var(
--navds-semantic-color-text-muted
);
--navds-radio-checkbox-color-background-hover: var(
--navds-semantic-color-interaction-primary-hover-subtle
);
@@ -75,11 +72,6 @@
gap: var(--navds-spacing-1);
}
.navds-checkbox__description,
.navds-radio__description {
color: var(--navds-radio-checkbox-color-description);
}
.navds-checkbox--small > .navds-checkbox__input,
.navds-radio--small > .navds-radio__input {
width: 32px;
+2 -2
View File
@@ -16,7 +16,6 @@
--navds-select-color-background-disabled: var(
--navds-semantic-color-component-background-alternate
);
--navds-select-color-text-disabled: var(--navds-semantic-color-text);
}
.navds-select__input {
@@ -30,7 +29,7 @@
display: inline-block;
position: relative;
padding: 0.5rem;
padding-right: 2.5rem;
padding-right: 2rem;
}
.navds-select__input:hover {
@@ -47,6 +46,7 @@
display: flex;
width: 100%;
align-items: center;
color: var(--navds-semantic-color-text);
}
.navds-select__chevron {
-4
View File
@@ -72,10 +72,6 @@
padding: 0.75rem 0 0.75rem 3.25rem;
}
.navds-switch__description {
color: var(--navds-semantic-color-text-muted);
}
.navds-switch--right > .navds-switch__label-wrapper > .navds-switch__content {
padding: 0.75rem 3.25rem 0.75rem 0;
}
+1 -2
View File
@@ -12,7 +12,7 @@
--navds-textarea-color-shadow-error: var(
--navds-semantic-color-interaction-danger
);
--navds-textarea-color-counter-text: var(--navds-global-color-gray-400);
--navds-textarea-color-counter-text: var(--navds-semantic-color-text-muted);
--navds-textarea-color-counter-text-error: var(
--navds-semantic-color-interaction-danger
);
@@ -37,7 +37,6 @@
resize: none;
width: 100%;
display: block;
min-height: 48px;
color: var(--navds-text-field-color-text);
}
+20 -11
View File
@@ -15,7 +15,6 @@
--navds-help-text-color-shadow-hover: var(
--navds-semantic-color-interaction-primary
);
--navds-help-text-color-shadow-focus: var(--navds-semantic-color-focus);
--navds-help-text-color-popover-background: var(
--navds-semantic-color-feedback-info-background
);
@@ -35,27 +34,37 @@
font-size: 1.5rem;
}
.navds-help-text__button:hover {
color: var(--navds-help-text-color-hover);
background: var(--navds-help-text-color-background-hover);
box-shadow: 0 0 0 2px var(--navds-help-text-color-shadow-hover);
}
.navds-help-text__button:focus {
outline: none;
color: var(--navds-help-text-color-focus);
background: var(--navds-help-text-color-background-focus);
box-shadow: 0 0 0 3px var(--navds-help-text-color-shadow-focus);
box-shadow: 0 0 0 1px var(--navds-global-color-white),
0 0 0 4px var(--navds-semantic-color-focus);
}
.navds-help-text__icon {
border-radius: var(--navds-border-radius-full);
}
.navds-help-text__popover > .navds-popover__arrow::before {
.navds-help-text__popover > .navds-popover__arrow {
background-color: var(--navds-help-text-color-popover-background);
}
.navds-help-text__popover.navds-popover {
background-color: var(--navds-help-text-color-popover-background);
max-width: 65ch;
--navds-popover-color-border: rgba(38 38 38 / 0.22);
}
.navds-help-text__icon--filled {
display: none;
}
.navds-help-text__button:where(:hover, :focus, [aria-expanded="true"])
> .navds-help-text__icon {
display: none;
}
.navds-help-text__button:where(:hover, :focus, [aria-expanded="true"])
> .navds-help-text__icon--filled {
display: inherit;
}
+1 -7
View File
@@ -7,12 +7,12 @@
@import "alert.css";
@import "button.css";
@import "content-container.css";
@import "chat.css";
@import "guide-panel.css";
@import "form/index.css";
@import "help-text.css";
@import "link.css";
@import "loader.css";
@import "menu.css";
@import "modal.css";
@import "pagination.css";
@import "popover.css";
@@ -22,12 +22,6 @@
@import "panel.css";
@import "link-panel.css";
@import "read-more.css";
@import "speech-bubble.css";
@import "step-indicator.css";
@import "stepper.css";
@import "table.css";
@import "tabs.css";
/* Navno spesific packages */
@import "page-header.css";
@import "card.css";
-102
View File
@@ -1,102 +0,0 @@
:root {
--navds-menu-color-text: var(--navds-semantic-color-link);
--navds-menu-color-text-hover: var(--navds-semantic-color-text);
--navds-menu-color-text-focus: var(--navds-semantic-color-text);
--navds-menu-color-background-hover: var(--navds-global-color-blue-50);
--navds-menu-color-text-active: var(--navds-semantic-color-text);
--navds-menu-outline-focus: var(--navds-semantic-color-focus);
}
.navds-menu__list {
list-style: none;
margin: 0;
padding: 0;
padding: 0 0.5rem;
}
.navds-menu__list--inner {
padding: 0;
}
.navds-menu-collapse__button {
cursor: pointer;
background-color: transparent;
border: none;
font: inherit;
text-align: inherit;
margin: 0;
width: 100%;
justify-content: space-between;
align-items: center;
font-weight: var(--navds-font-weight-bold);
color: var(--navds-menu-color-text);
}
.navds-menu-item,
.navds-menu-collapse__button {
font-weight: var(--navds-font-weight-bold);
display: flex;
padding: var(--navds-spacing-3) var(--navds-spacing-2);
text-decoration: none;
}
.navds-menu-item:focus,
.navds-menu-collapse__button:focus {
outline: 3px solid var(--navds-menu-outline-focus);
outline-offset: -3px;
color: var(--navds-menu-color-text-focus);
}
.navds-menu-collapse__button:focus > .navds-menu-collapse__expand-icon {
color: var(--navds-menu-color-focus);
}
.navds-menu-item:hover,
.navds-menu-collapse__button:hover {
background-color: var(--navds-menu-color-background-hover);
color: var(--navds-menu-color-text-hover);
}
.navds-menu-item--active {
box-shadow: -0.5rem 0 var(--navds-semantic-color-link);
color: var(--navds-menu-color-text-active);
text-decoration: none;
}
/* Collapse icon */
.navds-menu-collapse__expand-icon {
font-size: 1.5rem;
flex-shrink: 0;
margin-left: var(--navds-spacing-2);
}
.navds-menu-collapse__expand-icon--filled,
.navds-menu-collapse__button:hover > .navds-menu-collapse__expand-icon {
display: none;
}
.navds-menu-collapse__button:hover > .navds-menu-collapse__expand-icon--filled {
display: block;
}
.navds-menu-collapse--open
> .navds-menu-collapse__button
> .navds-menu-collapse__expand-icon {
transform: rotate(180deg);
}
/* Nesting levels */
.navds-menu__list[data-depth="1"] .navds-menu-collapse__button,
.navds-menu__list[data-depth="1"] .navds-menu-item {
padding-left: var(--navds-spacing-6);
}
.navds-menu__list[data-depth="2"] .navds-menu-collapse__button,
.navds-menu__list[data-depth="2"] .navds-menu-item {
padding-left: var(--navds-spacing-10);
}
.navds-menu__list[data-depth="3"] .navds-menu-collapse__button,
.navds-menu__list[data-depth="3"] .navds-menu-item {
padding-left: var(--navds-spacing-14);
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "0.18.27",
"version": "1.3.7",
"description": "Css for NAV Designsystem components",
"author": "NAV Designsystem team",
"keywords": [
@@ -20,7 +20,7 @@
"watch": "postcss --watch --use postcss-import -o dist/index.css index.css"
},
"devDependencies": {
"@navikt/ds-tokens": "^0.9.7",
"@navikt/ds-tokens": "^1.3.7",
"normalize.css": "^8.0.1",
"postcss": "^8.3.6",
"postcss-cli": "^8.3.1",
-76
View File
@@ -1,76 +0,0 @@
:root {
--navds-page-header-color-background: var(
--navds-semantic-color-component-background-light
);
--navds-page-header-color-shadow-situation: var(
--navds-global-color-orange-400
);
--navds-page-header-color-shadow-product: var(--navds-global-color-green-400);
--navds-page-header-color-shadow-guide: var(
--navds-global-color-deepblue-400
);
}
.navds-page-header {
display: flex;
justify-content: center;
background-color: var(--navds-page-header-color-background);
padding: 1.5rem calc((100vw - 100%) / 2);
margin-left: calc((100vw - 100%) / -2);
margin-right: calc((100vw - 100%) / -2);
}
.navds-page-header__wrapper {
width: 100%;
max-width: 56.5rem;
text-align: left;
}
.navds-page-header__title {
display: flex;
margin: 0 auto;
width: 100%;
position: relative;
flex-direction: column;
}
.navds-page-header--left > .navds-page-header__wrapper {
text-align: left;
}
.navds-page-header--center > .navds-page-header__wrapper {
text-align: center;
}
.navds-page-header__illustration {
margin-right: 1.5rem;
pointer-events: none;
}
.navds-page-header__illustration > svg {
width: 5rem;
height: 5rem;
}
.navds-page-header--situation {
box-shadow: 0 -4px 0 var(--navds-page-header-color-shadow-situation) inset;
}
.navds-page-header--product {
box-shadow: 0 -4px 0 var(--navds-page-header-color-shadow-product) inset;
}
.navds-page-header--guide {
box-shadow: 0 -4px 0 var(--navds-page-header-color-shadow-guide) inset;
}
@media (max-width: 649px) {
.navds-page-header__illustration > svg {
width: 3rem;
height: 3rem;
}
.navds-page-header__title {
font-size: var(--navds-font-size-heading-xlarge);
}
}
+18 -72
View File
@@ -1,25 +1,12 @@
:root {
--navds-pagination-color-background-hover: var(
--navds-semantic-color-canvas-background
);
--navds-pagination-color-background-active: var(
--navds-semantic-color-interaction-primary-selected
);
--navds-pagination-color-text-active: var(
--navds-semantic-color-text-inverted
);
--navds-pagination-color-background-selected: var(
--navds-semantic-color-interaction-primary
--navds-semantic-color-interaction-primary-selected
);
--navds-pagination-color-text-selected: var(
--navds-semantic-color-text-inverted
);
}
.navds-pagination {
display: flex;
}
.navds-pagination__list {
margin: 0;
padding: 0;
@@ -32,89 +19,48 @@
display: flex;
align-items: center;
justify-content: center;
width: var(--navds-spacing-8);
width: var(--navds-spacing-12);
cursor: default;
}
.navds-pagination--small .navds-pagination__ellipsis {
width: var(--navds-spacing-8);
}
.navds-pagination--xsmall .navds-pagination__ellipsis {
width: var(--navds-spacing-6);
}
.navds-pagination__item {
display: flex;
cursor: pointer;
margin: 0;
text-decoration: none;
border: none;
background: none;
border-radius: var(--navds-border-radius-small);
padding: var(--navds-spacing-1) var(--navds-spacing-3);
color: var(--navds-semantic-color-text);
}
.navds-pagination--small .navds-pagination__item {
padding: 2px var(--navds-spacing-2);
}
.navds-pagination__item:hover {
background-color: var(--navds-pagination-color-background-hover);
}
.navds-pagination__item:active {
background-color: var(--navds-pagination-color-background-active);
color: var(--navds-pagination-color-text-active);
}
.navds-pagination__item:focus {
box-shadow: inset 0 0 0 2px var(--navds-semantic-color-focus),
inset 0 0 0 3px white;
outline: none;
.navds-pagination--medium .navds-pagination__item {
border-radius: var(--navds-border-radius-medium);
}
.navds-pagination__item[aria-current="true"] {
background-color: var(--navds-pagination-color-background-selected);
color: var(--navds-pagination-color-text-selected);
font-weight: var(--navds-font-weight-bold);
}
.navds-pagination__item[aria-current="true"]:focus {
box-shadow: inset 0 0 0 1px var(--navds-button-color-tertiary-border-active),
var(--navds-shadow-focus);
}
.navds-pagination__prev-next {
display: flex;
cursor: pointer;
margin: 0;
padding: 0;
border: none;
background: none;
text-decoration: underline;
color: var(--navds-semantic-color-link);
align-items: center;
gap: var(--navds-spacing-1);
border-radius: var(--navds-border-radius-small);
}
.navds-pagination__prev-next:focus {
outline: none;
box-shadow: inset 0 0 0 2px var(--navds-semantic-color-focus);
.navds-pagination--small .navds-pagination__prev-next {
padding: 0.375rem;
}
.navds-pagination__prev-next:disabled {
cursor: not-allowed;
opacity: 0.3;
}
.navds-pagination__prev-next-icon {
margin: 7px;
}
.navds-pagination--small .navds-pagination__prev-next-icon {
margin: var(--navds-spacing-1);
font-size: 1rem;
}
.navds-pagination__next-text {
padding-left: 0.75rem;
}
.navds-pagination__prev-text {
padding-right: 0.75rem;
.navds-pagination--xsmall .navds-pagination__prev-next {
padding: 0.125rem;
}
.navds-pagination--invisible {
+5 -27
View File
@@ -28,55 +28,33 @@
}
.navds-popover__arrow {
position: absolute;
z-index: -1;
}
.navds-popover__arrow::before {
display: block;
content: "";
transform: rotate(45deg);
background-color: var(--navds-popover-color-background);
border: 1px solid;
border-color: var(--navds-popover-color-border);
width: 1rem;
height: 1rem;
top: 0;
left: 0;
}
.navds-popover[data-popper-placement^="top"] > .navds-popover__arrow {
bottom: calc(1rem / -2);
}
.navds-popover[data-popper-placement^="top"] > .navds-popover__arrow::before {
.navds-popover[data-placement^="top"] > .navds-popover__arrow {
border-left-color: transparent;
border-top-color: transparent;
}
.navds-popover[data-popper-placement^="bottom"] > .navds-popover__arrow {
top: calc(1rem / -2);
}
/* prettier-ignore */
.navds-popover[data-popper-placement^="bottom"] > .navds-popover__arrow::before {
.navds-popover[data-placement^="bottom"] > .navds-popover__arrow {
border-bottom-color: transparent;
border-right-color: transparent;
}
.navds-popover[data-popper-placement^="left"] > .navds-popover__arrow {
right: calc(1rem / -2);
}
.navds-popover[data-popper-placement^="left"] > .navds-popover__arrow::before {
.navds-popover[data-placement^="left"] > .navds-popover__arrow {
border-left-color: transparent;
border-bottom-color: transparent;
}
.navds-popover[data-popper-placement^="right"] > .navds-popover__arrow {
left: calc(1rem / -2);
}
.navds-popover[data-popper-placement^="right"] > .navds-popover__arrow::before {
.navds-popover[data-placement^="right"] > .navds-popover__arrow {
border-right-color: transparent;
border-top-color: transparent;
}
+19 -20
View File
@@ -1,11 +1,11 @@
.navds-read-more {
.navds-read-more__button {
cursor: pointer;
margin: 0;
border: none;
background: none;
display: flex;
align-items: center;
gap: var(--navds-spacing-2);
align-items: flex-start;
gap: 0.125rem;
color: var(--navds-semantic-color-link);
border-radius: var(--navds-border-radius-small);
padding: var(--navds-spacing-1) var(--navds-spacing-1) var(--navds-spacing-1)
@@ -13,44 +13,43 @@
text-align: start;
}
.navds-read-more--small {
.navds-read-more--small .navds-read-more__button {
padding: 2px var(--navds-spacing-1) 2px 2px;
}
.navds-read-more:hover {
.navds-read-more__button:hover {
background-color: rgba(38 38 38 / 0.06);
}
.navds-read-more:active {
.navds-read-more__button:active {
background-color: rgba(38 38 38 / 0.1);
}
.navds-read-more:focus {
.navds-read-more__button:focus {
outline: none;
box-shadow: var(--navds-shadow-focus);
}
.navds-read-more + .ReactCollapse--collapse {
transition: all 250ms cubic-bezier(0.4, 0, 0.2, 1);
padding-top: var(--navds-spacing-1);
}
.navds-read-more:not(.navds-read-more--open) + .ReactCollapse--collapse {
padding: 0;
}
.navds-read-more__content {
margin-top: var(--navds-spacing-1);
border-left: 2px solid rgba(38 38 38 / 0.36);
margin-left: 11px;
padding-left: 15px;
padding-left: 11px;
}
.navds-read-more__expand-icon {
font-size: 1.25rem;
height: 1.5rem;
flex-shrink: 0;
}
.navds-read-more--open > .navds-read-more__expand-icon {
.navds-read-more--small .navds-read-more__expand-icon {
height: 1.25rem;
}
.navds-read-more--open
> .navds-read-more__button
> .navds-read-more__expand-icon {
transform: rotate(-180deg);
}
@@ -58,11 +57,11 @@
display: none;
}
.navds-read-more:hover
.navds-read-more__button:hover
> .navds-read-more__expand-icon.navds-read-more__expand-icon--filled {
display: inherit;
}
.navds-read-more:hover > .navds-read-more__expand-icon {
.navds-read-more__button:hover > .navds-read-more__expand-icon {
display: none;
}
-85
View File
@@ -1,85 +0,0 @@
:root {
--navds-speechbubble-color-background: var(
--navds-semantic-color-component-background-alternate
);
--navds-speechbubble-color-illustration: var(--navds-semantic-color-text);
--navds-speechbubble-color-illustration-background: var(
--navds-semantic-color-canvas-background
);
--navds-speechbubble-color-detail-text: var(
--navds-semantic-color-text-muted
);
}
.navds-speechbubble {
display: flex;
align-items: flex-end;
gap: var(--navds-spacing-4);
}
.navds-speechbubble--right {
flex-direction: row-reverse;
}
.navds-speechbubble__bubble-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: var(--navds-spacing-3);
}
.navds-speechbubble--right .navds-speechbubble__bubble-list {
align-items: flex-end;
}
.navds-speechbubble__illustration {
align-items: center;
background: var(--navds-speechbubble-color-illustration-background);
color: var(--navds-speechbubble-color-illustration);
border-radius: var(--navds-border-radius-full);
display: flex;
flex-shrink: 0;
justify-content: center;
overflow: hidden;
height: 3rem;
width: 3rem;
}
.navds-speechbubble__illustration svg {
align-self: center;
height: 100%;
width: 100%;
}
.navds-speechbubble__bubble {
padding: 1rem;
box-shadow: var(--navds-shadow-small);
width: fit-content;
max-width: 37.5rem;
background-color: var(--navds-speechbubble-color-background);
border-radius: var(--navds-border-radius-xlarge);
border-bottom-left-radius: 2px;
display: flex;
flex-direction: column;
gap: var(--navds-spacing-2);
}
.navds-speechbubble__bubble:focus {
box-shadow: var(--navds-shadow-focus);
outline: none;
}
.navds-speechbubble--right .navds-speechbubble__bubble {
border-radius: var(--navds-border-radius-xlarge);
border-bottom-right-radius: 2px;
}
.navds-speechbubble__top-text {
color: var(--navds-speechbubble-color-detail-text);
}
.navds-speechbubble--right .navds-speechbubble__top-text {
align-self: flex-end;
}
-202
View File
@@ -1,202 +0,0 @@
:root {
--navds-step-indicator-color-step-line: var(--navds-semantic-color-divider);
--navds-step-indicator-color-step-text: var(--navds-semantic-color-text);
--navds-step-indicator-color-step-label: var(
--navds-semantic-color-interaction-primary
);
--navds-step-indicator-color-step-number-background: var(
--navds-semantic-color-canvas-background-light
);
--navds-step-indicator-color-step-number-background-finished: var(
--navds-semantic-color-canvas-background
);
--navds-step-indicator-color-step-number-shadow: var(
--navds-semantic-color-border
);
--navds-step-indicator-color-step-number-shadow-active: var(
--navds-semantic-color-interaction-primary-selected
);
--navds-step-indicator-color-step-number-shadow-hover: var(
--navds-semantic-color-interaction-primary
);
--navds-step-indicator-color-step-number-background-active: var(
--navds-semantic-color-interaction-primary-selected
);
--navds-step-indicator-color-step-number-text-active: var(
--navds-semantic-color-text-inverted
);
--navds-step-indicator-color-step-number-shadow-inset: var(
--navds-semantic-color-component-background-light
);
}
/* StepIndicator */
.navds-step-indicator {
display: flex;
align-items: flex-start;
padding: 0;
margin: 0;
}
/* Step */
.navds-step-indicator__step-wrapper {
padding: 0 var(--navds-spacing-2);
flex: 1;
position: relative;
list-style: none;
min-width: 10rem;
}
.navds-step-indicator__step-wrapper--hidelabel {
min-width: 5rem;
}
.navds-step-indicator__step {
display: flex;
align-items: center;
flex-direction: column;
padding: 0;
background: none;
border: none;
appearance: none;
width: 100%;
flex-shrink: 1;
color: var(--navds-step-indicator-color-step-text);
text-decoration: none;
cursor: pointer;
}
.navds-step-indicator__step-number {
flex-shrink: 0;
display: flex;
width: 2rem;
height: 2rem;
margin: 0.5rem;
border-radius: var(--navds-border-radius-full);
align-items: center;
justify-content: center;
box-shadow: 0 0 0 1px var(--navds-step-indicator-color-step-number-shadow);
background-color: var(--navds-step-indicator-color-step-number-background);
}
.navds-step-indicator__step-wrapper:first-child
> .navds-step-indicator__step
> .navds-step-indicator__step-number {
padding-right: 0;
}
.navds-step-indicator__step-wrapper:last-child
> .navds-step-indicator__step
> .navds-step-indicator__step-number {
padding-left: 0;
}
.navds-step-indicator__step-label {
width: 100%;
margin-top: var(--navds-spacing-4);
text-align: center;
color: var(--navds-step-indicator-color-step-label);
text-decoration: underline;
}
.navds-step-indicator__step-line {
flex: 1 1 100%;
position: absolute;
top: 1.5rem;
right: calc(50% + 2rem);
left: calc(-50% + 2rem);
display: block;
border-top: 2px solid var(--navds-step-indicator-color-step-line);
border-radius: var(--navds-border-radius-medium);
pointer-events: none;
}
.navds-step-indicator__step--active > .navds-step-indicator__step-label {
color: var(--navds-step-indicator-color-step-text);
font-weight: bold;
}
.navds-step-indicator__step--active > .navds-step-indicator__step-number {
background-color: var(
--navds-step-indicator-color-step-number-background-active
);
color: var(--navds-step-indicator-color-step-number-text-active);
box-shadow: 0 0 0 1px
var(--navds-step-indicator-color-step-number-shadow-active);
width: 2.5rem;
height: 2.5rem;
margin: 0.25rem;
}
.navds-step-indicator__step:focus {
outline: none;
}
.navds-step-indicator__step:hover > .navds-step-indicator__step-label {
text-decoration: none;
}
.navds-step-indicator__step.navds-step-indicator__step--disabled:hover
> .navds-step-indicator__step-label {
text-decoration: underline;
}
.navds-step-indicator__step--active > .navds-step-indicator__step-label,
.navds-step-indicator__step--active.navds-step-indicator__step--disabled:hover
> .navds-step-indicator__step-label {
text-decoration: none;
}
.navds-step-indicator__step:hover > .navds-step-indicator__step-number {
background: var(--navds-step-indicator-color-step-number-background);
box-shadow: 0 0 0 2px
var(--navds-step-indicator-color-step-number-shadow-hover);
}
.navds-step-indicator__step--active:hover > .navds-step-indicator__step-number {
background-color: var(
--navds-step-indicator-color-step-number-background-active
);
color: var(--navds-step-indicator-color-step-number-text-active);
box-shadow: 0 0 0 1px
var(--navds-step-indicator-color-step-number-shadow-active);
}
.navds-step-indicator__step:focus > .navds-step-indicator__step-number {
box-shadow: var(--navds-shadow-focus);
outline: none;
}
.navds-step-indicator__step--active:focus > .navds-step-indicator__step-number {
box-shadow: 0 0 0 1px inset
var(--navds-step-indicator-color-step-number-shadow-inset),
var(--navds-shadow-focus);
}
.navds-step-indicator__step--disabled:hover
> .navds-step-indicator__step-number {
box-shadow: 0 0 0 1px var(--navds-step-indicator-color-step-number-shadow);
}
.navds-step-indicator__step--disabled.navds-step-indicator__step--active:disabled
> .navds-step-indicator__step-number {
box-shadow: 0 0 0 1px
var(--navds-step-indicator-color-step-number-shadow-active);
}
/* Finished state */
.navds-step-indicator__step--finished > .navds-step-indicator__step-number,
.navds-step-indicator__step--finished.navds-step-indicator__step--disabled
> .navds-step-indicator__step-number {
background: var(--navds-step-indicator-color-step-number-background-finished);
}
/* Disabled */
.navds-step-indicator__step--disabled > .navds-step-indicator__step-number,
.navds-step-indicator__step--disabled > .navds-step-indicator__step-label {
opacity: 0.3;
}
.navds-step-indicator__step--disabled {
cursor: not-allowed;
}
+61 -3
View File
@@ -36,6 +36,11 @@
grid-column: 1;
}
.navds-stepper__step--behind.navds-stepper__step--completed
+ .navds-stepper__line {
background-color: var(--navds-global-color-blue-500);
}
.navds-stepper__line--1 {
grid-row: line-1;
display: none;
@@ -55,7 +60,6 @@
display: grid;
grid-template-columns: [circle] var(--navds-stepper-circle-size) [content] auto;
gap: var(--navds-spacing-2);
align-items: baseline;
justify-content: flex-start;
text-decoration: none;
cursor: pointer;
@@ -73,6 +77,11 @@ button.navds-stepper__step {
text-align: inherit;
}
.navds-stepper__step--non-interactive {
color: var(--navds-global-color-gray-600);
cursor: default;
}
:where(.navds-stepper__step):focus {
outline: none;
box-shadow: var(--navds-shadow-focus);
@@ -91,10 +100,17 @@ button.navds-stepper__step {
line-height: 1;
}
.navds-stepper__circle--success {
border: none;
background: none;
font-size: 28px;
}
.navds-stepper__content {
min-width: fit-content;
line-height: 1.5;
grid-column: content;
padding-top: 0.035rem;
}
/* Horizontal */
@@ -161,11 +177,15 @@ button.navds-stepper__step {
color: var(--navds-semantic-color-interaction-primary-selected);
}
:where(.navds-stepper__step:not(.navds-stepper__step--active):hover)
.navds-stepper__content {
:where(.navds-stepper__step:hover) .navds-stepper__content {
text-decoration: underline;
}
:where(.navds-stepper__step--non-interactive:hover, .navds-stepper__step--active:hover)
.navds-stepper__content {
text-decoration: none;
}
:where(.navds-stepper__step--active) .navds-stepper__circle {
background-color: var(--navds-semantic-color-interaction-primary-selected);
border-color: var(--navds-semantic-color-interaction-primary-selected);
@@ -178,3 +198,41 @@ button.navds-stepper__step {
--navds-semantic-color-interaction-primary-hover-subtle
);
}
/* Non-interactive */
:where(.navds-stepper__step--non-interactive.navds-stepper__step--active)
.navds-stepper__content {
color: var(--navds-global-color-gray-900);
}
.navds-stepper__step--non-interactive.navds-stepper__step--behind.navds-stepper__step--completed
+ .navds-stepper__line {
background-color: var(--navds-global-color-gray-600);
}
:where(.navds-stepper__step--non-interactive.navds-stepper__step--active)
.navds-stepper__circle {
background-color: var(--navds-global-color-gray-900);
border-color: var(--navds-global-color-gray-900);
color: var(--navds-global-color-white);
}
:where(.navds-stepper__step--non-interactive:hover) .navds-stepper__circle {
background-color: transparent;
}
:where(.navds-stepper__step--non-interactive.navds-stepper__step--active:hover)
.navds-stepper__circle {
background-color: var(--navds-global-color-gray-900);
}
:where(.navds-stepper__step--completed.navds-stepper__step--active)
.navds-stepper__circle {
background-color: inherit;
color: var(--navds-global-color-deepblue-500);
}
:where(.navds-stepper__step--completed.navds-stepper__step--active.navds-stepper__step--non-interactive)
.navds-stepper__circle {
color: var(--navds-global-color-gray-900);
}
+26 -10
View File
@@ -33,7 +33,7 @@
display: table-row;
}
.navds-table__body .navds-table__row:hover {
.navds-table__body .navds-table__row--shade-on-hover:hover {
background-color: var(--navds-table-row-color-background-hover);
}
@@ -41,20 +41,21 @@
background-color: var(--navds-table-row-color-background-selected);
}
.navds-table__body .navds-table__row--selected:hover {
.navds-table__body
.navds-table__row--shade-on-hover.navds-table__row--selected:hover {
background-color: var(--navds-table-row-color-background-selected-hover);
}
.navds-table--zebra-stripes
.navds-table__body
.navds-table__row:nth-child(odd):not(:hover):not(.navds-table__row--selected) {
:where(.navds-table__row:nth-child(odd):not(.navds-table__row--selected)) {
background-color: var(--navds-table-row-color-background-zebra);
}
.navds-table--zebra-stripes
.navds-table__body
.navds-table__expandable-row:nth-child(4n
+ 1):not(:hover):not(.navds-table__row--selected) {
:where(.navds-table__expandable-row:nth-child(4n
+ 1):not(.navds-table__row--selected)) {
background-color: transparent;
}
@@ -87,11 +88,19 @@
text-align: center;
}
.navds-table__body .navds-table__row:hover .navds-table__header-cell,
.navds-table__body .navds-table__row:hover .navds-table__data-cell {
where(.navds-table__body
.navds-table__row--shade-on-hover:hover)
.navds-table__header-cell,
where(.navds-table__body
.navds-table__row--shade-on-hover:hover)
.navds-table__data-cell {
border-color: var(--navds-table-cell-color-border-hover);
}
where(.navds-table__expandable-row--open:hover) .navds-table__data-cell {
border-bottom-color: transparent;
}
.navds-table--small .navds-table__header-cell,
.navds-table--small .navds-table__data-cell {
padding: var(--navds-spacing-2) var(--navds-spacing-3);
@@ -160,8 +169,16 @@
flex-shrink: 0;
}
.navds-table__expandable-row--open .navds-table__header-cell,
.navds-table__expandable-row:not(.navds-table__expandable-row--open)
.navds-table__data-cell {
transition: border-bottom-color 190ms cubic-bezier(0.6, 0.04, 0.98, 0.335);
}
.navds-table__expandable-row--open .navds-table__data-cell {
border-bottom-color: transparent;
}
.navds-table__expandable-row--open .navds-table__header-cell {
border-color: var(--navds-semantic-color-border-muted);
}
@@ -224,8 +241,7 @@
display: none;
}
.navds-table__expanded-row-collapse {
transition: height 250ms cubic-bezier(0.4, 0, 0.2, 1);
.navds-table__expanded-row-collapse:not([style*="height: 0px;"]) {
border-bottom: 1px solid var(--navds-table-cell-color-border);
}
+4
View File
@@ -74,6 +74,10 @@
gap: var(--navds-spacing-1);
}
.navds-tabs__tab-inner svg {
flex-shrink: 0;
}
.navds-tabs__tab-icon--top > .navds-tabs__tab-inner {
flex-direction: column;
gap: 0;
+6 -4
View File
@@ -18,6 +18,12 @@
);
}
.navds-toggle-group__wrapper {
display: grid;
justify-items: start;
gap: var(--navds-spacing-2);
}
.navds-toggle-group {
border-radius: 7px; /* Custom value OK */
background-color: var(--navds-toggle-group-color-background);
@@ -91,7 +97,3 @@
> svg {
font-size: 1.125rem;
}
.navds-toggle-group__label {
margin-bottom: 0.5rem;
}
-3
View File
@@ -10,9 +10,6 @@
.navds-tooltip {
z-index: var(--navds-z-index-tooltip);
}
.navds-tooltip__inner {
background-color: var(--navds-semantic-color-component-background-inverted);
color: var(--navds-semantic-color-text-inverted);
border-radius: var(--navds-border-radius-small);
+32 -18
View File
@@ -1,28 +1,42 @@
# @navikt/ds-icons
# NAV icons
Leverer [NAVs ikoner](https://design.nav.no/resources/icons) i React og SVG.
All of NAVs own icons (400+ and counting)
## Installering
- As just SVG
- As React-components
```sh
// yarn
yarn add @navikt/ds-icons
## Installation
// npm
npm install @navikt/ds-icons
Install `@navikt/ds-icons` with yarn
```bash
yarn add @navikt/ds-icons
```
## Bruk
Install `@navikt/ds-icons` with npm
```jsx
/* ESM (anbefalt for tree-shaking)*/
import { Down } from "@navikt/ds-icons";
/* CJS */
import { Down } from "@navikt/cjs/ds-icons";
<Down aria-label="Åpne meny" />;
```bash
npm install @navikt/ds-icons
```
## Dokumentasjon
## Usage
- [Ikonsøk](https://design.nav.no/resources/icons)
Use as a regular React-component
```javascript
import { Star } from "@navikt/ds-icons";
function App() {
return <Star title="star" />;
}
```
## Learn more
- [Designsystem documentation](https://aksel.nav.no/designsystem)
- [Storybook](https://master--5f801fb2aea7820022de2936.chromatic.com/)
- [Icon-search](https://aksel.nav.no/designsystem/side/ikoner)
## License
[MIT](https://github.com/navikt/Designsystemet/blob/master/LICENCE)
+36
View File
@@ -1763,6 +1763,18 @@
"created_at": "2021-01-12T13:29:09.125Z",
"pageName": "People"
},
{
"name": "PeopleInCircle",
"description": "",
"created_at": "2022-07-07T09:09:15.789Z",
"pageName": "People"
},
{
"name": "PeopleInCircleFilled",
"description": "",
"created_at": "2022-07-07T09:09:15.782Z",
"pageName": "People"
},
{
"name": "Picture",
"description": "",
@@ -1943,6 +1955,30 @@
"created_at": "2021-01-11T13:37:55.658Z",
"pageName": "Arrow"
},
{
"name": "RotateLeft",
"description": "",
"created_at": "2022-08-03T12:27:13.304Z",
"pageName": "Interface"
},
{
"name": "RotateLeftFilled",
"description": "",
"created_at": "2022-08-03T12:27:13.309Z",
"pageName": "Interface"
},
{
"name": "RotateRight",
"description": "",
"created_at": "2022-08-03T12:27:13.299Z",
"pageName": "Interface"
},
{
"name": "RotateRightFilled",
"description": "",
"created_at": "2022-08-03T12:27:13.294Z",
"pageName": "Interface"
},
{
"name": "Ruler",
"description": "",
+6 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-icons",
"version": "0.8.19",
"version": "1.3.7",
"description": "NAVs egne ikoner i SVG og React format",
"repository": {
"type": "git",
@@ -31,19 +31,20 @@
"build": "yarn clean && copyfiles util/* src && yarn create-icons && concurrently \"tsc\" \"tsc -p tsconfig.esm.json\" && yarn create-package-json-pointers-to-esm",
"update": "ts-node figma/index.ts dotenv/config"
},
"dependencies": {
"uuid": "^8.3.2"
},
"peerDependencies": {
"@types/react": "^17.0.30 || ^18.0.0",
"react": "^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
},
"devDependencies": {
"@svgr/cli": "6.2.1",
"@types/lodash.startcase": "^4.4.6",
"@types/node": "^17.0.35",
"@types/rimraf": "3.0.2",
"@types/uuid": "^8.3.1",
"axios": "^0.21.3",
"concurrently": "7.2.1",
"copyfiles": "^2.4.1",
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12C21 14.7218 19.7918 17.1615 17.8824 18.8118C17.331 16.0672 14.9069 14 12 14C9.09309 14 6.669 16.0672 6.11764 18.8118C4.20824 17.1615 3 14.7218 3 12ZM8 20.0645C9.20496 20.6633 10.5632 21 12 21C13.4368 21 14.795 20.6633 16 20.0645V20C16 17.7909 14.2091 16 12 16C9.79086 16 8 17.7909 8 20V20.0645ZM12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1ZM12 11C10.8954 11 10 10.1046 10 9C10 7.89543 10.8954 7 12 7C13.1046 7 14 7.89543 14 9C14 10.1046 13.1046 11 12 11ZM8 9C8 11.2091 9.79086 13 12 13C14.2091 13 16 11.2091 16 9C16 6.79086 14.2091 5 12 5C9.79086 5 8 6.79086 8 9Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 857 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23ZM15 9C15 7.34315 13.6569 6 12 6C10.3431 6 9 7.34315 9 9C9 10.6569 10.3431 12 12 12C13.6569 12 15 10.6569 15 9ZM6.11764 18.8118C6.669 16.0672 9.09309 14 12 14C14.9069 14 17.331 16.0672 17.8824 18.8118C16.3048 20.1753 14.2487 21 12 21C9.75127 21 7.69516 20.1753 6.11764 18.8118Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 560 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.2931 5.29289L13.7931 1.79289L15.2074 3.20711L13.4145 5H16C19.3137 5 22 7.68629 22 11V15H20V11C20 8.79086 18.2091 7 16 7H13.4145L15.2074 8.79289L13.7931 10.2071L10.2931 6.70711L9.58603 6L10.2931 5.29289ZM4 11C2.89543 11 2 11.8954 2 13V20C2 21.1046 2.89543 22 4 22H11C12.1046 22 13 21.1046 13 20V13C13 11.8954 12.1046 11 11 11H4ZM4 13H11V20H4V13Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 519 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 0C0.447715 0 0 0.447716 0 1V23C0 23.5523 0.447716 24 1 24H23C23.5523 24 24 23.5523 24 23V1C24 0.447715 23.5523 0 23 0H1ZM12.7931 1.79289L9.29314 5.29289L8.58603 6L9.29314 6.70711L12.7931 10.2071L14.2074 8.79289L12.4145 7H15C17.2091 7 19 8.79086 19 11V15H21V11C21 7.68629 18.3137 5 15 5H12.4145L14.2074 3.20711L12.7931 1.79289ZM3 13.5C3 12.6716 3.67157 12 4.5 12H10.5C11.3284 12 12 12.6716 12 13.5V19.5C12 20.3284 11.3284 21 10.5 21H4.5C3.67157 21 3 20.3284 3 19.5V13.5Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 643 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 7H10.5859L8.79299 8.79289L10.2072 10.2071L13.7072 6.7071L14.4143 6.00002L13.7072 5.29292L10.2072 1.79267L8.79297 3.20684L10.586 5H8C4.68629 5 2 7.68629 2 11V15H4V11C4 8.79086 5.79086 7 8 7ZM13 11C11.8954 11 11 11.8954 11 13V20C11 21.1046 11.8954 22 13 22H20C21.1046 22 22 21.1046 22 20V13C22 11.8954 21.1046 11 20 11H13ZM13 13H20V20H13V13Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 513 B

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 0C0.447715 0 0 0.447716 0 1V23C0 23.5523 0.447716 24 1 24H23C23.5523 24 24 23.5523 24 23V1C24 0.447715 23.5523 0 23 0H1ZM11.5858 7H9C6.79086 7 5 8.79086 5 11V15H3V11C3 7.68629 5.68629 5 9 5H11.5859L9.79287 3.20682L11.2071 1.79266L14.7071 5.2929L15.4142 6.00001L14.7071 6.70709L11.2071 10.2071L9.79289 8.79288L11.5858 7ZM12 13.5C12 12.6716 12.6716 12 13.5 12H19.5C20.3284 12 21 12.6716 21 13.5V19.5C21 20.3284 20.3284 21 19.5 21H13.5C12.6716 21 12 20.3284 12 19.5V13.5Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 642 B

+13 -2
View File
@@ -1,3 +1,14 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM17.0465 7.67114L18.4456 9.10034L9.71768 17.4992L6 14.0182L7.39515 12.5852L9.71359 14.7034L17.0465 7.67114Z" fill="#262626"/>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM17.0465 7.67114L18.4456 9.10034L9.71768 17.4992L6 14.0182L7.39515 12.5852L9.71359 14.7034L17.0465 7.67114Z"
fill="#262626"
/>
</svg>

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 534 B

+37 -20
View File
@@ -1,22 +1,39 @@
import { useLayoutEffect, useState } from "react";
import { v4 } from "uuid";
//https://github.com/mui/material-ui/blob/master/packages/mui-utils/src/useId.ts
import React, { useEffect, useState } from "react";
const canUseDOM = (): boolean => {
return (
typeof window !== "undefined" &&
typeof window.document !== "undefined" &&
typeof window.document.createElement !== "undefined"
);
};
let globalId = 0;
function useGlobalId(idOverride?: string): string | undefined {
const [defaultId, setDefaultId] = useState(idOverride);
const id = idOverride || defaultId;
useEffect(() => {
if (defaultId == null) {
// Fallback to this default id when possible.
// Use the incrementing value for client-side rendering only.
// We can't use it server-side.
// If you want to use random values please consider the Birthday Problem: https://en.wikipedia.org/wiki/Birthday_problem
globalId += 1;
setDefaultId(`navds-id-${globalId}`);
}
}, [defaultId]);
return id;
}
export const useClientLayoutEffect = canUseDOM() ? useLayoutEffect : () => {};
export const useId: (id?: string) => string = (id) => {
const [newId, setNewId] = useState<string | undefined>(undefined);
useClientLayoutEffect(() => {
setNewId(v4());
}, []);
return id ?? newId ?? "";
};
// eslint-disable-next-line no-useless-concat -- Workaround for https://github.com/webpack/webpack/issues/14814
const maybeReactUseId: undefined | (() => string) = (React as any)[
// eslint-disable-next-line no-useless-concat
"useId" + ""
];
/**
*
* @example <div id={useId()} />
* @param idOverride
* @returns {string}
*/
export function useId(idOverride?: string): string | undefined {
if (maybeReactUseId !== undefined) {
const reactId = maybeReactUseId();
return idOverride ?? reactId;
}
// eslint-disable-next-line react-hooks/rules-of-hooks -- `useId` is invariant at runtime.
return useGlobalId(idOverride);
}
+44
View File
@@ -0,0 +1,44 @@
# NAV React-components
All of NAVs core React-components
- Uses styling from `@navikt/ds-css`
- All components implemented with React.forwardRef!
- Most components extend native html-elements.
## Installation
Install `@navikt/ds-react` with yarn
```bash
yarn add @navikt/ds-react
```
Install `@navikt/ds-react` with npm
```bash
npm install @navikt/ds-react
```
## Usage
Remember to also import @navikt/ds-css to apply styling! See README-link under "learn more"-section below.
```javascript
import { Button } from "@navikt/ds-react";
function App() {
return <Button variant="secondary">Click me!</Button>;
}
```
## Learn more
- [Designsystem documentation](https://aksel.nav.no/designsystem)
- [Component-docs](https://aksel.nav.no/designsystem/side/oversikt-komponenter)
- [Storybook](https://master--5f801fb2aea7820022de2936.chromatic.com/)
- [ds-css README](https://github.com/navikt/Designsystemet/blob/master/%40navikt/core/css/README.md)
## License
[MIT](https://github.com/navikt/Designsystemet/blob/master/LICENCE)
+5
View File
@@ -1 +1,6 @@
import "@testing-library/jest-dom/extend-expect";
global.ResizeObserver = jest.fn().mockImplementation(() => ({
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
}));
+14 -16
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "0.19.24",
"version": "1.3.7",
"description": "NAV designsystem react components",
"author": "NAV Designsystem team",
"license": "MIT",
@@ -35,28 +35,21 @@
"test": "jest"
},
"dependencies": {
"@floating-ui/react-dom": "0.6.0",
"@material-ui/core": "^4.12.3",
"@navikt/ds-icons": "^0.8.19",
"@popperjs/core": "^2.10.1",
"@radix-ui/react-tabs": "0.1.5",
"@radix-ui/react-toggle-group": "0.1.5",
"classnames": "^2.2.6",
"react-collapse": "^5.1.0",
"react-merge-refs": "^1.1.0",
"react-modal": "3.15.1",
"react-popper": "^2.2.5",
"uuid": "^8.3.2"
"@floating-ui/react-dom-interactions": "0.9.2",
"@navikt/ds-icons": "^1.3.7",
"@radix-ui/react-tabs": "1.0.0",
"@radix-ui/react-toggle-group": "1.0.0",
"clsx": "^1.1.1",
"react-modal": "3.15.1"
},
"devDependencies": {
"@testing-library/dom": "8.13.0",
"@testing-library/jest-dom": "^5.16.0",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^14.0.0",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^14.2.0",
"@types/faker": "5.5.8",
"@types/jest": "^27.0.1",
"@types/node": "^17.0.35",
"@types/react-collapse": "^5.0.1",
"@types/react-modal": "^3.13.1",
"concurrently": "7.2.1",
"copyfiles": "^2.4.1",
@@ -75,5 +68,10 @@
"peerDependencies": {
"@types/react": "^17.0.30 || ^18.0.0",
"react": "^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}
@@ -1,4 +1,4 @@
import cl from "classnames";
import cl from "clsx";
import React, { forwardRef } from "react";
import AccordionItem, { AccordionItemType } from "./AccordionItem";
import AccordionContent, { AccordionContentType } from "./AccordionContent";
@@ -1,6 +1,6 @@
import cl from "classnames";
import cl from "clsx";
import React, { forwardRef, useContext } from "react";
import { Collapse, UnmountClosed } from "react-collapse";
import AnimateHeight from "../util/AnimateHeight";
import { BodyLong } from "../typography";
import { AccordionItemContext } from "./AccordionItem";
@@ -8,8 +8,6 @@ export interface AccordionContentProps
extends React.HTMLAttributes<HTMLDivElement> {
/**
* Content inside Accordion.Content
* If renderContentWhenClosed is false in Accordion.Item,
* this will be removed from dom when Accordion is closed
*/
children: React.ReactNode;
}
@@ -19,7 +17,7 @@ export type AccordionContentType = React.ForwardRefExoticComponent<
>;
const AccordionContent: AccordionContentType = forwardRef(
({ children, className, id, ...rest }, ref) => {
({ children, className, ...rest }, ref) => {
const context = useContext(AccordionItemContext);
if (context === null) {
@@ -29,21 +27,17 @@ const AccordionContent: AccordionContentType = forwardRef(
return null;
}
const CollapseComponent = context.renderContentWhenClosed
? Collapse
: UnmountClosed;
return (
<div ref={ref} aria-labelledby={context.buttonId} {...rest}>
<CollapseComponent isOpened={context.open}>
<BodyLong
as="div"
className={cl("navds-accordion__content", className)}
>
{children}
</BodyLong>
</CollapseComponent>
</div>
<AnimateHeight height={context.open ? "auto" : 0} duration={250}>
<BodyLong
{...rest}
as="div"
ref={ref}
className={cl("navds-accordion__content", className)}
>
{children}
</BodyLong>
</AnimateHeight>
);
}
);
@@ -1,8 +1,8 @@
import { Expand, ExpandFilled } from "@navikt/ds-icons";
import cl from "classnames";
import cl from "clsx";
import React, { forwardRef, useContext } from "react";
import { Heading } from "..";
import { AccordionItemContext } from "./AccordionItem";
import { useClientLayoutEffect, useId } from "..";
export interface AccordionHeaderProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
@@ -17,15 +17,8 @@ export type AccordionHeaderType = React.ForwardRefExoticComponent<
>;
const AccordionHeader: AccordionHeaderType = forwardRef(
({ children, className, id, onClick, ...rest }, ref) => {
({ children, className, onClick, ...rest }, ref) => {
const context = useContext(AccordionItemContext);
const newId = useId(id);
const setButtonId = context && context.setButtonId;
useClientLayoutEffect(() => {
setButtonId && setButtonId(id ? newId : `accordionContent-${newId}`);
}, [setButtonId, newId]);
if (context === null) {
console.error(
@@ -45,18 +38,18 @@ const AccordionHeader: AccordionHeaderType = forwardRef(
<button
{...rest}
ref={ref}
id={context.buttonId}
className={cl(
"navds-accordion__header",
className,
"navds-heading",
"navds-heading--small"
)}
className={cl("navds-accordion__header", className)}
type="button"
onClick={handleClick}
aria-expanded={context.open}
>
<span className="navds-accordion__header-content">{children}</span>
<Heading
size="small"
as="span"
className="navds-accordion__header-content"
>
{children}
</Heading>
<Expand aria-hidden className="navds-accordion__expand-icon" />
<ExpandFilled
aria-hidden
@@ -1,4 +1,4 @@
import cl from "classnames";
import cl from "clsx";
import React, { createContext, forwardRef, useState } from "react";
export interface AccordionItemProps
@@ -18,11 +18,6 @@ export interface AccordionItemProps
* @default false
*/
defaultOpen?: boolean;
/**
* Removes content inside Accordion.Content if false from dom when closed
* @default false
*/
renderContentWhenClosed?: boolean;
}
export type AccordionItemType = React.ForwardRefExoticComponent<
@@ -32,9 +27,6 @@ export type AccordionItemType = React.ForwardRefExoticComponent<
export interface AccordionItemContextProps {
open: boolean;
toggleOpen: () => void;
setButtonId: (id: string) => void;
buttonId: string;
renderContentWhenClosed: boolean;
}
export const AccordionItemContext =
@@ -42,20 +34,10 @@ export const AccordionItemContext =
const AccordionItem: AccordionItemType = forwardRef(
(
{
children,
className,
open,
defaultOpen = false,
renderContentWhenClosed = false,
onClick,
id,
...rest
},
{ children, className, open, defaultOpen = false, onClick, id, ...rest },
ref
) => {
const [internalOpen, setInternalOpen] = useState<boolean>(defaultOpen);
const [buttonId, setButtonId] = useState("");
return (
<div
@@ -73,9 +55,6 @@ const AccordionItem: AccordionItemType = forwardRef(
setInternalOpen((iOpen) => !iOpen);
}
},
renderContentWhenClosed,
setButtonId,
buttonId,
}}
>
{children}
@@ -17,45 +17,45 @@ export default {
const Content = () => (
<Accordion.Content>
Magna aliquip aliquip fugiat nostrud nostrud velit pariatur veniam officia
laboris voluptate officia pariatur.Lorem est ex anim velit occaecat nisi qui
nostrud sit consectetur consectetur officia nostrud ullamco. Est ex duis
proident nostrud elit qui laborum anim minim eu eiusmod. Veniam in nostrud
sunt tempor velit incididunt sint ex dolor qui velit id eu. Deserunt magna
sunt velit in. Est exercitation id cillum qui do. Minim adipisicing nostrud
commodo proident occaecat aliquip nulla anim proident reprehenderit. Magna
ipsum officia veniam cupidatat duis veniam dolore reprehenderit mollit
velit.Ut consequat commodo minim occaecat id pariatur. Nisi enim tempor
laborum commodo. Tempor sit quis nostrud eu cupidatat sunt commodo
reprehenderit irure deserunt eiusmod ipsum. Exercitation quis commodo cillum
eiusmod eiusmod. Do laborum qui proident commodo adipisicing eiusmod id.
laboris voluptate officia pariatur. <a href="#Lorem">Lorem est</a> ex anim
velit occaecat nisi qui nostrud sit consectetur consectetur officia nostrud
ullamco. Est ex duis proident nostrud elit qui laborum anim minim eu
eiusmod. Veniam in nostrud sunt tempor velit incididunt sint ex dolor qui
velit id eu. Deserunt magna sunt velit in. Est exercitation id cillum qui
do. Minim adipisicing nostrud commodo proident occaecat aliquip nulla anim
proident reprehenderit. Magna ipsum officia veniam cupidatat duis veniam
dolore reprehenderit mollit velit. Ut consequat commodo minim occaecat id
pariatur. Nisi enim tempor laborum commodo. Tempor sit quis nostrud eu
cupidatat sunt commodo reprehenderit irure deserunt eiusmod ipsum.
Exercitation quis commodo cillum eiusmod eiusmod. Do laborum qui proident
commodo adipisicing eiusmod id.
</Accordion.Content>
);
export const Default = (props) => {
const Item = (props) => {
const [open, setOpen] = useState(false);
const Item = () =>
props.controlled ? (
<Accordion.Item
open={open}
renderContentWhenClosed={props.renderContentWhenClosed}
>
<Accordion.Header onClick={() => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Content />
</Accordion.Item>
) : (
<Accordion.Item renderContentWhenClosed={props.renderContentWhenClosed}>
<Accordion.Header>Accordion header text</Accordion.Header>
<Content />
</Accordion.Item>
);
return props.controlled ? (
<Accordion.Item open={open}>
<Accordion.Header onClick={() => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Content />
</Accordion.Item>
) : (
<Accordion.Item>
<Accordion.Header>Accordion header text</Accordion.Header>
<Content />
</Accordion.Item>
);
};
export const Default = (props) => {
return (
<div style={{ width: 500 }}>
<Accordion>
{[...Array(props.nItems ? props.nItems : 2)].map((_, y) => (
<Item key={y} />
<Item key={y} {...props} />
))}
</Accordion>
</div>
@@ -64,7 +64,6 @@ export const Default = (props) => {
Default.args = {
controlled: false,
renderContentWhenClosed: false,
nItems: 2,
};
+2 -2
View File
@@ -4,7 +4,7 @@ import {
SuccessColored,
WarningColored,
} from "@navikt/ds-icons";
import cl from "classnames";
import cl from "clsx";
import React, { forwardRef } from "react";
import { BodyLong } from "..";
@@ -23,7 +23,7 @@ export interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
*/
size?: "medium" | "small";
/**
* Toggles full-width Alert (removes border-radius)
* Removes border-radius
* @default false
*/
fullWidth?: boolean;
@@ -13,6 +13,12 @@ export default {
options: ["error", "warning", "info", "success"],
},
},
size: {
control: {
type: "radio",
options: ["medium", "small"],
},
},
},
};
@@ -36,6 +42,7 @@ export const Default = (props) => (
Default.args = {
children: "Id elit esse enim reprehenderit enim nisi veniam nostrud.",
fullWidth: false,
};
export const Small = () => {
+39 -14
View File
@@ -1,7 +1,6 @@
import React, { useRef, useState, forwardRef } from "react";
import mergeRefs from "react-merge-refs";
import cl from "classnames";
import { BodyShort, OverridableComponent, Loader } from "../";
import React, { useRef, useState, forwardRef, useMemo } from "react";
import cl from "clsx";
import { OverridableComponent, Loader, mergeRefs, Label } from "../";
import { useClientLayoutEffect } from "../util";
export interface ButtonProps
@@ -9,7 +8,7 @@ export interface ButtonProps
/**
* Button content
*/
children: React.ReactNode;
children?: React.ReactNode;
/**
* Changes design and interaction-visuals
* @default "primary"
@@ -30,6 +29,15 @@ export interface ButtonProps
* @default false
*/
loading?: boolean;
/**
* Button Icon
*/
icon?: React.ReactNode;
/**
* Icon position in Button
* @default "left"
*/
iconPosition?: "left" | "right";
}
export const Button: OverridableComponent<ButtonProps, HTMLButtonElement> =
@@ -44,14 +52,17 @@ export const Button: OverridableComponent<ButtonProps, HTMLButtonElement> =
loading = false,
disabled,
style,
icon,
iconPosition = "left",
...rest
},
ref
) => {
const buttonRef = useRef<HTMLButtonElement | null>(null);
const mergedRef = mergeRefs([buttonRef, ref]);
const [widthOverride, setWidthOverride] = useState<number>();
const mergedRef = useMemo(() => mergeRefs([buttonRef, ref]), [ref]);
useClientLayoutEffect(() => {
if (loading) {
const requestID = window.requestAnimationFrame(() => {
@@ -77,6 +88,7 @@ export const Button: OverridableComponent<ButtonProps, HTMLButtonElement> =
`navds-button--${size}`,
{
"navds-button--loading": widthOverride,
"navds-button--icon-only": !!icon && !children,
}
)}
style={{
@@ -85,14 +97,27 @@ export const Button: OverridableComponent<ButtonProps, HTMLButtonElement> =
}}
disabled={disabled ?? widthOverride ? true : undefined}
>
<BodyShort
as="span"
className="navds-button__inner"
size={size === "medium" ? "medium" : "small"}
aria-live="polite"
>
{widthOverride ? <Loader size={size} /> : children}
</BodyShort>
{widthOverride ? (
<Loader size={size} />
) : (
<>
{icon && iconPosition === "left" && (
<span className="navds-button__icon">{icon}</span>
)}
{children && (
<Label
as="span"
size={size === "medium" ? "medium" : "small"}
aria-live="polite"
>
{children}
</Label>
)}
{icon && iconPosition === "right" && (
<span className="navds-button__icon">{icon}</span>
)}
</>
)}
</Component>
);
}
@@ -18,7 +18,13 @@ export default {
size: {
control: {
type: "radio",
options: ["medium", "small"],
options: ["medium", "small", "xsmall"],
},
},
iconPosition: {
control: {
type: "radio",
options: ["left", "right"],
},
},
},
@@ -40,10 +46,14 @@ const varSwitch = {
export const Default = (props) => {
return (
<Button variant={props.variant} size={props.size} loading={props.loading}>
{props.icon ? <Star /> : null}
<Button
variant={props.variant}
size={props.size}
loading={props.loading}
icon={props.icon ? <Star /> : undefined}
iconPosition={props.iconPosition}
>
{props.children}
{props.icon ? <Star /> : null}
</Button>
);
};
@@ -51,6 +61,7 @@ export const Default = (props) => {
Default.args = {
icon: false,
loading: false,
iconPosition: "left",
children: "Knapp",
};
@@ -114,26 +125,31 @@ export const Icon = () => (
<div className="colgap">
<div className="rowgap">
{variants.map((variant) => (
<Button key={variant} variant={variant}>
<Star aria-hidden />
<span className="navds-sr-only">Stjerne</span>
</Button>
<Button
key={variant}
variant={variant}
icon={<Star title="Stjerne" />}
/>
))}
</div>
<div className="rowgap">
{variants.map((variant) => (
<Button key={variant} variant={variant} size="small">
<Star aria-hidden />
<span className="navds-sr-only">Stjerne</span>
</Button>
<Button
key={variant}
variant={variant}
size="small"
icon={<Star title="Stjerne" />}
/>
))}
</div>
<div className="rowgap">
{variants.map((variant) => (
<Button key={variant} variant={variant} size="xsmall">
<Star aria-hidden />
<span className="navds-sr-only">Stjerne</span>
</Button>
<Button
key={variant}
variant={variant}
size="xsmall"
icon={<Star title="Stjerne" />}
/>
))}
</div>
</div>
@@ -142,29 +158,40 @@ export const Icon = () => (
export const IconWText = () => (
<div className="colgap">
<div className="rowgap">
{variants.map((variant) => (
<Button key={variant} variant={variant}>
<Star aria-hidden />
{variants.map((variant, i) => (
<Button
key={variant}
variant={variant}
icon={<Star title="Stjerne" />}
iconPosition={i % 2 ? "left" : "right"}
>
{varSwitch[variant]}
<Star aria-hidden />
</Button>
))}
</div>
<div className="rowgap">
{variants.map((variant) => (
<Button key={variant} variant={variant} size="small">
<Star aria-hidden />
{variants.map((variant, i) => (
<Button
key={variant}
variant={variant}
size="small"
icon={<Star title="Stjerne" />}
iconPosition={i % 2 ? "left" : "right"}
>
{varSwitch[variant]}
<Star aria-hidden />
</Button>
))}
</div>
<div className="rowgap">
{variants.map((variant) => (
<Button key={variant} variant={variant} size="xsmall">
<Star aria-hidden />
{variants.map((variant, i) => (
<Button
key={variant}
variant={variant}
size="xsmall"
icon={<Star title="Stjerne" />}
iconPosition={i % 2 ? "left" : "right"}
>
{varSwitch[variant]}
<Star aria-hidden />
</Button>
))}
</div>
-32
View File
@@ -1,32 +0,0 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import { OverridableComponent } from "..";
export interface MicroCardProps
extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
/**
* Link text
*/
children: React.ReactNode;
}
export const MicroCard: OverridableComponent<
MicroCardProps,
HTMLAnchorElement
> = forwardRef(({ className, as: Component = "a", children, ...rest }, ref) => (
<Component
ref={ref}
className={cl(
"navds-card__micro",
"navds-detail",
"navds-detail--small",
className
)}
title={children}
{...rest}
>
{children}
</Component>
));
export default MicroCard;
-2
View File
@@ -1,2 +0,0 @@
export { default as MicroCard } from "./MicroCard";
export { MicroCardProps } from "./MicroCard";
@@ -1,26 +0,0 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import { MicroCard } from "../index.ts";
<Meta title="ds-react(deprecated)/card/intro" />
# Hvordan ta i bruk card
## MicroCard
Kan brukes som en vanlig lenke direkte:
```
<MicroCard href="/lenke/til/side">Lenketekst</MicroCard>
```
<Canvas>
<MicroCard href="/lenke/til/side">Lenketekst</MicroCard>
</Canvas>
Hvis man ønsker å ta i bruk nextjs sin `Link`-komponent:
```jsx
<Link href="/lenke/til/side" passHref>
<MicroCard>Lenketekst</MicroCard>
</Link>
```
@@ -1,16 +0,0 @@
import React from "react";
import { MicroCard } from "../index";
import { Meta } from "@storybook/react/types-6-0";
export default {
title: "ds-react(deprecated)/card",
component: MicroCard,
} as Meta;
export const All = () => {
return (
<div>
<h2>MicroCard</h2>
<MicroCard href="#">Sit laborum aliqua.</MicroCard>
</div>
);
};
+52
View File
@@ -0,0 +1,52 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "clsx";
import { Detail } from "../typography";
export interface BubbleProps extends HTMLAttributes<HTMLDivElement> {
/**
* Bubble text
*/
children: React.ReactNode;
/**
* name/sender on bubble
*/
name?: string;
/**
* Timestamp for sent message
*/
timestamp?: string;
/**
* Background color on bubble
*/
backgroundColor?: string;
}
export type BubbleType = React.ForwardRefExoticComponent<
BubbleProps & React.RefAttributes<HTMLDivElement>
>;
const Bubble: BubbleType = forwardRef(
({ children, className, name, timestamp, backgroundColor, ...rest }, ref) => {
return (
<div
ref={ref}
className={cl("navds-chat__bubble", className)}
style={{ backgroundColor: backgroundColor }}
tabIndex={0}
{...rest}
>
{(timestamp || name) && (
<div className="navds-chat__top-text">
{name && <Detail className="navds-chat__name">{name}</Detail>}
{timestamp && (
<Detail className="navds-chat__timestamp">{timestamp}</Detail>
)}
</div>
)}
{children}
</div>
);
}
);
export default Bubble;
+96
View File
@@ -0,0 +1,96 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "clsx";
import Bubble, { BubbleType } from "./Bubble";
import { BodyLong, BodyShort } from "..";
export interface ChatProps extends HTMLAttributes<HTMLDivElement> {
/**
* Children of type <Chat.Bubble />
*/
children: React.ReactNode;
/**
* Chat-message name
*/
name?: string;
/**
* Timestamp for sent message
*/
timestamp?: string;
/**
* Avatar for messenger. Regular text for initials works to
*/
avatar: React.ReactNode;
/**
* Background color on bubbles
*/
backgroundColor?: string;
/**
* Background color for avatar
*/
avatarBgColor?: string;
/**
* Positions avatar and Bubbles
* @default "left"
*/
position?: "left" | "right";
}
interface ChatComponent
extends React.ForwardRefExoticComponent<
ChatProps & React.RefAttributes<HTMLDivElement>
> {
Bubble: BubbleType;
}
export const Chat = forwardRef<HTMLDivElement, ChatProps>(
(
{
children,
className,
name,
timestamp,
avatar,
position = "left",
avatarBgColor,
backgroundColor,
...rest
},
ref
) => {
return (
<div
ref={ref}
className={cl("navds-chat", className, `navds-chat--${position}`)}
{...rest}
>
<BodyShort
as="div"
className="navds-chat__avatar"
style={{ backgroundColor: avatarBgColor }}
>
{avatar}
</BodyShort>
<ol className="navds-chat__bubble-wrapper">
{React.Children.map(children, (child, i) => {
if (React.isValidElement(child)) {
return (
<BodyLong as="li">
{React.cloneElement(child, {
name: name && i === 0 ? name : undefined,
timestamp: timestamp && i === 0 ? timestamp : undefined,
backgroundColor,
...child.props,
})}
</BodyLong>
);
}
})}
</ol>
</div>
);
}
) as ChatComponent;
Chat.Bubble = Bubble;
export default Chat;
@@ -0,0 +1,198 @@
import React from "react";
import { Chat } from "../index";
import { Meta } from "@storybook/react/types-6-0";
export default {
title: "ds-react/Chat",
component: Chat,
argTypes: {
backgroundColor: {
control: {
type: "text",
},
},
avatarBgColor: {
control: {
type: "text",
},
},
},
} as Meta;
export const Default = (props) => {
return (
<Chat
avatar={props?.avatar ?? "ON"}
name={props?.name ?? "Ola Normann"}
timestamp={props?.timestamp ?? "01.01.21 14:00"}
avatarBgColor={props?.avatarBgColor}
backgroundColor={props?.backgroundColor}
>
<Chat.Bubble>
Aute minim nisi sunt mollit duis sunt nulla minim non proident.
</Chat.Bubble>
<Chat.Bubble>Tempor fugiat amet eu sint in in ullamco.</Chat.Bubble>
<Chat.Bubble>
Adipisicing laborum est eu laborum est sit in commodo enim sint laboris
labore nisi ut.
</Chat.Bubble>
</Chat>
);
};
Default.args = {
name: "Ola Normann",
timestamp: "01.01.21 14:00",
avatar: "ON",
};
export const Farger = () => {
return (
<Chat
avatar={"ON"}
name={"Ola Normann"}
timestamp={"01.01.21 14:00"}
avatarBgColor={"var(--navds-global-color-lightblue-200)"}
backgroundColor={"var(--navds-global-color-lightblue-100)"}
>
<Chat.Bubble>
Aute minim nisi sunt mollit duis sunt nulla minim non proident.
</Chat.Bubble>
<Chat.Bubble>Tempor fugiat amet eu sint in in ullamco.</Chat.Bubble>
<Chat.Bubble>
Adipisicing laborum est eu laborum est sit in commodo enim sint laboris
labore nisi ut.
</Chat.Bubble>
</Chat>
);
};
export const Position = () => {
return (
<div className="colgap">
<Chat
avatar={"ON"}
name={"Ola Normann"}
timestamp={"01.01.21 14:00"}
backgroundColor="rgba(255, 249, 240, 1)"
avatarBgColor="rgba(255, 236, 204, 1)"
>
<Chat.Bubble>
Adipisicing laborum est eu laborum est sit in commodo enim sint
laboris labore nisi ut.
</Chat.Bubble>
</Chat>
<Chat
avatar={"KH"}
name={"Kari Høyli"}
timestamp={"01.01.21 14:32"}
position="right"
backgroundColor="rgba(230, 240, 255, 1)"
avatarBgColor="rgba(204, 225, 255, 1)"
>
<Chat.Bubble>
Reprehenderit pariatur officia exercitation laboris.
</Chat.Bubble>
<Chat.Bubble>
Enim velit deserunt do quis. Eu fugiat magna esse dolore ad sunt sit
est dolore incididunt. Occaecat cupidatat magna.
</Chat.Bubble>
</Chat>
<Chat
avatar={"ON"}
name={"Ola Normann"}
timestamp={"01.01.21 15:00"}
backgroundColor="rgba(255, 249, 240, 1)"
avatarBgColor="rgba(255, 236, 204, 1)"
>
<Chat.Bubble>
Exercitation irure Lorem cupidatat culpa anim cillum esse ullamco qui
dolore laborum et Lorem. Labore sunt duis id Lorem voluptate commodo
ea esse. Dolore esse aliqua proident ea ad commodo ut dolore voluptate
labore sunt aute.
</Chat.Bubble>
</Chat>
</div>
);
};
export const Avatar = () => {
return (
<Chat avatar={<Illustration />} timestamp={"01.01.21 14:00"}>
<Chat.Bubble>
Aute minim nisi sunt mollit duis sunt nulla minim non proident.
</Chat.Bubble>
<Chat.Bubble>Tempor fugiat amet eu sint in in ullamco.</Chat.Bubble>
<Chat.Bubble>
Adipisicing laborum est eu laborum est sit in commodo enim sint laboris
labore nisi ut.
</Chat.Bubble>
</Chat>
);
};
const Illustration = () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 93">
<path
fill="#e7e5e2"
d="M14 50.7C15 52.3 17.9 81 26.5 81S39 51.8 39 50.3c-13.2-7.6-25 .4-25 .4z"
/>
<path
fill="#5c4378"
d="M38.7 50.2c6 2.9 15.3 10.9 15.3 18.3V93H0V68.5c0-7.1 8.5-14.8 14.5-18-.3.2-.5.3-.5.3 1 1.7 3.8 9.2 12.4 9.2C35 60 39 51.9 39 50.4c-.1-.1-.2-.2-.3-.2z"
/>
<path
fill="#d2242a"
d="M46.7 76H31.2c-.7 0-1.3-.6-1.2-1.3v-8.5c0-.7.6-1.3 1.3-1.3h15.5c.7 0 1.3.6 1.3 1.3v8.5c-.1.7-.7 1.3-1.4 1.3"
/>
<path
fill="#fff"
d="M42.9 71c0 2.1-1.7 3.8-3.8 3.8-2.1 0-3.8-1.7-3.8-3.8s1.7-3.8 3.8-3.8c2.1 0 3.8 1.7 3.8 3.8m-8.7 1.7h-.7l.8-1.9h.7l-.8 1.9zm9.3 0H43l.8-1.9h.5l-.8 1.9zm1.2 0h-.2l.8-1.9h.2l-.8 1.9z"
/>
<path
fill="#c52d35"
d="M36.2 72.7h.6s.1 0 .1-.1v-1.8s0-.1-.1-.1h-.6s-.1 0-.1.1l-.2.6v.1h.2l.1 1.2c0-.1 0 0 0 0"
/>
<path
fill="#c52d35"
d="M37.5 72.7h.6s.1 0 .1-.1v-1.8s0-.1-.1-.1h-.9s-.1 0-.1.1l-.2.6-.1.1h.5c.1 0 .2.1.2.2v1c-.1-.1-.1 0 0 0m2.6-1.9h-.6s-.1 0-.1.1v1.8s0 .1.1.1h.6s.1 0 .1-.1l.2-.6V72h-.2l-.1-1.2"
/>
<path
fill="#c52d35"
d="M37.7 72.7h.4s.1 0 .1-.1l.2-.6v-.1h-.2c0 .1-.5.8-.5.8zm3.9-1.9h.7s.1 0 0 .1l-.7 1.8H41l.6-1.9"
/>
<path
fill="#c52d35"
d="M40.8 70.8h-1c-.1 0 .3.1.3.1l.7 1.7s0 .1.1.1h.6l-.7-1.9m-1.3.6v.4s-.1-.4-.3-.4c-.3 0-.3.2-.3.3 0 .1.1.3.2.3h.5l-.3.7H39c-.2 0-.9-.3-.9-.9 0-.6.5-1 .9-1 .2-.1.5.2.5.6 0-.1 0-.1 0 0z"
/>
<path
fill="#5a1f57"
d="M39.9 66.7h-1.6c-.1 0-.2-.1-.2-.2v-.3c0-.1.1-.2.2-.2h1.6c.1 0 .2.1.2.2v.3c0 .2-.1.2-.2.2"
/>
<path fill="#c2b5cf" d="M38.7 66.5h.9V64h-.9v2.5z" />
<path
fill="#e7e5e2"
d="M47.2 35.3C44.7 45.6 36.6 53.1 27 53.1S9.3 45.6 6.8 35.3c-.2.1-.5.1-.8.1-1.1 0-2-.8-2-1.7v-7c0-1 .9-1.7 2-1.7h.2C7.7 13.1 16.4 4 27 4c10.6 0 19.3 9.1 20.8 21h.2c1.1 0 2 .8 2 1.7v7c0 1-.9 1.7-2 1.7-.3 0-.5 0-.8-.1z"
/>
<path
fill="#635e59"
d="M19 27.6c-1.4.1-1.9-2-1.4-3.4.1-.3.6-1.5 1.4-1.5.8 0 1.2.7 1.3.8.6 1.4.3 4-1.3 4.1m16.2 0c1.4.1 1.9-2 1.4-3.4-.1-.3-.6-1.5-1.4-1.5-.8 0-1.2.7-1.3.8-.6 1.4-.3 4 1.3 4.1"
/>
<path
fill="#d1bfa3"
d="M26.8 34.6c-.4 0-.7-.1-1-.2-.3-.1-.4-.4-.3-.7.1-.3.4-.4.7-.3.5.2 1.5.1 2.2-.4.7-.4 1.1-1 1.2-1.5.1-.4-.1-.9-.4-1.3-.2-.2-.8-.2-1.6-.1-.3 0-.5-.1-.6-.4 0-.3.1-.5.4-.6 1.2-.2 2.1 0 2.6.6.5.7.8 1.4.6 2.1-.1.8-.7 1.6-1.7 2.2-.6.3-1.4.6-2.1.6z"
/>
<path
fill="#593a32"
d="M27.1 42.1h-.3c-5.3-.2-7.3-4.1-7.4-4.3-.1-.3 0-.6.2-.7.2-.1.6 0 .7.2.1.1 1.9 3.6 6.6 3.8 4.7.2 6.4-3.7 6.4-3.7.1-.3.4-.4.7-.3.3.1.4.4.3.7-.1 0-2.1 4.3-7.2 4.3z"
/>
<path
fill="#f6b873"
d="M6.6 30.7c.1-.1.1-.2.1-.3v-2c-.1-5.6 1.8-8.1 3.4-10.1 0 0-1 4.3-.3 3.4 3.8-5 21.4-1.6 25-8.1.5 3.6-4.1 4.6-4.1 4.6 3.7.7 6.9-.8 7.7-2.5.3 1.4-.6 2.4-1.9 3.4 4.5-.9 4.6-4 4.6-4 .6 4.1 5.3 2.5 5.3 9.3v6c0 .3.2.6.5.6h.5c.3 0 .5-.3.5-.6V26c.3-15.6-8.5-26-20.6-26C15.9 0 5 10.4 5 24.1v6.3c0 .4.2.6.5.6h.6c.2 0 .3-.1.5-.3"
/>
<path
fill="#f6b873"
d="M25.9 43.4c-4.4 0-8-1.4-8-3.2s3.6-3.2 8-3.2 8 1.4 8 3.2c0 1.8-3.6 3.2-8 3.2m.8-9.4c-2.9 0-4.7.7-8.8 2.1-12.7 4.6-11.6-14-11.6-14C3.4 46 18.6 52 26.5 52c8.1 0 24.1-8.1 21-30 0 0 .4 17.1-12.9 13.8-3.7-.9-5-1.8-7.9-1.8z"
/>
</svg>
);
+1
View File
@@ -0,0 +1 @@
export { default as Chat, ChatProps } from "./Chat";
@@ -1,5 +1,5 @@
import cl from "classnames";
import React, { forwardRef } from "react";
import cl from "clsx";
import { BodyLong, Checkbox, CheckboxProps, ErrorMessage } from "..";
import { useFormField } from "./useFormField";
@@ -27,7 +27,7 @@ export interface ConfirmationPanelProps
}
export const ConfirmationPanel = forwardRef<
HTMLDivElement,
HTMLInputElement,
ConfirmationPanelProps
>(({ className, children, label, ...props }, ref) => {
const { errorId, showErrorMsg, hasError, size, inputProps } = useFormField(
@@ -37,7 +37,6 @@ export const ConfirmationPanel = forwardRef<
return (
<div
ref={ref}
className={cl("navds-confirmation-panel", "navds-form-field", className, {
"navds-confirmation-panel--small": size === "small",
"navds-confirmation-panel--error": hasError,
@@ -53,7 +52,13 @@ export const ConfirmationPanel = forwardRef<
{children}
</BodyLong>
)}
<Checkbox {...props} {...inputProps} error={hasError} size={size}>
<Checkbox
ref={ref}
{...props}
{...inputProps}
error={hasError}
size={size}
>
{label}
</Checkbox>
</div>
@@ -1,6 +1,6 @@
import cl from "classnames";
import cl from "clsx";
import React, { FieldsetHTMLAttributes, forwardRef, useContext } from "react";
import { BodyShort, Detail, Label, ErrorMessage, omit } from "../..";
import { BodyLong, Detail, Label, ErrorMessage, omit } from "../..";
import { FormFieldProps } from "../useFormField";
import { useFieldset } from "./useFieldset";
@@ -106,7 +106,7 @@ export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
</Label>
{!!description &&
(size === "medium" ? (
<BodyShort
<BodyLong
className={cl("navds-fieldset__description", {
"navds-sr-only": !!hideLegend,
})}
@@ -115,7 +115,7 @@ export const Fieldset = forwardRef<HTMLFieldSetElement, FieldsetProps>(
as="div"
>
{props.description}
</BodyShort>
</BodyLong>
) : (
<Detail
className={cl("navds-fieldset__description", {
+4 -5
View File
@@ -1,7 +1,7 @@
import React, { forwardRef, SelectHTMLAttributes } from "react";
import cl from "classnames";
import cl from "clsx";
import { Expand } from "@navikt/ds-icons";
import { BodyShort, Label, ErrorMessage, omit, Detail } from "..";
import { BodyLong, Label, ErrorMessage, omit, Detail } from "..";
import { FormFieldProps, useFormField } from "./useFormField";
export interface SelectProps
@@ -66,7 +66,6 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
<Label
htmlFor={inputProps.id}
size={size}
as="label"
className={cl("navds-form-field__label", {
"navds-sr-only": hideLabel,
})}
@@ -76,7 +75,7 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
{!!description && (
<>
{size === "medium" ? (
<BodyShort
<BodyLong
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
@@ -85,7 +84,7 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
as="div"
>
{description}
</BodyShort>
</BodyLong>
) : (
<Detail
className={cl("navds-form-field__description", {
+1 -1
View File
@@ -1,4 +1,4 @@
import cl from "classnames";
import cl from "clsx";
import React, {
forwardRef,
InputHTMLAttributes,
+6 -7
View File
@@ -1,6 +1,6 @@
import React, { forwardRef, InputHTMLAttributes } from "react";
import cl from "classnames";
import { BodyShort, Detail, Label, ErrorMessage, omit } from "..";
import cl from "clsx";
import { BodyLong, Detail, Label, ErrorMessage, omit } from "..";
import { FormFieldProps, useFormField } from "./useFormField";
export interface TextFieldProps
@@ -9,11 +9,11 @@ export interface TextFieldProps
/**
* Controlled value
*/
value?: string;
value?: string | number;
/**
* Defaults input-value without needing controlled-state
*/
defaultValue?: string;
defaultValue?: string | number;
/**
* Exposes the HTML size attribute
*/
@@ -70,7 +70,6 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
<Label
htmlFor={inputProps.id}
size={size}
as="label"
className={cl("navds-form-field__label", {
"navds-sr-only": hideLabel,
})}
@@ -81,7 +80,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
{!!description && (
<>
{size === "medium" ? (
<BodyShort
<BodyLong
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
@@ -90,7 +89,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
as="div"
>
{description}
</BodyShort>
</BodyLong>
) : (
<Detail
className={cl("navds-form-field__description", {
+13 -12
View File
@@ -1,9 +1,9 @@
import React, { forwardRef, useState } from "react";
import cl from "classnames";
import TextareaAutosize from "@material-ui/core/TextareaAutosize";
import { BodyShort, Label, ErrorMessage, omit, Detail } from "..";
import cl from "clsx";
import { BodyShort, BodyLong, Label, ErrorMessage, omit, Detail } from "..";
import { FormFieldProps, useFormField } from "./useFormField";
import { useId } from "..";
import TextareaAutosize from "../util/TextareaAutoSize";
/**
* TODO: Mulighet for lokalisering av sr-only/counter text
@@ -68,7 +68,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
...rest
} = props;
const maxLengthId = `TextareaMaxLength-${useId()}`;
const maxLengthId = useId();
const hasMaxLength = maxLength !== undefined && maxLength > 0;
const [controlledValue, setControlledValue] = useState<string>(
@@ -76,13 +76,17 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
);
const getMinRows = () => {
let rows = rest?.minRows && rest?.minRows >= 3 ? rest?.minRows : 3;
let rows = rest?.minRows ? rest?.minRows : 3;
if (size === "small") {
rows = rest?.minRows && rest?.minRows >= 2 ? rest?.minRows : 2;
rows = rest?.minRows ? rest?.minRows : 2;
}
return rows;
};
const describedBy = cl(inputProps["aria-describedby"], {
[maxLengthId ?? ""]: hasMaxLength,
});
return (
<div
className={cl(
@@ -99,7 +103,6 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
<Label
htmlFor={inputProps.id}
size={size}
as="label"
className={cl("navds-form-field__label", {
"navds-sr-only": hideLabel,
})}
@@ -109,7 +112,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
{!!description && (
<>
{size === "medium" ? (
<BodyShort
<BodyLong
className={cl("navds-form-field__description", {
"navds-sr-only": hideLabel,
})}
@@ -118,7 +121,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
as="div"
>
{description}
</BodyShort>
</BodyLong>
) : (
<Detail
className={cl("navds-form-field__description", {
@@ -152,9 +155,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
"navds-textarea--counter": hasMaxLength,
}
)}
aria-describedby={cl(inputProps["aria-describedby"], {
[maxLengthId]: hasMaxLength,
})}
{...(describedBy ? { "aria-describedby": describedBy } : {})}
/>
{hasMaxLength && (
<>
@@ -1,6 +1,5 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { act, fireEvent, render, screen } from "@testing-library/react";
import faker from "faker";
import { Checkbox, CheckboxGroup } from ".";
@@ -15,9 +14,8 @@ test("checkbox group chains onChange calls", async () => {
const onChange = jest.fn();
const value = faker.datatype.string();
const label = faker.datatype.string();
const user = userEvent.setup();
render(
const { getByLabelText } = render(
<CheckboxGroup legend="legend" onChange={onGroupChange}>
<Checkbox onChange={onChange} value={value}>
{label}
@@ -25,7 +23,9 @@ test("checkbox group chains onChange calls", async () => {
</CheckboxGroup>
);
await user.click(screen.getByLabelText(label));
await act(async () => {
fireEvent.click(getByLabelText(label));
});
expect(onGroupChange).toBeCalledTimes(1);
expect(onGroupChange).toBeCalledWith([value]);
@@ -42,10 +42,14 @@ describe("Checkbox handles controlled-state correctly", () => {
);
test("Checkbox is still checked after click when controlled", async () => {
const user = userEvent.setup();
render(<CheckboxComponent value={["value1", "value2"]} />);
await user.click(screen.getByLabelText("label1"));
await user.click(screen.getByLabelText("label2"));
const { getByLabelText } = render(
<CheckboxComponent value={["value1", "value2"]} />
);
await act(async () => {
fireEvent.click(getByLabelText("label1"));
fireEvent.click(getByLabelText("label2"));
});
expect((screen.getByLabelText("label1") as HTMLInputElement).checked).toBe(
true
@@ -58,22 +62,21 @@ describe("Checkbox handles controlled-state correctly", () => {
test("onChange called with expected values", async () => {
const onGroupChange = jest.fn();
const user = userEvent.setup();
render(
const { getByLabelText } = render(
<CheckboxComponent
onChange={onGroupChange}
value={["value1", "value2"]}
/>
);
await user.click(screen.getByLabelText("label1"));
await act(async () => {
fireEvent.click(getByLabelText("label1"));
expect(onGroupChange).lastCalledWith(["value2"]);
expect(onGroupChange).lastCalledWith(["value2"]);
await user.click(screen.getByLabelText("label2"));
expect(onGroupChange).lastCalledWith(["value1"]);
fireEvent.click(getByLabelText("label2"));
expect(onGroupChange).lastCalledWith(["value1"]);
});
});
test("Checkboxes updates after value-prop change", () => {
@@ -1,5 +1,5 @@
import React, { forwardRef, InputHTMLAttributes } from "react";
import cl from "classnames";
import cl from "clsx";
import useCheckbox from "./useCheckbox";
import { FormFieldProps } from "../useFormField";
import { BodyShort, Detail, omit } from "../..";
@@ -84,24 +84,24 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
}}
/>
<label htmlFor={inputProps.id} className="navds-checkbox__label">
<div
<span
className={cl("navds-checkbox__content", {
"navds-sr-only": props.hideLabel,
})}
>
<BodyShort as="div" size={size}>
<BodyShort as="span" size={size}>
{props.children}
</BodyShort>
{props.description && (
<Description
as="div"
as="span"
size="small"
className="navds-checkbox__description"
>
{props.description}
</Description>
)}
</div>
</span>
</label>
</div>
);
@@ -1,5 +1,5 @@
import React, { createContext, forwardRef, useContext, useState } from "react";
import cl from "classnames";
import cl from "clsx";
import { Fieldset, FieldsetProps, FieldsetContext } from "..";
export interface CheckboxGroupState {
@@ -8,6 +8,9 @@ export default {
subcomponents: {
CheckboxGroup,
},
argTypes: {
size: { control: { type: "select", options: ["medium", "small"] } },
},
} as Meta;
export const Default = (props) => {
@@ -22,7 +25,7 @@ export const Default = (props) => {
onChange={props.controlled ? setState : undefined}
hideLegend={props.hideLegend}
error={props.errorGroup ? "Errormelding for checkboxgruppe" : undefined}
{...props}
size={props?.size}
>
<Checkbox
value="checkbox1"
@@ -1,5 +1,5 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import cl from "clsx";
import { Heading, BodyShort } from "../..";
import ErrorSummaryItem, { ErrorSummaryItemType } from "./ErrorSummaryItem";
import { useId } from "../../util";
@@ -58,13 +58,13 @@ export const ErrorSummary = forwardRef<HTMLDivElement, ErrorSummaryProps>(
tabIndex={-1}
aria-live="polite"
aria-relevant="all"
aria-labelledby={`error-summary-${headingId}`}
aria-labelledby={headingId}
>
<Heading
className="navds-error-summary__heading"
as={headingTag}
size="small"
id={`error-summary-${headingId}`}
id={headingId}
>
{heading}
</Heading>
@@ -1,5 +1,5 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import cl from "clsx";
import { OverridableComponent } from "../..";
export interface ErrorSummaryItemProps
+5 -5
View File
@@ -1,5 +1,5 @@
import React, { forwardRef, InputHTMLAttributes } from "react";
import cl from "classnames";
import cl from "clsx";
import { BodyShort, Detail, omit } from "../..";
import { FormFieldProps } from "../useFormField";
import { useRadio } from "./useRadio";
@@ -40,20 +40,20 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>((props, ref) => {
ref={ref}
/>
<label htmlFor={inputProps.id} className="navds-radio__label">
<div className="navds-radio__content">
<BodyShort as="div" size={size}>
<span className="navds-radio__content">
<BodyShort as="span" size={size}>
{props.children}
</BodyShort>
{props.description && (
<Description
as="div"
as="span"
size="small"
className="navds-radio__description"
>
{props.description}
</Description>
)}
</div>
</span>
</label>
</div>
);
@@ -1,5 +1,5 @@
import React, { forwardRef, useContext } from "react";
import cl from "classnames";
import cl from "clsx";
import { Fieldset, FieldsetContext, FieldsetProps } from "..";
import { useId } from "../..";
@@ -8,6 +8,9 @@ export default {
subcomponents: {
RadioGroup,
},
argTypes: {
size: { control: { type: "select", options: ["medium", "small"] } },
},
} as Meta;
export const Default = (props) => {
@@ -21,7 +24,7 @@ export const Default = (props) => {
onChange={props.controlled ? setState : undefined}
hideLegend={props.hideLegend}
error={props.errorGroup ? "Errormelding" : undefined}
{...props}
size={props?.size}
>
<Radio value="radio1">{props.children || "Apple"}</Radio>
<Radio
@@ -38,6 +41,7 @@ export const Default = (props) => {
Default.args = {
controlled: false,
size: "medium",
legend: "Legend-tekst",
radioDescription: false,
hideLegend: false,
+11 -5
View File
@@ -1,14 +1,21 @@
import { Close, Search as SearchIcon } from "@navikt/ds-icons";
import cl from "classnames";
import cl from "clsx";
import React, {
forwardRef,
InputHTMLAttributes,
useCallback,
useMemo,
useRef,
useState,
} from "react";
import mergeRefs from "react-merge-refs";
import { BodyShort, ErrorMessage, Label, omit, useEventListener } from "../..";
import {
BodyShort,
ErrorMessage,
Label,
mergeRefs,
omit,
useEventListener,
} from "../..";
import { FormFieldProps, useFormField } from "../useFormField";
import SearchButton, { SearchButtonType } from "./SearchButton";
@@ -103,7 +110,7 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
} = props;
const searchRef = useRef<HTMLInputElement | null>(null);
const mergedRef = mergeRefs([searchRef, ref]);
const mergedRef = useMemo(() => mergeRefs([searchRef, ref]), [ref]);
const [wrapperRef, setWrapperRef] = useState<HTMLDivElement | null>(null);
const [internalValue, setInternalValue] = useState(defaultValue ?? "");
@@ -156,7 +163,6 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
<Label
htmlFor={inputProps.id}
size={size}
as="label"
className={cl("navds-form-field__label", {
"navds-sr-only": hideLabel,
})}
@@ -1,5 +1,5 @@
import { Search } from "@navikt/ds-icons";
import cl from "classnames";
import cl from "clsx";
import React, { forwardRef, useContext } from "react";
import { Button, ButtonProps } from "../..";
import { SearchContext } from "./Search";
@@ -7,7 +7,7 @@ import { SearchContext } from "./Search";
export interface SearchButtonProps
extends Omit<ButtonProps, "size" | "children" | "variant"> {
/**
* Text set before <Search/> icon
* Text set after <Search/> icon
*/
children?: React.ReactNode;
}
@@ -36,9 +36,13 @@ const SearchButton: SearchButtonType = forwardRef(
variant={variant === "secondary" ? "secondary" : "primary"}
className={cl("navds-search__button-search", className)}
disabled={context?.disabled ?? disabled}
icon={
<Search
{...(children ? { "aria-hidden": true } : { title: "Søk" })}
/>
}
>
<Search aria-hidden />
{children ? children : <span className="navds-sr-only">Søk</span>}
{children}
</Button>
);
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { useContext } from "react";
import cl from "classnames";
import cl from "clsx";
import { FieldsetContext } from "./index";
import { useId } from "../index";
+1 -1
View File
@@ -1,5 +1,5 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import cl from "clsx";
type Column = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
export interface CellProps extends HTMLAttributes<HTMLDivElement> {
@@ -1,5 +1,5 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import cl from "clsx";
export interface ContentContainerProps extends HTMLAttributes<HTMLDivElement> {
/**
+1 -1
View File
@@ -1,5 +1,5 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import cl from "clsx";
export interface GridProps extends HTMLAttributes<HTMLDivElement> {
/**
Loaded 100 of 238 files, more files were not shown because too many files have changed in this diff. Show more