@navikt/ds-react 6.0.0-alpha.7 → 6.0.0

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.
Files changed (124) hide show
  1. package/cjs/date/parts/DateWrapper.js +2 -2
  2. package/cjs/date/parts/DateWrapper.js.map +1 -1
  3. package/cjs/form/error-summary/ErrorSummary.d.ts +3 -9
  4. package/cjs/form/error-summary/ErrorSummary.js +9 -4
  5. package/cjs/form/error-summary/ErrorSummary.js.map +1 -1
  6. package/cjs/form/error-summary/ErrorSummaryItem.d.ts +1 -1
  7. package/cjs/form/error-summary/ErrorSummaryItem.js +1 -2
  8. package/cjs/form/error-summary/ErrorSummaryItem.js.map +1 -1
  9. package/cjs/form/search/Search.d.ts +1 -1
  10. package/cjs/form/search/Search.js +1 -1
  11. package/cjs/index.js +1 -0
  12. package/cjs/index.js.map +1 -1
  13. package/cjs/modal/Modal.context.d.ts +9 -0
  14. package/cjs/modal/Modal.context.js +10 -0
  15. package/cjs/modal/Modal.context.js.map +1 -0
  16. package/cjs/modal/Modal.js +3 -6
  17. package/cjs/modal/Modal.js.map +1 -1
  18. package/cjs/modal/ModalHeader.js +2 -6
  19. package/cjs/modal/ModalHeader.js.map +1 -1
  20. package/cjs/modal/types.d.ts +24 -3
  21. package/cjs/panel/Panel.d.ts +9 -16
  22. package/cjs/panel/Panel.js +6 -16
  23. package/cjs/panel/Panel.js.map +1 -1
  24. package/cjs/popover/Popover.js +2 -2
  25. package/cjs/popover/Popover.js.map +1 -1
  26. package/cjs/table/types.d.ts +1 -1
  27. package/cjs/tooltip/Tooltip.js +3 -3
  28. package/cjs/tooltip/Tooltip.js.map +1 -1
  29. package/cjs/util/create-context.d.ts +2 -5
  30. package/cjs/util/create-context.js +9 -5
  31. package/cjs/util/create-context.js.map +1 -1
  32. package/cjs/util/types/OverridableComponent.d.ts +1 -1
  33. package/esm/date/parts/DateWrapper.js +3 -3
  34. package/esm/date/parts/DateWrapper.js.map +1 -1
  35. package/esm/form/error-summary/ErrorSummary.d.ts +3 -9
  36. package/esm/form/error-summary/ErrorSummary.js +10 -5
  37. package/esm/form/error-summary/ErrorSummary.js.map +1 -1
  38. package/esm/form/error-summary/ErrorSummaryItem.d.ts +1 -1
  39. package/esm/form/error-summary/ErrorSummaryItem.js +1 -2
  40. package/esm/form/error-summary/ErrorSummaryItem.js.map +1 -1
  41. package/esm/form/search/Search.d.ts +1 -1
  42. package/esm/form/search/Search.js +1 -1
  43. package/esm/index.js +1 -0
  44. package/esm/index.js.map +1 -1
  45. package/esm/modal/Modal.context.d.ts +9 -0
  46. package/esm/modal/Modal.context.js +6 -0
  47. package/esm/modal/Modal.context.js.map +1 -0
  48. package/esm/modal/Modal.js +3 -6
  49. package/esm/modal/Modal.js.map +1 -1
  50. package/esm/modal/ModalHeader.js +3 -7
  51. package/esm/modal/ModalHeader.js.map +1 -1
  52. package/esm/modal/types.d.ts +24 -3
  53. package/esm/panel/Panel.d.ts +9 -16
  54. package/esm/panel/Panel.js +6 -16
  55. package/esm/panel/Panel.js.map +1 -1
  56. package/esm/popover/Popover.js +2 -2
  57. package/esm/popover/Popover.js.map +1 -1
  58. package/esm/table/types.d.ts +1 -1
  59. package/esm/tooltip/Tooltip.js +4 -4
  60. package/esm/tooltip/Tooltip.js.map +1 -1
  61. package/esm/util/create-context.d.ts +2 -5
  62. package/esm/util/create-context.js +10 -6
  63. package/esm/util/create-context.js.map +1 -1
  64. package/esm/util/types/OverridableComponent.d.ts +1 -1
  65. package/package.json +6 -6
  66. package/src/accordion/accordion.stories.tsx +121 -135
  67. package/src/button/button.stories.tsx +88 -185
  68. package/src/chat/chat.stories.tsx +285 -186
  69. package/src/date/datepicker/datepicker.stories.tsx +6 -2
  70. package/src/date/monthpicker/monthpicker.stories.tsx +2 -1
  71. package/src/date/parts/DateWrapper.tsx +3 -3
  72. package/src/dropdown/dropdown.stories.tsx +1 -1
  73. package/src/form/error-summary/ErrorSummary.tsx +11 -15
  74. package/src/form/error-summary/ErrorSummaryItem.tsx +8 -10
  75. package/src/form/error-summary/error-summary.stories.tsx +2 -56
  76. package/src/form/search/Search.tsx +4 -4
  77. package/src/form/stories/confirmation-panel.stories.tsx +1 -1
  78. package/src/form/stories/textarea.stories.tsx +1 -1
  79. package/src/help-text/help-text.stories.tsx +2 -1
  80. package/src/index.ts +1 -0
  81. package/src/internal-header/header.stories.tsx +2 -1
  82. package/src/layout/bleed/Bleed.stories.tsx +2 -1
  83. package/src/layout/box/Box.stories.tsx +2 -1
  84. package/src/layout/sidemal-test/navno-sidemal.stories.tsx +4 -1
  85. package/src/link/stories/link.stories.tsx +20 -22
  86. package/src/link-panel/link-panel.stories.tsx +1 -1
  87. package/src/list/list.stories.tsx +2 -1
  88. package/src/loader/loader.stories.tsx +1 -1
  89. package/src/modal/Modal.context.ts +13 -0
  90. package/src/modal/Modal.test.tsx +2 -2
  91. package/src/modal/Modal.tsx +6 -8
  92. package/src/modal/ModalHeader.tsx +3 -7
  93. package/src/modal/modal.stories.tsx +33 -6
  94. package/src/modal/types.ts +21 -4
  95. package/src/panel/Panel.tsx +9 -16
  96. package/src/popover/Popover.tsx +2 -2
  97. package/src/stepper/stepper.stories.tsx +1 -1
  98. package/src/table/stories/{table.stories.tsx → table-1.stories.tsx} +118 -92
  99. package/src/table/stories/{table-expandable.stories.tsx → table-2-expandable.stories.tsx} +10 -34
  100. package/src/table/stories/{table-async.stories.tsx → table-3-async.stories.tsx} +5 -3
  101. package/src/table/stories/tests/table.stories.tsx +4 -1
  102. package/src/table/types.ts +1 -1
  103. package/src/tabs/Tabs.test.tsx +109 -0
  104. package/src/toggle-group/ToggleGroup.test.tsx +54 -0
  105. package/src/tooltip/Tooltip.tsx +4 -10
  106. package/src/tooltip/tooltip.stories.tsx +4 -1
  107. package/src/typography/stories/bodylong.stories.tsx +49 -3
  108. package/src/typography/stories/bodyshort.stories.tsx +50 -4
  109. package/src/typography/stories/detail.stories.tsx +32 -3
  110. package/src/typography/stories/error-message.stories.tsx +34 -3
  111. package/src/typography/stories/heading.stories.tsx +32 -3
  112. package/src/typography/stories/label.stories.tsx +38 -3
  113. package/src/util/create-context.tsx +26 -15
  114. package/src/util/types/OverridableComponent.ts +1 -1
  115. package/_docs.json +0 -20247
  116. package/cjs/modal/ModalContext.d.ts +0 -7
  117. package/cjs/modal/ModalContext.js +0 -9
  118. package/cjs/modal/ModalContext.js.map +0 -1
  119. package/esm/modal/ModalContext.d.ts +0 -7
  120. package/esm/modal/ModalContext.js +0 -3
  121. package/esm/modal/ModalContext.js.map +0 -1
  122. package/src/modal/ModalContext.ts +0 -7
  123. package/src/panel/panel.stories.tsx +0 -63
  124. package/src/typography/stories/ingress.stories.tsx +0 -50
@@ -1,16 +1,27 @@
1
1
  import React, { useState } from "react";
2
2
  import { Table, TableProps } from "../";
3
- import { Alert, Button, Checkbox, CheckboxGroup, Link } from "../..";
3
+ import { Button } from "../../button";
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";
4
11
 
5
12
  export default {
6
13
  title: "ds-react/Table",
7
14
  component: Table,
15
+ parameters: {
16
+ chromatic: { disable: true },
17
+ },
8
18
  };
9
19
 
10
20
  interface Props extends TableProps {
11
21
  button?: boolean;
12
22
  shadeOnHover?: boolean;
13
23
  }
24
+
14
25
  const TableComponent = ({ button, shadeOnHover, ...rest }: Props) => (
15
26
  <Table {...rest}>
16
27
  <Table.Header>
@@ -89,75 +100,59 @@ export const Buttons = () => <TableComponent size="small" button />;
89
100
 
90
101
  export const WithDivs = () => {
91
102
  return (
92
- <>
93
- <Alert variant="warning">
94
- Obs! Hvis man skal bygge tabeller uten å bruke vanlig {"<tabell> "}
95
- -markup er det svært viktig at man supplerer elementene med{" "}
96
- <Link href="https://www.w3.org/TR/wai-aria-practices-1.1/examples/table/table.html">
97
- riktige
98
- </Link>{" "}
99
- role-attributter og display-stiler for å bevare den semantiske verdien i
100
- tabellene. Vi anbefaler fortsatt å ikke ta i bruk denne metoden hvis
101
- mulig, da nettleseren ikke kan tolke tabellen like bra uten riktig
102
- markup.
103
- </Alert>
104
- <div className="navds-table" role="table">
105
- <div className="navds-table__header" role="rowgroup">
106
- <div className="navds-table__row" role="row">
107
- <div className="navds-table__header-cell" role="columnheader">
108
- Fornavn
109
- </div>
110
- <div className="navds-table__header-cell" role="columnheader">
111
- Etternavn
112
- </div>
113
- <div className="navds-table__header-cell" role="columnheader">
114
- Rolle
115
- </div>
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
116
138
  </div>
117
139
  </div>
118
- <div className="navds-table__body" role="rowgroup">
119
- <div className="navds-table__row" role="row">
120
- <div className="navds-table__data-cell" role="cell">
121
- Jean-Luc
122
- </div>
123
- <div className="navds-table__data-cell" role="cell">
124
- Picard
125
- </div>
126
- <div className="navds-table__data-cell" role="cell">
127
- Kaptein
128
- </div>
140
+ <div className="navds-table__row" role="row">
141
+ <div className="navds-table__data-cell" role="cell">
142
+ Geordi
129
143
  </div>
130
- <div className="navds-table__row" role="row">
131
- <div className="navds-table__data-cell" role="cell">
132
- William
133
- </div>
134
- <div className="navds-table__data-cell" role="cell">
135
- Riker
136
- </div>
137
- <div className="navds-table__data-cell" role="cell">
138
- Kommandør
139
- </div>
144
+ <div className="navds-table__data-cell" role="cell">
145
+ La Forge
140
146
  </div>
141
- <div className="navds-table__row" role="row">
142
- <div className="navds-table__data-cell" role="cell">
143
- Geordi
144
- </div>
145
- <div className="navds-table__data-cell" role="cell">
146
- La Forge
147
- </div>
148
- <div className="navds-table__data-cell" role="cell">
149
- Sjefsingeniør
150
- </div>
147
+ <div className="navds-table__data-cell" role="cell">
148
+ Sjefsingeniør
151
149
  </div>
152
150
  </div>
153
151
  </div>
154
- </>
152
+ </div>
155
153
  );
156
154
  };
157
155
 
158
- export const Selection = () => <SelectionTable />;
159
- export const SelectionSmall = () => <SelectionTable size="small" />;
160
-
161
156
  const SelectionTable = ({ size = "medium" }: { size?: "small" | "medium" }) => {
162
157
  const useToggleList = (initialState) => {
163
158
  const [list, setList] = useState(initialState);
@@ -182,7 +177,7 @@ const SelectionTable = ({ size = "medium" }: { size?: "small" | "medium" }) => {
182
177
  <Table.DataCell>
183
178
  <Checkbox
184
179
  size={size}
185
- checked={selectedRows.includes("all")}
180
+ indeterminate
186
181
  onChange={() => toggleSelectedRow("all")}
187
182
  >
188
183
  Select all
@@ -212,12 +207,12 @@ const SelectionTable = ({ size = "medium" }: { size?: "small" | "medium" }) => {
212
207
  <Table.DataCell>USA</Table.DataCell>
213
208
  <Table.DataCell>38</Table.DataCell>
214
209
  </Table.Row>
215
- <Table.Row selected={selectedRows.includes("2")}>
210
+ <Table.Row selected>
216
211
  <Table.DataCell>
217
212
  <Checkbox
218
213
  size={size}
219
214
  hideLabel
220
- checked={selectedRows.includes("2")}
215
+ checked
221
216
  onChange={() => toggleSelectedRow("2")}
222
217
  aria-labelledby={`x_r2-${size}`}
223
218
  >
@@ -231,36 +226,67 @@ const SelectionTable = ({ size = "medium" }: { size?: "small" | "medium" }) => {
231
226
  <Table.DataCell>Denmark</Table.DataCell>
232
227
  <Table.DataCell>11</Table.DataCell>
233
228
  </Table.Row>
234
- <Table.Row selected={selectedRows.includes("3")}>
235
- <Table.DataCell>
236
- <CheckboxGroup legend="velg flere felt" hideLegend>
237
- <Checkbox
238
- size={size}
239
- hideLabel
240
- checked={selectedRows.includes("3")}
241
- onChange={() => toggleSelectedRow("3")}
242
- aria-labelledby={`x_r3-${size}`}
243
- >
244
- {" "}
245
- </Checkbox>
246
- <Checkbox
247
- size={size}
248
- hideLabel
249
- checked={selectedRows.includes("3")}
250
- onChange={() => toggleSelectedRow("3")}
251
- aria-labelledby={`x_r3-${size}`}
252
- >
253
- {" "}
254
- </Checkbox>
255
- </CheckboxGroup>
256
- </Table.DataCell>
257
- <Table.HeaderCell scope="row" colSpan={4}>
258
- <span id={`x_r3-${size}`}>
259
- Don&apos;t stack multiple checkboxes
260
- </span>
261
- </Table.HeaderCell>
262
- </Table.Row>
263
229
  </Table.Body>
264
230
  </Table>
265
231
  );
266
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
+ };
@@ -1,10 +1,15 @@
1
1
  import React, { useState } from "react";
2
- import { Table } from "..";
3
- import { Button, Checkbox, Link } from "../..";
2
+ import { Button } from "../../button";
3
+ import { Checkbox } from "../../form";
4
+ import { Link } from "../../link";
5
+ import Table from "../Table";
4
6
 
5
7
  export default {
6
8
  title: "ds-react/Table",
7
9
  component: Table,
10
+ parameters: {
11
+ chromatic: { disable: true },
12
+ },
8
13
  };
9
14
 
10
15
  export const Expandable = () => {
@@ -25,6 +30,7 @@ export const Expandable = () => {
25
30
  content={row.content}
26
31
  key={row.name}
27
32
  togglePlacement="right"
33
+ defaultOpen
28
34
  >
29
35
  {columns.map(({ key }) => (
30
36
  <Table.DataCell key={key}>{row[key]}</Table.DataCell>
@@ -50,7 +56,7 @@ export const ExpandableLarge = () => {
50
56
  </Table.Header>
51
57
  <Table.Body>
52
58
  {data.slice(0, 1).map((row) => (
53
- <Table.ExpandableRow content={row.content} key={row.name}>
59
+ <Table.ExpandableRow defaultOpen content={row.content} key={row.name}>
54
60
  {columns.map(({ key }) => (
55
61
  <Table.DataCell key={key}>{row[key]}</Table.DataCell>
56
62
  ))}
@@ -87,7 +93,7 @@ export const ExpandableSmall = () => {
87
93
  </Table.Header>
88
94
  <Table.Body>
89
95
  {data.slice(0, 1).map((row) => (
90
- <Table.ExpandableRow content={row.content} key={row.name}>
96
+ <Table.ExpandableRow defaultOpen content={row.content} key={row.name}>
91
97
  {columns.map(({ key }) => (
92
98
  <Table.DataCell key={key}>{row[key]}</Table.DataCell>
93
99
  ))}
@@ -235,36 +241,6 @@ const data = [
235
241
  },
236
242
  ];
237
243
 
238
- export const ExpandableOpen = () => {
239
- return (
240
- <Table zebraStripes>
241
- <Table.Header>
242
- <Table.Row>
243
- {columns.map(({ key, name }) => (
244
- <Table.HeaderCell key={key}>{name}</Table.HeaderCell>
245
- ))}
246
- <Table.HeaderCell />
247
- </Table.Row>
248
- </Table.Header>
249
- <Table.Body>
250
- {data.map((row) => (
251
- <Table.ExpandableRow
252
- expansionDisabled={row.animal === "Sel"}
253
- content={row.content}
254
- key={row.name}
255
- togglePlacement="right"
256
- defaultOpen
257
- >
258
- {columns.map(({ key }) => (
259
- <Table.DataCell key={key}>{row[key]}</Table.DataCell>
260
- ))}
261
- </Table.ExpandableRow>
262
- ))}
263
- </Table.Body>
264
- </Table>
265
- );
266
- };
267
-
268
244
  export const ClickableRow = () => {
269
245
  const [isRowOpen1, setIsRowOpen1] = useState(false);
270
246
  const [isRowOpen2, setIsRowOpen2] = useState(false);
@@ -1,14 +1,16 @@
1
1
  import React, { useState } from "react";
2
2
  import useSWR from "swr";
3
- import { Loader, Pagination, SortState } from "../..";
4
- import { Table } from "../index";
3
+ import { Loader } from "../../loader";
4
+ import { Pagination } from "../../pagination";
5
+ import Table from "../Table";
6
+ import { SortState } from "../types";
5
7
  import peopleJson from "./people.json";
6
8
 
7
9
  export default {
8
10
  title: "ds-react/Table",
9
11
  component: Table,
10
12
  parameters: {
11
- chromatic: { delay: 500 },
13
+ chromatic: { disable: true },
12
14
  },
13
15
  };
14
16
 
@@ -1,10 +1,13 @@
1
1
  import { expect, fn, userEvent, within } from "@storybook/test";
2
2
  import React from "react";
3
- import { Table } from "../..";
3
+ import Table from "../../Table";
4
4
 
5
5
  export default {
6
6
  title: "ds-react/Table/Tests",
7
7
  component: Table,
8
+ parameters: {
9
+ chromatic: { disable: true },
10
+ },
8
11
  };
9
12
 
10
13
  export const ClickableRowTest = {
@@ -1,4 +1,4 @@
1
1
  export interface SortState {
2
2
  orderBy: string;
3
- direction: "ascending" | "descending";
3
+ direction: "ascending" | "descending" | "none";
4
4
  }
@@ -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
+ });
@@ -12,14 +12,8 @@ import {
12
12
  useInteractions,
13
13
  } from "@floating-ui/react";
14
14
  import cl from "clsx";
15
- import React, {
16
- HTMLAttributes,
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 = useContext(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({
@@ -1,6 +1,9 @@
1
1
  import { Meta } from "@storybook/react";
2
2
  import React from "react";
3
- import { Alert, Button, Search, Tooltip } from "..";
3
+ import { Alert } from "../alert";
4
+ import { Button } from "../button";
5
+ import { Search } from "../form";
6
+ import Tooltip from "./Tooltip";
4
7
 
5
8
  export default {
6
9
  title: "ds-react/Tooltip",
@@ -1,13 +1,16 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { expect, within } from "@storybook/test";
3
3
  import React from "react";
4
- import { BodyLong } from "..";
5
- import { VStack } from "../..";
4
+ import { VStack } from "../../layout/stack";
5
+ import BodyLong from "../BodyLong";
6
6
 
7
7
  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 Default: Story = {
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
+ };