@griddo/ax 1.74.25 → 1.74.27

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "1.74.25",
4
+ "version": "1.74.27",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Carlos Torres <carlos.torres@secuoyas.com>",
@@ -229,5 +229,5 @@
229
229
  "publishConfig": {
230
230
  "access": "public"
231
231
  },
232
- "gitHead": "48ba7633e22251e27382c46d1da311dbe3147918"
232
+ "gitHead": "d7b0b5155bf123938bb8b79167848e67fc7570f1"
233
233
  }
@@ -0,0 +1,246 @@
1
+ import * as React from "react";
2
+ import { ThemeProvider } from "styled-components";
3
+ import { render, cleanup, screen, fireEvent } from "@testing-library/react";
4
+ import "@testing-library/jest-dom";
5
+
6
+ import { parseTheme } from "@ax/helpers";
7
+ import ActionMenu, { IActionMenuProps } from "@ax/components/ActionMenu";
8
+ import globalTheme from "@ax/themes/theme.json";
9
+
10
+ afterEach(cleanup);
11
+
12
+ describe("Action menu component rendering", () => {
13
+ it("should render the component with options hidden", () => {
14
+ const defaultProps: IActionMenuProps = {
15
+ icon: "more",
16
+ options: [
17
+ {
18
+ label: "Option 1",
19
+ icon: "modified",
20
+ action: jest.fn(),
21
+ },
22
+ {
23
+ label: "Option 2",
24
+ icon: "active",
25
+ action: jest.fn(),
26
+ },
27
+ ],
28
+ };
29
+
30
+ render(
31
+ <ThemeProvider theme={parseTheme(globalTheme)}>
32
+ <ActionMenu {...defaultProps} />
33
+ </ThemeProvider>
34
+ );
35
+
36
+ const actionMenuWrapper = screen.getByTestId("action-menu-wrapper");
37
+ expect(actionMenuWrapper).toBeTruthy();
38
+ const menuItems = screen.queryAllByTestId("action-menu-item");
39
+ expect(menuItems.length).toBe(0);
40
+ });
41
+ });
42
+
43
+ describe("Action menu events", () => {
44
+ it("should show the component with 2 options on icon click", () => {
45
+ const defaultProps: IActionMenuProps = {
46
+ icon: "more",
47
+ options: [
48
+ {
49
+ label: "Option 1",
50
+ icon: "modified",
51
+ action: jest.fn(),
52
+ },
53
+ {
54
+ label: "Option 2",
55
+ icon: "active",
56
+ action: jest.fn(),
57
+ },
58
+ ],
59
+ };
60
+
61
+ render(
62
+ <ThemeProvider theme={parseTheme(globalTheme)}>
63
+ <ActionMenu {...defaultProps} />
64
+ </ThemeProvider>
65
+ );
66
+
67
+ const actionMenuWrapper = screen.getByTestId("action-menu-wrapper");
68
+ expect(actionMenuWrapper).toBeTruthy();
69
+ const iconAction = screen.getByTestId("icon-action-component");
70
+ expect(iconAction).toBeTruthy();
71
+ fireEvent.click(iconAction);
72
+
73
+ const menuItems = screen.getAllByTestId("action-menu-item");
74
+ expect(menuItems.length).toBe(2);
75
+ });
76
+
77
+ it("should show the component with option with helptext", () => {
78
+ const helpText = "this is the helptext";
79
+ const defaultProps: IActionMenuProps = {
80
+ icon: "more",
81
+ options: [
82
+ {
83
+ label: "Option 1",
84
+ icon: "modified",
85
+ action: jest.fn(),
86
+ helpText,
87
+ },
88
+ ],
89
+ };
90
+
91
+ render(
92
+ <ThemeProvider theme={parseTheme(globalTheme)}>
93
+ <ActionMenu {...defaultProps} />
94
+ </ThemeProvider>
95
+ );
96
+
97
+ const actionMenuWrapper = screen.getByTestId("action-menu-wrapper");
98
+ expect(actionMenuWrapper).toBeTruthy();
99
+ const iconAction = screen.getByTestId("icon-action-component");
100
+ expect(iconAction).toBeTruthy();
101
+ fireEvent.click(iconAction);
102
+
103
+ const helpTextComponent = screen.getByText(helpText);
104
+ expect(helpTextComponent).toBeTruthy();
105
+ });
106
+
107
+ it("should show the component with option with original class", () => {
108
+ const defaultProps: IActionMenuProps = {
109
+ icon: "more",
110
+ options: [
111
+ {
112
+ label: "Option 1",
113
+ icon: "modified",
114
+ action: jest.fn(),
115
+ color: true,
116
+ },
117
+ {
118
+ label: "Option 2",
119
+ icon: "active",
120
+ action: jest.fn(),
121
+ },
122
+ ],
123
+ };
124
+
125
+ render(
126
+ <ThemeProvider theme={parseTheme(globalTheme)}>
127
+ <ActionMenu {...defaultProps} />
128
+ </ThemeProvider>
129
+ );
130
+
131
+ const actionMenuWrapper = screen.getByTestId("action-menu-wrapper");
132
+ expect(actionMenuWrapper).toBeTruthy();
133
+ const iconAction = screen.getByTestId("icon-action-component");
134
+ expect(iconAction).toBeTruthy();
135
+ fireEvent.click(iconAction);
136
+ const menuItems = screen.getAllByTestId("action-menu-item");
137
+
138
+ expect(menuItems[0]).toHaveClass("original");
139
+ expect(menuItems[1]).not.toHaveClass("original");
140
+ });
141
+
142
+ it("should hide the component on second icon click", () => {
143
+ const defaultProps: IActionMenuProps = {
144
+ icon: "more",
145
+ options: [
146
+ {
147
+ label: "Option 1",
148
+ icon: "modified",
149
+ action: jest.fn(),
150
+ },
151
+ {
152
+ label: "Option 2",
153
+ icon: "active",
154
+ action: jest.fn(),
155
+ },
156
+ ],
157
+ };
158
+
159
+ render(
160
+ <ThemeProvider theme={parseTheme(globalTheme)}>
161
+ <ActionMenu {...defaultProps} />
162
+ </ThemeProvider>
163
+ );
164
+
165
+ const actionMenuWrapper = screen.getByTestId("action-menu-wrapper");
166
+ expect(actionMenuWrapper).toBeTruthy();
167
+ const iconAction = screen.getByTestId("icon-action-component");
168
+ expect(iconAction).toBeTruthy();
169
+ fireEvent.click(iconAction);
170
+
171
+ const menuItems = screen.getAllByTestId("action-menu-item");
172
+ expect(menuItems.length).toBe(2);
173
+
174
+ fireEvent.click(iconAction);
175
+
176
+ const menuItems2 = screen.queryAllByTestId("action-menu-item");
177
+ expect(menuItems2.length).toBe(0);
178
+ });
179
+
180
+ it("should call action on item click and hide component", () => {
181
+ const actionMock = jest.fn();
182
+ const defaultProps: IActionMenuProps = {
183
+ icon: "more",
184
+ options: [
185
+ {
186
+ label: "Option 1",
187
+ icon: "modified",
188
+ action: actionMock,
189
+ },
190
+ ],
191
+ };
192
+
193
+ render(
194
+ <ThemeProvider theme={parseTheme(globalTheme)}>
195
+ <ActionMenu {...defaultProps} />
196
+ </ThemeProvider>
197
+ );
198
+
199
+ const iconAction = screen.getByTestId("icon-action-component");
200
+ fireEvent.click(iconAction);
201
+
202
+ const menuItems = screen.getAllByTestId("action-menu-item");
203
+ expect(menuItems.length).toBe(1);
204
+ fireEvent.click(menuItems[0]);
205
+
206
+ expect(actionMock).toBeCalledTimes(1);
207
+
208
+ const menuItems2 = screen.queryAllByTestId("action-menu-item");
209
+ expect(menuItems2.length).toBe(0);
210
+ });
211
+
212
+ it("should show disabled item", () => {
213
+ const actionMock = jest.fn();
214
+ const defaultProps: IActionMenuProps = {
215
+ icon: "more",
216
+ options: [
217
+ {
218
+ label: "Option 1",
219
+ icon: "modified",
220
+ action: actionMock,
221
+ disabled: true,
222
+ },
223
+ {
224
+ label: "Option 2",
225
+ icon: "active",
226
+ action: jest.fn(),
227
+ },
228
+ ],
229
+ };
230
+
231
+ render(
232
+ <ThemeProvider theme={parseTheme(globalTheme)}>
233
+ <ActionMenu {...defaultProps} />
234
+ </ThemeProvider>
235
+ );
236
+
237
+ const iconAction = screen.getByTestId("icon-action-component");
238
+ fireEvent.click(iconAction);
239
+
240
+ const menuItems = screen.getAllByTestId("action-menu-item");
241
+ expect(menuItems.length).toBe(2);
242
+
243
+ expect(menuItems[0]).toHaveAttribute("disabled");
244
+ expect(menuItems[1]).not.toHaveAttribute("disabled");
245
+ });
246
+ });
@@ -11,8 +11,8 @@ afterEach(cleanup);
11
11
 
12
12
  const defaultProps = mock<IProps>();
13
13
 
14
- describe("AsyncSelect component rendering", () => {
15
- test("should render the component AsyncSelect", () => {
14
+ describe("ColorPicker component rendering", () => {
15
+ test("should render the component ColorPicker", () => {
16
16
  defaultProps.value = "#000000";
17
17
  defaultProps.theme = parseTheme(globalTheme);
18
18
 
@@ -21,7 +21,7 @@ describe("AsyncSelect component rendering", () => {
21
21
  <ColorPicker {...defaultProps} />
22
22
  </ThemeProvider>
23
23
  );
24
- expect(screen.getByTestId("colorPickerWrapper")).toBeTruthy();
24
+ expect(screen.getByTestId("color-picker-wrapper")).toBeTruthy();
25
25
  });
26
26
 
27
27
  test("should render the Picker", () => {
@@ -36,14 +36,50 @@ describe("AsyncSelect component rendering", () => {
36
36
  const inputActionComponent = screen.getByTestId("icon-action-component");
37
37
  expect(inputActionComponent).toBeTruthy();
38
38
  fireEvent.click(inputActionComponent);
39
- expect(screen.findByTestId("pickerWrapper")).toBeTruthy();
39
+ expect(screen.findByTestId("picker-wrapper")).toBeTruthy();
40
+ });
41
+
42
+ test("should not render the text input field if onlyFixedColors is true", () => {
43
+ defaultProps.theme = "griddo-default";
44
+ defaultProps.error = true;
45
+ defaultProps.onlyFixedColors = true;
46
+ defaultProps.colors = [
47
+ {
48
+ theme: "griddo-default",
49
+ options: [
50
+ { name: "chart1", hex: "#d9e3f0" },
51
+ { name: "chart2", hex: "#697689" },
52
+ { name: "chart2", hex: "#37d67a" },
53
+ ],
54
+ },
55
+ {
56
+ theme: "griddo-alternative",
57
+ options: [
58
+ { name: "chart1", hex: "#fffff" },
59
+ { name: "chart2", hex: "#ddddd" },
60
+ { name: "chart2", hex: "#00000" },
61
+ ],
62
+ },
63
+ ];
64
+
65
+ render(
66
+ <ThemeProvider theme={parseTheme(globalTheme)}>
67
+ <ColorPicker {...defaultProps} />
68
+ </ThemeProvider>
69
+ );
70
+ const inputActionComponent = screen.getByTestId("icon-action-component");
71
+ expect(inputActionComponent).toBeTruthy();
72
+ fireEvent.click(inputActionComponent);
73
+ expect(screen.queryByTestId("input-picker")).not.toBeTruthy();
40
74
  });
41
75
  });
42
76
 
43
- describe("AsyncSelect events", () => {
77
+ describe("ColorPicker events", () => {
44
78
  test("should trigger the onChange", () => {
45
79
  defaultProps.value = "#000000";
46
80
  defaultProps.theme = parseTheme(globalTheme);
81
+ defaultProps.colors = ["#000000", "#d9e3f0", "#f47373", "#697689"];
82
+ defaultProps.onlyFixedColors = false;
47
83
  const onChangeMock = defaultProps.onChange as jest.MockedFunction<(newColor: string) => void>;
48
84
 
49
85
  render(
@@ -51,7 +87,7 @@ describe("AsyncSelect events", () => {
51
87
  <ColorPicker {...defaultProps} />
52
88
  </ThemeProvider>
53
89
  );
54
- const inputComponent = screen.getByTestId("inputPickerWrapper");
90
+ const inputComponent = screen.getByTestId("input-picker-wrapper");
55
91
  expect(inputComponent).toBeTruthy();
56
92
  fireEvent.change(inputComponent, { target: { value: 555 } });
57
93
  expect(onChangeMock).not.toBeCalled();
@@ -73,7 +109,7 @@ describe("AsyncSelect events", () => {
73
109
  <ColorPicker {...defaultProps} />
74
110
  </ThemeProvider>
75
111
  );
76
- const inputComponent = screen.getByTestId("inputPickerWrapper");
112
+ const inputComponent = screen.getByTestId("input-picker-wrapper");
77
113
  expect(inputComponent).toBeTruthy();
78
114
  fireEvent.change(inputComponent, { target: { value: "#fff" } });
79
115
  expect(handleValidationMock).toBeCalled();
@@ -93,7 +129,7 @@ describe("AsyncSelect events", () => {
93
129
  const inputActionComponent = screen.getByTestId("icon-action-component");
94
130
  expect(inputActionComponent).toBeTruthy();
95
131
  fireEvent.click(inputActionComponent);
96
- const inputPicker = await screen.findByTestId("inputPicker");
132
+ const inputPicker = await screen.findByTestId("input-picker");
97
133
  expect(inputPicker).toBeTruthy();
98
134
  fireEvent.change(inputPicker, { target: { value: "#fff" } });
99
135
  expect(onChangeMock).toBeCalled();
@@ -114,7 +150,7 @@ describe("AsyncSelect events", () => {
114
150
  const inputActionComponent = screen.getByTestId("icon-action-component");
115
151
  expect(inputActionComponent).toBeTruthy();
116
152
  fireEvent.click(inputActionComponent);
117
- const inputPicker = await screen.findByTestId("inputPicker");
153
+ const inputPicker = await screen.findByTestId("input-picker");
118
154
  expect(inputPicker).toBeTruthy();
119
155
  fireEvent.change(inputPicker, { target: { value: "#fff" } });
120
156
  expect(onChangeMock).toBeCalled();
@@ -138,7 +174,7 @@ describe("AsyncSelect events", () => {
138
174
  const inputActionComponent = screen.getByTestId("icon-action-component");
139
175
  expect(inputActionComponent).toBeTruthy();
140
176
  fireEvent.click(inputActionComponent);
141
- const gridItem = await screen.findAllByTestId("gridItem");
177
+ const gridItem = await screen.findAllByTestId("grid-item");
142
178
  // is getting the default colors
143
179
  expect(gridItem).toHaveLength(9);
144
180
  });
@@ -161,7 +197,7 @@ describe("AsyncSelect events", () => {
161
197
  const inputActionComponent = screen.getByTestId("icon-action-component");
162
198
  expect(inputActionComponent).toBeTruthy();
163
199
  fireEvent.click(inputActionComponent);
164
- const gridItem = await screen.findAllByTestId("gridItem");
200
+ const gridItem = await screen.findAllByTestId("grid-item");
165
201
  // it's getting the color passed
166
202
  expect(gridItem).toHaveLength(1);
167
203
  });
@@ -178,7 +214,7 @@ describe("AsyncSelect events", () => {
178
214
  <ColorPicker {...defaultProps} />
179
215
  </ThemeProvider>
180
216
  );
181
- const inputComponent = screen.getByTestId("inputPickerWrapper");
217
+ const inputComponent = screen.getByTestId("input-picker-wrapper");
182
218
  expect(inputComponent).toBeTruthy();
183
219
  fireEvent.blur(inputComponent, { target: { value: "#fff" } });
184
220
  expect(handleValidationMock).toBeCalled();
@@ -0,0 +1,94 @@
1
+ import * as React from "react";
2
+ import { ThemeProvider } from "styled-components";
3
+ import { render, cleanup, screen, fireEvent } from "@testing-library/react";
4
+ import "@testing-library/jest-dom";
5
+
6
+ import { parseTheme } from "@ax/helpers";
7
+ import InformativeMenu, { IInformativeMenuProps } from "@ax/components/InformativeMenu";
8
+ import globalTheme from "@ax/themes/theme.json";
9
+
10
+ afterEach(cleanup);
11
+
12
+ describe("Informative Menu component rendering", () => {
13
+ it("should render the component hidden", () => {
14
+ const defaultProps: IInformativeMenuProps = {
15
+ message: "This is the message",
16
+ icon: "alert",
17
+ actionText: "Got it",
18
+ };
19
+
20
+ render(
21
+ <ThemeProvider theme={parseTheme(globalTheme)}>
22
+ <InformativeMenu {...defaultProps} />
23
+ </ThemeProvider>
24
+ );
25
+
26
+ expect(screen.queryByText(defaultProps.message)).toBeFalsy();
27
+ });
28
+
29
+ it("should render the component with message on mouse enter", () => {
30
+ const defaultProps: IInformativeMenuProps = {
31
+ message: "This is the message",
32
+ icon: "alert",
33
+ actionText: "Got it",
34
+ };
35
+
36
+ render(
37
+ <ThemeProvider theme={parseTheme(globalTheme)}>
38
+ <InformativeMenu {...defaultProps} />
39
+ </ThemeProvider>
40
+ );
41
+
42
+ const iconAction = screen.getByTestId("icon-action-component");
43
+ expect(iconAction).toBeTruthy();
44
+ fireEvent.mouseEnter(iconAction);
45
+ const componentText = screen.getByText(defaultProps.message);
46
+ expect(componentText).toBeTruthy();
47
+ const button = screen.getByText(defaultProps.actionText).closest("button");
48
+ expect(button).toBeTruthy();
49
+ });
50
+
51
+ it("should hide the component with message on mouse leave", () => {
52
+ const defaultProps: IInformativeMenuProps = {
53
+ message: "This is the message",
54
+ icon: "alert",
55
+ actionText: "Got it",
56
+ };
57
+
58
+ render(
59
+ <ThemeProvider theme={parseTheme(globalTheme)}>
60
+ <InformativeMenu {...defaultProps} />
61
+ </ThemeProvider>
62
+ );
63
+
64
+ const iconAction = screen.getByTestId("icon-action-component");
65
+ expect(iconAction).toBeTruthy();
66
+ fireEvent.mouseEnter(iconAction);
67
+ expect(screen.getByText(defaultProps.message)).toBeTruthy();
68
+ fireEvent.mouseLeave(iconAction);
69
+ expect(screen.queryByText(defaultProps.message)).toBeFalsy();
70
+ });
71
+
72
+ it("should hide the component on button click", () => {
73
+ const defaultProps: IInformativeMenuProps = {
74
+ message: "This is the message",
75
+ icon: "alert",
76
+ actionText: "Got it",
77
+ };
78
+
79
+ render(
80
+ <ThemeProvider theme={parseTheme(globalTheme)}>
81
+ <InformativeMenu {...defaultProps} />
82
+ </ThemeProvider>
83
+ );
84
+
85
+ const iconAction = screen.getByTestId("icon-action-component");
86
+ expect(iconAction).toBeTruthy();
87
+ fireEvent.mouseEnter(iconAction);
88
+ expect(screen.getByText(defaultProps.message)).toBeTruthy();
89
+ const button = screen.getByText(defaultProps.actionText).closest("button");
90
+ expect(button).toBeTruthy();
91
+ button && fireEvent.click(button);
92
+ expect(screen.queryByText(defaultProps.message)).toBeFalsy();
93
+ });
94
+ });
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ import { ThemeProvider } from "styled-components";
3
+ import { render, cleanup, screen } from "@testing-library/react";
4
+ import "@testing-library/jest-dom";
5
+
6
+ import { parseTheme } from "@ax/helpers";
7
+ import ProgressBar, { IProgressBarProps } from "@ax/components/ProgressBar";
8
+ import globalTheme from "@ax/themes/theme.json";
9
+
10
+ afterEach(cleanup);
11
+
12
+ describe("ProgressBar component rendering", () => {
13
+ it("should render the component", () => {
14
+ const defaultProps: IProgressBarProps = {
15
+ percentage: 0,
16
+ };
17
+
18
+ render(
19
+ <ThemeProvider theme={parseTheme(globalTheme)}>
20
+ <ProgressBar {...defaultProps} />
21
+ </ThemeProvider>
22
+ );
23
+
24
+ const tracker = screen.getByTestId("progressbar-tracker");
25
+ expect(tracker).toBeTruthy();
26
+ });
27
+ });
@@ -0,0 +1,356 @@
1
+ import * as React from "react";
2
+
3
+ import { ThemeProvider } from "styled-components";
4
+ import { CalledWithMock, mock } from "jest-mock-extended";
5
+ import { render, screen, cleanup, fireEvent } from "@testing-library/react";
6
+ import { parseTheme } from "@ax/helpers";
7
+
8
+ import SideModal, { ISideModalProps } from "@ax/components/SideModal";
9
+ import globalTheme from "@ax/themes/theme.json";
10
+
11
+ afterEach(cleanup);
12
+
13
+ const defaultProps = mock<ISideModalProps>();
14
+
15
+ describe("SideModal component rendering", () => {
16
+ it("should render the component", () => {
17
+ const handleClickMock = jest.fn();
18
+ const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
19
+ defaultProps.categories = [
20
+ { featured: true, label: "All", value: "all" },
21
+ { label: "Articles And Events", value: "articlesAndEvents" },
22
+ ];
23
+ defaultProps.isOpen = true;
24
+ defaultProps.theme = "default-theme";
25
+ defaultProps.whiteList = ["EventsDistributor", "ArticlesDistributor"];
26
+ defaultProps.handleClick = handleClickMock;
27
+ defaultProps.toggleModal = toggleModalMock;
28
+ defaultProps.optionsType = "modules";
29
+
30
+ render(
31
+ <ThemeProvider theme={parseTheme(globalTheme)}>
32
+ <SideModal {...defaultProps} />
33
+ </ThemeProvider>
34
+ );
35
+
36
+ const sideModal = screen.getByTestId("side-modal");
37
+ expect(sideModal).toBeTruthy();
38
+ });
39
+
40
+ it("should not render the component if isOpen is false", () => {
41
+ const handleClickMock = jest.fn();
42
+ const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
43
+ defaultProps.categories = [
44
+ { featured: true, label: "All", value: "all" },
45
+ { label: "Articles And Events", value: "articlesAndEvents" },
46
+ ];
47
+ defaultProps.isOpen = false;
48
+ defaultProps.theme = "default-theme";
49
+ defaultProps.whiteList = ["EventsDistributor", "ArticlesDistributor"];
50
+ defaultProps.handleClick = handleClickMock;
51
+ defaultProps.toggleModal = toggleModalMock;
52
+ defaultProps.optionsType = "modules";
53
+
54
+ render(
55
+ <ThemeProvider theme={parseTheme(globalTheme)}>
56
+ <SideModal {...defaultProps} />
57
+ </ThemeProvider>
58
+ );
59
+
60
+ const sideModal = screen.queryByTestId("side-modal");
61
+ expect(sideModal).not.toBeTruthy();
62
+ });
63
+
64
+ it("should render optiontype as title", () => {
65
+ defaultProps.isOpen = true;
66
+ render(
67
+ <ThemeProvider theme={parseTheme(globalTheme)}>
68
+ <SideModal {...defaultProps} />
69
+ </ThemeProvider>
70
+ );
71
+
72
+ const sideModalTitle = screen.getByTestId("side-modal-title");
73
+ expect(sideModalTitle).toBeTruthy();
74
+ expect(sideModalTitle.textContent).toEqual("modules");
75
+ });
76
+
77
+ it("should render close button", () => {
78
+ render(
79
+ <ThemeProvider theme={parseTheme(globalTheme)}>
80
+ <SideModal {...defaultProps} />
81
+ </ThemeProvider>
82
+ );
83
+
84
+ const closeButton = screen.getByTestId("side-modal-close-button");
85
+ expect(closeButton).toBeTruthy();
86
+ });
87
+
88
+ it("should render default check if setDefault prop exists", () => {
89
+ defaultProps.setDefault = {
90
+ action: jest.fn(),
91
+ checked: false,
92
+ title: "Set the default header",
93
+ };
94
+ render(
95
+ <ThemeProvider theme={parseTheme(globalTheme)}>
96
+ <SideModal {...defaultProps} />
97
+ </ThemeProvider>
98
+ );
99
+
100
+ const checkfield = screen.getByTestId("check-field-wrapper");
101
+ expect(checkfield).toBeTruthy();
102
+ });
103
+
104
+ it("should render options", () => {
105
+ defaultProps.setDefault = undefined;
106
+ render(
107
+ <ThemeProvider theme={parseTheme(globalTheme)}>
108
+ <SideModal {...defaultProps} />
109
+ </ThemeProvider>
110
+ );
111
+
112
+ const options = screen.getAllByTestId("side-modal-option");
113
+ expect(options).toBeTruthy();
114
+ expect(options.length).toEqual(2);
115
+ });
116
+
117
+ it("should render option thumbnails", () => {
118
+ render(
119
+ <ThemeProvider theme={parseTheme(globalTheme)}>
120
+ <SideModal {...defaultProps} />
121
+ </ThemeProvider>
122
+ );
123
+
124
+ const thumbnails = screen.getAllByTestId("side-modal-option-img");
125
+ expect(thumbnails).toBeTruthy();
126
+ expect(thumbnails.length).toEqual(2);
127
+ });
128
+
129
+ it("should render all options when All filter is selected", () => {
130
+ const handleClickMock = jest.fn();
131
+ const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
132
+ defaultProps.categories = [
133
+ { featured: true, label: "All", value: "all" },
134
+ { label: "Content", value: "content" },
135
+ { label: "Collections", value: "collections" },
136
+ ];
137
+ defaultProps.isOpen = true;
138
+ defaultProps.theme = "default-theme";
139
+ defaultProps.whiteList = ["BasicContent", "CardCollection"];
140
+ defaultProps.handleClick = handleClickMock;
141
+ defaultProps.toggleModal = toggleModalMock;
142
+ defaultProps.optionsType = "modules";
143
+
144
+ render(
145
+ <ThemeProvider theme={parseTheme(globalTheme)}>
146
+ <SideModal {...defaultProps} />
147
+ </ThemeProvider>
148
+ );
149
+ const filters = screen.getAllByTestId("side-modal-nav-link");
150
+ expect(filters).toBeTruthy();
151
+ expect(filters.length).toEqual(3);
152
+ const allFilter = filters[0];
153
+ expect(allFilter.textContent).toEqual("All");
154
+ const links = screen.getAllByTestId("side-modal-link");
155
+ const allOptionLink = links[0];
156
+ const selectedStyles = getComputedStyle(allOptionLink);
157
+ expect(selectedStyles.color).toEqual("rgb(32, 34, 76)");
158
+ const options = screen.getAllByTestId("side-modal-option");
159
+ expect(options).toBeTruthy();
160
+ expect(options.length).toEqual(2);
161
+ expect(options[0].textContent).toEqual("Basic Content");
162
+ expect(options[1].textContent).toEqual("Card Collection");
163
+ });
164
+
165
+ it("should render components modal if option type is components", () => {
166
+ const handleClickMock = jest.fn();
167
+ const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
168
+ defaultProps.componentOptions = {
169
+ image: { component: "LinkableImage", editorID: 11, parentEditorID: 6 },
170
+ video: { component: "Video", editorID: 12, parentEditorID: 6 },
171
+ };
172
+ defaultProps.isOpen = true;
173
+ defaultProps.theme = "default-theme";
174
+ defaultProps.whiteList = ["LinkableImage", "Video"];
175
+ defaultProps.handleClick = handleClickMock;
176
+ defaultProps.toggleModal = toggleModalMock;
177
+ defaultProps.optionsType = "components";
178
+
179
+ render(
180
+ <ThemeProvider theme={parseTheme(globalTheme)}>
181
+ <SideModal {...defaultProps} />
182
+ </ThemeProvider>
183
+ );
184
+ const options = screen.getAllByTestId("side-modal-option");
185
+ expect(options).toBeTruthy();
186
+ expect(options.length).toEqual(2);
187
+ });
188
+ });
189
+
190
+ describe("SideModal component events", () => {
191
+ it("should call handle click and toggle modal on click option", () => {
192
+ const handleClickMock = jest.fn();
193
+ const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
194
+ defaultProps.categories = [
195
+ { featured: true, label: "All", value: "all" },
196
+ { label: "Articles And Events", value: "articlesAndEvents" },
197
+ ];
198
+ defaultProps.componentOptions = undefined;
199
+ defaultProps.isOpen = true;
200
+ defaultProps.theme = "default-theme";
201
+ defaultProps.whiteList = ["Accordion", "AddressCollection"];
202
+ defaultProps.handleClick = handleClickMock;
203
+ defaultProps.toggleModal = toggleModalMock;
204
+ defaultProps.optionsType = "modules";
205
+
206
+ render(
207
+ <ThemeProvider theme={parseTheme(globalTheme)}>
208
+ <SideModal {...defaultProps} />
209
+ </ThemeProvider>
210
+ );
211
+
212
+ const options = screen.getAllByTestId("side-modal-option");
213
+ expect(options).toBeTruthy();
214
+ expect(options.length).toEqual(2);
215
+ const option = options[0];
216
+ fireEvent.click(option);
217
+ expect(handleClickMock).toHaveBeenCalled();
218
+ expect(toggleModalMock).toHaveBeenCalled();
219
+ });
220
+
221
+ it("should select filter on click", () => {
222
+ const handleClickMock = jest.fn();
223
+ const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
224
+ defaultProps.categories = [
225
+ { featured: true, label: "All", value: "all" },
226
+ { label: "Content", value: "content" },
227
+ { label: "Collections", value: "collections" },
228
+ ];
229
+ defaultProps.isOpen = true;
230
+ defaultProps.theme = "default-theme";
231
+ defaultProps.whiteList = ["BasicContent", "CardCollection"];
232
+ defaultProps.handleClick = handleClickMock;
233
+ defaultProps.toggleModal = toggleModalMock;
234
+ defaultProps.optionsType = "modules";
235
+
236
+ render(
237
+ <ThemeProvider theme={parseTheme(globalTheme)}>
238
+ <SideModal {...defaultProps} />
239
+ </ThemeProvider>
240
+ );
241
+
242
+ const filters = screen.getAllByTestId("side-modal-nav-link");
243
+ expect(filters).toBeTruthy();
244
+ expect(filters.length).toEqual(3);
245
+ const allFilter = filters[0];
246
+ const contentFilter = filters[1];
247
+ expect(allFilter.textContent).toEqual("All");
248
+ expect(contentFilter.textContent).toEqual("Content");
249
+ const links = screen.getAllByTestId("side-modal-link");
250
+ expect(links).toBeTruthy();
251
+ expect(links.length).toEqual(3);
252
+ const contentOptionLink = links[1];
253
+ const notSelectedStyles = getComputedStyle(contentOptionLink);
254
+ expect(notSelectedStyles.color).toEqual("rgba(32, 34, 76, 0.6)");
255
+ fireEvent.click(contentFilter);
256
+ const selectedStyles = getComputedStyle(contentOptionLink);
257
+ expect(selectedStyles.color).toEqual("rgb(32, 34, 76)");
258
+ });
259
+
260
+ it("should filter by category on click", () => {
261
+ const handleClickMock = jest.fn();
262
+ const toggleModalMock = jest.fn() as CalledWithMock<void, []> & (() => void);
263
+ defaultProps.categories = [
264
+ { featured: true, label: "All", value: "all" },
265
+ { label: "Content", value: "content" },
266
+ { label: "Collections", value: "collections" },
267
+ ];
268
+ defaultProps.isOpen = true;
269
+ defaultProps.theme = "default-theme";
270
+ defaultProps.whiteList = ["BasicContent", "CardCollection"];
271
+ defaultProps.handleClick = handleClickMock;
272
+ defaultProps.toggleModal = toggleModalMock;
273
+ defaultProps.optionsType = "modules";
274
+
275
+ render(
276
+ <ThemeProvider theme={parseTheme(globalTheme)}>
277
+ <SideModal {...defaultProps} />
278
+ </ThemeProvider>
279
+ );
280
+
281
+ const filters = screen.getAllByTestId("side-modal-nav-link");
282
+ const options = screen.getAllByTestId("side-modal-option");
283
+ expect(options.length).toEqual(2);
284
+ expect(filters).toBeTruthy();
285
+ expect(filters.length).toEqual(3);
286
+ const contentFilter = filters[1];
287
+ expect(contentFilter.textContent).toEqual("Content");
288
+ fireEvent.click(contentFilter);
289
+ expect(options.length).toEqual(2);
290
+ });
291
+
292
+ it("should filter by query", () => {
293
+ defaultProps.showSearch = true;
294
+
295
+ render(
296
+ <ThemeProvider theme={parseTheme(globalTheme)}>
297
+ <SideModal {...defaultProps} />
298
+ </ThemeProvider>
299
+ );
300
+ const filterButton = screen.getByTestId("icon-search-wrapper");
301
+
302
+ expect(filterButton).toBeTruthy();
303
+ fireEvent.click(filterButton);
304
+ const searchFieldWrapper = screen.getByTestId("search-field-wrapper");
305
+ expect(searchFieldWrapper).toBeTruthy();
306
+ const input = screen.getByTestId("search-input");
307
+ fireEvent.click(searchFieldWrapper);
308
+ fireEvent.change(input, { target: { value: "Basic content" } });
309
+ fireEvent.keyDown(input, { key: "Enter", code: "Enter", charCode: 13 });
310
+ const options = screen.getAllByTestId("side-modal-option");
311
+ expect(options.length).toEqual(1);
312
+ expect(options[0].textContent).toEqual("Basic Content");
313
+ });
314
+
315
+ it("should call toggle modal on click outside the modal", () => {
316
+ const map: any = {};
317
+
318
+ document.addEventListener = jest.fn((event, callback) => {
319
+ map[event] = callback;
320
+ });
321
+
322
+ render(
323
+ <ThemeProvider theme={parseTheme(globalTheme)}>
324
+ <SideModal {...defaultProps} />
325
+ </ThemeProvider>
326
+ );
327
+
328
+ map.mousedown({
329
+ target: document.body,
330
+ });
331
+
332
+ expect(defaultProps.toggleModal).toHaveBeenCalled();
333
+ });
334
+
335
+ it("should not call toggle modal on click inside the modal", () => {
336
+ const map: any = {};
337
+
338
+ document.addEventListener = jest.fn((event, callback) => {
339
+ map[event] = callback;
340
+ });
341
+
342
+ render(
343
+ <ThemeProvider theme={parseTheme(globalTheme)}>
344
+ <SideModal {...defaultProps} />
345
+ </ThemeProvider>
346
+ );
347
+
348
+ const title = screen.getByTestId("side-modal-title");
349
+
350
+ map.mousedown({
351
+ target: title,
352
+ });
353
+
354
+ expect(defaultProps.toggleModal).not.toHaveBeenCalled();
355
+ });
356
+ });
@@ -4,7 +4,7 @@ import { FloatingMenu, Icon, IconAction, Tooltip } from "@ax/components";
4
4
 
5
5
  import * as S from "./style";
6
6
 
7
- const ActionMenu = (props: IProps): JSX.Element => {
7
+ const ActionMenu = (props: IActionMenuProps): JSX.Element => {
8
8
  const { options, icon, className, tooltip } = props;
9
9
 
10
10
  const MoreInfoButton = () => (
@@ -32,7 +32,7 @@ const ActionMenu = (props: IProps): JSX.Element => {
32
32
  );
33
33
 
34
34
  return (
35
- <S.Wrapper className={className}>
35
+ <S.Wrapper className={className} data-testid="action-menu-wrapper">
36
36
  <Tooltip content={tooltip} hideOnClick>
37
37
  <FloatingMenu Button={MoreInfoButton}>
38
38
  <S.ActionMenu>{options.map((item: IOption) => ActionMenuItem(item))}</S.ActionMenu>
@@ -51,7 +51,7 @@ interface IOption {
51
51
  color?: boolean;
52
52
  }
53
53
 
54
- interface IProps {
54
+ export interface IActionMenuProps {
55
55
  options: IOption[];
56
56
  icon: string;
57
57
  className?: string;
@@ -11,7 +11,6 @@ import PreviewForm from "./PreviewForm";
11
11
  import Header from "./Header";
12
12
 
13
13
  import * as S from "./style";
14
-
15
14
  const navigationModulesTypes = ["header", "footer"];
16
15
 
17
16
  const ConfigPanel = (props: IStateProps): JSX.Element => {
@@ -1,26 +1,13 @@
1
1
  import React, { useState } from "react";
2
- import { hex3to6 } from "../helpers";
2
+ import { hex3to6, defaultColors } from "./../helpers";
3
3
 
4
4
  import * as S from "./style";
5
5
 
6
6
  const Picker = (props: IProps): JSX.Element => {
7
- const { value, onChange, colors } = props;
8
-
7
+ const { value, onChange, colors, onlyFixedColors } = props;
9
8
  const [color, setColor] = useState(value);
10
9
  const [inputValue, setInputValue] = useState(value);
11
10
 
12
- const defaultColors = [
13
- "#d9e3f0",
14
- "#f47373",
15
- "#697689",
16
- "#37d67a",
17
- "#2ccce4",
18
- "#555555",
19
- "#dce775",
20
- "#ff8a65",
21
- "#ba68c8",
22
- ];
23
-
24
11
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
25
12
  let newValue = e.target.value;
26
13
  setInputValue(newValue);
@@ -38,9 +25,10 @@ const Picker = (props: IProps): JSX.Element => {
38
25
  }
39
26
  };
40
27
 
41
- const handleClick = (newColor: string) => () => {
42
- setInputValue(newColor);
43
- setColor(newColor);
28
+ const handleClick = (newColor: string | any ) => () => {
29
+ const gridColor = typeof newColor !== "object" ? newColor : newColor.hex;
30
+ setInputValue(gridColor);
31
+ setColor(gridColor);
44
32
  onChange(newColor);
45
33
  };
46
34
 
@@ -57,24 +45,29 @@ const Picker = (props: IProps): JSX.Element => {
57
45
  const gridColors = colors ? colors : defaultColors;
58
46
 
59
47
  return (
60
- <S.Wrapper data-testid="pickerWrapper">
48
+ <S.Wrapper data-testid="picker-wrapper">
61
49
  <S.Cover background={color} light={isLight(color)}>
62
50
  {color}
63
51
  </S.Cover>
64
52
  <S.Grid>
65
- {gridColors.map((item: string) => (
66
- <S.GridItem
67
- data-testid="gridItem"
68
- key={item}
69
- background={item}
70
- onClick={handleClick(item)}
71
- selected={item === color}
72
- />
73
- ))}
53
+ {gridColors.map((item: any) => {
54
+ const gridColor = typeof item === "object" ? item.hex : item;
55
+ return (
56
+ <S.GridItem
57
+ data-testid="grid-item"
58
+ key={gridColor}
59
+ background={gridColor}
60
+ onClick={handleClick(item)}
61
+ selected={gridColor === color}
62
+ />
63
+ );
64
+ })}
74
65
  </S.Grid>
75
- <S.InputWrapper>
76
- <S.Input data-testid="inputPicker" type="text" value={inputValue} onChange={handleChange} />
77
- </S.InputWrapper>
66
+ {!onlyFixedColors ? (
67
+ <S.InputWrapper>
68
+ <S.Input data-testid="input-picker" type="text" value={inputValue} onChange={handleChange} />
69
+ </S.InputWrapper>
70
+ ) : null}
78
71
  </S.Wrapper>
79
72
  );
80
73
  };
@@ -83,6 +76,7 @@ export interface IProps {
83
76
  value: string;
84
77
  colors?: string[];
85
78
  onChange: (newColor: string) => void;
79
+ onlyFixedColors?: boolean;
86
80
  }
87
81
 
88
82
  export default Picker;
@@ -3,4 +3,39 @@ const hex3to6 = (color: string) => {
3
3
  return "#" + hexcolor.split('').map((hex: string) => hex + hex).join('');
4
4
  }
5
5
 
6
- export { hex3to6 };
6
+ const defaultOptions = (vusOptions: Record<string, unknown>[]) => {
7
+ return !vusOptions.find((entry) => entry.theme);
8
+ };
9
+
10
+ const defaultColors = [
11
+ "#d9e3f0",
12
+ "#f47373",
13
+ "#697689",
14
+ "#37d67a",
15
+ "#2ccce4",
16
+ "#555555",
17
+ "#dce775",
18
+ "#ff8a65",
19
+ "#ba68c8",
20
+ ];
21
+
22
+ const getOptions = (theme: string, onlyFixedColors: boolean | undefined, colorOptions: any[] | undefined) => {
23
+ if (!colorOptions) return defaultColors;
24
+ if (onlyFixedColors) return colorOptions;
25
+
26
+ const themes = colorOptions.filter((entry) => entry.theme).map((entry) => entry.theme);
27
+ const themeExists = themes.includes(theme);
28
+ const defaultsOptions = colorOptions.filter((entry) => typeof entry === "string");
29
+
30
+ // 1 - Si options solo tiene las defaults options (legacy) devuelve las defaults.
31
+ // 2 - Si options no tiene el theme, devuelve las defaults.
32
+ if (defaultOptions(colorOptions) || !themeExists) return defaultsOptions;
33
+
34
+ // Si options tiene el theme, devuelve las options de ese theme.
35
+ const optionsObj = colorOptions.find((entry) => entry.theme === theme);
36
+
37
+ return optionsObj && optionsObj.options;
38
+ };
39
+
40
+
41
+ export { hex3to6, getOptions, defaultColors };
@@ -2,18 +2,48 @@ import React, { useRef, useState, memo, useReducer, useCallback } from "react";
2
2
 
3
3
  import { useHandleClickOutside } from "@ax/hooks";
4
4
  import { IconAction } from "@ax/components";
5
+ import { defaultColors, getOptions, hex3to6 } from "./helpers";
5
6
  import Picker from "./Picker";
6
- import { hex3to6 } from "./helpers";
7
7
 
8
8
  import * as S from "./style";
9
9
 
10
10
  const ColorPicker = (props: IProps): JSX.Element => {
11
- const { value, onChange, error, colors, handleValidation, theme } = props;
11
+ const { value, onChange, error, colors = [], handleValidation, theme, onlyFixedColors } = props;
12
+
13
+ const getCurrentColors = () => {
14
+ if (onlyFixedColors) {
15
+ const currentOption = colors?.find((options: any) => options.theme === theme);
16
+ return currentOption ? currentOption?.options : defaultColors;
17
+ } else {
18
+ return colors.length ? colors : defaultColors;
19
+ }
20
+ };
12
21
 
13
- const initialState = { color: value, inputValue: value };
22
+ const currentColors = getCurrentColors();
23
+
24
+ const getInitialState = () => {
25
+ const defaultColor = currentColors[0];
26
+ if (onlyFixedColors) {
27
+ const currentValue = currentColors.find((color: any) => color.name === value);
28
+ const isObject = typeof defaultColor === "object";
29
+
30
+ let color;
31
+ if (currentValue) {
32
+ color = isObject ? currentValue.hex : currentValue;
33
+ } else {
34
+ color = isObject ? defaultColor.hex : defaultColor;
35
+ }
36
+
37
+ return { color, inputValue: color };
38
+ } else {
39
+ const color = value ? value : defaultColor;
40
+ return { color, inputValue: color };
41
+ }
42
+ };
43
+
44
+ const initialState = getInitialState();
14
45
  const reducer = useCallback((state: any, payload: any) => ({ ...state, ...payload }), []);
15
46
  const [state, dispatch] = useReducer(reducer, initialState);
16
-
17
47
  const [isVisible, setIsVisible] = useState(false);
18
48
  const wrapper = useRef<HTMLDivElement>(null);
19
49
 
@@ -44,9 +74,12 @@ const ColorPicker = (props: IProps): JSX.Element => {
44
74
  error && handleValidation && handleValidation(inputValue, { colorHex: true });
45
75
  };
46
76
 
47
- const handlePickerChange = (color: string) => {
48
- dispatch({ color, inputValue: color });
49
- onChange(color);
77
+ const handlePickerChange = (value: string | any) => {
78
+ const isObject = typeof value === "object";
79
+ const hex = !isObject ? value : value.hex;
80
+ const name = !isObject ? value : value.name;
81
+ dispatch({ color: hex, inputValue: hex });
82
+ onChange(name);
50
83
  };
51
84
 
52
85
  const handleOnBlur = (e: React.FocusEvent<HTMLInputElement>) => {
@@ -57,44 +90,32 @@ const ColorPicker = (props: IProps): JSX.Element => {
57
90
 
58
91
  const icon = isVisible ? "close" : "colorPicker";
59
92
 
60
- const defaultOptions = (vusOptions: Record<string, unknown>[]) => {
61
- return !vusOptions.find((entry) => entry.theme);
62
- };
63
-
64
- const getOptions = (theme: string, colorOptions: any[] | undefined) => {
65
- if (!colorOptions) return undefined;
66
-
67
- const themes = colorOptions.filter((entry) => entry.theme).map((entry) => entry.theme);
68
- const themeExists = themes.includes(theme);
69
- const defaultsOptions = colorOptions.filter((entry) => typeof entry === "string");
70
-
71
- // 1 - Si options solo tiene las defaults options (legacy) devuelve las defaults.
72
- // 2 - Si options no tiene el theme, devuelve las defaults.
73
- if (defaultOptions(colorOptions) || !themeExists) return defaultsOptions;
74
-
75
- // Si options tiene el theme, devuelve las options de ese theme.
76
- const optionsObj = colorOptions.find((entry) => entry.theme === theme);
77
- return optionsObj && optionsObj.options;
78
- };
79
-
80
93
  return (
81
- <S.Wrapper ref={wrapper} data-testid="colorPickerWrapper">
94
+ <S.Wrapper ref={wrapper} data-testid="color-picker-wrapper">
82
95
  <S.InputWrapper>
83
96
  <S.ColorWrapper background={state.color} />
84
97
  <S.Input
85
- data-testid="inputPickerWrapper"
98
+ data-testid="input-picker-wrapper"
86
99
  type="text"
87
100
  value={state.inputValue}
88
101
  onChange={handleInputChange}
89
102
  error={error}
90
103
  placeholder="#FFFFFF"
91
104
  onBlur={handleOnBlur}
105
+ readOnly={onlyFixedColors}
92
106
  />
93
107
  <S.IconWrapper>
94
108
  <IconAction icon={icon} size="s" onClick={togglePicker} />
95
109
  </S.IconWrapper>
96
110
  </S.InputWrapper>
97
- {isVisible && <Picker value={state.color} onChange={handlePickerChange} colors={getOptions(theme, colors)} />}
111
+ {isVisible && (
112
+ <Picker
113
+ value={state.color}
114
+ onChange={handlePickerChange}
115
+ colors={getOptions(theme, onlyFixedColors, currentColors)}
116
+ onlyFixedColors={onlyFixedColors}
117
+ />
118
+ )}
98
119
  </S.Wrapper>
99
120
  );
100
121
  };
@@ -102,10 +123,11 @@ const ColorPicker = (props: IProps): JSX.Element => {
102
123
  export interface IProps {
103
124
  value: string;
104
125
  error?: boolean;
105
- colors?: string[] | Record<string, unknown>[];
126
+ colors?: string[] | Record<string, unknown>[] | any[];
106
127
  onChange: (newColor: string) => void;
107
128
  handleValidation?: (value: string, validators: Record<string, unknown>) => void;
108
129
  theme: string;
130
+ onlyFixedColors?: boolean;
109
131
  }
110
132
 
111
133
  export default memo(ColorPicker);
@@ -4,7 +4,7 @@ import { Button, FloatingMenu, IconAction } from "@ax/components";
4
4
 
5
5
  import * as S from "./style";
6
6
 
7
- const InformativeMenu = (props: IProps): JSX.Element => {
7
+ const InformativeMenu = (props: IInformativeMenuProps): JSX.Element => {
8
8
  const { icon, message, actionText, iconSize, position } = props;
9
9
 
10
10
  const InfoButton = () => <IconAction icon={icon} size={iconSize} />;
@@ -25,11 +25,11 @@ const InformativeMenu = (props: IProps): JSX.Element => {
25
25
  );
26
26
  };
27
27
 
28
- interface IProps {
28
+ export interface IInformativeMenuProps {
29
29
  icon: string;
30
30
  message: string;
31
31
  actionText: string;
32
- iconSize?: "s" | "m" | undefined;
32
+ iconSize?: "s" | "m";
33
33
  position?: string;
34
34
  }
35
35
  export default InformativeMenu;
@@ -10,13 +10,13 @@ const ProgressBar = (props: IProgressBarProps): JSX.Element => {
10
10
  };
11
11
 
12
12
  return (
13
- <S.Tracker>
13
+ <S.Tracker data-testid="progressbar-tracker">
14
14
  <S.ProgressInTracker percentage={percentageLimits(0, percentage, 100)} />
15
15
  </S.Tracker>
16
16
  );
17
17
  };
18
18
 
19
- interface IProgressBarProps {
19
+ export interface IProgressBarProps {
20
20
  percentage: number;
21
21
  }
22
22
 
@@ -28,7 +28,7 @@ const SideModalOption = (props: IProps) => {
28
28
 
29
29
  return (
30
30
  <S.Item onClick={setOption} data-testid="side-modal-option">
31
- <S.Thumbnail {...thumbnailProps} />
31
+ <S.Thumbnail data-testid="side-modal-option-img" {...thumbnailProps} />
32
32
  {label}
33
33
  </S.Item>
34
34
  );
@@ -58,13 +58,19 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
58
58
  // eslint-disable-next-line react-hooks/exhaustive-deps
59
59
  }, [current, whiteList]);
60
60
 
61
+ const handleToggleModal = () => {
62
+ setSearchQuery("");
63
+ toggleModal();
64
+ };
65
+
61
66
  const node = useRef<any>(null);
67
+
62
68
  const handleClickOutside = (e: any) => {
63
69
  if (node.current.contains(e.target)) {
64
70
  return;
65
71
  }
66
72
 
67
- toggleModal();
73
+ handleToggleModal();
68
74
  };
69
75
 
70
76
  useHandleClickOutside(isOpen, handleClickOutside);
@@ -87,8 +93,10 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
87
93
 
88
94
  return (
89
95
  <MenuItem key={`${value}${i}`} active={isSelected}>
90
- <S.NavLink onClick={filterOptions}>
91
- <S.Link active={isSelected}>{label}</S.Link>
96
+ <S.NavLink onClick={filterOptions} data-testid="side-modal-nav-link">
97
+ <S.Link data-testid="side-modal-link" active={isSelected}>
98
+ {label}
99
+ </S.Link>
92
100
  </S.NavLink>
93
101
  </MenuItem>
94
102
  );
@@ -115,7 +123,6 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
115
123
  const filteredOptions =
116
124
  options.options &&
117
125
  options.options.map((option: any, i: number) => {
118
- if (typeof option !== "object" && typeof option !== "string") return null;
119
126
  const displayName = getDisplayName(option.component ? option.component : option);
120
127
  if (searchQuery.length > 0) {
121
128
  const name = displayName.toLowerCase();
@@ -126,7 +133,7 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
126
133
  <SideModalOption
127
134
  option={option}
128
135
  handleClick={handleClick}
129
- toggleModal={toggleModal}
136
+ toggleModal={handleToggleModal}
130
137
  key={`${option}${i}`}
131
138
  theme={theme}
132
139
  >
@@ -139,20 +146,20 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
139
146
  ? createPortal(
140
147
  <S.Wrapper ref={node} optionsType={optionsType} data-testid="side-modal">
141
148
  <S.Header>
142
- <S.Title>{optionsType}</S.Title>
149
+ <S.Title data-testid="side-modal-title">{optionsType}</S.Title>
143
150
  {showSearch && optionsType !== "components" && (
144
151
  <S.SearchWrapper>
145
152
  <SearchField onChange={setSearchQuery} closeOnInactive />
146
153
  </S.SearchWrapper>
147
154
  )}
148
155
  {!showSearch && (
149
- <S.ButtonWrapper>
150
- <IconAction icon="close" onClick={toggleModal} />
156
+ <S.ButtonWrapper data-testid="side-modal-close-button">
157
+ <IconAction icon="close" onClick={handleToggleModal} />
151
158
  </S.ButtonWrapper>
152
159
  )}
153
160
  </S.Header>
154
161
  {setDefault && !setDefault.checked && (
155
- <S.CheckFieldWrapper>
162
+ <S.CheckFieldWrapper data-testid="check-field-wrapper">
156
163
  <CheckField
157
164
  name="setDefault"
158
165
  value="setDefault"
@@ -177,7 +184,7 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
177
184
  : null;
178
185
  };
179
186
 
180
- interface ISideModalProps {
187
+ export interface ISideModalProps {
181
188
  isOpen: boolean;
182
189
  whiteList: string[] | undefined;
183
190
  categories?: ModuleCategoryInfo[];
@@ -55,6 +55,7 @@ const Form = (props: IProps): JSX.Element => {
55
55
  <FieldsBehavior
56
56
  title="Image"
57
57
  name="image"
58
+ fullWidth={true}
58
59
  fieldType="ImageField"
59
60
  value={itemImage || null}
60
61
  onChange={setImageValue}