@usefui/components 1.5.1

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 (104) hide show
  1. package/CHANGELOG.md +233 -0
  2. package/LICENSE +21 -0
  3. package/README.md +0 -0
  4. package/babel.config.js +12 -0
  5. package/dist/index.d.mts +1299 -0
  6. package/dist/index.d.ts +1299 -0
  7. package/dist/index.js +3701 -0
  8. package/dist/index.mjs +3586 -0
  9. package/package.json +44 -0
  10. package/src/__tests__/Accordion.test.tsx +106 -0
  11. package/src/__tests__/Avatar.test.tsx +89 -0
  12. package/src/__tests__/Badge.test.tsx +58 -0
  13. package/src/__tests__/Button.test.tsx +88 -0
  14. package/src/__tests__/Checkbox.test.tsx +106 -0
  15. package/src/__tests__/Collapsible.test.tsx +79 -0
  16. package/src/__tests__/Dialog.test.tsx +109 -0
  17. package/src/__tests__/Dropdown.test.tsx +159 -0
  18. package/src/__tests__/Field.test.tsx +100 -0
  19. package/src/__tests__/OTPField.test.tsx +199 -0
  20. package/src/__tests__/Overlay.test.tsx +70 -0
  21. package/src/__tests__/Page.test.tsx +98 -0
  22. package/src/__tests__/Portal.test.tsx +28 -0
  23. package/src/__tests__/Sheet.test.tsx +125 -0
  24. package/src/__tests__/Switch.test.tsx +90 -0
  25. package/src/__tests__/Tabs.test.tsx +129 -0
  26. package/src/__tests__/Toggle.test.tsx +67 -0
  27. package/src/__tests__/Toolbar.test.tsx +147 -0
  28. package/src/__tests__/Tooltip.test.tsx +88 -0
  29. package/src/accordion/Accordion.stories.tsx +89 -0
  30. package/src/accordion/hooks/index.tsx +39 -0
  31. package/src/accordion/index.tsx +170 -0
  32. package/src/avatar/Avatar.stories.tsx +62 -0
  33. package/src/avatar/index.tsx +90 -0
  34. package/src/avatar/styles/index.ts +79 -0
  35. package/src/badge/Badge.stories.tsx +60 -0
  36. package/src/badge/index.tsx +58 -0
  37. package/src/badge/styles/index.ts +109 -0
  38. package/src/button/Button.stories.tsx +47 -0
  39. package/src/button/index.tsx +79 -0
  40. package/src/button/styles/index.ts +180 -0
  41. package/src/checkbox/Checkbox.stories.tsx +100 -0
  42. package/src/checkbox/hooks/index.tsx +40 -0
  43. package/src/checkbox/index.tsx +147 -0
  44. package/src/checkbox/styles/index.ts +139 -0
  45. package/src/collapsible/Collapsible.stories.tsx +95 -0
  46. package/src/collapsible/hooks/index.tsx +50 -0
  47. package/src/collapsible/index.tsx +137 -0
  48. package/src/dialog/Dialog.stories.tsx +73 -0
  49. package/src/dialog/hooks/index.tsx +35 -0
  50. package/src/dialog/index.tsx +221 -0
  51. package/src/dialog/styles/index.ts +72 -0
  52. package/src/divider/index.ts +10 -0
  53. package/src/dropdown/Dropdown.stories.tsx +100 -0
  54. package/src/dropdown/hooks/index.tsx +64 -0
  55. package/src/dropdown/index.tsx +316 -0
  56. package/src/dropdown/styles/index.ts +90 -0
  57. package/src/field/Field.stories.tsx +146 -0
  58. package/src/field/hooks/index.tsx +28 -0
  59. package/src/field/index.tsx +183 -0
  60. package/src/field/styles/index.ts +166 -0
  61. package/src/index.ts +33 -0
  62. package/src/otp-field/OTPField.stories.tsx +50 -0
  63. package/src/otp-field/hooks/index.tsx +13 -0
  64. package/src/otp-field/index.tsx +234 -0
  65. package/src/otp-field/styles/index.ts +33 -0
  66. package/src/otp-field/types/index.ts +23 -0
  67. package/src/overlay/Overlay.stories.tsx +59 -0
  68. package/src/overlay/index.tsx +58 -0
  69. package/src/overlay/styles/index.ts +26 -0
  70. package/src/page/Page.stories.tsx +85 -0
  71. package/src/page/index.tsx +265 -0
  72. package/src/page/styles/index.ts +59 -0
  73. package/src/portal/Portal.stories.tsx +27 -0
  74. package/src/portal/index.tsx +36 -0
  75. package/src/scrollarea/Scrollarea.stories.tsx +99 -0
  76. package/src/scrollarea/index.tsx +27 -0
  77. package/src/scrollarea/styles/index.ts +71 -0
  78. package/src/sheet/Sheet.stories.tsx +86 -0
  79. package/src/sheet/hooks/index.tsx +47 -0
  80. package/src/sheet/index.tsx +190 -0
  81. package/src/sheet/styles/index.ts +69 -0
  82. package/src/switch/Switch.stories.tsx +96 -0
  83. package/src/switch/hooks/index.tsx +33 -0
  84. package/src/switch/index.tsx +122 -0
  85. package/src/switch/styles/index.ts +118 -0
  86. package/src/table/index.tsx +138 -0
  87. package/src/table/styles/index.ts +48 -0
  88. package/src/tabs/Tabs.stories.tsx +87 -0
  89. package/src/tabs/hooks/index.tsx +35 -0
  90. package/src/tabs/index.tsx +161 -0
  91. package/src/tabs/styles/index.ts +9 -0
  92. package/src/toggle/Toggle.stories.tsx +118 -0
  93. package/src/toggle/index.tsx +55 -0
  94. package/src/toggle/styles/index.ts +0 -0
  95. package/src/toolbar/Toolbar.stories.tsx +89 -0
  96. package/src/toolbar/hooks/index.tsx +35 -0
  97. package/src/toolbar/index.tsx +243 -0
  98. package/src/toolbar/styles/index.ts +129 -0
  99. package/src/tooltip/Tooltip.stories.tsx +60 -0
  100. package/src/tooltip/index.tsx +177 -0
  101. package/src/tooltip/styles/index.ts +38 -0
  102. package/src/utils/index.ts +2 -0
  103. package/tsconfig.json +18 -0
  104. package/vitest.config.ts +16 -0
@@ -0,0 +1,125 @@
1
+ import React from "react";
2
+
3
+ import { test, vi, afterEach, describe, expect } from "vitest";
4
+ import {
5
+ screen,
6
+ render,
7
+ cleanup,
8
+ waitFor,
9
+ fireEvent,
10
+ } from "@testing-library/react";
11
+ import { axe, toHaveNoViolations } from "jest-axe";
12
+
13
+ import { Sheet } from "../../src";
14
+ import {
15
+ ComponentSideEnum,
16
+ ComponentSizeEnum,
17
+ TComponentSize,
18
+ } from "../../../../types";
19
+
20
+ afterEach(async () => {
21
+ vi.clearAllMocks();
22
+ vi.resetModules();
23
+ cleanup();
24
+ });
25
+
26
+ const onClickCallback = vi.fn();
27
+ const onClickCallbackInner = vi.fn();
28
+
29
+ const SheetDefault = (args: {
30
+ open?: boolean;
31
+ closeOnInteract?: boolean;
32
+ shortcut?: boolean;
33
+ side?: ComponentSideEnum;
34
+ sizing?: ComponentSizeEnum;
35
+ hotkey?: string;
36
+ }) => {
37
+ return (
38
+ <Sheet.Root>
39
+ <Sheet.Trigger name="external" onClick={onClickCallback}>
40
+ Ext Trigger
41
+ </Sheet.Trigger>
42
+
43
+ <Sheet
44
+ open={args.open}
45
+ side={args.side as any}
46
+ sizing={args.sizing as TComponentSize}
47
+ shortcut={args.shortcut}
48
+ hotkey={args.hotkey}
49
+ aria-label="test-sheet"
50
+ >
51
+ <h4>test-content</h4>
52
+ <Sheet.Trigger name="inner" onClick={onClickCallbackInner}>
53
+ Inner Trigger
54
+ </Sheet.Trigger>
55
+ </Sheet>
56
+ </Sheet.Root>
57
+ );
58
+ };
59
+
60
+ expect.extend(toHaveNoViolations);
61
+ describe("Sheet", () => {
62
+ test("Renders without accessibility violation", async () => {
63
+ const { container } = render(<SheetDefault open />);
64
+ const ComponentContainer = await axe(container);
65
+
66
+ expect(ComponentContainer).toHaveNoViolations();
67
+ });
68
+ test("Renders with accessibility definition", async () => {
69
+ render(<SheetDefault />);
70
+ const ExtTrigger = screen.getByLabelText("external-action");
71
+
72
+ expect(ExtTrigger.getAttribute("data-state")).toBe("closed");
73
+
74
+ fireEvent.click(ExtTrigger);
75
+ await waitFor(() => {
76
+ const Content = screen.getByLabelText("test-sheet");
77
+ const InnerTrigger = screen.getByLabelText("inner-action");
78
+
79
+ expect(ExtTrigger.getAttribute("data-state")).toBe("open");
80
+ expect(InnerTrigger.getAttribute("data-state")).toBe("open");
81
+
82
+ expect(Content.getAttribute("role")).toBe("dialog");
83
+ expect(Content.getAttribute("data-state")).toBe("open");
84
+ expect(Content.getAttribute("tabIndex")).toBe("-1");
85
+ expect(Content.getAttribute("aria-labelledby")).toBeDefined();
86
+ });
87
+ });
88
+ test("Fires the defined callback functions and toggle the content when the triggers are clicked", async () => {
89
+ render(<SheetDefault />);
90
+
91
+ fireEvent.click(screen.getByLabelText("external-action"));
92
+ await waitFor(() => expect(onClickCallback).toHaveBeenCalled());
93
+
94
+ fireEvent.click(screen.getByLabelText("inner-action"));
95
+ await waitFor(() => expect(onClickCallbackInner).toHaveBeenCalled());
96
+ });
97
+ test("Renders the component by default if open is defined", async () => {
98
+ render(<SheetDefault open />);
99
+ await waitFor(() =>
100
+ expect(screen.getByLabelText("test-sheet")).toBeDefined()
101
+ );
102
+ });
103
+ test("Removes the component from the DOM if the Overlay is clicked and closeOnInteract is defined", async () => {
104
+ render(<SheetDefault open closeOnInteract />);
105
+ await waitFor(() => {
106
+ const Overlay = screen.getByLabelText("test-sheet-overlay");
107
+
108
+ expect(Overlay).toBeDefined();
109
+ expect(Overlay.getAttribute("aria-hidden")).toBe("true");
110
+ });
111
+
112
+ fireEvent.click(screen.getByLabelText("test-sheet-overlay"));
113
+ expect(() => screen.getByRole("region")).toThrow();
114
+ expect(() => screen.getByLabelText("test-sheet-overlay")).toThrow();
115
+ });
116
+ test("Toggle the component when the keyboard shortcut is pressed", async () => {
117
+ const { container } = render(<SheetDefault open shortcut hotkey="a" />);
118
+ expect(screen.getByText("test-content")).toBeDefined();
119
+
120
+ fireEvent.keyDown(container, { key: "a", code: "KeyA", ctrlKey: true });
121
+ await waitFor(() =>
122
+ expect(() => screen.getByText("test-content")).toThrow()
123
+ );
124
+ });
125
+ });
@@ -0,0 +1,90 @@
1
+ import React from "react";
2
+
3
+ import { test, vi, afterEach, describe, expect } from "vitest";
4
+ import {
5
+ screen,
6
+ render,
7
+ cleanup,
8
+ waitFor,
9
+ fireEvent,
10
+ } from "@testing-library/react";
11
+ import { axe, toHaveNoViolations } from "jest-axe";
12
+
13
+ import { Switch } from "../../src/switch";
14
+
15
+ afterEach(async () => {
16
+ vi.clearAllMocks();
17
+ vi.resetModules();
18
+ cleanup();
19
+ });
20
+
21
+ const onClickCallback = vi.fn();
22
+ const Switchefault = (args: { defaultChecked?: boolean }) => {
23
+ return (
24
+ <Switch.Root>
25
+ <label id="label" htmlFor="switch-test">
26
+ test switch
27
+ </label>
28
+ <Switch
29
+ defaultChecked={args.defaultChecked}
30
+ onClick={onClickCallback}
31
+ aria-labelledby="label"
32
+ disabled={false}
33
+ >
34
+ <Switch.Thumb />
35
+ </Switch>
36
+ </Switch.Root>
37
+ );
38
+ };
39
+
40
+ expect.extend(toHaveNoViolations);
41
+ describe("Switch", () => {
42
+ test("Renders without accessibility violation", async () => {
43
+ const { container } = render(<Switchefault />);
44
+ const ComponentContainer = await axe(container);
45
+
46
+ expect(ComponentContainer).toHaveNoViolations();
47
+ });
48
+ test("Renders with accessibility definition", async () => {
49
+ render(<Switchefault />);
50
+ const Trigger = screen.getByTitle("switch-trigger");
51
+ const Thumb = screen.getByTitle("switch-thumb");
52
+
53
+ expect(Trigger.getAttribute("value")).toBe("false");
54
+ expect(Trigger.getAttribute("type")).toBe("button");
55
+ expect(Trigger.getAttribute("aria-checked")).toBe("false");
56
+ expect(Trigger.getAttribute("data-disabled")).toBe("false");
57
+
58
+ expect(Thumb.getAttribute("aria-hidden")).toBeDefined();
59
+ expect(Thumb.getAttribute("tabIndex")).toBe("-1");
60
+ expect(Thumb.getAttribute("role")).toBe("presentation");
61
+ expect(Thumb.getAttribute("data-checked")).toBe("false");
62
+ });
63
+ test("Update the component state on click and fires the defined callback function", async () => {
64
+ render(<Switchefault />);
65
+ const Trigger = screen.getByTitle("switch-trigger");
66
+ const Thumb = screen.getByTitle("switch-thumb");
67
+
68
+ fireEvent.click(Trigger);
69
+
70
+ await waitFor(() => {
71
+ expect(Trigger.getAttribute("value")).toBe("true");
72
+ expect(Trigger.getAttribute("aria-checked")).toBe("true");
73
+ expect(Thumb.getAttribute("data-checked")).toBe("true");
74
+ expect(Thumb.getAttribute("data-checked")).toBe("true");
75
+
76
+ expect(onClickCallback).toHaveBeenCalled();
77
+ expect(onClickCallback).toHaveBeenCalledTimes(1);
78
+ });
79
+ });
80
+ test("Renders as checked if defaultChecked is defined", async () => {
81
+ render(<Switchefault defaultChecked />);
82
+ const Trigger = screen.getByTitle("switch-trigger");
83
+ const Thumb = screen.getByTitle("switch-thumb");
84
+
85
+ expect(Trigger.getAttribute("value")).toBe("true");
86
+ expect(Trigger.getAttribute("aria-checked")).toBe("true");
87
+ expect(Thumb.getAttribute("data-checked")).toBe("true");
88
+ expect(Thumb.getAttribute("data-checked")).toBe("true");
89
+ });
90
+ });
@@ -0,0 +1,129 @@
1
+ import React from "react";
2
+
3
+ import { test, vi, afterEach, describe, expect } from "vitest";
4
+ import {
5
+ screen,
6
+ render,
7
+ cleanup,
8
+ waitFor,
9
+ fireEvent,
10
+ } from "@testing-library/react";
11
+ import { axe, toHaveNoViolations } from "jest-axe";
12
+
13
+ import { Tabs } from "../../src/tabs";
14
+
15
+ afterEach(async () => {
16
+ vi.clearAllMocks();
17
+ vi.resetModules();
18
+ cleanup();
19
+ });
20
+
21
+ const onClickCallback = vi.fn();
22
+ const TabsDefault = () => {
23
+ return (
24
+ <Tabs.Root>
25
+ <Tabs>
26
+ <Tabs.Trigger value="1">trigger 1</Tabs.Trigger>
27
+ <Tabs.Trigger onClick={onClickCallback} value="2">
28
+ trigger 2
29
+ </Tabs.Trigger>
30
+ </Tabs>
31
+ <Tabs.Content value="1">
32
+ <p>item 1</p>
33
+ </Tabs.Content>
34
+ <Tabs.Content value="2">
35
+ <p>item 2</p>
36
+ </Tabs.Content>
37
+ </Tabs.Root>
38
+ );
39
+ };
40
+
41
+ expect.extend(toHaveNoViolations);
42
+ describe("Tabs", () => {
43
+ test("Renders without accessibility violation", async () => {
44
+ const { container } = render(<TabsDefault />);
45
+ const ComponentContainer = await axe(container);
46
+
47
+ expect(ComponentContainer).toHaveNoViolations();
48
+ });
49
+ test("Renders with accessibility definition", async () => {
50
+ render(<TabsDefault />);
51
+ const Trigger = screen.getByTitle("1-tab");
52
+ const Content = screen.getByTitle("1-tabpanel");
53
+ const ScndTrigger = screen.getByTitle("2-tab");
54
+ const ScndContent = screen.getByTitle("2-tabpanel");
55
+
56
+ expect(Trigger.getAttribute("role")).toBe("tab");
57
+ expect(Trigger.getAttribute("value")).toBe("1");
58
+ expect(Trigger.getAttribute("aria-selected")).toBe("true");
59
+ expect(Trigger.getAttribute("data-state")).toBe("active");
60
+ expect(Trigger.getAttribute("data-controls")).toBeDefined();
61
+
62
+ expect(Content.getAttribute("role")).toBe("tabpanel");
63
+ expect(Content.getAttribute("data-value")).toBe("1");
64
+ expect(Content.getAttribute("data-state")).toBe("active");
65
+ expect(Content.getAttribute("aria-labelledby")).toBeDefined();
66
+
67
+ expect(ScndTrigger.getAttribute("aria-selected")).toBe("false");
68
+ expect(ScndTrigger.getAttribute("data-state")).toBe("inactive");
69
+ expect(ScndContent.getAttribute("data-state")).toBe("inactive");
70
+ });
71
+ test("Update the component state on click and fires the defined callback function", async () => {
72
+ render(<TabsDefault />);
73
+ const Trigger = screen.getByTitle("1-tab");
74
+ const Content = screen.getByTitle("1-tabpanel");
75
+ const ScndTrigger = screen.getByTitle("2-tab");
76
+ const ScndContent = screen.getByTitle("2-tabpanel");
77
+
78
+ expect(screen.getByText("item 1")).toBeDefined();
79
+ fireEvent.click(ScndTrigger);
80
+ await waitFor(() => {
81
+ expect(Trigger.getAttribute("aria-selected")).toBe("false");
82
+ expect(Trigger.getAttribute("data-state")).toBe("inactive");
83
+ expect(Content.getAttribute("data-state")).toBe("inactive");
84
+
85
+ expect(ScndTrigger.getAttribute("aria-selected")).toBe("true");
86
+ expect(ScndTrigger.getAttribute("data-state")).toBe("active");
87
+ expect(ScndContent.getAttribute("data-state")).toBe("active");
88
+
89
+ expect(onClickCallback).toHaveBeenCalled();
90
+ expect(onClickCallback).toHaveBeenCalledTimes(1);
91
+
92
+ expect(() => screen.getByText("item 1")).toThrow();
93
+ expect(screen.getByText("item 2")).toBeDefined();
94
+ });
95
+ });
96
+ test("Renders the desired section as open if defaultOpen is defined", async () => {
97
+ render(
98
+ <Tabs.Root>
99
+ <Tabs defaultOpen="2">
100
+ <Tabs.Trigger value="1">trigger 1</Tabs.Trigger>
101
+ <Tabs.Trigger onClick={onClickCallback} value="2">
102
+ trigger 2
103
+ </Tabs.Trigger>
104
+ </Tabs>
105
+ <Tabs.Content value="1">
106
+ <p>item 1</p>
107
+ </Tabs.Content>
108
+ <Tabs.Content value="2">
109
+ <p>item 2</p>
110
+ </Tabs.Content>
111
+ </Tabs.Root>
112
+ );
113
+ const Trigger = screen.getByTitle("1-tab");
114
+ const Content = screen.getByTitle("1-tabpanel");
115
+ const ScndTrigger = screen.getByTitle("2-tab");
116
+ const ScndContent = screen.getByTitle("2-tabpanel");
117
+
118
+ expect(Trigger.getAttribute("aria-selected")).toBe("false");
119
+ expect(Trigger.getAttribute("data-state")).toBe("inactive");
120
+ expect(Content.getAttribute("data-state")).toBe("inactive");
121
+
122
+ expect(ScndTrigger.getAttribute("aria-selected")).toBe("true");
123
+ expect(ScndTrigger.getAttribute("data-state")).toBe("active");
124
+ expect(ScndContent.getAttribute("data-state")).toBe("active");
125
+
126
+ expect(() => screen.getByText("item 1")).toThrow();
127
+ expect(screen.getByText("item 2")).toBeDefined();
128
+ });
129
+ });
@@ -0,0 +1,67 @@
1
+ import React from "react";
2
+
3
+ import { test, vi, afterEach, describe, expect } from "vitest";
4
+ import {
5
+ screen,
6
+ render,
7
+ cleanup,
8
+ waitFor,
9
+ fireEvent,
10
+ } from "@testing-library/react";
11
+ import { axe, toHaveNoViolations } from "jest-axe";
12
+
13
+ import { Toggle } from "../../src/toggle";
14
+
15
+ afterEach(async () => {
16
+ vi.clearAllMocks();
17
+ vi.resetModules();
18
+ cleanup();
19
+ });
20
+
21
+ const onClickCallback = vi.fn();
22
+ const ToggleDefault = (args: { defaultChecked?: boolean }) => {
23
+ return (
24
+ <Toggle defaultChecked={args.defaultChecked} onClick={onClickCallback}>
25
+ Test
26
+ </Toggle>
27
+ );
28
+ };
29
+
30
+ expect.extend(toHaveNoViolations);
31
+ describe("Toggle", () => {
32
+ test("Renders without accessibility violation", async () => {
33
+ const { container } = render(<ToggleDefault />);
34
+ const ComponentContainer = await axe(container);
35
+
36
+ expect(ComponentContainer).toHaveNoViolations();
37
+ });
38
+ test("Renders with accessibility definition", async () => {
39
+ render(<ToggleDefault />);
40
+ const ToggleComponent = screen.getByRole("switch");
41
+
42
+ expect(ToggleComponent.getAttribute("type")).toBe("button");
43
+ expect(ToggleComponent.getAttribute("value")).toBe("false");
44
+ expect(ToggleComponent.getAttribute("data-checked")).toBe("false");
45
+ expect(ToggleComponent.getAttribute("data-disabled")).toBe("false");
46
+ });
47
+ test("Update the component state on click and fires the defined callback function", async () => {
48
+ render(<ToggleDefault />);
49
+ const ToggleComponent = screen.getByRole("switch");
50
+
51
+ fireEvent.click(ToggleComponent);
52
+ await waitFor(() => {
53
+ expect(ToggleComponent.getAttribute("value")).toBe("true");
54
+ expect(ToggleComponent.getAttribute("data-checked")).toBe("true");
55
+
56
+ expect(onClickCallback).toHaveBeenCalled();
57
+ expect(onClickCallback).toHaveBeenCalledTimes(1);
58
+ });
59
+ });
60
+ test("Renders as checked if defaultChecked is defined", async () => {
61
+ render(<ToggleDefault defaultChecked />);
62
+ const ToggleComponent = screen.getByRole("switch");
63
+
64
+ expect(ToggleComponent.getAttribute("value")).toBe("true");
65
+ expect(ToggleComponent.getAttribute("data-checked")).toBe("true");
66
+ });
67
+ });
@@ -0,0 +1,147 @@
1
+ import React from "react";
2
+
3
+ import { test, vi, afterEach, describe, expect } from "vitest";
4
+ import {
5
+ screen,
6
+ render,
7
+ cleanup,
8
+ waitFor,
9
+ fireEvent,
10
+ } from "@testing-library/react";
11
+ import { axe, toHaveNoViolations } from "jest-axe";
12
+
13
+ import { Toolbar } from "../../src/toolbar";
14
+ import {
15
+ ComponentSizeEnum,
16
+ ComponentSideEnum,
17
+ TComponentSize,
18
+ } from "../../../../types";
19
+
20
+ afterEach(async () => {
21
+ vi.clearAllMocks();
22
+ vi.resetModules();
23
+ cleanup();
24
+ });
25
+
26
+ const onClickCallback = vi.fn();
27
+ const ToolbarDefault = (args: {
28
+ showoncollapse?: boolean;
29
+ defaultOpen?: boolean;
30
+ shortcut?: boolean;
31
+ side?: ComponentSideEnum;
32
+ sizing?: ComponentSizeEnum;
33
+ hotkey?: string;
34
+ }) => {
35
+ return (
36
+ <Toolbar.Root>
37
+ <Toolbar
38
+ side={args.side}
39
+ sizing={args.sizing as TComponentSize}
40
+ defaultOpen={args.defaultOpen}
41
+ shortcut={args.shortcut}
42
+ hotkey={args.hotkey}
43
+ >
44
+ <Toolbar.Section showoncollapse={args.showoncollapse}>
45
+ <Toolbar.Item aria-label="test-item">item</Toolbar.Item>
46
+ <Toolbar.Item aria-label="test-item-2">item2</Toolbar.Item>
47
+ </Toolbar.Section>
48
+
49
+ <Toolbar.Trigger onClick={onClickCallback}>&hArr;</Toolbar.Trigger>
50
+ </Toolbar>
51
+ </Toolbar.Root>
52
+ );
53
+ };
54
+
55
+ expect.extend(toHaveNoViolations);
56
+ describe("Toolbar", () => {
57
+ test("Renders without accessibility violation", async () => {
58
+ const { container } = render(<ToolbarDefault />);
59
+ const ComponentContainer = await axe(container);
60
+ expect(ComponentContainer).toHaveNoViolations();
61
+ });
62
+ test("Renders with accessibility definition", async () => {
63
+ render(<ToolbarDefault />);
64
+ const Container = screen.getByRole("toolbar");
65
+ const Trigger = screen.getByRole("button");
66
+
67
+ expect(() => screen.getByText("item")).toThrow();
68
+
69
+ expect(Container).toBeDefined();
70
+ expect(Container.getAttribute("aria-label")).toBeDefined();
71
+ expect(Container.getAttribute("aria-controls")).toBeDefined();
72
+ expect(Container.getAttribute("aria-expanded")).toBe("false");
73
+ expect(Container.getAttribute("aria-orientation")).toBe("vertical");
74
+ expect(Container.getAttribute("data-side")).toBe("left");
75
+
76
+ expect(Trigger).toBeDefined();
77
+ expect(Trigger.getAttribute("id")).toBe(
78
+ Container.getAttribute("aria-controls")
79
+ );
80
+
81
+ fireEvent.click(Trigger);
82
+ await waitFor(() => {
83
+ const Item = screen.getByText("item");
84
+
85
+ expect(Item).toBeDefined();
86
+ expect(Item.getAttribute("tabIndex")).toBe("-1");
87
+ expect(Item.getAttribute("aria-hidden")).toBe("true");
88
+ expect(Item.getAttribute("data-expanded")).toBe("true");
89
+ expect(Item.getAttribute("aria-describedby")).toBeDefined();
90
+ });
91
+ });
92
+ test("Update the component state on click and fires the defined callback function", async () => {
93
+ render(<ToolbarDefault />);
94
+ const Trigger = screen.getByRole("button");
95
+
96
+ fireEvent.click(Trigger);
97
+ await waitFor(() => {
98
+ expect(onClickCallback).toHaveBeenCalled();
99
+ expect(onClickCallback).toHaveBeenCalledTimes(1);
100
+ });
101
+ });
102
+ test("Toggle the component when the trigger is clicked", async () => {
103
+ render(<ToolbarDefault />);
104
+ const Trigger = screen.getByRole("button");
105
+
106
+ expect(() => screen.getByText("item")).toThrow();
107
+ fireEvent.click(Trigger);
108
+ await waitFor(() => {
109
+ expect(screen.getByText("item")).toBeDefined();
110
+ });
111
+ });
112
+ test("Toggle the component when the children item is clicked if showoncollapse is defined", async () => {
113
+ render(<ToolbarDefault showoncollapse />);
114
+ const Item = screen.getByLabelText("test-item");
115
+ const Container = screen.getByRole("toolbar");
116
+
117
+ fireEvent.click(Item);
118
+ await waitFor(() => {
119
+ expect(screen.getByLabelText("test-item")).toBeDefined();
120
+ expect(Container.getAttribute("aria-expanded")).toBe("true");
121
+ });
122
+ });
123
+ test("Renders the children sections even when it's closed if showoncollapse is defined", async () => {
124
+ render(<ToolbarDefault showoncollapse />);
125
+ const Item = screen.getByLabelText("test-item");
126
+ const Container = screen.getByRole("toolbar");
127
+
128
+ fireEvent.click(Item);
129
+ await waitFor(() => {
130
+ expect(screen.getByLabelText("test-item")).toBeDefined();
131
+ expect(Container.getAttribute("aria-expanded")).toBe("true");
132
+ });
133
+ });
134
+ test("Renders the component opened if defaultOpen is defined", async () => {
135
+ render(<ToolbarDefault defaultOpen />);
136
+ expect(screen.getByText("item")).toBeDefined();
137
+ });
138
+ test("Toggle the component when the keyboard shortcut is pressed", async () => {
139
+ const { container } = render(
140
+ <ToolbarDefault defaultOpen shortcut hotkey="a" />
141
+ );
142
+ expect(screen.getByText("item")).toBeDefined();
143
+
144
+ fireEvent.keyDown(container, { key: "a", code: "KeyA", ctrlKey: true });
145
+ await waitFor(() => expect(() => screen.getByText("item")).toThrow());
146
+ });
147
+ });
@@ -0,0 +1,88 @@
1
+ import React from "react";
2
+
3
+ import { test, vi, afterEach, describe, expect } from "vitest";
4
+ import {
5
+ screen,
6
+ render,
7
+ cleanup,
8
+ waitFor,
9
+ fireEvent,
10
+ } from "@testing-library/react";
11
+ import { axe, toHaveNoViolations } from "jest-axe";
12
+
13
+ import { Tooltip } from "../";
14
+ import { ComponentSizeEnum } from "../../../../types";
15
+
16
+ afterEach(async () => {
17
+ vi.clearAllMocks();
18
+ vi.resetModules();
19
+ cleanup();
20
+ });
21
+
22
+ const TooltipDefault = (args: {
23
+ content: string;
24
+ delay?: number;
25
+ sizing?: ComponentSizeEnum;
26
+ raw?: boolean;
27
+ }) => {
28
+ return (
29
+ <Tooltip content={args.content} delay={args.delay} raw={args.raw}>
30
+ <span>Hover me</span>
31
+ </Tooltip>
32
+ );
33
+ };
34
+
35
+ expect.extend(toHaveNoViolations);
36
+ describe("Tooltip", () => {
37
+ test("Renders without accessibility violation", async () => {
38
+ const { container } = render(<TooltipDefault content="Test content" />);
39
+ const ComponentContainer = await axe(container);
40
+ expect(ComponentContainer).toHaveNoViolations();
41
+ });
42
+
43
+ test("Renders tooltip content on hover", async () => {
44
+ render(<TooltipDefault content="Test content" />);
45
+ const tooltipTrigger = screen.getByText("Hover me");
46
+
47
+ fireEvent.mouseEnter(tooltipTrigger);
48
+
49
+ await waitFor(() => {
50
+ expect(screen.getByText("Test content")).toBeDefined();
51
+ });
52
+
53
+ fireEvent.mouseLeave(tooltipTrigger);
54
+
55
+ await waitFor(() => {
56
+ expect(() => screen.getByText("Test content")).toThrow();
57
+ });
58
+ });
59
+
60
+ test("Applies delay before showing tooltip", async () => {
61
+ render(<TooltipDefault content="Test content" delay={200} />);
62
+ const tooltipTrigger = screen.getByText("Hover me");
63
+
64
+ fireEvent.mouseEnter(tooltipTrigger);
65
+ expect(() => screen.getByText("Test content")).toThrow();
66
+
67
+ await waitFor(() => {
68
+ expect(screen.getByText("Test content")).toBeDefined();
69
+ });
70
+ });
71
+
72
+ test("Hide content on mouse leave", async () => {
73
+ render(<TooltipDefault content="Test content" />);
74
+ const tooltipTrigger = screen.getByText("Hover me");
75
+
76
+ fireEvent.mouseEnter(tooltipTrigger);
77
+
78
+ await waitFor(() => {
79
+ expect(screen.getByText("Test content")).toBeDefined();
80
+ });
81
+
82
+ fireEvent.mouseLeave(tooltipTrigger);
83
+
84
+ await waitFor(() => {
85
+ expect(() => screen.getByText("Test content")).toThrow();
86
+ });
87
+ });
88
+ });