@onewelcome/react-lib-components 1.2.0 → 1.4.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 (97) hide show
  1. package/dist/Button/IconButton.d.ts +2 -1
  2. package/dist/DataGrid/DataGrid.d.ts +1 -0
  3. package/dist/DataGrid/DataGridActions/DataGridActions.d.ts +2 -1
  4. package/dist/Form/Form.d.ts +3 -3
  5. package/dist/Notifications/SlideInModal/SlideInModal.d.ts +1 -1
  6. package/dist/Tabs/Tab.d.ts +5 -9
  7. package/dist/Tabs/TabButton.d.ts +3 -6
  8. package/dist/Tabs/Tabs.d.ts +1 -2
  9. package/dist/hooks/useDebouncedCallback.d.ts +1 -0
  10. package/dist/index.d.ts +1 -0
  11. package/dist/react-lib-components.cjs.development.js +472 -395
  12. package/dist/react-lib-components.cjs.development.js.map +1 -1
  13. package/dist/react-lib-components.cjs.production.min.js +1 -1
  14. package/dist/react-lib-components.cjs.production.min.js.map +1 -1
  15. package/dist/react-lib-components.esm.js +473 -397
  16. package/dist/react-lib-components.esm.js.map +1 -1
  17. package/package.json +1 -1
  18. package/src/Breadcrumbs/Breadcrumbs.tsx +46 -38
  19. package/src/Button/BaseButton.tsx +23 -20
  20. package/src/Button/Button.module.scss +9 -0
  21. package/src/Button/Button.tsx +40 -40
  22. package/src/Button/IconButton.tsx +28 -28
  23. package/src/ContextMenu/ContextMenu.tsx +161 -160
  24. package/src/ContextMenu/ContextMenuItem.tsx +55 -49
  25. package/src/DataGrid/DataGrid.tsx +1 -0
  26. package/src/DataGrid/DataGridActions/DataGridActions.module.scss +1 -1
  27. package/src/DataGrid/DataGridActions/DataGridActions.test.tsx +4 -2
  28. package/src/DataGrid/DataGridActions/DataGridActions.tsx +95 -87
  29. package/src/DataGrid/DataGridActions/DataGridColumnsToggle.tsx +64 -64
  30. package/src/DataGrid/DataGridBody/DataGridCell.tsx +42 -44
  31. package/src/DataGrid/DataGridBody/DataGridRow.tsx +29 -29
  32. package/src/DataGrid/DataGridHeader/DataGridHeader.tsx +78 -78
  33. package/src/DataGrid/DataGridHeader/DataGridHeaderCell.tsx +48 -48
  34. package/src/Form/Checkbox/Checkbox.tsx +134 -130
  35. package/src/Form/Fieldset/Fieldset.tsx +81 -78
  36. package/src/Form/Form.tsx +9 -4
  37. package/src/Form/FormControl/FormControl.module.scss +1 -20
  38. package/src/Form/FormControl/FormControl.tsx +36 -35
  39. package/src/Form/FormGroup/FormGroup.tsx +62 -62
  40. package/src/Form/FormHelperText/FormHelperText.tsx +19 -18
  41. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.tsx +58 -53
  42. package/src/Form/Input/Input.tsx +90 -87
  43. package/src/Form/Label/Label.tsx +17 -16
  44. package/src/Form/Radio/Radio.tsx +91 -91
  45. package/src/Form/Select/Option.tsx +66 -60
  46. package/src/Form/Select/Select.tsx +207 -209
  47. package/src/Form/Textarea/Textarea.tsx +51 -53
  48. package/src/Form/Toggle/Toggle.tsx +26 -23
  49. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.tsx +51 -43
  50. package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +112 -106
  51. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.tsx +67 -62
  52. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +42 -37
  53. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +94 -94
  54. package/src/Form/Wrapper/Wrapper/Wrapper.tsx +73 -73
  55. package/src/Icon/Icon.module.scss +1 -0
  56. package/src/Icon/Icon.tsx +19 -16
  57. package/src/Link/Link.tsx +68 -63
  58. package/src/Notifications/BaseModal/BaseModal.tsx +68 -68
  59. package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.tsx +13 -10
  60. package/src/Notifications/BaseModal/BaseModalContent/BaseModalContent.tsx +33 -25
  61. package/src/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.tsx +20 -17
  62. package/src/Notifications/Dialog/Dialog.tsx +83 -83
  63. package/src/Notifications/Dialog/DialogActions/DialogActions.tsx +17 -14
  64. package/src/Notifications/Dialog/DialogTitle/DialogTitle.tsx +15 -12
  65. package/src/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.tsx +40 -40
  66. package/src/Notifications/SlideInModal/SlideInModal.module.scss +5 -5
  67. package/src/Notifications/SlideInModal/SlideInModal.test.tsx +7 -2
  68. package/src/Notifications/SlideInModal/SlideInModal.tsx +47 -27
  69. package/src/Pagination/Pagination.tsx +169 -169
  70. package/src/Popover/Popover.module.scss +1 -0
  71. package/src/Popover/Popover.tsx +43 -33
  72. package/src/ProgressBar/ProgressBar.tsx +17 -14
  73. package/src/Skeleton/Skeleton.tsx +23 -20
  74. package/src/StatusIndicator/StatusIndicator.tsx +18 -15
  75. package/src/Tabs/{TabPanel.module.scss → Tab.module.scss} +1 -1
  76. package/src/Tabs/Tab.test.tsx +1 -39
  77. package/src/Tabs/Tab.tsx +16 -10
  78. package/src/Tabs/TabButton.module.scss +0 -4
  79. package/src/Tabs/TabButton.test.tsx +3 -31
  80. package/src/Tabs/TabButton.tsx +35 -49
  81. package/src/Tabs/Tabs.test.tsx +40 -33
  82. package/src/Tabs/Tabs.tsx +107 -101
  83. package/src/TextEllipsis/TextEllipsis.tsx +50 -41
  84. package/src/Tiles/Tile.tsx +58 -56
  85. package/src/Tiles/Tiles.tsx +44 -41
  86. package/src/Tooltip/Tooltip.tsx +101 -100
  87. package/src/Typography/Typography.tsx +47 -44
  88. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.tsx +55 -52
  89. package/src/Wizard/WizardSteps/WizardSteps.tsx +25 -22
  90. package/src/hooks/useDebouncedCallback.test.ts +140 -0
  91. package/src/hooks/useDebouncedCallback.tsx +32 -0
  92. package/src/index.ts +1 -0
  93. package/src/mixins.module.scss +2 -2
  94. package/src/util/helper.test.tsx +0 -28
  95. package/dist/Tabs/TabPanel.d.ts +0 -8
  96. package/src/Tabs/TabPanel.test.tsx +0 -92
  97. package/src/Tabs/TabPanel.tsx +0 -43
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React, { ComponentPropsWithRef } from "react";
17
+ import React, { ForwardRefRenderFunction, ComponentPropsWithRef } from "react";
18
18
  import classes from "./Skeleton.module.scss";
19
19
 
20
20
  export interface Props extends Omit<ComponentPropsWithRef<"div">, "children"> {
@@ -23,23 +23,26 @@ export interface Props extends Omit<ComponentPropsWithRef<"div">, "children"> {
23
23
  width?: number | string;
24
24
  }
25
25
 
26
- export const Skeleton = React.forwardRef<HTMLDivElement, Props>(
27
- ({ variant = "text", height, width, className, style, ...rest }: Props, ref) => {
28
- const classNames = [classes["skeleton"]];
29
- !height && classNames.push(classes["no-height"]);
30
- variant === "text" && classNames.push(classes["text"]);
31
- variant === "circular" && classNames.push(classes["circular"]);
32
- className && classNames.push(className);
26
+ const SkeletonComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
27
+ { variant = "text", height, width, className, style, ...rest }: Props,
28
+ ref
29
+ ) => {
30
+ const classNames = [classes["skeleton"]];
31
+ !height && classNames.push(classes["no-height"]);
32
+ variant === "text" && classNames.push(classes["text"]);
33
+ variant === "circular" && classNames.push(classes["circular"]);
34
+ className && classNames.push(className);
33
35
 
34
- return (
35
- <span
36
- {...rest}
37
- aria-busy="true"
38
- aria-hidden="true"
39
- ref={ref}
40
- style={{ ...style, width, height }}
41
- className={classNames.join(" ")}
42
- ></span>
43
- );
44
- }
45
- );
36
+ return (
37
+ <span
38
+ {...rest}
39
+ aria-busy="true"
40
+ aria-hidden="true"
41
+ ref={ref}
42
+ style={{ ...style, width, height }}
43
+ className={classNames.join(" ")}
44
+ ></span>
45
+ );
46
+ };
47
+
48
+ export const Skeleton = React.forwardRef(SkeletonComponent);
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React, { ComponentPropsWithRef, ReactNode } from "react";
17
+ import React, { ForwardRefRenderFunction, ComponentPropsWithRef, ReactNode } from "react";
18
18
  import { Typography, Props as TypographyProps } from "../Typography/Typography";
19
19
  import classes from "./StatusIndicator.module.scss";
20
20
 
@@ -25,17 +25,20 @@ export interface Props extends ComponentPropsWithRef<"div"> {
25
25
  typographyProps?: TypographyProps;
26
26
  }
27
27
 
28
- export const StatusIndicator = React.forwardRef<HTMLDivElement, Props>(
29
- ({ children, status, badgeProps, typographyProps, ...rest }: Props, ref) => {
30
- return (
31
- <div {...rest} className={classes["status-indicator"]} ref={ref}>
32
- <div
33
- className={`${classes["status-badge"]} ${classes[status]} ${badgeProps?.className ?? ""}`}
34
- />
35
- <Typography {...typographyProps} spacing={{ margin: "0" }} variant="body" tag="div">
36
- {typographyProps?.children || children}
37
- </Typography>
38
- </div>
39
- );
40
- }
41
- );
28
+ const StatusIndicatorComponent: ForwardRefRenderFunction<HTMLDivElement, Props> = (
29
+ { children, status, badgeProps, typographyProps, ...rest }: Props,
30
+ ref
31
+ ) => {
32
+ return (
33
+ <div {...rest} className={classes["status-indicator"]} ref={ref}>
34
+ <div
35
+ className={`${classes["status-badge"]} ${classes[status]} ${badgeProps?.className ?? ""}`}
36
+ />
37
+ <Typography {...typographyProps} spacing={{ margin: "0" }} variant="body" tag="div">
38
+ {typographyProps?.children || children}
39
+ </Typography>
40
+ </div>
41
+ );
42
+ };
43
+
44
+ export const StatusIndicator = React.forwardRef(StatusIndicatorComponent);
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- .tabpanel {
17
+ .tab {
18
18
  display: none;
19
19
 
20
20
  &:focus-visible {
@@ -14,8 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React, { useEffect, useRef } from "react";
18
- import { Tabs } from "./Tabs";
17
+ import React from "react";
19
18
  import { Tab, Props } from "./Tab";
20
19
  import { render } from "@testing-library/react";
21
20
 
@@ -48,40 +47,3 @@ describe("Tab should render", () => {
48
47
  expect(tab).toBeTruthy();
49
48
  });
50
49
  });
51
-
52
- describe("Tab useRef should work for panel and button", () => {
53
- it("gives us back the proper refs", () => {
54
- type logRefsFunction = (
55
- buttonRef: React.RefObject<HTMLButtonElement>,
56
- panelRef: React.RefObject<HTMLDivElement>
57
- ) => void;
58
- const ExampleComponent = ({ logRefs }: { logRefs: logRefsFunction }) => {
59
- const ref1 = useRef<HTMLButtonElement>(null);
60
- const ref2 = useRef<HTMLDivElement>(null);
61
-
62
- useEffect(() => {
63
- if (ref1.current && ref2.current) {
64
- logRefs(ref1, ref2);
65
- }
66
- }, [ref1, ref2]);
67
-
68
- return (
69
- <Tabs>
70
- <Tab buttonRef={ref1} panelRef={ref2} title="ShouldBeButtonRef">
71
- <span>Should be panel ref</span>
72
- </Tab>
73
- </Tabs>
74
- );
75
- };
76
-
77
- const setCorrectText = (
78
- buttonRef: React.RefObject<HTMLButtonElement>,
79
- panelRef: React.RefObject<HTMLDivElement>
80
- ) => {
81
- expect(buttonRef.current?.innerHTML).toContain("ShouldBeButtonRef");
82
- expect(panelRef.current?.innerHTML).toEqual("<span>Should be panel ref</span>");
83
- };
84
-
85
- render(<ExampleComponent logRefs={setCorrectText} />);
86
- });
87
- });
package/src/Tabs/Tab.tsx CHANGED
@@ -14,20 +14,26 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React from "react";
17
+ import React, { HTMLProps } from "react";
18
+ import classes from "./Tab.module.scss";
18
19
 
19
- export interface Props {
20
+ export interface Props extends HTMLProps<HTMLDivElement> {
20
21
  title: string;
21
- children?: React.ReactNode;
22
- selected?: boolean;
23
- focussed?: boolean;
24
- buttonRef?: React.RefObject<HTMLButtonElement>;
25
- panelRef?: React.RefObject<HTMLDivElement>;
26
- onTabButtonClick?: () => void;
22
+ children?: unknown;
23
+ tabActive?: boolean;
27
24
  }
28
25
 
29
- export const Tab = (args: Props) => {
26
+ export const Tab = ({ children, tabActive, ...rest }: Props) => {
30
27
  return (
31
- <div {...args}>{`A <Tab /> component should only be used inside the <Tabs /> component.`}</div>
28
+ <div
29
+ {...rest}
30
+ aria-hidden={!tabActive}
31
+ role="tabpanel"
32
+ className={`${classes["tab"]} ${tabActive ? classes["selected"] : ""} ${
33
+ rest.className ?? ""
34
+ }`}
35
+ >
36
+ {children}
37
+ </div>
32
38
  );
33
39
  };
@@ -34,10 +34,6 @@
34
34
  outline-color: var(--color-focus);
35
35
  }
36
36
 
37
- &.focussed:not(:focus-visible) {
38
- outline: none;
39
- }
40
-
41
37
  span {
42
38
  color: var(--tab-text-color);
43
39
  font-weight: normal;
@@ -45,41 +45,13 @@ describe("Tab should render", () => {
45
45
  expect(tabButton).toBeTruthy();
46
46
  });
47
47
 
48
- it("should be selected when prop selected is passed", () => {
48
+ it("should be focussed when prop focused is passed", () => {
49
49
  const { tabButton } = createTabButton(defaultParams => ({
50
50
  ...defaultParams,
51
- selected: true
51
+ focused: true
52
52
  }));
53
53
 
54
- expect(tabButton).toHaveAttribute("aria-selected", "true");
55
- expect(tabButton).toHaveAttribute("tabIndex", "0");
56
- });
57
-
58
- it("should be focussed when prop focussed is passed", () => {
59
- const { tabButton } = createTabButton(defaultParams => ({
60
- ...defaultParams,
61
- focussed: true
62
- }));
63
-
64
- expect(tabButton).toHaveClass("focussed");
65
- });
66
-
67
- it("should set accessibility attributes when prop tabPanelId is passed", () => {
68
- const { tabButton } = createTabButton(defaultParams => ({
69
- ...defaultParams,
70
- tabPanelId: "fakeId"
71
- }));
72
-
73
- expect(tabButton).toHaveAttribute("aria-controls", "fakeId");
74
- });
75
-
76
- it("should set id attribute when prop tabId is passed", () => {
77
- const { tabButton } = createTabButton(defaultParams => ({
78
- ...defaultParams,
79
- tabId: "fakeId"
80
- }));
81
-
82
- expect(tabButton).toHaveAttribute("id", "fakeId");
54
+ expect(tabButton).toHaveFocus();
83
55
  });
84
56
 
85
57
  it("should set class when prop className is passed", () => {
@@ -14,61 +14,47 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React, { ComponentPropsWithRef, useEffect } from "react";
17
+ import React, {
18
+ ForwardRefRenderFunction,
19
+ ComponentPropsWithRef,
20
+ createRef,
21
+ RefObject,
22
+ useEffect
23
+ } from "react";
18
24
  import classes from "./TabButton.module.scss";
19
25
 
20
26
  export interface Props extends ComponentPropsWithRef<"button"> {
21
27
  children?: string;
22
- selected?: boolean;
23
- focussed?: boolean;
24
- tabId?: string;
25
- tabPanelId?: string;
26
- onTabButtonClick?: () => void;
28
+ tabActive?: boolean;
29
+ focused?: boolean;
27
30
  }
28
31
 
29
- export const TabButton = React.forwardRef<HTMLButtonElement, Props>(
30
- (
31
- {
32
- children,
33
- selected = false,
34
- focussed = false,
35
- tabId,
36
- tabPanelId,
37
- className,
38
- onTabButtonClick,
39
- ...rest
40
- }: Props,
41
- ref
42
- ) => {
43
- useEffect(() => {
44
- if (focussed && ref) {
45
- (ref as React.MutableRefObject<HTMLButtonElement>).current.focus();
46
- }
47
- }, [focussed]);
32
+ const TabButtonComponent: ForwardRefRenderFunction<HTMLButtonElement, Props> = (
33
+ { children, tabActive, focused, ...rest }: Props,
34
+ ref
35
+ ) => {
36
+ let buttonRef = (ref as RefObject<HTMLButtonElement>) || createRef<HTMLButtonElement>();
48
37
 
49
- const classNames = [classes["tabbutton"]];
38
+ useEffect(() => {
39
+ if (focused && buttonRef.current) {
40
+ buttonRef.current.focus();
41
+ }
42
+ }, [buttonRef.current, focused]);
50
43
 
51
- selected && classNames.push(classes["selected"]);
52
- focussed && !selected && classNames.push(classes["focussed"]);
53
- className && classNames.push(className);
44
+ return (
45
+ <button
46
+ {...rest}
47
+ className={`${classes["tabbutton"]} ${tabActive ? classes["selected"] : ""} ${
48
+ rest.className ?? ""
49
+ }`}
50
+ ref={buttonRef}
51
+ role="tab"
52
+ type="button"
53
+ >
54
+ <span aria-hidden="true">{children}</span>
55
+ {children}
56
+ </button>
57
+ );
58
+ };
54
59
 
55
- return (
56
- <button
57
- {...rest}
58
- aria-selected={selected}
59
- key={tabId}
60
- className={classNames.join(" ")}
61
- ref={ref}
62
- role="tab"
63
- tabIndex={selected ? 0 : -1}
64
- type="button"
65
- aria-controls={tabPanelId}
66
- id={tabId}
67
- onClick={onTabButtonClick}
68
- >
69
- <span aria-hidden="true">{children}</span>
70
- {children}
71
- </button>
72
- );
73
- }
74
- );
60
+ export const TabButton = React.forwardRef(TabButtonComponent);
@@ -19,13 +19,19 @@ import { Tabs, Props } from "./Tabs";
19
19
  import { render } from "@testing-library/react";
20
20
  import { TabButton as Tab } from "./TabButton";
21
21
  import userEvent from "@testing-library/user-event";
22
+ import { act } from "react-dom/test-utils";
22
23
 
23
24
  const defaultParams: Props = {
24
- "aria-label": "Entertainment",
25
25
  children: [
26
- <Tab title="Tab1">Tabpanel1 content</Tab>,
27
- <Tab title="Tab2">Tabpanel2 content</Tab>,
28
- <Tab title="Tab3">Tabpanel3 content</Tab>
26
+ <Tab key="tab1" title="Tab1">
27
+ Tabpanel1 content
28
+ </Tab>,
29
+ <Tab key="tab2" title="Tab2">
30
+ Tabpanel2 content
31
+ </Tab>,
32
+ <Tab key="tab3" title="Tab3">
33
+ Tabpanel3 content
34
+ </Tab>
29
35
  ]
30
36
  };
31
37
 
@@ -82,7 +88,7 @@ describe("Tabs should render", () => {
82
88
  expect(tabpanel3).toHaveClass("selected");
83
89
  });
84
90
 
85
- it("switches to tab and tabpanel when tab is clicked", () => {
91
+ it("switches to tab and tabpanel when tab is clicked", async () => {
86
92
  const { tabs } = createTabs(defaultParams => ({
87
93
  ...defaultParams
88
94
  }));
@@ -103,7 +109,7 @@ describe("Tabs should render", () => {
103
109
  expect(tabpanel1).toHaveClass("selected");
104
110
  expect(tabpanel3).not.toHaveClass("selected");
105
111
 
106
- userEvent.click(tab3);
112
+ await userEvent.click(tab3);
107
113
 
108
114
  tabButtons = tablist.querySelectorAll(".tabbutton");
109
115
 
@@ -120,7 +126,7 @@ describe("Tabs should render", () => {
120
126
  expect(tabpanel3).toHaveClass("selected");
121
127
  });
122
128
 
123
- it("triggers the onTabChange when switching tabs", () => {
129
+ it("triggers the onTabChange when switching tabs", async () => {
124
130
  const onTabChangeHandler = jest.fn();
125
131
 
126
132
  const { tabs } = createTabs(defaultParams => ({
@@ -133,7 +139,7 @@ describe("Tabs should render", () => {
133
139
 
134
140
  let tab3 = tabButtons[2] as HTMLButtonElement;
135
141
 
136
- userEvent.click(tab3);
142
+ await userEvent.click(tab3);
137
143
 
138
144
  expect(onTabChangeHandler).toHaveBeenCalled();
139
145
  });
@@ -149,7 +155,6 @@ describe("Tabs should not render other children then tab components", () => {
149
155
  );
150
156
 
151
157
  const tabs = queries.getByTestId("tabs");
152
-
153
158
  expect(tabs).toBeDefined();
154
159
  expect(tabs).toBeEmptyDOMElement;
155
160
  });
@@ -169,7 +174,9 @@ describe("Tabs should comply with accessibility rules", () => {
169
174
  let tabpanel1 = tabpanels.firstChild as HTMLDivElement;
170
175
  let tabpanel3 = tabpanels.lastChild as HTMLDivElement;
171
176
 
172
- tab1.focus();
177
+ act(() => {
178
+ tab1.focus();
179
+ });
173
180
 
174
181
  tabButtons = tablist.querySelectorAll(".tabbutton");
175
182
  tab1 = tabButtons[0] as HTMLButtonElement;
@@ -179,14 +186,13 @@ describe("Tabs should comply with accessibility rules", () => {
179
186
 
180
187
  expect(tab1).toHaveFocus();
181
188
  expect(tab1).toHaveClass("selected");
182
- expect(tab1).not.toHaveClass("focussed");
183
189
  expect(tab3).not.toHaveClass("selected");
184
- expect(tab3).not.toHaveClass("focussed");
190
+ expect(tab3).not.toHaveFocus();
185
191
  expect(tabpanel1).toHaveClass("selected");
186
192
  expect(tabpanel3).not.toHaveClass("selected");
187
193
 
188
- userEvent.keyboard("[ArrowLeft]");
189
- userEvent.keyboard("[Space]");
194
+ await userEvent.keyboard("[ArrowLeft]");
195
+ await userEvent.keyboard("[Space]");
190
196
 
191
197
  tabButtons = tablist.querySelectorAll(".tabbutton");
192
198
  tab1 = tabButtons[0] as HTMLButtonElement;
@@ -197,12 +203,12 @@ describe("Tabs should comply with accessibility rules", () => {
197
203
  expect(tab3).toHaveFocus();
198
204
  expect(tab3).toHaveClass("selected");
199
205
  expect(tab1).not.toHaveClass("selected");
200
- expect(tab1).not.toHaveClass("focussed");
206
+ expect(tab1).not.toHaveFocus();
201
207
  expect(tabpanel3).toHaveClass("selected");
202
208
  expect(tabpanel1).not.toHaveClass("selected");
203
209
 
204
- userEvent.keyboard("[ArrowRight]");
205
- userEvent.keyboard("[Enter]");
210
+ await userEvent.keyboard("[ArrowRight]");
211
+ await userEvent.keyboard("[Enter]");
206
212
 
207
213
  tabButtons = tablist.querySelectorAll(".tabbutton");
208
214
  tab1 = tabButtons[0] as HTMLButtonElement;
@@ -213,21 +219,21 @@ describe("Tabs should comply with accessibility rules", () => {
213
219
  expect(tab1).toHaveFocus();
214
220
  expect(tab1).toHaveClass("selected");
215
221
  expect(tab3).not.toHaveClass("selected");
216
- expect(tab3).not.toHaveClass("focussed");
222
+ expect(tab3).not.toHaveFocus();
217
223
  expect(tabpanel1).toHaveClass("selected");
218
224
  expect(tabpanel3).not.toHaveClass("selected");
219
225
 
220
- userEvent.keyboard("[End]");
226
+ await userEvent.keyboard("[End]");
221
227
 
222
228
  tabButtons = tablist.querySelectorAll(".tabbutton");
223
229
  tab1 = tabButtons[0] as HTMLButtonElement;
224
230
  tab3 = tabButtons[2] as HTMLButtonElement;
225
231
 
226
232
  expect(tab3).toHaveFocus();
227
- expect(tab3).toHaveClass("focussed");
228
- expect(tab1).not.toHaveClass("focussed");
233
+ expect(tab3).toHaveFocus();
234
+ expect(tab1).not.toHaveFocus();
229
235
 
230
- userEvent.keyboard("[Home]");
236
+ await userEvent.keyboard("[Home]");
231
237
 
232
238
  tabButtons = tablist.querySelectorAll(".tabbutton");
233
239
  tab1 = tabButtons[0] as HTMLButtonElement;
@@ -235,10 +241,10 @@ describe("Tabs should comply with accessibility rules", () => {
235
241
 
236
242
  expect(tab1).toHaveFocus();
237
243
  expect(tab1).toHaveClass("selected");
238
- expect(tab3).not.toHaveClass("focussed");
244
+ expect(tab3).not.toHaveFocus();
239
245
 
240
246
  // should have no effect
241
- userEvent.keyboard("a");
247
+ await userEvent.keyboard("a");
242
248
 
243
249
  tabButtons = tablist.querySelectorAll(".tabbutton");
244
250
  tab1 = tabButtons[0] as HTMLButtonElement;
@@ -246,9 +252,9 @@ describe("Tabs should comply with accessibility rules", () => {
246
252
 
247
253
  expect(tab1).toHaveFocus();
248
254
  expect(tab1).toHaveClass("selected");
249
- expect(tab3).not.toHaveClass("focussed");
255
+ expect(tab3).not.toHaveFocus();
250
256
 
251
- userEvent.keyboard("[ArrowRight]");
257
+ await userEvent.keyboard("[ArrowRight]");
252
258
 
253
259
  tabButtons = tablist.querySelectorAll(".tabbutton");
254
260
  tab1 = tabButtons[0] as HTMLButtonElement;
@@ -256,10 +262,10 @@ describe("Tabs should comply with accessibility rules", () => {
256
262
 
257
263
  expect(tab1).not.toHaveFocus();
258
264
  expect(tab3).not.toHaveFocus();
259
- expect(tab1).not.toHaveClass("focussed");
260
- expect(tab3).not.toHaveClass("focussed");
265
+ expect(tab1).not.toHaveFocus();
266
+ expect(tab3).not.toHaveFocus();
261
267
 
262
- userEvent.keyboard("[ArrowLeft]");
268
+ await userEvent.keyboard("[ArrowLeft]");
263
269
 
264
270
  tabButtons = tablist.querySelectorAll(".tabbutton");
265
271
  tab1 = tabButtons[0] as HTMLButtonElement;
@@ -267,18 +273,19 @@ describe("Tabs should comply with accessibility rules", () => {
267
273
 
268
274
  expect(tab1).toHaveFocus();
269
275
  expect(tab1).toHaveClass("selected");
270
- expect(tab3).not.toHaveClass("focussed");
276
+ expect(tab3).not.toHaveFocus();
271
277
 
272
- userEvent.keyboard("[ArrowLeft]");
278
+ await userEvent.keyboard("[ArrowLeft]");
273
279
 
274
280
  tabButtons = tablist.querySelectorAll(".tabbutton");
275
281
  tab1 = tabButtons[0] as HTMLButtonElement;
276
282
  tab3 = tabButtons[2] as HTMLButtonElement;
277
283
 
278
- tab3.blur();
284
+ act(() => {
285
+ tab3.blur();
286
+ });
279
287
 
280
288
  expect(tab1).not.toHaveFocus();
281
289
  expect(tab3).not.toHaveFocus();
282
- expect(tab1).toHaveClass("selected");
283
290
  });
284
291
  });