Compare commits

...
Author SHA1 Message Date
Ken 36a5ed09af Lerna versionbump [ci skip] 2022-08-18 08:06:11 +02:00
Ken 6f3091d0e8 nextjs eksempel versjoner 2022-08-18 08:05:44 +02:00
Ken 79e4ab9499 la til ds-css-internal css for nextjs-eksempel 2022-08-18 08:04:37 +02:00
Ken e2e7961302 oppdatert ikoner 2022-08-18 07:46:47 +02:00
Ken 722bbcc3cb Oppdatert floating-ui versjon (#1618) 2022-08-18 07:40:07 +02:00
Ken 687e9822d5 yarn lock 2022-08-17 10:43:30 +02:00
Ken a1454ed86f Merge branch 'master' into big-one-oh 2022-08-17 10:42:46 +02:00
Ken 5f71be7678 Oppdatert Label i checkbox/radio til å bruke span (#1617) 2022-08-17 09:42:15 +02:00
Ken b5d7e49d74 Fikset domvalideringsfeil der aria-describedby ikke har noe innhold i textarea 2022-08-17 09:09:48 +02:00
Ken e52394ac6b Lerna versionbump [ci skip] 2022-08-15 07:52:30 +02:00
Ken 189ee1454e css-internal readme typo 2022-08-15 07:51:41 +02:00
Andreas Nordahl f21595afa2 error message as p, plus add overridable and ref 2022-08-10 14:59:08 +02:00
Andreas Nordahl fe24ced90d update lockfile 2022-08-10 10:52:28 +02:00
Andreas Nordahl 1a88d50809 Lerna versionbump [ci skip] 2022-08-10 10:47:31 +02:00
larseirikhansen f9f6a1db44 making readme more beginner friendly (#1612) 2022-08-09 13:34:44 +02:00
larseirikhansen ec88b293c9 restrict children type to string (#1609) 2022-08-09 13:11:31 +02:00
Andreas Nordahl 27456b0187 inline label classes in HeaderCell to avoid Overridable type bug 2022-08-08 16:03:19 +02:00
Martin Berglund 5a207c222e Update description color
radio, checkbox and switch
2022-08-08 14:00:52 +02:00
Martin Berglund 513a1c5a1c Default Label component to label element 2022-08-08 13:53:18 +02:00
Martin Berglund cd2b2fece2 Add size controls to checkbox and radio story 2022-08-08 13:37:24 +02:00
Martin Berglund 2b33e30e54 Replace component for increased line-height 2022-08-08 13:35:44 +02:00
Ken 56d8c26a53 yarn lock sync 2022-07-24 23:58:50 +02:00
Ken 4801a8491a tester props-spread 2022-07-22 13:02:39 +02:00
Ken e943e71637 Lerna versionbump [ci skip] 2022-07-22 11:29:42 +02:00
Ken 41106f6dd3 yarn lock 2022-07-22 11:27:20 +02:00
Ken 40837111c0 fjernet fixed strategy fra copytoclipboard 2022-07-22 11:19:35 +02:00
Ken 999cc95310 codemod cli 2022-07-20 14:15:48 +02:00
Ken 93d59968f2 Lerna versionbump [ci skip] 2022-07-20 14:06:51 +02:00
Ken 70b6beed75 alle build-filer med i codemod 2022-07-20 14:04:55 +02:00
Ken 9102781d5c Lerna versionbump [ci skip] 2022-07-20 13:49:42 +02:00
Ken 4405c89d5f la til riktige transforms i codemod 2022-07-20 13:46:38 +02:00
Ken 309cd0fba3 fikset readme 2022-07-20 13:43:20 +02:00
Ken 5f1ca61501 Lerna versionbump [ci skip] 2022-07-20 13:16:20 +02:00
Ken a75622752e fikset pagination prop-error 2022-07-20 13:08:04 +02:00
Ken 62a00f745c fikset pagination codemod 2022-07-20 12:43:57 +02:00
Ken 7b946d76ac Merge branch 'master' into big-one-oh 2022-07-20 12:22:02 +02:00
Ken 0e42521c90 oppdatert gap button xsmall 2022-07-08 14:06:18 +02:00
Ken 95e5891b27 yarn lock 2022-07-08 13:16:56 +02:00
Ken 9230adaa89 Animert expandableRow 2022-07-08 13:15:39 +02:00
Ken 1885f0e935 Lokal versjon av react-animate-height (#1603) 2022-07-08 12:55:43 +02:00
Ken c718348749 Merge branch 'master' into big-one-oh 2022-07-08 10:55:09 +02:00
Andreas NordahlandKen 2166a7933f read more 1.0 (#1601)
* read more 1.0

* fikset small readmore

* fjernet ubrukt css

Co-authored-by: Ken <ken.aleksander@gmail.com>
2022-07-08 10:50:23 +02:00
Andreas Nordahl 70ba56e218 confirmation panel input ref (#1602) 2022-07-08 10:33:36 +02:00
69a21190b0 Button 1.0 (#1600)
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
Co-authored-by: Ken <ken.aleksander@gmail.com>
2022-07-08 10:32:07 +02:00
Andreas Nordahl 72c52f6cda remove renderContentWhenClosed prop (#1593)
* remove renderContentWhenClosed prop

* fix default controlled accordion story
2022-07-06 13:38:26 +02:00
Andreas Nordahl ae297ee3fd Merge branch 'master' into big-one-oh 2022-07-04 15:22:22 +02:00
Andreas Nordahl e3ce3d0a28 Merge branch 'master' into big-one-oh 2022-07-04 11:03:41 +02:00
Ken d4cf0d2b1e yarn lock 2022-07-01 14:07:45 +02:00
Ken 60f1397043 Lerna versionbump [ci skip] 2022-07-01 13:43:45 +02:00
Ken 4d78c35ec2 yarn lock 2022-07-01 13:40:43 +02:00
Ken 343fd910a8 Merge branch 'master' into big-one-oh 2022-07-01 13:40:19 +02:00
Ken 86c3545fb7 codemod readme 2022-07-01 13:39:29 +02:00
Ken f1341c6666 la til readmes 2022-07-01 13:13:47 +02:00
Ken 0949ba0b56 publishaccess 2022-07-01 12:41:12 +02:00
Ken 2ae9f382fb Lerna versionbump [ci skip] 2022-07-01 12:34:07 +02:00
Ken 95476ff04e codemod-versjon 2022-07-01 12:28:55 +02:00
Ken 12be3f9ba6 yarn lock 2022-07-01 12:26:54 +02:00
Ken 9d00cecc92 Merge branch 'master' into big-one-oh 2022-07-01 12:25:58 +02:00
Ken 755fd0cf3c Helptext figma-sync (#1586) 2022-06-30 16:22:11 +02:00
Ken 9295bda19d fjernet console.logs 2022-06-30 13:14:11 +02:00
Ken 2688b488e5 fikset bruk av mergeRefs i ds 2022-06-30 13:11:57 +02:00
Ken 6aacf70c3d fikset tooltip-infinite render bug 2022-06-30 13:09:27 +02:00
Ken d211a06f5f fikset checkbox tester 2022-06-30 09:52:29 +02:00
Ken e8ea9a8e34 Oppdatert small alert, banner -> fullWidth prop (#1584) 2022-06-30 09:36:03 +02:00
Ken 7fef4d5ef8 Merge branch 'master' into big-one-oh 2022-06-29 14:23:15 +02:00
Ken a7f04b4902 Erstattet "classnames" med "clsx" (#1577) 2022-06-29 10:31:40 +02:00
Ken e0fa04930d synced yarn lock 2022-06-24 09:17:47 +02:00
Ken 57cea8cb6d Merge branch 'master' into big-one-oh 2022-06-24 09:17:27 +02:00
Ken 1884c6345b Migrert popover og tooltip til floating-ui (#1571)
* oppdatert tooltip

* oppdatert popover

* fikset helptext popover

* fjernet popperjs

* yarn lock

* fikset ssr popover

* fjernet react-dom versjon for floating-ui

* fjernet bruk av placement type

* tooltip-tester

* tooltip-tester

* fikset popover outside-click

* render popover/tooltip with styles

* fjernet gamle tester

* focus-loss test for tooltip

* migration

* forsøk på react types fix

* ryddet opp i storybook

* tester å fjerne react-collapse typer

* type-install

* react-dom versjon

* gjorde types-react optional som peer

* yarn lock
2022-06-24 09:16:53 +02:00
Ken cb962e0332 Update Migrering-v1.md 2022-06-22 11:35:51 +02:00
Ken b246578fe9 yarn lock 2022-06-21 19:38:27 +02:00
Ken 1d42e573bf Merge branch 'master' into big-one-oh 2022-06-21 19:38:16 +02:00
Ken 1eea43c36f Merge branch 'master' into big-one-oh 2022-06-20 13:07:35 +02:00
Ken 6fe7227345 Merge branch 'master' into big-one-oh 2022-06-17 10:55:20 +02:00
Ken 362c8991c9 migration-guide 2022-06-17 10:54:32 +02:00
Ken 204bc1e010 [FIX] Alert synket med Figma (#1570)
* alert fullWidth -> banner

* fikset styling spacing
2022-06-17 10:49:51 +02:00
Kenandgithub-actions[bot] 7ac379364e Oppdatert useId og TextareaAutoSize (#1568)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-16 21:08:16 +02:00
Ken cff48a3c47 Merge branch 'master' into big-one-oh 2022-06-16 12:22:07 +02:00
Ken a8c4aa785f Merge branch 'master' into big-one-oh 2022-06-16 11:32:14 +02:00
Ken aebbaef65e textarea example 2022-06-15 23:34:08 +02:00
Ken 5009beddb0 textareaautosize 2022-06-15 23:28:52 +02:00
Ken 7247c19b15 textareaautosize 2022-06-15 22:36:19 +02:00
Ken 8e8d8a093f Merge branch 'master' into big-one-oh 2022-06-15 21:56:24 +02:00
Kenandgithub-actions[bot] 08bd97cfa1 Dependency updates for react-18 (#1567)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-15 21:55:31 +02:00
Ken cd80f303c8 Merge branch 'master' into big-one-oh 2022-06-15 15:38:44 +02:00
Ken 23a32607e7 grid stories 2022-06-14 20:10:16 +02:00
Ken 15a7ae44d4 Merge branch 'master' into big-one-oh 2022-06-14 19:54:14 +02:00
Ken 6e6d052283 header stories 2022-06-14 19:23:25 +02:00
Ken 0d8a35350b dropdown story 2022-06-14 18:57:12 +02:00
Ken 9bc50d4775 copytoclipboard stories 2022-06-14 18:51:39 +02:00
Ken 4bac85e5e2 Merge branch 'master' into big-one-oh 2022-06-14 13:22:48 +02:00
Ken 9868c49c37 Merge branch 'master' into big-one-oh 2022-06-14 10:13:19 +02:00
Ken 077454002c Merge branch 'master' into big-one-oh 2022-06-14 09:46:15 +02:00
Ken bc423af462 table-stories 2022-06-13 16:00:32 +02:00
Ken a009536b79 linkpanel stories 2022-06-13 15:52:55 +02:00
Ken c7735d179d guidepanel stoies 2022-06-13 15:48:17 +02:00
Ken 390e8ffd33 lint-fix 2022-06-13 15:40:54 +02:00
Ken 422d4548c5 fjernet shadow-card token 2022-06-13 15:40:29 +02:00
Ken f74b35a69a Fjernet StepindIcator fra kodebase (erstattes av Stepper) (#1559) 2022-06-13 15:37:12 +02:00
Ken 69497cad51 Fjernet navno pakker (#1557) 2022-06-13 15:33:45 +02:00
Ken 0e02a74089 migreringsguide 2022-06-13 15:33:23 +02:00
Ken 852d859f93 Fjernet Menu (#1556) 2022-06-13 15:29:43 +02:00
Ken 99fed38942 Merge branch 'master' into big-one-oh 2022-06-13 15:09:38 +02:00
Ken 1fbe799a56 Merge branch 'master' into big-one-oh 2022-06-13 12:07:27 +02:00
Ken 2b5527cbb3 yarn lock 2022-06-13 12:06:33 +02:00
Ken 88e951fa8c Merge branch 'master' into big-one-oh 2022-06-13 12:06:20 +02:00
Ken cd22e3e682 migreringsguide 2022-06-13 08:45:51 +02:00
Ken 4d28da3aa4 Oppdatert SpeechBubble API og styling (#1549) 2022-06-13 08:38:48 +02:00
Ken 51ed62741c yarn lock 2022-06-10 20:14:14 +02:00
Ken 560a1dc96d Merge branch 'master' into big-one-oh 2022-06-10 20:13:49 +02:00
KenandAndreas Nordahl 0fc11d8e88 Pagination (#1459)
* la til forwardref

* gjør forrige/neste usynlig

* large versjon

* sync pagination

* render pagination item as link

* types n stuff

* bump border radius on medium items

* update yarn.lock

* update yarn.lock

* oppdatert stories

* optional onpagechange

Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
2022-06-10 15:25:09 +02:00
Ken 4b0505164f git merge master 2022-06-09 16:48:20 +02:00
Ken 02d7b89d2b Samversjonering (#1543) 2022-06-08 12:27:05 +02:00
Ken e38b4f87ed Merge branch 'master' into big-one-oh 2022-06-08 11:50:41 +02:00
Andreas Nordahl 7bf8900e0f oopsie 2022-06-07 11:11:13 +02:00
Andreas Nordahl 5337f2f716 add chromatic pr for big-one-oh (#1537) 2022-06-07 11:09:17 +02:00
Ken d4eae9ce0b [BREAKING] Oppdatert Tabs (#1536) 2022-06-07 11:05:19 +02:00
Ken e12f49660f Merge branch 'master' into big-one-oh 2022-06-07 10:42:32 +02:00
Andreas Nordahl 6e4716ef3e make divider internal to dropdown (#1534) 2022-06-03 14:42:19 +02:00
218 changed files with 5033 additions and 5770 deletions

No files matched your search

+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: {
+1 -1
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: "",
},
},
+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.0.0",
"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)
-4
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;
}
-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;
+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-muted);
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;
-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
View File
@@ -37,7 +37,6 @@
resize: none;
width: 100%;
display: block;
min-height: 48px;
color: var(--navds-text-field-color-text);
}
+19 -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,36 @@
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);
--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.29",
"version": "1.0.0",
"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.8",
"@navikt/ds-tokens": "^1.0.0",
"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;
}
+1 -2
View File
@@ -224,8 +224,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;
-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)
+24
View File
@@ -1955,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.20",
"version": "1.0.0",
"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",
+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

+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.27",
"version": "1.0.0",
"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.20",
"@popperjs/core": "^2.10.1",
"@radix-ui/react-tabs": "^1.0.0",
"@radix-ui/react-toggle-group": "^1.0.0",
"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.0.0",
"@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,202 @@
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 />}
name={"Ola Normann"}
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,
+4 -5
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
@@ -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> {
/**
@@ -0,0 +1,68 @@
import * as React from "react";
import { BodyLong } from "../..";
import { Grid, Cell, ContentContainer } from "../index";
export default {
title: "ds-react/Grid",
component: { Grid, Cell },
parameters: {
layout: "fullscreen",
},
};
export const Default = () => {
return (
<>
<ContentContainer>
<span>
Grid har ikke blitt oppdatert siden 2020 og vil på sikt få større
endringer eller deprecates. Vi anbefaler derfor å ikke ta vår
grid-løsning i bruk for nå.
</span>
<Grid>
<Cell className="cell" xs={12} sm={6} lg={4}>
Kolonne
</Cell>
<Cell className="cell" xs={12} sm={6} lg={4}>
Kolonne
</Cell>
<Cell className="cell" xs={12} sm={12} lg={4}>
Kolonne
</Cell>
</Grid>
<style>{`.cell {padding: 1rem; background: repeating-linear-gradient(
45deg,
#d6d6d6,
#d6d6d6 10px,
transparent 10px,
transparent 20px
);}`}</style>
</ContentContainer>
</>
);
};
export const Contentcontainer = () => {
return (
<>
<ContentContainer className="container">
<BodyLong size="medium">-- Innhold --</BodyLong>
</ContentContainer>
<style>{`.container {
display: flex;
border-radius: var(--navds-border-radius-medium);
justify-content: center;
align-items: center;
margin-bottom: 1.5rem;
min-height: 10rem;
background: repeating-linear-gradient(
45deg,
#d6d6d6,
#d6d6d6 10px,
transparent 10px,
transparent 20px
);
}`}</style>
</>
);
};
@@ -1,79 +0,0 @@
import { Meta, Canvas } from "@storybook/addon-docs";
import { Grid, Cell } from "../../index";
<Meta title="ds-react/grid/intro" />
# Hvordan ta i bruk Grid
```jsx
<ContentContainer>
<Grid>
<Cell xs={12} sm={6} lg={4}>
Kolonne
</Cell>
<Cell xs={12} sm={6} lg={4}>
Kolonne
</Cell>
<Cell xs={12} sm={12} lg={4}>
Kolonne
</Cell>
</Grid>
</ContentContainer>
```
### ContentContainer
Denne fungerer som en wrapper som sentrer innholdet og passer på at anbefalt maksbredde ikke blir overskredet.
Stylingen som blir satt av den:
```css
.navds-content-container {
margin-left: auto;
margin-right: auto;
max-width: 79.5rem; # (1272px)
padding: var(--navds-spacing-4); # 1rem
}
@media (min-width: 448px) {
.navds-content-container {
padding: var(--navds-spacing-6); # 1.5rem
}
}
```
## Bredder
Bredden til hver `Cell` bestemmes av propsene `lg`, `md`, `sm`og `xs`
som respektivt styrer disse breakpointene
```jsx
type Column = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
/**
* Cell columns on width < 448px
*/
xs: Column;
/**
* Cell columns on min-width: 448
*/
sm?: Column;
/**
* Cell columns on min-width: 648
*/
md?: Column;
/**
* Cell columns on min-width: 960px
*/
lg?: Column;
```
Eks `xs={12} lg={4}` vil da si at `Cell` tar opp
4/12 av griddet når `width > 960px` og 12/12 av griddet
når skjermen er `width < 448px`
Griddet er dynamiskt, noe som vil si at griddet altids består av 12 columns
selv om skjermen er 1920px eller 400px. Innholdes "presses" altså sammen.
@@ -1,51 +0,0 @@
import * as React from "react";
import { BodyLong } from "../..";
import { Grid, Cell, ContentContainer } from "../index";
import "./styles.css";
export default {
title: "ds-react/grid",
component: { Grid, Cell },
parameters: {
layout: "fullscreen",
backgrounds: {
default: "NAV gray",
values: [
{
name: "white",
value: "#ffffff",
},
{
name: "NAV gray",
value: "#f1f1f1",
},
],
},
},
};
export const All = () => {
return (
<ContentContainer>
<Grid>
<Cell className={"navds-story-cell"} xs={12} sm={6} lg={4}>
Kolonne
</Cell>
<Cell className={"navds-story-cell"} xs={12} sm={6} lg={4}>
Kolonne
</Cell>
<Cell className={"navds-story-cell"} xs={12} sm={12} lg={4}>
Kolonne
</Cell>
</Grid>
</ContentContainer>
);
};
export const Contentcontainer = () => {
return (
<ContentContainer className={"navds-story-content-container"}>
<BodyLong size="medium">-- Innhold --</BodyLong>
</ContentContainer>
);
};
@@ -1,21 +0,0 @@
.navds-story-cell {
border-radius: var(--navds-border-radius-medium);
background: white;
padding: 1rem;
}
.navds-story-content-container {
display: flex;
border-radius: var(--navds-border-radius-medium);
justify-content: center;
align-items: center;
margin-bottom: 1.5rem;
min-height: 10rem;
background: repeating-linear-gradient(
45deg,
#d6d6d6,
#d6d6d6 10px,
transparent 10px,
transparent 20px
);
}
+1 -1
View File
@@ -1,5 +1,5 @@
import React, { forwardRef, HTMLAttributes } from "react";
import cl from "classnames";
import cl from "clsx";
import { DefaultIllustration } from "./Illustration";
export interface GuideProps
extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
@@ -1,6 +1,6 @@
import React, { forwardRef, HTMLAttributes } from "react";
import Guide from "./Guide";
import cl from "classnames";
import cl from "clsx";
export interface GuidePanelProps extends HTMLAttributes<HTMLDivElement> {
/**
+23 -9
View File
@@ -1,9 +1,7 @@
import { Helptext as HelpTextIcon } from "@navikt/ds-icons";
import { Placement } from "@popperjs/core";
import cl from "classnames";
import React, { forwardRef, useRef, useState } from "react";
import mergeRefs from "react-merge-refs";
import { Popover, PopoverProps } from "..";
import { Helptext as HelpTextIcon, HelptextFilled } from "@navikt/ds-icons";
import cl from "clsx";
import React, { forwardRef, useMemo, useRef, useState } from "react";
import { Popover, PopoverProps, mergeRefs } from "..";
export interface HelpTextProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
@@ -11,7 +9,7 @@ export interface HelpTextProps
/**
* Helptext-dialog content
*/
children: React.ReactNode;
children: string;
/**
* Adds a title-tooltip with the given text
* @default "hjelp"
@@ -21,7 +19,19 @@ export interface HelpTextProps
* Default dialog-placement on open
* @default "top"
*/
placement?: Placement;
placement?:
| "top"
| "bottom"
| "right"
| "left"
| "top-start"
| "top-end"
| "bottom-start"
| "bottom-end"
| "right-start"
| "right-end"
| "left-start"
| "left-end";
}
export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
@@ -38,7 +48,7 @@ export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
ref
) => {
const buttonRef = useRef<HTMLButtonElement | null>(null);
const mergedRef = mergeRefs([buttonRef, ref]);
const mergedRef = useMemo(() => mergeRefs([buttonRef, ref]), [ref]);
const [open, setOpen] = useState(false);
return (
@@ -55,6 +65,10 @@ export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
aria-expanded={open}
>
<HelpTextIcon className="navds-help-text__icon" title={title} />
<HelptextFilled
className="navds-help-text__icon navds-help-text__icon--filled"
title={title}
/>
</button>
<Popover
onClose={() => setOpen(false)}
@@ -1,5 +1,5 @@
import React from "react";
import { TextField, HelpText } from "..";
import React, { useEffect, useRef } from "react";
import { HelpText } from "..";
export default {
title: "ds-react/HelpText",
@@ -9,6 +9,7 @@ export default {
control: {
type: "radio",
options: [
"top",
"bottom",
"right",
"left",
@@ -20,9 +21,6 @@ export default {
"right-end",
"left-start",
"left-end",
"auto",
"auto-start",
"auto-end",
],
},
},
@@ -47,17 +45,15 @@ Default.args = {
title: "show tooltip",
};
export const Inline = () => {
export const Open = () => {
const ref = useRef<HTMLButtonElement | null>(null);
useEffect(() => {
ref.current && ref.current.click();
}, []);
return (
<TextField
label={
<div style={{ display: "flex", gap: 8 }}>
Text field label
<HelpText title="show tooltip">
Id ullamco excepteur elit fugiat labore.
</HelpText>
</div>
}
/>
<HelpText ref={ref} title="show tooltip" strategy="fixed">
Id ullamco excepteur elit fugiat labore.
</HelpText>
);
};
+1 -7
View File
@@ -8,14 +8,12 @@ export * from "./guide-panel";
export * from "./link";
export * from "./link-panel";
export * from "./loader";
export * from "./menu";
export * from "./modal";
export * from "./pagination";
export * from "./panel";
export * from "./popover";
export * from "./read-more";
export * from "./speech-bubble";
export * from "./step-indicator";
export * from "./chat";
export * from "./stepper";
export * from "./tag";
export * from "./toggle-group";
@@ -24,7 +22,3 @@ export * from "./tabs";
export * from "./tooltip";
export * from "./typography";
export * from "./util";
/* Navno spesific packages */
export * from "./card";
export * from "./page-header";
@@ -1,7 +1,7 @@
import React, { forwardRef } from "react";
import { Panel, OverridableComponent } from "..";
import { Next } from "@navikt/ds-icons";
import cl from "classnames";
import cl from "clsx";
import { LinkPanelTitle, LinkPanelTitleType } from "./LinkPanelTitle";
import {
LinkPanelDescription,
@@ -1,5 +1,5 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import cl from "clsx";
import { BodyLong } from "..";
interface LinkPanelDescriptionProps
@@ -1,5 +1,5 @@
import React, { forwardRef } from "react";
import cl from "classnames";
import cl from "clsx";
import { OverridableComponent } from "..";
interface LinkPanelTitleProps extends React.HTMLAttributes<HTMLDivElement> {
Loaded 100 of 218 files, more files were not shown because too many files have changed in this diff. Show more