@navikt/ds-react 0.17.19 → 0.17.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,30 +1,29 @@
1
- import React, { useState } from "react";
1
+ import { Star } from "@navikt/ds-icons";
2
+ import React from "react";
2
3
  import { Button } from "./index";
3
- import { Success } from "@navikt/ds-icons";
4
4
 
5
5
  export default {
6
- title: "ds-react/button",
6
+ title: "ds-react/Button",
7
7
  component: Button,
8
8
  parameters: {
9
9
  chromatic: { delay: 300 },
10
10
  },
11
+ argTypes: {
12
+ variant: {
13
+ control: {
14
+ type: "radio",
15
+ options: ["primary", "secondary", "tertiary", "danger"],
16
+ },
17
+ },
18
+ size: {
19
+ control: {
20
+ type: "radio",
21
+ options: ["medium", "small"],
22
+ },
23
+ },
24
+ },
11
25
  };
12
26
 
13
- const Section = ({ children }) => (
14
- <div
15
- style={{
16
- display: "flex",
17
- gap: 16,
18
- gridAutoFlow: "column",
19
- justifyContent: "start",
20
- padding: 24,
21
- paddingLeft: 0,
22
- }}
23
- >
24
- {children}
25
- </div>
26
- );
27
-
28
27
  const variants: Array<"primary" | "secondary" | "tertiary" | "danger"> = [
29
28
  "primary",
30
29
  "secondary",
@@ -39,119 +38,132 @@ const varSwitch = {
39
38
  danger: "Danger",
40
39
  };
41
40
 
42
- export const All = () => {
43
- const [loadingState, setLoadingState] = useState(true);
44
- const [content, setContent] = useState<string>("");
41
+ export const Default = (props) => {
42
+ return (
43
+ <Button variant={props.variant} size={props.size} loading={props.loading}>
44
+ {props.icon ? <Star /> : null}
45
+ {props.children}
46
+ {props.icon ? <Star /> : null}
47
+ </Button>
48
+ );
49
+ };
45
50
 
46
- const toggleLoading = () => {
47
- setLoadingState(!loadingState);
48
- };
51
+ Default.args = {
52
+ icon: false,
53
+ loading: false,
54
+ children: "Knapp",
55
+ };
49
56
 
50
- return (
51
- <div style={{ paddingLeft: "1rem" }}>
52
- <h1>Button</h1>
53
- <Section>
54
- {variants.map((variant) => (
55
- <Button key={variant} variant={variant}>
56
- {varSwitch[variant]}
57
- </Button>
58
- ))}
59
- </Section>
60
- <h2>disabled</h2>
61
- <Section>
62
- {variants.map((variant) => (
63
- <Button key={variant} variant={variant} disabled>
64
- {varSwitch[variant]}
65
- </Button>
66
- ))}
67
- </Section>
68
- <h2>As link</h2>
69
- <Section>
70
- {variants.map((variant) => (
71
- <Button as="a" key={variant} variant={variant} href="the-link">
72
- {varSwitch[variant]}
73
- </Button>
74
- ))}
75
- </Section>
76
- <h2>Small</h2>
77
- <Section>
78
- {variants.map((variant) => (
79
- <Button key={variant} variant={variant} size="small">
80
- {varSwitch[variant]}
81
- </Button>
82
- ))}
83
- </Section>
84
- <h2>Xsmall</h2>
85
- <Section>
86
- {variants.map((variant) => (
87
- <Button key={variant} variant={variant} size="xsmall">
88
- {varSwitch[variant]}
89
- </Button>
90
- ))}
91
- </Section>
92
- <h2>Button w/icon</h2>
93
- <Section>
94
- {variants.map((variant) => (
95
- <Button key={variant} variant={variant}>
96
- {variant} <Success />
97
- </Button>
98
- ))}
99
- </Section>
100
- <Section>
101
- {variants.map((variant) => (
102
- <Button key={variant} variant={variant}>
103
- <span className="navds-sr-only">Success ikon</span>
104
- <Success />
105
- </Button>
106
- ))}
107
- </Section>
108
- <h2>Small w/icon</h2>
109
- <Section>
110
- {variants.map((variant) => (
111
- <Button key={variant} variant={variant} size="small">
112
- <Success /> {variant}
113
- </Button>
114
- ))}
115
- </Section>
116
- <Section>
117
- {variants.map((variant) => (
118
- <Button key={variant} variant={variant} size="small">
119
- <span className="navds-sr-only">Success ikon</span>
120
- <Success />
121
- </Button>
122
- ))}
123
- </Section>
124
- <h2>Button w/loader</h2>
125
- <Button onClick={toggleLoading}>Toggle loaders</Button>
126
- <Button onClick={() => setContent((content) => `${content} wat`)}>
127
- Change content
57
+ export const Small = () => (
58
+ <div className="rowgap">
59
+ {variants.map((variant) => (
60
+ <Button key={variant} variant={variant} size="small">
61
+ {varSwitch[variant]}
128
62
  </Button>
129
- <Section>
130
- {variants.map((variant) => (
131
- <Button
132
- key={variant}
133
- variant={variant}
134
- loading={loadingState}
135
- onClick={toggleLoading}
136
- >
137
- {content || varSwitch[variant]}
138
- </Button>
139
- ))}
140
- </Section>
141
- <h2>Small w/loader</h2>
142
- <Section>
143
- {variants.map((variant) => (
144
- <Button
145
- key={variant}
146
- variant={variant}
147
- size="small"
148
- loading={loadingState}
149
- onClick={toggleLoading}
150
- >
151
- {varSwitch[variant]}
152
- </Button>
153
- ))}
154
- </Section>
63
+ ))}
64
+ </div>
65
+ );
66
+
67
+ export const XSmall = () => (
68
+ <div className="rowgap">
69
+ {variants.map((variant) => (
70
+ <Button key={variant} variant={variant} size="xsmall">
71
+ {varSwitch[variant]}
72
+ </Button>
73
+ ))}
74
+ </div>
75
+ );
76
+
77
+ export const Loading = () => (
78
+ <div className="colgap">
79
+ <div className="rowgap">
80
+ {variants.map((variant) => (
81
+ <Button key={variant} variant={variant} loading>
82
+ {varSwitch[variant]}
83
+ </Button>
84
+ ))}
155
85
  </div>
156
- );
157
- };
86
+ <div className="rowgap">
87
+ {variants.map((variant) => (
88
+ <Button key={variant} variant={variant} loading size="small">
89
+ {varSwitch[variant]}
90
+ </Button>
91
+ ))}
92
+ </div>
93
+ <div className="rowgap">
94
+ {variants.map((variant) => (
95
+ <Button key={variant} variant={variant} loading size="xsmall">
96
+ {varSwitch[variant]}
97
+ </Button>
98
+ ))}
99
+ </div>
100
+ </div>
101
+ );
102
+
103
+ export const Icon = () => (
104
+ <div className="colgap">
105
+ <div className="rowgap">
106
+ {variants.map((variant) => (
107
+ <Button key={variant} variant={variant}>
108
+ <Star />
109
+ </Button>
110
+ ))}
111
+ </div>
112
+ <div className="rowgap">
113
+ {variants.map((variant) => (
114
+ <Button key={variant} variant={variant} size="small">
115
+ <Star />
116
+ </Button>
117
+ ))}
118
+ </div>
119
+ <div className="rowgap">
120
+ {variants.map((variant) => (
121
+ <Button key={variant} variant={variant} size="xsmall">
122
+ <Star />
123
+ </Button>
124
+ ))}
125
+ </div>
126
+ </div>
127
+ );
128
+
129
+ export const IconWText = () => (
130
+ <div className="colgap">
131
+ <div className="rowgap">
132
+ {variants.map((variant) => (
133
+ <Button key={variant} variant={variant}>
134
+ <Star />
135
+ {varSwitch[variant]}
136
+ <Star />
137
+ </Button>
138
+ ))}
139
+ </div>
140
+ <div className="rowgap">
141
+ {variants.map((variant) => (
142
+ <Button key={variant} variant={variant} size="small">
143
+ <Star />
144
+ {varSwitch[variant]}
145
+ <Star />
146
+ </Button>
147
+ ))}
148
+ </div>
149
+ <div className="rowgap">
150
+ {variants.map((variant) => (
151
+ <Button key={variant} variant={variant} size="xsmall">
152
+ <Star />
153
+ {varSwitch[variant]}
154
+ <Star />
155
+ </Button>
156
+ ))}
157
+ </div>
158
+ </div>
159
+ );
160
+
161
+ export const Link = () => (
162
+ <div className="rowgap">
163
+ {variants.map((variant) => (
164
+ <Button key={variant} variant={variant} as="a" href="#thecakeisalie">
165
+ {varSwitch[variant]}
166
+ </Button>
167
+ ))}
168
+ </div>
169
+ );
@@ -1,7 +1,7 @@
1
1
  import { Meta, Canvas } from "@storybook/addon-docs";
2
2
  import { MicroCard } from "../index.ts";
3
3
 
4
- <Meta title="ds-react/card/intro" />
4
+ <Meta title="ds-react(deprecated)/card/intro" />
5
5
 
6
6
  # Hvordan ta i bruk card
7
7
 
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { MicroCard } from "../index";
3
3
  import { Meta } from "@storybook/react/types-6-0";
4
4
  export default {
5
- title: "ds-react/card",
5
+ title: "ds-react(deprecated)/card",
6
6
  component: MicroCard,
7
7
  } as Meta;
8
8
 
@@ -6,11 +6,12 @@ import { Checkbox, CheckboxGroup } from ".";
6
6
 
7
7
  const firstArgumentOfFirstCall = (fn: jest.Mock) => fn.mock.calls[0][0];
8
8
 
9
- test("checkbox group chains onChange calls", () => {
9
+ test("checkbox group chains onChange calls", async () => {
10
10
  const onGroupChange = jest.fn();
11
11
  const onChange = jest.fn();
12
12
  const value = faker.datatype.string();
13
13
  const label = faker.datatype.string();
14
+ const user = userEvent.setup();
14
15
 
15
16
  render(
16
17
  <CheckboxGroup legend="legend" onChange={onGroupChange}>
@@ -20,7 +21,7 @@ test("checkbox group chains onChange calls", () => {
20
21
  </CheckboxGroup>
21
22
  );
22
23
 
23
- userEvent.click(screen.getByLabelText(label));
24
+ await user.click(screen.getByLabelText(label));
24
25
 
25
26
  expect(onGroupChange).toBeCalledTimes(1);
26
27
  expect(onGroupChange).toBeCalledWith([value]);
@@ -36,21 +37,24 @@ describe("Checkbox handles controlled-state correctly", () => {
36
37
  </CheckboxGroup>
37
38
  );
38
39
 
39
- test("Checkbox is still checked after click when controlled", () => {
40
+ test("Checkbox is still checked after click when controlled", async () => {
41
+ const user = userEvent.setup();
40
42
  render(<CheckboxComponent value={["value1", "value2"]} />);
41
- userEvent.click(screen.getByLabelText("label1"));
42
- userEvent.click(screen.getByLabelText("label2"));
43
+ await user.click(screen.getByLabelText("label1"));
44
+ await user.click(screen.getByLabelText("label2"));
43
45
 
44
46
  expect((screen.getByLabelText("label1") as HTMLInputElement).checked).toBe(
45
47
  true
46
48
  );
49
+
47
50
  expect((screen.getByLabelText("label2") as HTMLInputElement).checked).toBe(
48
51
  true
49
52
  );
50
53
  });
51
54
 
52
- test("onChange called with expected values", () => {
55
+ test("onChange called with expected values", async () => {
53
56
  const onGroupChange = jest.fn();
57
+ const user = userEvent.setup();
54
58
 
55
59
  render(
56
60
  <CheckboxComponent
@@ -59,11 +63,11 @@ describe("Checkbox handles controlled-state correctly", () => {
59
63
  />
60
64
  );
61
65
 
62
- userEvent.click(screen.getByLabelText("label1"));
66
+ await user.click(screen.getByLabelText("label1"));
63
67
 
64
68
  expect(onGroupChange).lastCalledWith(["value2"]);
65
69
 
66
- userEvent.click(screen.getByLabelText("label2"));
70
+ await user.click(screen.getByLabelText("label2"));
67
71
 
68
72
  expect(onGroupChange).lastCalledWith(["value1"]);
69
73
  });
@@ -0,0 +1,178 @@
1
+ import React, { useState } from "react";
2
+ import { Checkbox, CheckboxGroup } from "../../index";
3
+ import { Meta } from "@storybook/react/types-6-0";
4
+
5
+ export default {
6
+ title: "ds-react/Form/Checkbox",
7
+ component: Checkbox,
8
+ subcomponents: {
9
+ CheckboxGroup,
10
+ },
11
+ } as Meta;
12
+
13
+ export const Default = (props) => {
14
+ const [state, setState] = useState(["checkbox1"]);
15
+
16
+ return (
17
+ <CheckboxGroup
18
+ legend={props.legend}
19
+ description={props.description}
20
+ value={props.controlled ? state : undefined}
21
+ onChange={props.controlled ? setState : undefined}
22
+ hideLegend={props.hideLegend}
23
+ error={props.errorGroup ? "Errormelding" : undefined}
24
+ {...props}
25
+ >
26
+ <Checkbox
27
+ value="checkbox1"
28
+ indeterminate={props.indeterminate}
29
+ hideLabel={props.hideLabel}
30
+ >
31
+ {props.children || "Apple"}
32
+ </Checkbox>
33
+ <Checkbox
34
+ value="checkbox2"
35
+ error={props.errorSingle}
36
+ description={
37
+ props.checkboxDescription ? "Orange description" : undefined
38
+ }
39
+ indeterminate={props.indeterminate}
40
+ hideLabel={props.hideLabel}
41
+ >
42
+ {props.children || "Orange"}
43
+ </Checkbox>
44
+ <Checkbox
45
+ value="checkbox3"
46
+ indeterminate={props.indeterminate}
47
+ hideLabel={props.hideLabel}
48
+ >
49
+ {props.children || "Banana"}
50
+ </Checkbox>
51
+ <Checkbox
52
+ value="checkbox4"
53
+ indeterminate={props.indeterminate}
54
+ hideLabel={props.hideLabel}
55
+ >
56
+ {props.children || "Melon"}
57
+ </Checkbox>
58
+ </CheckboxGroup>
59
+ );
60
+ };
61
+
62
+ Default.args = {
63
+ controlled: false,
64
+ legend: "Legend-tekst",
65
+ checkboxDescription: false,
66
+ hideLegend: false,
67
+ errorSingle: false,
68
+ children: "",
69
+ description: "",
70
+ };
71
+
72
+ export const Group = () => (
73
+ <CheckboxGroup legend="Group legend" defaultValue={["tekst2"]}>
74
+ <Checkbox value="tekst">Checkboxtekst</Checkbox>
75
+ <Checkbox value="tekst2">Checkboxtekst</Checkbox>
76
+ </CheckboxGroup>
77
+ );
78
+
79
+ export const GroupError = () => (
80
+ <CheckboxGroup
81
+ legend="Group legend"
82
+ defaultValue={["tekst2"]}
83
+ error="Group errormelding"
84
+ >
85
+ <Checkbox value="tekst">Checkboxtekst</Checkbox>
86
+ <Checkbox value="tekst2">Checkboxtekst</Checkbox>
87
+ </CheckboxGroup>
88
+ );
89
+
90
+ export const GroupSmall = () => (
91
+ <CheckboxGroup legend="Group legend" defaultValue={["tekst2"]} size="small">
92
+ <Checkbox value="tekst">Checkboxtekst</Checkbox>
93
+ <Checkbox value="tekst2">Checkboxtekst</Checkbox>
94
+ </CheckboxGroup>
95
+ );
96
+
97
+ export const GroupDescription = () => (
98
+ <CheckboxGroup
99
+ legend="Group legend"
100
+ defaultValue={["tekst2"]}
101
+ description="Group description"
102
+ >
103
+ <Checkbox value="tekst">Checkboxtekst</Checkbox>
104
+ <Checkbox value="tekst2">Checkboxtekst</Checkbox>
105
+ </CheckboxGroup>
106
+ );
107
+
108
+ export const Single = () => (
109
+ <div className="colspan">
110
+ <Checkbox value="tekst">Checkboxtekst</Checkbox>
111
+ <Checkbox value="tekst" defaultChecked>
112
+ Checkboxtekst
113
+ </Checkbox>
114
+ </div>
115
+ );
116
+
117
+ export const SingleSmall = () => (
118
+ <div className="colspan">
119
+ <Checkbox value="tekst" size="small">
120
+ Checkboxtekst
121
+ </Checkbox>
122
+ <Checkbox value="tekst" defaultChecked size="small">
123
+ Checkboxtekst
124
+ </Checkbox>
125
+ </div>
126
+ );
127
+
128
+ export const SingleDescription = () => (
129
+ <div className="colspan">
130
+ <Checkbox value="tekst" description="checkboxdescription">
131
+ Checkboxtekst
132
+ </Checkbox>
133
+ <Checkbox value="tekst" defaultChecked description="checkboxdescription">
134
+ Checkboxtekst
135
+ </Checkbox>
136
+ </div>
137
+ );
138
+
139
+ export const SingleError = () => (
140
+ <div className="colspan">
141
+ <Checkbox value="tekst" error>
142
+ Checkboxtekst
143
+ </Checkbox>
144
+ <Checkbox value="tekst" defaultChecked error>
145
+ Checkboxtekst
146
+ </Checkbox>
147
+ </div>
148
+ );
149
+
150
+ export const Indeterminate = () => {
151
+ const [checked, setChecked] = useState([true, false]);
152
+
153
+ return (
154
+ <>
155
+ <Checkbox
156
+ checked={checked[0] && checked[1]}
157
+ indeterminate={checked[0] !== checked[1]}
158
+ onChange={(e) => setChecked([e.target.checked, e.target.checked])}
159
+ >
160
+ Parent
161
+ </Checkbox>
162
+ <div style={{ paddingLeft: "2rem" }}>
163
+ <Checkbox
164
+ checked={checked[0]}
165
+ onChange={(e) => setChecked([e.target.checked, checked[1]])}
166
+ >
167
+ Child 1
168
+ </Checkbox>
169
+ <Checkbox
170
+ checked={checked[1]}
171
+ onChange={(e) => setChecked([checked[0], e.target.checked])}
172
+ >
173
+ Child 2
174
+ </Checkbox>
175
+ </div>
176
+ </>
177
+ );
178
+ };
@@ -0,0 +1,42 @@
1
+ import React from "react";
2
+ import { Meta } from "@storybook/react/types-6-0";
3
+ import { ErrorSummary } from "..";
4
+ export default {
5
+ title: "ds-react/Form/Errorsummary",
6
+ component: ErrorSummary,
7
+ argTypes: {
8
+ headingTag: {
9
+ control: {
10
+ type: "text",
11
+ },
12
+ },
13
+ size: {
14
+ control: {
15
+ type: "radio",
16
+ options: ["medium", "small"],
17
+ },
18
+ },
19
+ },
20
+ } as Meta;
21
+
22
+ export const Default = (props) => (
23
+ <ErrorSummary
24
+ heading="Feiloppsummering komponent"
25
+ headingTag={props.headingTag || "h2"}
26
+ size={props.size ?? undefined}
27
+ >
28
+ <ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
29
+ <ErrorSummary.Item href="#2">
30
+ Tekstfeltet må ha en godkjent e-mail
31
+ </ErrorSummary.Item>
32
+ </ErrorSummary>
33
+ );
34
+
35
+ export const Small = () => (
36
+ <ErrorSummary heading="Feiloppsummering komponent" size="small">
37
+ <ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
38
+ <ErrorSummary.Item href="#2">
39
+ Tekstfeltet må ha en godkjent e-mail
40
+ </ErrorSummary.Item>
41
+ </ErrorSummary>
42
+ );
@@ -31,7 +31,9 @@ describe("Controlled RadioGroup", () => {
31
31
  });
32
32
 
33
33
  describe("Uncontrolled RadioGroup", () => {
34
- test("handles state correctly", () => {
34
+ test("handles state correctly", async () => {
35
+ const user = userEvent.setup();
36
+
35
37
  render(<Group />);
36
38
 
37
39
  const input1 = screen.getByLabelText(label1) as HTMLInputElement;
@@ -40,13 +42,14 @@ describe("Uncontrolled RadioGroup", () => {
40
42
  expect(input1.checked).toBe(false);
41
43
  expect(input2.checked).toBe(false);
42
44
 
43
- userEvent.click(screen.getByLabelText(label2));
45
+ await user.click(screen.getByLabelText(label2));
44
46
 
45
47
  expect(input1.checked).toBe(false);
46
48
  expect(input2.checked).toBe(true);
47
49
  });
48
50
 
49
- test("handles defaultValue correctly", () => {
51
+ test("handles defaultValue correctly", async () => {
52
+ const user = userEvent.setup();
50
53
  render(<Group defaultValue={value1} />);
51
54
 
52
55
  const input1 = screen.getByLabelText(label1) as HTMLInputElement;
@@ -55,7 +58,7 @@ describe("Uncontrolled RadioGroup", () => {
55
58
  expect(input1.checked).toBe(true);
56
59
  expect(input2.checked).toBe(false);
57
60
 
58
- userEvent.click(screen.getByLabelText(label2));
61
+ await user.click(screen.getByLabelText(label2));
59
62
 
60
63
  expect(input1.checked).toBe(false);
61
64
  expect(input2.checked).toBe(true);