@navikt/ds-react 5.18.1 → 5.18.3
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.
- package/cjs/date/parts/DateWrapper.js +2 -2
- package/cjs/form/search/Search.js +1 -1
- package/cjs/modal/Modal.context.js +9 -0
- package/cjs/modal/Modal.js +3 -6
- package/cjs/modal/ModalHeader.js +2 -6
- package/cjs/popover/Popover.js +2 -2
- package/cjs/tooltip/Tooltip.js +3 -3
- package/cjs/util/create-context.js +9 -5
- package/esm/date/parts/DateWrapper.js +3 -3
- package/esm/date/parts/DateWrapper.js.map +1 -1
- package/esm/form/search/Search.js +1 -1
- package/esm/modal/Modal.context.d.ts +9 -0
- package/esm/modal/Modal.context.js +6 -0
- package/esm/modal/Modal.context.js.map +1 -0
- package/esm/modal/Modal.js +3 -6
- package/esm/modal/Modal.js.map +1 -1
- package/esm/modal/ModalHeader.js +3 -7
- package/esm/modal/ModalHeader.js.map +1 -1
- package/esm/popover/Popover.js +2 -2
- package/esm/popover/Popover.js.map +1 -1
- package/esm/tooltip/Tooltip.js +4 -4
- package/esm/tooltip/Tooltip.js.map +1 -1
- package/esm/util/create-context.d.ts +2 -5
- package/esm/util/create-context.js +10 -6
- package/esm/util/create-context.js.map +1 -1
- package/package.json +3 -3
- package/src/accordion/accordion.stories.tsx +121 -135
- package/src/chat/chat.stories.tsx +284 -206
- package/src/date/parts/DateWrapper.tsx +3 -3
- package/src/form/search/Search.tsx +3 -3
- package/src/modal/Modal.context.ts +13 -0
- package/src/modal/Modal.tsx +6 -8
- package/src/modal/ModalHeader.tsx +3 -7
- package/src/popover/Popover.tsx +2 -2
- package/src/table/stories/{table.stories.tsx → table-1.stories.tsx} +117 -94
- package/src/table/stories/{table-expandable.stories.tsx → table-2-expandable.stories.tsx} +6 -32
- package/src/table/stories/{table-async.stories.tsx → table-3-async.stories.tsx} +1 -1
- package/src/table/stories/tests/table.stories.tsx +3 -0
- package/src/tabs/Tabs.test.tsx +109 -0
- package/src/toggle-group/ToggleGroup.test.tsx +54 -0
- package/src/tooltip/Tooltip.tsx +4 -10
- package/src/typography/stories/bodylong.stories.tsx +47 -1
- package/src/typography/stories/bodyshort.stories.tsx +48 -2
- package/src/typography/stories/detail.stories.tsx +30 -1
- package/src/typography/stories/error-message.stories.tsx +32 -1
- package/src/typography/stories/heading.stories.tsx +30 -1
- package/src/typography/stories/label.stories.tsx +36 -1
- package/src/util/create-context.tsx +26 -15
- package/cjs/modal/ModalContext.js +0 -8
- package/esm/modal/ModalContext.d.ts +0 -7
- package/esm/modal/ModalContext.js +0 -3
- package/esm/modal/ModalContext.js.map +0 -1
- package/src/modal/ModalContext.ts +0 -7
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import { Table, TableProps } from "../";
|
|
3
|
-
import { Alert } from "../../alert";
|
|
4
3
|
import { Button } from "../../button";
|
|
5
|
-
import { Checkbox
|
|
6
|
-
import {
|
|
4
|
+
import { Checkbox } from "../../form";
|
|
5
|
+
import { VStack } from "../../layout/stack";
|
|
6
|
+
import {
|
|
7
|
+
Expandable,
|
|
8
|
+
ExpandableLarge,
|
|
9
|
+
ExpandableSmall,
|
|
10
|
+
} from "./table-2-expandable.stories";
|
|
7
11
|
|
|
8
12
|
export default {
|
|
9
13
|
title: "ds-react/Table",
|
|
10
14
|
component: Table,
|
|
15
|
+
parameters: {
|
|
16
|
+
chromatic: { disable: true },
|
|
17
|
+
},
|
|
11
18
|
};
|
|
12
19
|
|
|
13
20
|
interface Props extends TableProps {
|
|
14
21
|
button?: boolean;
|
|
15
22
|
shadeOnHover?: boolean;
|
|
16
23
|
}
|
|
24
|
+
|
|
17
25
|
const TableComponent = ({ button, shadeOnHover, ...rest }: Props) => (
|
|
18
26
|
<Table {...rest}>
|
|
19
27
|
<Table.Header>
|
|
@@ -92,75 +100,59 @@ export const Buttons = () => <TableComponent size="small" button />;
|
|
|
92
100
|
|
|
93
101
|
export const WithDivs = () => {
|
|
94
102
|
return (
|
|
95
|
-
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
103
|
+
<div className="navds-table" role="table">
|
|
104
|
+
<div className="navds-table__header" role="rowgroup">
|
|
105
|
+
<div className="navds-table__row" role="row">
|
|
106
|
+
<div className="navds-table__header-cell" role="columnheader">
|
|
107
|
+
Fornavn
|
|
108
|
+
</div>
|
|
109
|
+
<div className="navds-table__header-cell" role="columnheader">
|
|
110
|
+
Etternavn
|
|
111
|
+
</div>
|
|
112
|
+
<div className="navds-table__header-cell" role="columnheader">
|
|
113
|
+
Rolle
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
<div className="navds-table__body" role="rowgroup">
|
|
118
|
+
<div className="navds-table__row" role="row">
|
|
119
|
+
<div className="navds-table__data-cell" role="cell">
|
|
120
|
+
Jean-Luc
|
|
121
|
+
</div>
|
|
122
|
+
<div className="navds-table__data-cell" role="cell">
|
|
123
|
+
Picard
|
|
124
|
+
</div>
|
|
125
|
+
<div className="navds-table__data-cell" role="cell">
|
|
126
|
+
Kaptein
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
<div className="navds-table__row" role="row">
|
|
130
|
+
<div className="navds-table__data-cell" role="cell">
|
|
131
|
+
William
|
|
132
|
+
</div>
|
|
133
|
+
<div className="navds-table__data-cell" role="cell">
|
|
134
|
+
Riker
|
|
135
|
+
</div>
|
|
136
|
+
<div className="navds-table__data-cell" role="cell">
|
|
137
|
+
Kommandør
|
|
119
138
|
</div>
|
|
120
139
|
</div>
|
|
121
|
-
<div className="navds-
|
|
122
|
-
<div className="navds-
|
|
123
|
-
|
|
124
|
-
Jean-Luc
|
|
125
|
-
</div>
|
|
126
|
-
<div className="navds-table__data-cell" role="cell">
|
|
127
|
-
Picard
|
|
128
|
-
</div>
|
|
129
|
-
<div className="navds-table__data-cell" role="cell">
|
|
130
|
-
Kaptein
|
|
131
|
-
</div>
|
|
140
|
+
<div className="navds-table__row" role="row">
|
|
141
|
+
<div className="navds-table__data-cell" role="cell">
|
|
142
|
+
Geordi
|
|
132
143
|
</div>
|
|
133
|
-
<div className="navds-
|
|
134
|
-
|
|
135
|
-
William
|
|
136
|
-
</div>
|
|
137
|
-
<div className="navds-table__data-cell" role="cell">
|
|
138
|
-
Riker
|
|
139
|
-
</div>
|
|
140
|
-
<div className="navds-table__data-cell" role="cell">
|
|
141
|
-
Kommandør
|
|
142
|
-
</div>
|
|
144
|
+
<div className="navds-table__data-cell" role="cell">
|
|
145
|
+
La Forge
|
|
143
146
|
</div>
|
|
144
|
-
<div className="navds-
|
|
145
|
-
|
|
146
|
-
Geordi
|
|
147
|
-
</div>
|
|
148
|
-
<div className="navds-table__data-cell" role="cell">
|
|
149
|
-
La Forge
|
|
150
|
-
</div>
|
|
151
|
-
<div className="navds-table__data-cell" role="cell">
|
|
152
|
-
Sjefsingeniør
|
|
153
|
-
</div>
|
|
147
|
+
<div className="navds-table__data-cell" role="cell">
|
|
148
|
+
Sjefsingeniør
|
|
154
149
|
</div>
|
|
155
150
|
</div>
|
|
156
151
|
</div>
|
|
157
|
-
|
|
152
|
+
</div>
|
|
158
153
|
);
|
|
159
154
|
};
|
|
160
155
|
|
|
161
|
-
export const Selection = () => <SelectionTable />;
|
|
162
|
-
export const SelectionSmall = () => <SelectionTable size="small" />;
|
|
163
|
-
|
|
164
156
|
const SelectionTable = ({ size = "medium" }: { size?: "small" | "medium" }) => {
|
|
165
157
|
const useToggleList = (initialState) => {
|
|
166
158
|
const [list, setList] = useState(initialState);
|
|
@@ -185,7 +177,7 @@ const SelectionTable = ({ size = "medium" }: { size?: "small" | "medium" }) => {
|
|
|
185
177
|
<Table.DataCell>
|
|
186
178
|
<Checkbox
|
|
187
179
|
size={size}
|
|
188
|
-
|
|
180
|
+
indeterminate
|
|
189
181
|
onChange={() => toggleSelectedRow("all")}
|
|
190
182
|
>
|
|
191
183
|
Select all
|
|
@@ -215,12 +207,12 @@ const SelectionTable = ({ size = "medium" }: { size?: "small" | "medium" }) => {
|
|
|
215
207
|
<Table.DataCell>USA</Table.DataCell>
|
|
216
208
|
<Table.DataCell>38</Table.DataCell>
|
|
217
209
|
</Table.Row>
|
|
218
|
-
<Table.Row selected
|
|
210
|
+
<Table.Row selected>
|
|
219
211
|
<Table.DataCell>
|
|
220
212
|
<Checkbox
|
|
221
213
|
size={size}
|
|
222
214
|
hideLabel
|
|
223
|
-
checked
|
|
215
|
+
checked
|
|
224
216
|
onChange={() => toggleSelectedRow("2")}
|
|
225
217
|
aria-labelledby={`x_r2-${size}`}
|
|
226
218
|
>
|
|
@@ -234,36 +226,67 @@ const SelectionTable = ({ size = "medium" }: { size?: "small" | "medium" }) => {
|
|
|
234
226
|
<Table.DataCell>Denmark</Table.DataCell>
|
|
235
227
|
<Table.DataCell>11</Table.DataCell>
|
|
236
228
|
</Table.Row>
|
|
237
|
-
<Table.Row selected={selectedRows.includes("3")}>
|
|
238
|
-
<Table.DataCell>
|
|
239
|
-
<CheckboxGroup legend="velg flere felt" hideLegend>
|
|
240
|
-
<Checkbox
|
|
241
|
-
size={size}
|
|
242
|
-
hideLabel
|
|
243
|
-
checked={selectedRows.includes("3")}
|
|
244
|
-
onChange={() => toggleSelectedRow("3")}
|
|
245
|
-
aria-labelledby={`x_r3-${size}`}
|
|
246
|
-
>
|
|
247
|
-
{" "}
|
|
248
|
-
</Checkbox>
|
|
249
|
-
<Checkbox
|
|
250
|
-
size={size}
|
|
251
|
-
hideLabel
|
|
252
|
-
checked={selectedRows.includes("3")}
|
|
253
|
-
onChange={() => toggleSelectedRow("3")}
|
|
254
|
-
aria-labelledby={`x_r3-${size}`}
|
|
255
|
-
>
|
|
256
|
-
{" "}
|
|
257
|
-
</Checkbox>
|
|
258
|
-
</CheckboxGroup>
|
|
259
|
-
</Table.DataCell>
|
|
260
|
-
<Table.HeaderCell scope="row" colSpan={4}>
|
|
261
|
-
<span id={`x_r3-${size}`}>
|
|
262
|
-
Don't stack multiple checkboxes
|
|
263
|
-
</span>
|
|
264
|
-
</Table.HeaderCell>
|
|
265
|
-
</Table.Row>
|
|
266
229
|
</Table.Body>
|
|
267
230
|
</Table>
|
|
268
231
|
);
|
|
269
232
|
};
|
|
233
|
+
|
|
234
|
+
export const Selection = () => <SelectionTable />;
|
|
235
|
+
export const SelectionSmall = () => <SelectionTable size="small" />;
|
|
236
|
+
|
|
237
|
+
export const Chromatic = {
|
|
238
|
+
render: () => (
|
|
239
|
+
<VStack gap="8">
|
|
240
|
+
<div>
|
|
241
|
+
<h3>Default</h3>
|
|
242
|
+
<Default />
|
|
243
|
+
<h3>Zebra</h3>
|
|
244
|
+
<Zebra />
|
|
245
|
+
</div>
|
|
246
|
+
<div>
|
|
247
|
+
<h3>Large</h3>
|
|
248
|
+
<SizeLarge />
|
|
249
|
+
</div>
|
|
250
|
+
<div>
|
|
251
|
+
<h3>Medium</h3>
|
|
252
|
+
<SizeMedium />
|
|
253
|
+
</div>
|
|
254
|
+
<div>
|
|
255
|
+
<h3>Small</h3>
|
|
256
|
+
<SizeSmall />
|
|
257
|
+
</div>
|
|
258
|
+
<div>
|
|
259
|
+
<h3>With Buttons</h3>
|
|
260
|
+
<Buttons />
|
|
261
|
+
</div>
|
|
262
|
+
<div>
|
|
263
|
+
<h3>Custom with divs</h3>
|
|
264
|
+
<WithDivs />
|
|
265
|
+
</div>
|
|
266
|
+
<div>
|
|
267
|
+
<h3>Selection</h3>
|
|
268
|
+
<Selection />
|
|
269
|
+
</div>
|
|
270
|
+
<div>
|
|
271
|
+
<h3>Selection small</h3>
|
|
272
|
+
<SelectionSmall />
|
|
273
|
+
</div>
|
|
274
|
+
<h2>Expandable</h2>
|
|
275
|
+
<div>
|
|
276
|
+
<h3>Large</h3>
|
|
277
|
+
<ExpandableLarge />
|
|
278
|
+
</div>
|
|
279
|
+
<div>
|
|
280
|
+
<h3>Medium</h3>
|
|
281
|
+
<Expandable />
|
|
282
|
+
</div>
|
|
283
|
+
<div>
|
|
284
|
+
<h3>Small</h3>
|
|
285
|
+
<ExpandableSmall />
|
|
286
|
+
</div>
|
|
287
|
+
</VStack>
|
|
288
|
+
),
|
|
289
|
+
parameters: {
|
|
290
|
+
chromatic: { disable: false },
|
|
291
|
+
},
|
|
292
|
+
};
|
|
@@ -7,6 +7,9 @@ import Table from "../Table";
|
|
|
7
7
|
export default {
|
|
8
8
|
title: "ds-react/Table",
|
|
9
9
|
component: Table,
|
|
10
|
+
parameters: {
|
|
11
|
+
chromatic: { disable: true },
|
|
12
|
+
},
|
|
10
13
|
};
|
|
11
14
|
|
|
12
15
|
export const Expandable = () => {
|
|
@@ -27,6 +30,7 @@ export const Expandable = () => {
|
|
|
27
30
|
content={row.content}
|
|
28
31
|
key={row.name}
|
|
29
32
|
togglePlacement="right"
|
|
33
|
+
defaultOpen
|
|
30
34
|
>
|
|
31
35
|
{columns.map(({ key }) => (
|
|
32
36
|
<Table.DataCell key={key}>{row[key]}</Table.DataCell>
|
|
@@ -52,7 +56,7 @@ export const ExpandableLarge = () => {
|
|
|
52
56
|
</Table.Header>
|
|
53
57
|
<Table.Body>
|
|
54
58
|
{data.slice(0, 1).map((row) => (
|
|
55
|
-
<Table.ExpandableRow content={row.content} key={row.name}>
|
|
59
|
+
<Table.ExpandableRow defaultOpen content={row.content} key={row.name}>
|
|
56
60
|
{columns.map(({ key }) => (
|
|
57
61
|
<Table.DataCell key={key}>{row[key]}</Table.DataCell>
|
|
58
62
|
))}
|
|
@@ -89,7 +93,7 @@ export const ExpandableSmall = () => {
|
|
|
89
93
|
</Table.Header>
|
|
90
94
|
<Table.Body>
|
|
91
95
|
{data.slice(0, 1).map((row) => (
|
|
92
|
-
<Table.ExpandableRow content={row.content} key={row.name}>
|
|
96
|
+
<Table.ExpandableRow defaultOpen content={row.content} key={row.name}>
|
|
93
97
|
{columns.map(({ key }) => (
|
|
94
98
|
<Table.DataCell key={key}>{row[key]}</Table.DataCell>
|
|
95
99
|
))}
|
|
@@ -237,36 +241,6 @@ const data = [
|
|
|
237
241
|
},
|
|
238
242
|
];
|
|
239
243
|
|
|
240
|
-
export const ExpandableOpen = () => {
|
|
241
|
-
return (
|
|
242
|
-
<Table zebraStripes>
|
|
243
|
-
<Table.Header>
|
|
244
|
-
<Table.Row>
|
|
245
|
-
{columns.map(({ key, name }) => (
|
|
246
|
-
<Table.HeaderCell key={key}>{name}</Table.HeaderCell>
|
|
247
|
-
))}
|
|
248
|
-
<Table.HeaderCell />
|
|
249
|
-
</Table.Row>
|
|
250
|
-
</Table.Header>
|
|
251
|
-
<Table.Body>
|
|
252
|
-
{data.map((row) => (
|
|
253
|
-
<Table.ExpandableRow
|
|
254
|
-
expansionDisabled={row.animal === "Sel"}
|
|
255
|
-
content={row.content}
|
|
256
|
-
key={row.name}
|
|
257
|
-
togglePlacement="right"
|
|
258
|
-
defaultOpen
|
|
259
|
-
>
|
|
260
|
-
{columns.map(({ key }) => (
|
|
261
|
-
<Table.DataCell key={key}>{row[key]}</Table.DataCell>
|
|
262
|
-
))}
|
|
263
|
-
</Table.ExpandableRow>
|
|
264
|
-
))}
|
|
265
|
-
</Table.Body>
|
|
266
|
-
</Table>
|
|
267
|
-
);
|
|
268
|
-
};
|
|
269
|
-
|
|
270
244
|
export const ClickableRow = () => {
|
|
271
245
|
const [isRowOpen1, setIsRowOpen1] = useState(false);
|
|
272
246
|
const [isRowOpen2, setIsRowOpen2] = useState(false);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Tabs } from "./Tabs";
|
|
4
|
+
|
|
5
|
+
const TestTabs = ({
|
|
6
|
+
value,
|
|
7
|
+
onChange,
|
|
8
|
+
defaultValue,
|
|
9
|
+
selectionFollowsFocus,
|
|
10
|
+
loop,
|
|
11
|
+
iconPosition,
|
|
12
|
+
}: any) => (
|
|
13
|
+
<Tabs
|
|
14
|
+
value={value}
|
|
15
|
+
onChange={onChange}
|
|
16
|
+
defaultValue={defaultValue}
|
|
17
|
+
selectionFollowsFocus={selectionFollowsFocus}
|
|
18
|
+
loop={loop}
|
|
19
|
+
iconPosition={iconPosition}
|
|
20
|
+
>
|
|
21
|
+
<Tabs.List data-testid="tablist">
|
|
22
|
+
<Tabs.Tab value="tab1" data-testid="tab1" label="Tab 1" />
|
|
23
|
+
<Tabs.Tab value="tab2" data-testid="tab2" label="Tab 2" />
|
|
24
|
+
<Tabs.Tab value="tab3" data-testid="tab3" label="Tab 3" />
|
|
25
|
+
</Tabs.List>
|
|
26
|
+
<Tabs.Panel value="tab1" data-testid="tabpanel1">
|
|
27
|
+
Tabpanel 1
|
|
28
|
+
</Tabs.Panel>
|
|
29
|
+
<Tabs.Panel value="tab2" data-testid="tabpanel2">
|
|
30
|
+
Tabpanel 2
|
|
31
|
+
</Tabs.Panel>
|
|
32
|
+
<Tabs.Panel value="tab3" data-testid="tabpanel3">
|
|
33
|
+
Tabpanel 3
|
|
34
|
+
</Tabs.Panel>
|
|
35
|
+
</Tabs>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
describe("Tabs", () => {
|
|
39
|
+
test("sets default value correctly", () => {
|
|
40
|
+
render(<TestTabs defaultValue="tab2" />);
|
|
41
|
+
const tab = screen.getByTestId("tab2");
|
|
42
|
+
const panel = screen.getByTestId("tabpanel2");
|
|
43
|
+
|
|
44
|
+
expect(tab).toHaveAttribute("aria-selected", "true");
|
|
45
|
+
expect(panel).toHaveTextContent("Tabpanel 2");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("label-connection between tab and tabpanel is correct", async () => {
|
|
49
|
+
render(<TestTabs defaultValue="tab2" />);
|
|
50
|
+
const tab = screen.getByTestId("tab2");
|
|
51
|
+
const panel = screen.getByTestId("tabpanel2");
|
|
52
|
+
|
|
53
|
+
const controlsId = tab.getAttribute("aria-controls");
|
|
54
|
+
const panelLabelledBy = panel.getAttribute("aria-labelledby");
|
|
55
|
+
|
|
56
|
+
expect(controlsId).toEqual(panel.id);
|
|
57
|
+
expect(tab.id).toEqual(panelLabelledBy);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("sets correct attributes on active tab", () => {
|
|
61
|
+
render(<TestTabs defaultValue="tab2" />);
|
|
62
|
+
const tab = screen.getByTestId("tab2");
|
|
63
|
+
|
|
64
|
+
expect(tab).toHaveAttribute("aria-selected", "true");
|
|
65
|
+
expect(tab).toHaveAttribute("role", "tab");
|
|
66
|
+
expect(tab).toHaveAttribute("aria-controls");
|
|
67
|
+
expect(tab).toHaveAttribute("tabindex", "-1");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("sets correct attributes on idle tab", () => {
|
|
71
|
+
render(<TestTabs defaultValue="tab2" />);
|
|
72
|
+
const tab = screen.getByTestId("tab1");
|
|
73
|
+
|
|
74
|
+
expect(tab).toHaveAttribute("aria-selected", "false");
|
|
75
|
+
expect(tab).toHaveAttribute("role", "tab");
|
|
76
|
+
expect(tab).toHaveAttribute("aria-controls");
|
|
77
|
+
expect(tab).toHaveAttribute("tabindex", "-1");
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("sets correct attributes on active tabpanel", () => {
|
|
81
|
+
render(<TestTabs defaultValue="tab2" />);
|
|
82
|
+
const panel = screen.getByTestId("tabpanel2");
|
|
83
|
+
|
|
84
|
+
expect(panel).toHaveAttribute("aria-labelledby");
|
|
85
|
+
expect(panel).toHaveAttribute("role", "tabpanel");
|
|
86
|
+
expect(panel).toHaveAttribute("tabindex", "0");
|
|
87
|
+
expect(panel).toHaveTextContent("Tabpanel 2");
|
|
88
|
+
expect(panel).toHaveStyle({ display: "block" });
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("sets correct attributes on idle tabpanel", () => {
|
|
92
|
+
render(<TestTabs defaultValue="tab1" />);
|
|
93
|
+
const panel = screen.getByTestId("tabpanel2");
|
|
94
|
+
|
|
95
|
+
expect(panel).toHaveAttribute("aria-labelledby");
|
|
96
|
+
expect(panel).toHaveAttribute("role", "tabpanel");
|
|
97
|
+
expect(panel).toHaveAttribute("tabindex", "0");
|
|
98
|
+
expect(panel).toBeEmptyDOMElement();
|
|
99
|
+
expect(panel).toHaveStyle({ display: "none" });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("sets tabindex to 0 when focused", () => {
|
|
103
|
+
render(<TestTabs defaultValue="tab2" />);
|
|
104
|
+
const tab = screen.getByTestId("tab2");
|
|
105
|
+
|
|
106
|
+
fireEvent.focus(tab);
|
|
107
|
+
expect(tab).toHaveAttribute("tabindex", "0");
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { ToggleGroup } from "./ToggleGroup";
|
|
4
|
+
|
|
5
|
+
const TestToggleGroup = ({ value, onChange, defaultValue }: any) => (
|
|
6
|
+
<ToggleGroup value={value} onChange={onChange} defaultValue={defaultValue}>
|
|
7
|
+
<ToggleGroup.Item value="toggle1" data-testid="toggle1">
|
|
8
|
+
Toggle 1
|
|
9
|
+
</ToggleGroup.Item>
|
|
10
|
+
<ToggleGroup.Item value="toggle2" data-testid="toggle2">
|
|
11
|
+
Toggle 2
|
|
12
|
+
</ToggleGroup.Item>
|
|
13
|
+
<ToggleGroup.Item value="toggle3" data-testid="toggle3">
|
|
14
|
+
Toggle 3
|
|
15
|
+
</ToggleGroup.Item>
|
|
16
|
+
</ToggleGroup>
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
describe("ToggleGroup", () => {
|
|
20
|
+
test("sets default value correctly", () => {
|
|
21
|
+
render(<TestToggleGroup defaultValue="toggle2" />);
|
|
22
|
+
const toggle = screen.getByTestId("toggle2");
|
|
23
|
+
|
|
24
|
+
expect(toggle).toHaveAttribute("aria-checked", "true");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("sets correct attributes on active toggle", () => {
|
|
28
|
+
render(<TestToggleGroup defaultValue="toggle2" />);
|
|
29
|
+
const toggle = screen.getByTestId("toggle2");
|
|
30
|
+
|
|
31
|
+
expect(toggle).toHaveAttribute("aria-checked", "true");
|
|
32
|
+
expect(toggle).toHaveAttribute("role", "radio");
|
|
33
|
+
expect(toggle).toHaveAttribute("type", "button");
|
|
34
|
+
expect(toggle).toHaveAttribute("tabindex", "-1");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("sets correct attributes on idle toggle", () => {
|
|
38
|
+
render(<TestToggleGroup defaultValue="toggle1" />);
|
|
39
|
+
const toggle = screen.getByTestId("toggle2");
|
|
40
|
+
|
|
41
|
+
expect(toggle).toHaveAttribute("aria-checked", "false");
|
|
42
|
+
expect(toggle).toHaveAttribute("role", "radio");
|
|
43
|
+
expect(toggle).toHaveAttribute("type", "button");
|
|
44
|
+
expect(toggle).toHaveAttribute("tabindex", "-1");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("sets tabindex to 0 when focused", () => {
|
|
48
|
+
render(<TestToggleGroup defaultValue="toggle2" />);
|
|
49
|
+
const toggle = screen.getByTestId("toggle2");
|
|
50
|
+
|
|
51
|
+
fireEvent.focus(toggle);
|
|
52
|
+
expect(toggle).toHaveAttribute("tabindex", "0");
|
|
53
|
+
});
|
|
54
|
+
});
|
package/src/tooltip/Tooltip.tsx
CHANGED
|
@@ -12,14 +12,8 @@ import {
|
|
|
12
12
|
useInteractions,
|
|
13
13
|
} from "@floating-ui/react";
|
|
14
14
|
import cl from "clsx";
|
|
15
|
-
import React, {
|
|
16
|
-
|
|
17
|
-
cloneElement,
|
|
18
|
-
forwardRef,
|
|
19
|
-
useContext,
|
|
20
|
-
useRef,
|
|
21
|
-
} from "react";
|
|
22
|
-
import { ModalContext } from "../modal/ModalContext";
|
|
15
|
+
import React, { HTMLAttributes, cloneElement, forwardRef, useRef } from "react";
|
|
16
|
+
import { useModalContext } from "../modal/Modal.context";
|
|
23
17
|
import Portal from "../overlays/portal/Portal";
|
|
24
18
|
import { Detail } from "../typography";
|
|
25
19
|
import { useId } from "../util/hooks";
|
|
@@ -121,7 +115,7 @@ export const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(
|
|
|
121
115
|
});
|
|
122
116
|
|
|
123
117
|
const arrowRef = useRef<HTMLDivElement | null>(null);
|
|
124
|
-
const modalContext =
|
|
118
|
+
const modalContext = useModalContext(false);
|
|
125
119
|
const rootElement = modalContext ? modalContext.ref.current : undefined;
|
|
126
120
|
|
|
127
121
|
const {
|
|
@@ -195,7 +189,7 @@ export const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(
|
|
|
195
189
|
: children?.props["aria-describedby"],
|
|
196
190
|
}),
|
|
197
191
|
)}
|
|
198
|
-
<Portal rootElement={rootElement}>
|
|
192
|
+
<Portal rootElement={rootElement} asChild>
|
|
199
193
|
{_open && (
|
|
200
194
|
<div
|
|
201
195
|
{...getFloatingProps({
|
|
@@ -8,6 +8,9 @@ const meta = {
|
|
|
8
8
|
title: "ds-react/Typography/BodyLong",
|
|
9
9
|
component: BodyLong,
|
|
10
10
|
decorators: [(story) => <div style={{ maxWidth: "700px" }}>{story()}</div>],
|
|
11
|
+
parameters: {
|
|
12
|
+
chromatic: { disable: true },
|
|
13
|
+
},
|
|
11
14
|
} satisfies Meta<typeof BodyLong>;
|
|
12
15
|
|
|
13
16
|
export default meta;
|
|
@@ -17,7 +20,7 @@ type Story = StoryObj<typeof meta>;
|
|
|
17
20
|
const lorem =
|
|
18
21
|
"Hvis du ikke bor sammen med begge foreldrene dine, kan du ha rett til barnebidrag fra en eller begge foreldre mens du fullfører videregående skole eller tilsvarende.";
|
|
19
22
|
|
|
20
|
-
export const
|
|
23
|
+
export const Controls: Story = {
|
|
21
24
|
args: {
|
|
22
25
|
spacing: false,
|
|
23
26
|
children: lorem,
|
|
@@ -162,3 +165,46 @@ export const OverrideTag: Story = {
|
|
|
162
165
|
expect(legendBodyLong.tagName).toEqual("LEGEND");
|
|
163
166
|
},
|
|
164
167
|
};
|
|
168
|
+
|
|
169
|
+
export const Chromatic: Story = {
|
|
170
|
+
render: (...props) => (
|
|
171
|
+
<div>
|
|
172
|
+
<div>
|
|
173
|
+
<h2>Large</h2>
|
|
174
|
+
<h3>Size</h3>
|
|
175
|
+
{SizeLarge.render?.(...props)}
|
|
176
|
+
<h3>Spacing</h3>
|
|
177
|
+
{SpacingLarge.render?.(...props)}
|
|
178
|
+
</div>
|
|
179
|
+
<div>
|
|
180
|
+
<h2>Medium</h2>
|
|
181
|
+
<h3>Size</h3>
|
|
182
|
+
{SizeMedium.render?.(...props)}
|
|
183
|
+
<h3>Spacing</h3>
|
|
184
|
+
{SpacingMedium.render?.(...props)}
|
|
185
|
+
</div>
|
|
186
|
+
<div>
|
|
187
|
+
<h2>Small</h2>
|
|
188
|
+
<h3>Size</h3>
|
|
189
|
+
{SizeSmall.render?.(...props)}
|
|
190
|
+
<h3>Spacing</h3>
|
|
191
|
+
{SpacingSmall.render?.(...props)}
|
|
192
|
+
</div>
|
|
193
|
+
<div>
|
|
194
|
+
<h2>Colors</h2>
|
|
195
|
+
{Colors.render?.(...props)}
|
|
196
|
+
</div>
|
|
197
|
+
<div>
|
|
198
|
+
<h2>Align</h2>
|
|
199
|
+
{Align.render?.(...props)}
|
|
200
|
+
</div>
|
|
201
|
+
<div>
|
|
202
|
+
<h2>Override Tag</h2>
|
|
203
|
+
{OverrideTag.render?.(...props)}
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
),
|
|
207
|
+
parameters: {
|
|
208
|
+
chromatic: { disable: false },
|
|
209
|
+
},
|
|
210
|
+
};
|