@dxc-technology/halstack-react 0.0.0-b2237e2 → 0.0.0-b230d97

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 (148) hide show
  1. package/HalstackContext.js +55 -50
  2. package/accordion/Accordion.js +117 -104
  3. package/accordion/Accordion.stories.tsx +103 -15
  4. package/accordion/Accordion.test.js +9 -10
  5. package/accordion/types.d.ts +5 -4
  6. package/accordion-group/AccordionGroup.js +1 -21
  7. package/accordion-group/AccordionGroup.stories.tsx +27 -1
  8. package/accordion-group/AccordionGroup.test.js +20 -45
  9. package/accordion-group/types.d.ts +10 -3
  10. package/alert/Alert.js +1 -1
  11. package/box/Box.js +1 -1
  12. package/box/types.d.ts +1 -0
  13. package/bulleted-list/types.d.ts +1 -1
  14. package/button/Button.js +50 -70
  15. package/button/Button.stories.tsx +159 -8
  16. package/button/types.d.ts +7 -7
  17. package/card/types.d.ts +1 -0
  18. package/checkbox/Checkbox.d.ts +2 -2
  19. package/checkbox/Checkbox.js +92 -99
  20. package/checkbox/Checkbox.stories.tsx +131 -59
  21. package/checkbox/Checkbox.test.js +93 -16
  22. package/checkbox/types.d.ts +6 -2
  23. package/chip/Chip.js +16 -22
  24. package/chip/Chip.stories.tsx +96 -9
  25. package/chip/types.d.ts +1 -1
  26. package/common/variables.js +281 -259
  27. package/date-input/Calendar.d.ts +4 -0
  28. package/date-input/Calendar.js +258 -0
  29. package/date-input/DateInput.js +134 -237
  30. package/date-input/DateInput.stories.tsx +137 -38
  31. package/date-input/DateInput.test.js +494 -138
  32. package/date-input/DatePicker.d.ts +4 -0
  33. package/date-input/DatePicker.js +146 -0
  34. package/date-input/Icons.d.ts +6 -0
  35. package/date-input/Icons.js +75 -0
  36. package/date-input/YearPicker.d.ts +4 -0
  37. package/date-input/YearPicker.js +126 -0
  38. package/date-input/types.d.ts +51 -0
  39. package/dialog/Dialog.js +52 -28
  40. package/dialog/Dialog.stories.tsx +57 -2
  41. package/dialog/Dialog.test.js +34 -4
  42. package/dialog/types.d.ts +3 -2
  43. package/dropdown/Dropdown.d.ts +1 -1
  44. package/dropdown/Dropdown.js +246 -249
  45. package/dropdown/Dropdown.stories.tsx +245 -56
  46. package/dropdown/Dropdown.test.js +504 -108
  47. package/dropdown/DropdownMenu.d.ts +4 -0
  48. package/dropdown/DropdownMenu.js +70 -0
  49. package/dropdown/DropdownMenuItem.d.ts +4 -0
  50. package/dropdown/DropdownMenuItem.js +81 -0
  51. package/dropdown/types.d.ts +25 -5
  52. package/file-input/FileInput.d.ts +2 -2
  53. package/file-input/FileInput.js +177 -219
  54. package/file-input/FileInput.stories.tsx +122 -11
  55. package/file-input/FileInput.test.js +53 -12
  56. package/file-input/FileItem.d.ts +4 -14
  57. package/file-input/FileItem.js +38 -63
  58. package/file-input/types.d.ts +17 -0
  59. package/flex/Flex.d.ts +1 -1
  60. package/flex/Flex.js +31 -19
  61. package/flex/types.d.ts +15 -4
  62. package/footer/Footer.stories.tsx +99 -1
  63. package/footer/types.d.ts +2 -1
  64. package/header/Header.js +87 -87
  65. package/header/Header.stories.tsx +127 -6
  66. package/header/Icons.js +2 -2
  67. package/header/types.d.ts +3 -2
  68. package/layout/ApplicationLayout.js +3 -3
  69. package/layout/ApplicationLayout.stories.tsx +1 -0
  70. package/link/Link.js +1 -1
  71. package/link/types.d.ts +1 -1
  72. package/number-input/NumberInput.test.js +43 -7
  73. package/package.json +16 -21
  74. package/paginator/Icons.d.ts +5 -0
  75. package/paginator/Icons.js +16 -28
  76. package/paginator/Paginator.js +6 -12
  77. package/paginator/Paginator.stories.tsx +24 -0
  78. package/paginator/Paginator.test.js +18 -11
  79. package/password-input/PasswordInput.test.js +13 -12
  80. package/progress-bar/ProgressBar.d.ts +2 -2
  81. package/progress-bar/ProgressBar.js +56 -50
  82. package/progress-bar/ProgressBar.stories.jsx +36 -3
  83. package/progress-bar/ProgressBar.test.js +67 -22
  84. package/progress-bar/types.d.ts +3 -4
  85. package/quick-nav/QuickNav.js +11 -12
  86. package/quick-nav/QuickNav.stories.tsx +111 -19
  87. package/radio-group/Radio.d.ts +1 -1
  88. package/radio-group/Radio.js +43 -28
  89. package/radio-group/RadioGroup.js +24 -24
  90. package/radio-group/RadioGroup.stories.tsx +132 -18
  91. package/radio-group/RadioGroup.test.js +123 -96
  92. package/radio-group/types.d.ts +2 -2
  93. package/resultsetTable/Icons.d.ts +7 -0
  94. package/resultsetTable/Icons.js +51 -0
  95. package/resultsetTable/ResultsetTable.js +48 -107
  96. package/resultsetTable/ResultsetTable.stories.tsx +50 -25
  97. package/resultsetTable/ResultsetTable.test.js +40 -63
  98. package/resultsetTable/types.d.ts +2 -2
  99. package/select/Listbox.js +4 -10
  100. package/select/Option.js +11 -24
  101. package/select/Select.js +54 -50
  102. package/select/Select.stories.tsx +494 -149
  103. package/select/Select.test.js +338 -272
  104. package/select/types.d.ts +3 -5
  105. package/sidenav/Sidenav.js +8 -10
  106. package/sidenav/Sidenav.stories.tsx +148 -46
  107. package/sidenav/types.d.ts +1 -1
  108. package/slider/Slider.d.ts +2 -2
  109. package/slider/Slider.js +120 -95
  110. package/slider/Slider.stories.tsx +64 -1
  111. package/slider/Slider.test.js +121 -21
  112. package/slider/types.d.ts +6 -2
  113. package/spinner/Spinner.js +2 -2
  114. package/spinner/Spinner.stories.jsx +27 -1
  115. package/switch/Switch.d.ts +2 -2
  116. package/switch/Switch.js +135 -68
  117. package/switch/Switch.stories.tsx +41 -30
  118. package/switch/Switch.test.js +144 -17
  119. package/switch/types.d.ts +6 -2
  120. package/table/Table.js +1 -1
  121. package/table/Table.stories.jsx +80 -1
  122. package/table/Table.test.js +1 -1
  123. package/tabs/Tab.d.ts +4 -0
  124. package/tabs/Tab.js +133 -0
  125. package/tabs/Tabs.js +360 -104
  126. package/tabs/Tabs.stories.tsx +119 -5
  127. package/tabs/Tabs.test.js +217 -6
  128. package/tabs/types.d.ts +15 -5
  129. package/tabs-nav/NavTabs.js +5 -5
  130. package/tabs-nav/NavTabs.stories.tsx +8 -6
  131. package/tabs-nav/Tab.js +8 -12
  132. package/tabs-nav/types.d.ts +1 -1
  133. package/tag/Tag.js +1 -1
  134. package/tag/types.d.ts +1 -1
  135. package/text-input/Icons.d.ts +8 -0
  136. package/text-input/Icons.js +60 -0
  137. package/text-input/Suggestion.js +38 -9
  138. package/text-input/Suggestions.d.ts +4 -0
  139. package/text-input/Suggestions.js +134 -0
  140. package/text-input/TextInput.js +195 -292
  141. package/text-input/TextInput.stories.tsx +280 -185
  142. package/text-input/TextInput.test.js +737 -725
  143. package/text-input/types.d.ts +22 -3
  144. package/toggle-group/ToggleGroup.stories.tsx +42 -0
  145. package/toggle-group/types.d.ts +1 -1
  146. package/wizard/Wizard.stories.tsx +20 -0
  147. package/wizard/types.d.ts +1 -1
  148. package/common/RequiredComponent.js +0 -32
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import DxcTabs from "./Tabs";
3
3
  import Title from "../../.storybook/components/Title";
4
4
  import ExampleContainer from "../../.storybook/components/ExampleContainer";
5
+ import { HalstackProvider } from "../HalstackContext";
5
6
 
6
7
  export default {
7
8
  title: "Tabs",
@@ -9,9 +10,8 @@ export default {
9
10
  };
10
11
 
11
12
  const iconSVG = (
12
- <svg viewBox="0 0 24 24" fill="currentColor">
13
- <path d="M0 0h24v24H0z" fill="none" />
14
- <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
13
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" height="20" width="20" fill="currentColor">
14
+ <path d="m10 17-1.042-.938q-2.083-1.854-3.437-3.177-1.354-1.323-2.136-2.354Q2.604 9.5 2.302 8.646 2 7.792 2 6.896q0-1.854 1.271-3.125T6.396 2.5q1.021 0 1.979.438.958.437 1.625 1.229.667-.792 1.625-1.229.958-.438 1.979-.438 1.854 0 3.125 1.271T18 6.896q0 .896-.292 1.729-.291.833-1.073 1.854-.781 1.021-2.145 2.365-1.365 1.344-3.49 3.26Zm0-2.021q1.938-1.729 3.188-2.948 1.25-1.219 1.989-2.125.74-.906 1.031-1.614.292-.709.292-1.396 0-1.229-.833-2.063Q14.833 4 13.604 4q-.729 0-1.364.302-.636.302-1.094.844L10.417 6h-.834l-.729-.854q-.458-.542-1.114-.844Q7.083 4 6.396 4q-1.229 0-2.063.833-.833.834-.833 2.063 0 .687.271 1.364.271.678.989 1.573.719.896 1.98 2.125Q8 13.188 10 14.979Zm0-5.5Z" />
15
15
  </svg>
16
16
  );
17
17
 
@@ -29,6 +29,44 @@ const tabs: any = [
29
29
  {
30
30
  label: "Tab 4",
31
31
  },
32
+ {
33
+ label: "Tab 5",
34
+ },
35
+ {
36
+ label: "Tab 6",
37
+ },
38
+ {
39
+ label: "Tab 7",
40
+ },
41
+ ];
42
+
43
+ const disabledTabs: any = [
44
+ {
45
+ label: "Tab 1",
46
+ isDisabled: true,
47
+ },
48
+ {
49
+ label: "Tab 2",
50
+ isDisabled: true,
51
+ },
52
+ {
53
+ label: "Tab 3",
54
+ isDisabled: true,
55
+ },
56
+ ];
57
+
58
+ const firstDisabledTabs: any = [
59
+ {
60
+ label: "Tab 1",
61
+ isDisabled: true,
62
+ },
63
+ {
64
+ label: "Tab 2",
65
+ isDisabled: true,
66
+ },
67
+ {
68
+ label: "Tab 3",
69
+ },
32
70
  ];
33
71
 
34
72
  const tabsNotification = tabs.map((tab, index) => ({
@@ -36,16 +74,34 @@ const tabsNotification = tabs.map((tab, index) => ({
36
74
  notificationNumber: (index === 0 && true) || (index === 1 && 5) || (index === 2 && 200),
37
75
  }));
38
76
 
39
- const tabsIcon = tabs.map((tab) => ({ ...tab, icon: iconSVG }));
77
+ const tabsIcon = tabs.map((tab, index) =>
78
+ index <= tabs.length / 2
79
+ ? { ...tab, icon: "https://cdn-icons-png.flaticon.com/512/5039/5039041.png" }
80
+ : { ...tab, icon: iconSVG }
81
+ );
40
82
 
41
83
  const tabsNotificationIcon = tabsNotification.map((tab) => ({ ...tab, icon: iconSVG }));
42
84
 
85
+ const opinionatedTheme = {
86
+ tabs: {
87
+ baseColor: "#5f249f",
88
+ },
89
+ };
90
+
43
91
  export const Chromatic = () => (
44
92
  <>
45
93
  <ExampleContainer>
46
94
  <Title title="Only label" theme="light" level={4} />
47
95
  <DxcTabs tabs={tabs} />
48
96
  </ExampleContainer>
97
+ <ExampleContainer>
98
+ <Title title="Disabled tabs" theme="light" level={4} />
99
+ <DxcTabs activeTabIndex={0} tabs={disabledTabs} />
100
+ </ExampleContainer>
101
+ <ExampleContainer>
102
+ <Title title="First two tabs disabled" theme="light" level={4} />
103
+ <DxcTabs tabs={firstDisabledTabs} />
104
+ </ExampleContainer>
49
105
  <ExampleContainer pseudoState="pseudo-hover">
50
106
  <Title title="Hovered tabs" theme="light" level={4} />
51
107
  <DxcTabs tabs={tabs} />
@@ -106,7 +162,65 @@ export const Chromatic = () => (
106
162
  <ExampleContainer>
107
163
  <Title title="Xxlarge margin" theme="light" level={4} />
108
164
  <DxcTabs tabs={tabs} margin="xxlarge" />
109
- <hr />
165
+ </ExampleContainer>
166
+ <Title title="Opinionated theme" theme="light" level={2} />
167
+ <ExampleContainer>
168
+ <Title title="With icon and notification" theme="light" level={4} />
169
+ <HalstackProvider theme={opinionatedTheme}>
170
+ <DxcTabs tabs={tabsNotificationIcon} />
171
+ </HalstackProvider>
172
+ </ExampleContainer>
173
+ <ExampleContainer>
174
+ <Title title="Disabled" theme="light" level={4} />
175
+ <HalstackProvider theme={opinionatedTheme}>
176
+ <DxcTabs activeTabIndex={0} tabs={disabledTabs} />
177
+ </HalstackProvider>
178
+ </ExampleContainer>
179
+ <ExampleContainer pseudoState="pseudo-hover">
180
+ <Title title="Hovered" theme="light" level={4} />
181
+ <HalstackProvider theme={opinionatedTheme}>
182
+ <DxcTabs tabs={tabs} />
183
+ </HalstackProvider>
184
+ </ExampleContainer>
185
+ <ExampleContainer pseudoState="pseudo-focus">
186
+ <Title title="Focused" theme="light" level={4} />
187
+ <HalstackProvider theme={opinionatedTheme}>
188
+ <DxcTabs tabs={tabs} />
189
+ </HalstackProvider>
190
+ </ExampleContainer>
191
+ <ExampleContainer pseudoState="pseudo-active">
192
+ <Title title="Actived" theme="light" level={4} />
193
+ <HalstackProvider theme={opinionatedTheme}>
194
+ <DxcTabs tabs={tabs} />
195
+ </HalstackProvider>
110
196
  </ExampleContainer>
111
197
  </>
112
198
  );
199
+
200
+ export const ScrollableTabs = () => (
201
+ <>
202
+ <ExampleContainer>
203
+ <Title title="Only label" theme="light" level={4} />
204
+ <DxcTabs tabs={tabs} />
205
+ </ExampleContainer>
206
+ <ExampleContainer pseudoState="pseudo-hover">
207
+ <Title title="Hovered tabs" theme="light" level={4} />
208
+ <DxcTabs tabs={tabs} />
209
+ </ExampleContainer>
210
+ <ExampleContainer pseudoState="pseudo-focus">
211
+ <Title title="Focused tabs" theme="light" level={4} />
212
+ <DxcTabs tabs={tabs} />
213
+ </ExampleContainer>
214
+ <ExampleContainer pseudoState="pseudo-active">
215
+ <Title title="Actived tabs" theme="light" level={4} />
216
+ <DxcTabs tabs={tabs} />
217
+ </ExampleContainer>
218
+ </>
219
+ );
220
+
221
+ ScrollableTabs.parameters = {
222
+ viewport: {
223
+ defaultViewport: "iphonex",
224
+ },
225
+ chromatic: { viewports: [375], delay: 5000 },
226
+ };
package/tabs/Tabs.test.js CHANGED
@@ -25,6 +25,23 @@ var sampleTabsWithBadge = [{
25
25
  label: "Tab-3",
26
26
  notificationNumber: "101"
27
27
  }];
28
+ var sampleTabsMiddleDisabled = [{
29
+ label: "Tab-1"
30
+ }, {
31
+ label: "Tab-2",
32
+ isDisabled: true
33
+ }, {
34
+ label: "Tab-3"
35
+ }];
36
+ var sampleTabsLastTabNonDisabled = [{
37
+ label: "Tab-1",
38
+ isDisabled: true
39
+ }, {
40
+ label: "Tab-2",
41
+ isDisabled: true
42
+ }, {
43
+ label: "Tab-3"
44
+ }];
28
45
  describe("Tabs component tests", function () {
29
46
  test("Tabs render with correct labels", function () {
30
47
  var _render = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_Tabs["default"], {
@@ -103,18 +120,26 @@ describe("Tabs component tests", function () {
103
120
  tabs: sampleTabs,
104
121
  onTabClick: onTabClick
105
122
  })),
106
- getByText = _render6.getByText;
123
+ getByText = _render6.getByText,
124
+ getAllByRole = _render6.getAllByRole;
107
125
 
126
+ var tabs = getAllByRole("tab");
108
127
  var tab1 = getByText("Tab-1");
109
128
  var tab2 = getByText("Tab-2");
110
129
 
111
130
  _react2.fireEvent.click(tab2);
112
131
 
113
132
  expect(onTabClick).toHaveBeenCalledWith(1);
133
+ expect(tabs[0].getAttribute("aria-selected")).toBe("false");
134
+ expect(tabs[1].getAttribute("aria-selected")).toBe("true");
135
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
114
136
 
115
137
  _react2.fireEvent.click(tab1);
116
138
 
117
139
  expect(onTabClick).toHaveBeenCalledWith(0);
140
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
141
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
142
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
118
143
  });
119
144
  test("Controlled tabs", function () {
120
145
  var onTabClick = jest.fn();
@@ -124,17 +149,203 @@ describe("Tabs component tests", function () {
124
149
  onTabClick: onTabClick,
125
150
  activeTabIndex: 0
126
151
  })),
127
- getByText = _render7.getByText;
152
+ getByText = _render7.getByText,
153
+ getAllByRole = _render7.getAllByRole;
128
154
 
129
- var tab2 = getByText("Tab-2");
130
- var tab3 = getByText("Tab-3");
155
+ var tabs = getAllByRole("tab");
131
156
 
132
- _react2.fireEvent.click(tab2);
157
+ _react2.fireEvent.click(tabs[1]);
158
+
159
+ expect(onTabClick).toHaveBeenCalledWith(1);
160
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
161
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
162
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
163
+
164
+ _react2.fireEvent.click(tabs[2]);
165
+
166
+ expect(onTabClick).toHaveBeenCalledWith(2);
167
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
168
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
169
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
170
+ });
171
+ test("Uncontrolled tabs should have focus in the first non-disabled tab", function () {
172
+ var onTabClick = jest.fn();
173
+
174
+ var _render8 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_Tabs["default"], {
175
+ tabs: sampleTabsLastTabNonDisabled,
176
+ onTabClick: onTabClick
177
+ })),
178
+ getAllByRole = _render8.getAllByRole;
179
+
180
+ var tabs = getAllByRole("tab");
181
+ expect(tabs[0].hasAttribute("disabled")).toBeTruthy();
182
+ expect(tabs[1].hasAttribute("disabled")).toBeTruthy();
183
+ expect(tabs[2].hasAttribute("disabled")).toBeFalsy();
184
+ expect(tabs[0].getAttribute("aria-selected")).toBe("false");
185
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
186
+ expect(tabs[2].getAttribute("aria-selected")).toBe("true");
187
+ });
188
+ test("Controlled tabs with active index in disabled tab should not change focus to the first available tab", function () {
189
+ var onTabClick = jest.fn();
190
+
191
+ var _render9 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_Tabs["default"], {
192
+ tabs: sampleTabsLastTabNonDisabled,
193
+ onTabClick: onTabClick,
194
+ activeTabIndex: 0
195
+ })),
196
+ getAllByRole = _render9.getAllByRole;
197
+
198
+ var tabs = getAllByRole("tab");
199
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
200
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
201
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
202
+ expect(tabs[0].hasAttribute("disabled")).toBeTruthy();
203
+ expect(tabs[1].hasAttribute("disabled")).toBeTruthy();
204
+ expect(tabs[2].hasAttribute("disabled")).toBeFalsy();
205
+
206
+ _react2.fireEvent.click(tabs[2]);
207
+
208
+ expect(onTabClick).toHaveBeenCalledWith(2);
209
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
210
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
211
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
212
+ expect(tabs[0].hasAttribute("disabled")).toBeTruthy();
213
+ expect(tabs[1].hasAttribute("disabled")).toBeTruthy();
214
+ expect(tabs[2].hasAttribute("disabled")).toBeFalsy();
215
+ });
216
+ test("Select tabs with keyboard event arrows", function () {
217
+ var onTabClick = jest.fn();
218
+
219
+ var _render10 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_Tabs["default"], {
220
+ tabs: sampleTabs,
221
+ onTabClick: onTabClick
222
+ })),
223
+ getByText = _render10.getByText,
224
+ getByRole = _render10.getByRole,
225
+ getAllByRole = _render10.getAllByRole;
226
+
227
+ var tabList = getByRole("tablist");
228
+ var tab1 = getByText("Tab-1");
229
+ var tabs = getAllByRole("tab");
230
+
231
+ _react2.fireEvent.click(tab1);
232
+
233
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
234
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
235
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
236
+ expect(onTabClick).toHaveBeenCalledWith(0);
133
237
 
238
+ _react2.fireEvent.keyDown(tabList, {
239
+ key: "ArrowRight"
240
+ });
241
+
242
+ _react2.fireEvent.keyDown(tabList, {
243
+ key: "Enter"
244
+ });
245
+
246
+ expect(tabs[0].getAttribute("aria-selected")).toBe("false");
247
+ expect(tabs[1].getAttribute("aria-selected")).toBe("true");
248
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
134
249
  expect(onTabClick).toHaveBeenCalledWith(1);
135
250
 
136
- _react2.fireEvent.click(tab3);
251
+ _react2.fireEvent.keyDown(tabList, {
252
+ key: "ArrowRight"
253
+ });
254
+
255
+ _react2.fireEvent.keyDown(tabList, {
256
+ key: "Enter"
257
+ });
258
+
259
+ expect(tabs[0].getAttribute("aria-selected")).toBe("false");
260
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
261
+ expect(tabs[2].getAttribute("aria-selected")).toBe("true");
262
+ expect(onTabClick).toHaveBeenCalledWith(2);
263
+
264
+ _react2.fireEvent.keyDown(tabList, {
265
+ key: "ArrowLeft"
266
+ });
267
+
268
+ _react2.fireEvent.keyDown(tabList, {
269
+ key: "Enter"
270
+ });
271
+
272
+ expect(tabs[0].getAttribute("aria-selected")).toBe("false");
273
+ expect(tabs[1].getAttribute("aria-selected")).toBe("true");
274
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
275
+ expect(onTabClick).toHaveBeenCalledWith(1);
276
+
277
+ _react2.fireEvent.keyDown(tabList, {
278
+ key: "ArrowLeft"
279
+ });
280
+
281
+ _react2.fireEvent.keyDown(tabList, {
282
+ key: "Enter"
283
+ });
284
+
285
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
286
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
287
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
288
+ expect(onTabClick).toHaveBeenCalledWith(0);
289
+
290
+ _react2.fireEvent.keyDown(tabList, {
291
+ key: "ArrowLeft"
292
+ });
137
293
 
294
+ _react2.fireEvent.keyDown(tabList, {
295
+ key: "Enter"
296
+ });
297
+
298
+ expect(tabs[0].getAttribute("aria-selected")).toBe("false");
299
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
300
+ expect(tabs[2].getAttribute("aria-selected")).toBe("true");
301
+ expect(onTabClick).toHaveBeenCalledWith(2);
302
+
303
+ _react2.fireEvent.keyDown(tabList, {
304
+ key: "ArrowRight"
305
+ });
306
+
307
+ _react2.fireEvent.keyDown(tabList, {
308
+ key: "Enter"
309
+ });
310
+
311
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
312
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
313
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
314
+ expect(onTabClick).toHaveBeenCalledWith(0);
315
+ });
316
+ test("Skip disabled tab with keyboard event arrows", function () {
317
+ var onTabClick = jest.fn();
318
+
319
+ var _render11 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_Tabs["default"], {
320
+ tabs: sampleTabsMiddleDisabled,
321
+ onTabClick: onTabClick
322
+ })),
323
+ getByText = _render11.getByText,
324
+ getByRole = _render11.getByRole,
325
+ getAllByRole = _render11.getAllByRole;
326
+
327
+ var tabList = getByRole("tablist");
328
+ var tab1 = getByText("Tab-1");
329
+ var tabs = getAllByRole("tab");
330
+
331
+ _react2.fireEvent.click(tab1);
332
+
333
+ expect(tabs[0].getAttribute("aria-selected")).toBe("true");
334
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
335
+ expect(tabs[2].getAttribute("aria-selected")).toBe("false");
336
+ expect(onTabClick).toHaveBeenCalledWith(0);
337
+
338
+ _react2.fireEvent.keyDown(tabList, {
339
+ key: "ArrowRight"
340
+ });
341
+
342
+ _react2.fireEvent.keyDown(tabList, {
343
+ key: " "
344
+ });
345
+
346
+ expect(tabs[0].getAttribute("aria-selected")).toBe("false");
347
+ expect(tabs[1].getAttribute("aria-selected")).toBe("false");
348
+ expect(tabs[2].getAttribute("aria-selected")).toBe("true");
138
349
  expect(onTabClick).toHaveBeenCalledWith(2);
139
350
  });
140
351
  });
package/tabs/types.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  /// <reference types="react" />
2
- declare type Space = "xxsmall" | "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge";
3
- declare type Margin = {
2
+ export declare type Space = "xxsmall" | "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge";
3
+ export declare type Margin = {
4
4
  top?: Space;
5
5
  bottom?: Space;
6
6
  left?: Space;
7
7
  right?: Space;
8
8
  };
9
- declare type SVG = React.SVGProps<SVGSVGElement>;
9
+ declare type SVG = React.ReactNode & React.SVGProps<SVGSVGElement>;
10
10
  declare type TabCommonProps = {
11
11
  /**
12
12
  * Whether the tab is disabled or not.
@@ -21,7 +21,7 @@ declare type TabCommonProps = {
21
21
  */
22
22
  notificationNumber?: boolean | number;
23
23
  };
24
- declare type TabLabelProps = TabCommonProps & {
24
+ export declare type TabLabelProps = TabCommonProps & {
25
25
  /**
26
26
  * Tab label.
27
27
  */
@@ -31,7 +31,7 @@ declare type TabLabelProps = TabCommonProps & {
31
31
  */
32
32
  icon?: string | SVG;
33
33
  };
34
- declare type TabIconProps = TabCommonProps & {
34
+ export declare type TabIconProps = TabCommonProps & {
35
35
  /**
36
36
  * Tab label.
37
37
  */
@@ -41,6 +41,16 @@ declare type TabIconProps = TabCommonProps & {
41
41
  */
42
42
  icon: string | SVG;
43
43
  };
44
+ export declare type TabProps = {
45
+ tab: TabLabelProps | TabIconProps;
46
+ active: boolean;
47
+ tabIndex: number;
48
+ hasLabelAndIcon: boolean;
49
+ iconPosition: "top" | "left";
50
+ onClick: () => void;
51
+ onMouseEnter: () => void;
52
+ onMouseLeave: () => void;
53
+ };
44
54
  declare type Props = {
45
55
  /**
46
56
  * An array of objects representing the tabs.
@@ -91,15 +91,15 @@ var DxcNavTabs = function DxcNavTabs(_ref) {
91
91
  return getPropInChild(child, "active");
92
92
  });
93
93
 
94
- switch (event.keyCode) {
95
- case 37:
96
- // arrow left
94
+ switch (event.key) {
95
+ case "Left":
96
+ case "ArrowLeft":
97
97
  event.preventDefault();
98
98
  setInnerFocus(getPreviousTabIndex(children, innerFocus === null ? activeTab : innerFocus));
99
99
  break;
100
100
 
101
- case 39:
102
- // arrow right
101
+ case "Right":
102
+ case "ArrowRight":
103
103
  event.preventDefault();
104
104
  setInnerFocus(getNextTabIndex(children, innerFocus === null ? activeTab : innerFocus));
105
105
  break;
@@ -15,6 +15,8 @@ const iconSVG = (
15
15
  </svg>
16
16
  );
17
17
 
18
+ const largeIcon = "https://www.iconpacks.net/icons/1/free-pin-icon-48-thumb.png"
19
+
18
20
  export const Chromatic = () => (
19
21
  <>
20
22
  <ExampleContainer>
@@ -93,10 +95,10 @@ export const Chromatic = () => (
93
95
  <DxcNavTabs.Tab href="#" disabled icon={iconSVG}>
94
96
  Tab 2
95
97
  </DxcNavTabs.Tab>
96
- <DxcNavTabs.Tab href="#" icon={iconSVG}>
98
+ <DxcNavTabs.Tab href="#" icon={largeIcon}>
97
99
  Tab 3
98
100
  </DxcNavTabs.Tab>
99
- <DxcNavTabs.Tab href="#" icon={iconSVG}>
101
+ <DxcNavTabs.Tab href="#" icon={largeIcon}>
100
102
  Tab 4
101
103
  </DxcNavTabs.Tab>
102
104
  </DxcNavTabs>
@@ -104,7 +106,7 @@ export const Chromatic = () => (
104
106
  <ExampleContainer>
105
107
  <Title title="With icon position left" theme="light" level={4} />
106
108
  <DxcNavTabs iconPosition="left">
107
- <DxcNavTabs.Tab href="#" active icon={iconSVG}>
109
+ <DxcNavTabs.Tab href="#" active icon={largeIcon}>
108
110
  Tab 1
109
111
  </DxcNavTabs.Tab>
110
112
  <DxcNavTabs.Tab href="#" disabled icon={iconSVG}>
@@ -121,7 +123,7 @@ export const Chromatic = () => (
121
123
  <ExampleContainer>
122
124
  <Title title="With icon and notification number" theme="light" level={4} />
123
125
  <DxcNavTabs>
124
- <DxcNavTabs.Tab href="#" active icon={iconSVG} notificationNumber>
126
+ <DxcNavTabs.Tab href="#" active icon={largeIcon} notificationNumber>
125
127
  Tab 1
126
128
  </DxcNavTabs.Tab>
127
129
  <DxcNavTabs.Tab href="#" disabled icon={iconSVG} notificationNumber={5}>
@@ -130,7 +132,7 @@ export const Chromatic = () => (
130
132
  <DxcNavTabs.Tab href="#" icon={iconSVG} notificationNumber={120}>
131
133
  Tab 3
132
134
  </DxcNavTabs.Tab>
133
- <DxcNavTabs.Tab href="#" icon={iconSVG}>
135
+ <DxcNavTabs.Tab href="#" icon={largeIcon}>
134
136
  Tab 4
135
137
  </DxcNavTabs.Tab>
136
138
  </DxcNavTabs>
@@ -144,7 +146,7 @@ export const Chromatic = () => (
144
146
  <DxcNavTabs.Tab href="#" disabled icon={iconSVG} notificationNumber={5}>
145
147
  Tab 2
146
148
  </DxcNavTabs.Tab>
147
- <DxcNavTabs.Tab href="#" icon={iconSVG} notificationNumber={120}>
149
+ <DxcNavTabs.Tab href="#" icon={largeIcon} notificationNumber={120}>
148
150
  Tab 3
149
151
  </DxcNavTabs.Tab>
150
152
  <DxcNavTabs.Tab href="#" icon={iconSVG}>
package/tabs-nav/Tab.js CHANGED
@@ -23,7 +23,7 @@ var _Badge = _interopRequireDefault(require("../badge/Badge"));
23
23
 
24
24
  var _NavTabs = require("./NavTabs");
25
25
 
26
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6;
26
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
27
27
 
28
28
  var _excluded = ["href", "active", "icon", "disabled", "notificationNumber", "children"];
29
29
 
@@ -59,11 +59,9 @@ var DxcTab = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, _ref2) {
59
59
  var handleOnKeyDown = function handleOnKeyDown(event) {
60
60
  var _tabRef$current2;
61
61
 
62
- switch (event.keyCode) {
63
- case 13: // enter
64
-
65
- case 32:
66
- // space
62
+ switch (event.key) {
63
+ case " ":
64
+ case "Enter":
67
65
  tabRef === null || tabRef === void 0 ? void 0 : (_tabRef$current2 = tabRef.current) === null || _tabRef$current2 === void 0 ? void 0 : _tabRef$current2.click();
68
66
  event.preventDefault();
69
67
  break;
@@ -92,7 +90,7 @@ var DxcTab = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, _ref2) {
92
90
  tabIndex: active ? tabIndex : -1
93
91
  }, otherProps), icon && /*#__PURE__*/_react["default"].createElement(TabIconContainer, {
94
92
  iconPosition: iconPosition
95
- }, typeof icon === "string" ? /*#__PURE__*/_react["default"].createElement(TabIcon, {
93
+ }, typeof icon === "string" ? /*#__PURE__*/_react["default"].createElement("img", {
96
94
  src: icon
97
95
  }) : icon), /*#__PURE__*/_react["default"].createElement(LabelContainer, null, children, notificationNumber && /*#__PURE__*/_react["default"].createElement(BadgeContainer, null, /*#__PURE__*/_react["default"].createElement(_Badge["default"], {
98
96
  notificationText: notificationNumber > 99 ? "+99" : notificationNumber,
@@ -116,17 +114,15 @@ var Tab = _styledComponents["default"].a(_templateObject2 || (_templateObject2 =
116
114
  return !props.disabled && ":hover {\n background: #0000000D;\n }\n\n :focus {\n outline: 2px solid #33aaff};\n }\n\n :active {\n background: #0000001A;\n outline: 2px solid #33aaff};\n }";
117
115
  });
118
116
 
119
- var TabIcon = _styledComponents["default"].img(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])([""])));
120
-
121
- var TabIconContainer = _styledComponents["default"].div(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n max-height: 24px;\n max-width: 24px;\n margin-bottom: ", ";\n margin-right: ", ";\n overflow: hidden;\n display: flex;\n align-items: center;\n img,\n svg {\n height: 100%;\n width: 100%;\n }\n"])), function (props) {
117
+ var TabIconContainer = _styledComponents["default"].div(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n margin-bottom: ", ";\n margin-right: ", ";\n\n img,\n svg {\n height: 24px;\n width: 24px;\n }\n"])), function (props) {
122
118
  return props.iconPosition === "top" && "0.375rem";
123
119
  }, function (props) {
124
120
  return props.iconPosition === "left" && "0.625rem";
125
121
  });
126
122
 
127
- var LabelContainer = _styledComponents["default"].div(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n align-items: center;\n"])));
123
+ var LabelContainer = _styledComponents["default"].div(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n align-items: center;\n"])));
128
124
 
129
- var BadgeContainer = _styledComponents["default"].div(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n margin-left: 0.5rem;\n"])));
125
+ var BadgeContainer = _styledComponents["default"].div(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n margin-left: 0.5rem;\n"])));
130
126
 
131
127
  var _default = DxcTab;
132
128
  exports["default"] = _default;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- declare type SVG = React.SVGProps<SVGSVGElement>;
2
+ declare type SVG = React.ReactNode & React.SVGProps<SVGSVGElement>;
3
3
  export declare type TabProps = {
4
4
  /**
5
5
  * Whether the tab is active or not.
package/tag/Tag.js CHANGED
@@ -99,7 +99,7 @@ var sizes = {
99
99
  medium: "240px",
100
100
  large: "480px",
101
101
  fillParent: "100%",
102
- fitContent: "unset"
102
+ fitContent: "fit-content"
103
103
  };
104
104
 
105
105
  var calculateWidth = function calculateWidth(margin, size) {
package/tag/types.d.ts CHANGED
@@ -6,7 +6,7 @@ declare type Margin = {
6
6
  left?: Space;
7
7
  right?: Space;
8
8
  };
9
- declare type SVG = React.SVGProps<SVGSVGElement>;
9
+ declare type SVG = React.ReactNode & React.SVGProps<SVGSVGElement>;
10
10
  declare type TagCommonProps = {
11
11
  /**
12
12
  * If defined, the tag will be displayed as an anchor, using this prop as "href".
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ declare const icons: {
3
+ error: JSX.Element;
4
+ clear: JSX.Element;
5
+ increment: JSX.Element;
6
+ decrement: JSX.Element;
7
+ };
8
+ export default icons;