carbon-react 94.8.0 → 95.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/__internal__/focus-trap/focus-trap.component.js +3 -2
  2. package/lib/__internal__/tooltip-provider/index.d.ts +2 -0
  3. package/lib/__internal__/tooltip-provider/index.js +6 -3
  4. package/lib/__internal__/validations/validation-icon.component.js +3 -1
  5. package/lib/components/button/button.component.js +17 -8
  6. package/lib/components/button-toggle/button-toggle-icon.component.js +3 -4
  7. package/lib/components/button-toggle/button-toggle.style.js +2 -0
  8. package/lib/components/button-toggle-group/button-toggle-group.component.js +11 -3
  9. package/lib/components/button-toggle-group/button-toggle-group.d.ts +2 -0
  10. package/lib/components/checkbox/checkbox.component.js +6 -1
  11. package/lib/components/checkbox/checkbox.d.ts +2 -0
  12. package/lib/components/date/date.component.js +2 -1
  13. package/lib/components/decimal/decimal.component.js +4 -1
  14. package/lib/components/grouped-character/grouped-character.component.js +4 -1
  15. package/lib/components/heading/heading.component.js +8 -2
  16. package/lib/components/heading/heading.style.js +1 -0
  17. package/lib/components/help/help.component.js +24 -7
  18. package/lib/components/help/help.d.ts +2 -0
  19. package/lib/components/icon/icon-config.js +3 -5
  20. package/lib/components/icon/icon.component.js +16 -24
  21. package/lib/components/icon/icon.d.ts +3 -18
  22. package/lib/components/icon/icon.style.js +26 -77
  23. package/lib/components/link/link.component.js +8 -2
  24. package/lib/components/link/link.style.js +1 -0
  25. package/lib/components/message/type-icon/type-icon.component.js +1 -2
  26. package/lib/components/numeral-date/numeral-date.component.js +11 -3
  27. package/lib/components/numeral-date/numeral-date.d.ts +2 -0
  28. package/lib/components/pill/pill.component.js +1 -3
  29. package/lib/components/pill/pill.style.js +2 -0
  30. package/lib/components/radio-button/radio-button.component.js +5 -0
  31. package/lib/components/radio-button/radio-button.d.ts +2 -0
  32. package/lib/components/split-button/split-button.component.js +11 -4
  33. package/lib/components/switch/switch.component.js +6 -1
  34. package/lib/components/switch/switch.d.ts +2 -0
  35. package/lib/components/tabs/__internal__/tab-title/tab-title.style.js +10 -4
  36. package/lib/components/tabs/tabs.component.js +49 -31
  37. package/lib/components/textarea/textarea.component.js +6 -1
  38. package/lib/components/textarea/textarea.d.ts +2 -0
  39. package/lib/components/textbox/textbox.component.js +8 -3
  40. package/lib/components/textbox/textbox.d.ts +3 -1
  41. package/package.json +1 -1
@@ -17,8 +17,6 @@ var _iconUnicodes = _interopRequireDefault(require("./icon-unicodes"));
17
17
 
18
18
  var _base = _interopRequireDefault(require("../../style/themes/base"));
19
19
 
20
- var _palette = _interopRequireDefault(require("../../style/palette"));
21
-
22
20
  var _iconConfig = _interopRequireWildcard(require("./icon-config"));
23
21
 
24
22
  var _browserTypeCheck = _interopRequireWildcard(require("../../__internal__/utils/helpers/browser-type-check"));
@@ -31,60 +29,6 @@ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return
31
29
 
32
30
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
33
31
 
34
- const getBackgroundColor = (theme, bgTheme, disabled, isHover) => {
35
- if (bgTheme !== "none") {
36
- if (disabled) return theme.icon.disabled;
37
- }
38
-
39
- const palette = (0, _palette.default)({
40
- statusColor: theme.colors[bgTheme],
41
- businessColor: theme.colors.primary
42
- });
43
- const statuses = ["info", "error", "success", "warning"];
44
-
45
- if (statuses.includes(bgTheme)) {
46
- return isHover ? palette.statusColorShade(20) : theme.colors[bgTheme];
47
- }
48
-
49
- if (bgTheme === "business") {
50
- return isHover ? palette.businessColorShade(20) : theme.colors.primary;
51
- }
52
-
53
- return "transparent";
54
- };
55
-
56
- const getIconColor = (bgTheme, theme, iconColor, disabled, isHover) => {
57
- if (disabled) return theme.icon.disabled;
58
-
59
- if (bgTheme !== "none") {
60
- const whiteIconBackgrounds = ["error", "info", "business"];
61
- const darkIconBackgrounds = ["success", "warning"];
62
- if (whiteIconBackgrounds.includes(bgTheme)) return theme.colors.white;
63
-
64
- if (darkIconBackgrounds.includes(bgTheme)) {
65
- return isHover ? theme.icon.defaultHover : theme.icon.default;
66
- }
67
- }
68
-
69
- const palette = (0, _palette.default)({
70
- businessColor: theme.colors.primary
71
- });
72
-
73
- switch (iconColor) {
74
- case "on-dark-background":
75
- return theme.colors.white;
76
-
77
- case "on-light-background":
78
- return isHover ? theme.icon.onLightBackgroundHover : theme.icon.onLightBackground;
79
-
80
- case "business-color":
81
- return isHover ? palette.businessColorShade(20) : theme.colors.primary;
82
-
83
- default:
84
- return isHover ? theme.icon.defaultHover : theme.icon.default;
85
- }
86
- };
87
-
88
32
  function adjustIconBgSize(fontSize, bgSize) {
89
33
  var _replacements$fontSiz;
90
34
 
@@ -113,17 +57,16 @@ function adjustIconBgSize(fontSize, bgSize) {
113
57
 
114
58
  const StyledIcon = _styledComponents.default.span`
115
59
  ${({
116
- bgTheme,
117
60
  theme,
118
61
  color,
119
62
  bg,
120
63
  isInteractive,
121
- iconColor,
122
64
  bgSize,
123
65
  bgShape,
124
66
  type,
125
67
  fontSize,
126
- disabled
68
+ disabled,
69
+ hasTooltip
127
70
  }) => {
128
71
  let finalColor;
129
72
  let finalHoverColor;
@@ -131,7 +74,10 @@ const StyledIcon = _styledComponents.default.span`
131
74
  let bgHoverColor;
132
75
 
133
76
  try {
134
- if (color) {
77
+ if (disabled) {
78
+ finalColor = theme.icon.disabled;
79
+ finalHoverColor = theme.icon.disabled;
80
+ } else if (color) {
135
81
  const {
136
82
  color: renderedColor
137
83
  } = (0, _color.default)({
@@ -141,8 +87,8 @@ const StyledIcon = _styledComponents.default.span`
141
87
  finalColor = renderedColor;
142
88
  finalHoverColor = (0, _polished.shade)(0.2, renderedColor);
143
89
  } else {
144
- finalColor = getIconColor(bgTheme, theme, iconColor, disabled, false);
145
- finalHoverColor = getIconColor(bgTheme, theme, iconColor, disabled, true);
90
+ finalColor = theme.icon.default;
91
+ finalHoverColor = theme.icon.defaultHover;
146
92
  }
147
93
 
148
94
  if (bg) {
@@ -154,9 +100,12 @@ const StyledIcon = _styledComponents.default.span`
154
100
  });
155
101
  bgColor = backgroundColor;
156
102
  bgHoverColor = (0, _polished.shade)(0.2, backgroundColor);
103
+ } else if (disabled) {
104
+ bgColor = theme.icon.disabled;
105
+ bgHoverColor = theme.icon.disabled;
157
106
  } else {
158
- bgColor = getBackgroundColor(theme, bgTheme, disabled, false);
159
- bgHoverColor = getBackgroundColor(theme, bgTheme, disabled, true);
107
+ bgColor = "transparent";
108
+ bgHoverColor = "transparent";
160
109
  }
161
110
  } catch (e) {
162
111
  // eslint-disable-next-line no-console
@@ -164,11 +113,16 @@ const StyledIcon = _styledComponents.default.span`
164
113
  }
165
114
 
166
115
  return (0, _styledComponents.css)`
167
- display: inline-block;
168
116
  position: relative;
169
117
  color: ${finalColor};
170
118
  background-color: ${bgColor};
171
119
  vertical-align: middle;
120
+ align-items: center;
121
+ display: inline-flex;
122
+ justify-content: center;
123
+ height: ${adjustIconBgSize(fontSize, bgSize)};
124
+ width: ${adjustIconBgSize(fontSize, bgSize)};
125
+ border-radius: ${_iconConfig.default.backgroundShape[bgShape]};
172
126
 
173
127
  ${isInteractive && (0, _styledComponents.css)`
174
128
  &:hover {
@@ -177,15 +131,6 @@ const StyledIcon = _styledComponents.default.span`
177
131
  }
178
132
  `}
179
133
 
180
- ${bgTheme !== "none" && (0, _styledComponents.css)`
181
- align-items: center;
182
- display: inline-flex;
183
- justify-content: center;
184
- height: ${adjustIconBgSize(fontSize, bgSize)};
185
- width: ${adjustIconBgSize(fontSize, bgSize)};
186
- border-radius: ${_iconConfig.default.backgroundShape[bgShape]};
187
- `}
188
-
189
134
  &::before {
190
135
  -webkit-font-smoothing: antialiased;
191
136
  -moz-osx-font-smoothing: grayscale;
@@ -209,6 +154,12 @@ const StyledIcon = _styledComponents.default.span`
209
154
  display: block;
210
155
  }
211
156
 
157
+ ${hasTooltip && `
158
+ :focus {
159
+ outline: 2px solid ${theme.colors.focus};
160
+ }
161
+ `}
162
+
212
163
  ${_styledSystem.margin}
213
164
  `;
214
165
  }}
@@ -220,9 +171,7 @@ StyledIcon.propTypes = {
220
171
  disabled: _propTypes.default.bool,
221
172
  bgSize: _propTypes.default.oneOf(["extra-small", "small", "medium", "large", "extra-large"]),
222
173
  bgShape: _propTypes.default.oneOf(_iconConfig.ICON_SHAPES),
223
- bgTheme: _propTypes.default.oneOf([..._iconConfig.ICON_COLORS, ..._iconConfig.ICON_BACKGROUNDS, ""]),
224
- fontSize: _propTypes.default.oneOf(["small", "medium", "large", "extra-large"]),
225
- iconColor: _propTypes.default.oneOf(_iconConfig.ICON_COLORS)
174
+ fontSize: _propTypes.default.oneOf(["small", "medium", "large", "extra-large"])
226
175
  };
227
176
  StyledIcon.defaultProps = {
228
177
  theme: _base.default
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
 
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
 
10
+ var _styledComponents = require("styled-components");
11
+
10
12
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
13
 
12
14
  var _icon = _interopRequireDefault(require("../icon"));
@@ -17,6 +19,8 @@ var _link = require("./link.style");
17
19
 
18
20
  var _tags = _interopRequireDefault(require("../../__internal__/utils/helpers/tags/tags"));
19
21
 
22
+ var _themes = require("../../style/themes");
23
+
20
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
25
 
22
26
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -44,6 +48,8 @@ const Link = /*#__PURE__*/_react.default.forwardRef(({
44
48
  target,
45
49
  ...rest
46
50
  }, ref) => {
51
+ const theme = (0, _react.useContext)(_styledComponents.ThemeContext) || _themes.baseTheme;
52
+
47
53
  const tabIndex = tabbable && !disabled ? "0" : "-1";
48
54
 
49
55
  const handleOnKeyDown = ev => {
@@ -66,8 +72,8 @@ const Link = /*#__PURE__*/_react.default.forwardRef(({
66
72
  const hasProperAlignment = icon && iconAlign === currentAlignment;
67
73
  return hasProperAlignment ? /*#__PURE__*/_react.default.createElement(_icon.default, {
68
74
  type: icon,
69
- bgTheme: "none",
70
- iconColor: "business-color",
75
+ bgSize: "extra-small",
76
+ color: theme.colors.primary,
71
77
  disabled: disabled,
72
78
  ariaLabel: ariaLabel,
73
79
  tooltipMessage: tooltipMessage,
@@ -54,6 +54,7 @@ const StyledLink = _styledComponents.default.span`
54
54
  color: ${isSkipLink ? theme.text.color : theme.colors.primary};
55
55
  display: inline-block;
56
56
  ${_icon.default} {
57
+ display: inline-block;
57
58
  position: relative;
58
59
  vertical-align: middle;
59
60
  ${iconAlign === "left" && (0, _styledComponents.css)`
@@ -23,8 +23,7 @@ const TypeIcon = ({
23
23
  variant: variant,
24
24
  transparent: transparent
25
25
  }, /*#__PURE__*/_react.default.createElement(_icon.default, {
26
- type: variant,
27
- bgTheme: "none"
26
+ type: variant
28
27
  }));
29
28
  };
30
29
 
@@ -29,6 +29,8 @@ var _formField = _interopRequireDefault(require("../../__internal__/form-field")
29
29
 
30
30
  var _inputBehaviour = require("../../__internal__/input-behaviour");
31
31
 
32
+ var _tooltipProvider = require("../../__internal__/tooltip-provider");
33
+
32
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
35
 
34
36
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -82,6 +84,7 @@ const NumeralDate = ({
82
84
  enableInternalError,
83
85
  enableInternalWarning,
84
86
  tooltipPosition,
87
+ helpAriaLabel,
85
88
  ...rest
86
89
  }) => {
87
90
  const l = (0, _useLocale.default)();
@@ -165,7 +168,9 @@ const NumeralDate = ({
165
168
  const internalMessage = Object.keys(internalMessages).reduce((string, key) => internalMessages[key] ? `${string + internalMessages[key]}\n` : string, "");
166
169
  const internalError = enableInternalError ? internalMessage + error : error;
167
170
  const internalWarning = enableInternalWarning ? internalMessage + warning : warning;
168
- return /*#__PURE__*/_react.default.createElement(_inputBehaviour.InputGroupBehaviour, null, /*#__PURE__*/_react.default.createElement(_formField.default, _extends({
171
+ return /*#__PURE__*/_react.default.createElement(_tooltipProvider.TooltipProvider, {
172
+ helpAriaLabel: helpAriaLabel
173
+ }, /*#__PURE__*/_react.default.createElement(_inputBehaviour.InputGroupBehaviour, null, /*#__PURE__*/_react.default.createElement(_formField.default, _extends({
169
174
  "data-component": dataComponent,
170
175
  "data-element": dataElement,
171
176
  "data-role": dataRole,
@@ -225,7 +230,7 @@ const NumeralDate = ({
225
230
  size: size,
226
231
  tooltipPosition: tooltipPosition
227
232
  })));
228
- }))));
233
+ })))));
229
234
  };
230
235
 
231
236
  NumeralDate.propTypes = {
@@ -338,7 +343,10 @@ NumeralDate.propTypes = {
338
343
  size: _propTypes.default.oneOf(["small", "medium", "large"]),
339
344
 
340
345
  /** Overrides the default tooltip position */
341
- tooltipPosition: _propTypes.default.oneOf(["top", "bottom", "left", "right"])
346
+ tooltipPosition: _propTypes.default.oneOf(["top", "bottom", "left", "right"]),
347
+
348
+ /** Aria label for rendered help component */
349
+ helpAriaLabel: _propTypes.default.string
342
350
  };
343
351
  var _default = NumeralDate;
344
352
  exports.default = _default;
@@ -88,6 +88,8 @@ export interface NumeralDateProps extends ValidationPropTypes, MarginProps {
88
88
  validationOnLabel?: boolean;
89
89
  /** Overrides the default tooltip position */
90
90
  tooltipPosition?: "top" | "bottom" | "left" | "right";
91
+ /** Aria label for rendered help component */
92
+ helpAriaLabel?: string;
91
93
  }
92
94
 
93
95
  declare function NumeralDate(props: NumeralDateProps): JSX.Element;
@@ -32,9 +32,7 @@ const renderCloseIcon = onDelete => /*#__PURE__*/_react.default.createElement(_i
32
32
  "data-element": "close",
33
33
  "aria-label": "close"
34
34
  }, /*#__PURE__*/_react.default.createElement(_icon.default, {
35
- type: "cross",
36
- bgSize: "small",
37
- bgTheme: "none"
35
+ type: "cross"
38
36
  }));
39
37
 
40
38
  const Pill = ({
@@ -173,6 +173,8 @@ const PillStyle = _styledComponents.default.span`
173
173
  ${_icon.default} {
174
174
  font-size: 12px;
175
175
  padding: 0 4px;
176
+ height: unset;
177
+ width: unset;
176
178
 
177
179
  &:hover,
178
180
  &:focus {
@@ -68,6 +68,7 @@ const RadioButton = /*#__PURE__*/_react.default.forwardRef(({
68
68
  "data-component": dataComponent,
69
69
  "data-element": dataElement,
70
70
  "data-role": dataRole,
71
+ helpAriaLabel,
71
72
  ...props
72
73
  }, ref) => {
73
74
  const marginProps = (0, _utils.filterStyledSystemMarginProps)(props);
@@ -113,6 +114,7 @@ const RadioButton = /*#__PURE__*/_react.default.forwardRef(({
113
114
  ...props
114
115
  };
115
116
  return /*#__PURE__*/_react.default.createElement(_tooltipProvider.TooltipProvider, {
117
+ helpAriaLabel: helpAriaLabel,
116
118
  tooltipPosition: tooltipPosition
117
119
  }, /*#__PURE__*/_react.default.createElement(_radioButton.default, _extends({
118
120
  "data-component": dataComponent,
@@ -209,6 +211,9 @@ RadioButton.propTypes = { ...marginPropTypes,
209
211
 
210
212
  /** Overrides the default tooltip position */
211
213
  tooltipPosition: _propTypes.default.oneOf(["top", "bottom", "left", "right"]),
214
+
215
+ /** Aria label for rendered help component */
216
+ helpAriaLabel: _propTypes.default.string,
212
217
  ...radioButtonGroupPassedProps
213
218
  };
214
219
  RadioButton.defaultProps = {
@@ -18,6 +18,8 @@ export interface RadioButtonProps
18
18
  value: string;
19
19
  /** Overrides the default tooltip position */
20
20
  tooltipPosition?: "top" | "bottom" | "left" | "right";
21
+ /** Aria label for rendered help component */
22
+ helpAriaLabel?: string;
21
23
  }
22
24
 
23
25
  declare function RadioButton(
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
 
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
 
10
+ var _styledComponents = require("styled-components");
11
+
10
12
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
13
 
12
14
  var _propTypes2 = _interopRequireDefault(require("@styled-system/prop-types"));
@@ -29,6 +31,8 @@ var _popover = _interopRequireDefault(require("../../__internal__/popover"));
29
31
 
30
32
  var _utils = require("../../style/utils");
31
33
 
34
+ var _themes = require("../../style/themes");
35
+
32
36
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
37
 
34
38
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -54,6 +58,8 @@ const SplitButton = ({
54
58
  text,
55
59
  ...rest
56
60
  }) => {
61
+ const theme = (0, _react.useContext)(_styledComponents.ThemeContext) || _themes.baseTheme;
62
+
57
63
  const isToggleButtonFocused = (0, _react.useRef)(false);
58
64
  const buttonLabelId = (0, _react.useRef)((0, _guid.default)());
59
65
  const additionalButtons = (0, _react.useRef)([]);
@@ -161,8 +167,8 @@ const SplitButton = ({
161
167
 
162
168
  function getIconColor() {
163
169
  const colorsMap = {
164
- primary: "on-dark-background",
165
- secondary: "business-color"
170
+ primary: theme.colors.white,
171
+ secondary: theme.colors.primary
166
172
  };
167
173
  return colorsMap[buttonType || as];
168
174
  }
@@ -180,8 +186,9 @@ const SplitButton = ({
180
186
  key: "toggle-button"
181
187
  }, toggleButtonProps()), /*#__PURE__*/_react.default.createElement(_icon.default, {
182
188
  type: "dropdown",
183
- bgTheme: "none",
184
- iconColor: getIconColor(),
189
+ bgSize: "extra-small",
190
+ color: getIconColor(),
191
+ bg: "transparent",
185
192
  disabled: disabled
186
193
  }))];
187
194
  }
@@ -59,6 +59,7 @@ const Switch = ({
59
59
  "data-component": dataComponent,
60
60
  "data-element": dataElement,
61
61
  "data-role": dataRole,
62
+ helpAriaLabel,
62
63
  ...rest
63
64
  }) => {
64
65
  const isControlled = checked !== undefined;
@@ -123,6 +124,7 @@ const Switch = ({
123
124
  ...rest
124
125
  };
125
126
  return /*#__PURE__*/_react.default.createElement(_tooltipProvider.TooltipProvider, {
127
+ helpAriaLabel: helpAriaLabel,
126
128
  tooltipPosition: tooltipPosition
127
129
  }, /*#__PURE__*/_react.default.createElement(_switch.default, switchStyleProps, /*#__PURE__*/_react.default.createElement(_checkableInput.default, inputProps, /*#__PURE__*/_react.default.createElement(_switchSlider.default, switchSliderProps))));
128
130
  };
@@ -241,7 +243,10 @@ Switch.propTypes = {
241
243
  required: _propTypes.default.bool,
242
244
 
243
245
  /** Overrides the default tooltip position */
244
- tooltipPosition: _propTypes.default.oneOf(["top", "bottom", "left", "right"])
246
+ tooltipPosition: _propTypes.default.oneOf(["top", "bottom", "left", "right"]),
247
+
248
+ /** Aria label for rendered help component */
249
+ helpAriaLabel: _propTypes.default.string
245
250
  };
246
251
  Switch.defaultProps = {
247
252
  labelInline: false,
@@ -29,6 +29,8 @@ export interface SwitchProps extends CommonCheckableInputProps, MarginProps {
29
29
  value?: string;
30
30
  /** Overrides the default tooltip position */
31
31
  tooltipPosition?: "top" | "bottom" | "left" | "right";
32
+ /** Aria label for rendered help component */
33
+ helpAriaLabel?: string;
32
34
  }
33
35
 
34
36
  declare function Switch(props: SwitchProps): JSX.Element;
@@ -344,10 +344,6 @@ const StyledTabTitle = _styledComponents.default.li`
344
344
  padding-bottom: 0px;
345
345
  `}
346
346
 
347
- &:focus {
348
- outline: ${isInSidebar ? "none;" : `2px solid ${theme.colors.focus};`}
349
- }
350
-
351
347
  &:hover {
352
348
  background-color: ${theme.colors.white};
353
349
  border-bottom-color: ${alternateStyling ? `${theme.tab.background};` : `${theme.colors.primary};`}
@@ -355,6 +351,16 @@ const StyledTabTitle = _styledComponents.default.li`
355
351
  cursor: default;
356
352
  }
357
353
  `}
354
+
355
+ ${({
356
+ theme,
357
+ isInSidebar
358
+ }) => `
359
+ &:focus {
360
+ outline: ${isInSidebar ? "none;" : `2px solid ${theme.colors.focus};`}
361
+ z-index: 1;
362
+ }
363
+ `}
358
364
 
359
365
  ${({
360
366
  position,
@@ -59,9 +59,22 @@ const Tabs = ({
59
59
  headerWidth,
60
60
  ...rest
61
61
  }) => {
62
- const tabRefs = (0, _react.useRef)([]);
62
+ /** The children nodes converted into an Array */
63
+ const filteredChildren = (0, _react.useMemo)(() => _react.Children.toArray(children).filter(child => child), [children]);
64
+ /** Array of the tabIds for the child nodes */
65
+
66
+ const tabIds = () => {
67
+ return filteredChildren.map(child => child.props.tabId);
68
+ };
69
+ /** Array of refs to the TabTitle nodes */
70
+
71
+
72
+ const tabRefs = (0, _react.useMemo)(() => Array.from({
73
+ length: filteredChildren.length
74
+ }).map(() => /*#__PURE__*/(0, _react.createRef)()), [filteredChildren.length]);
63
75
  const previousSelectedTabId = (0, _react.useRef)(selectedTabId);
64
76
  const [selectedTabIdState, setSelectedTabIdState] = (0, _react.useState)();
77
+ const [tabStopId, setTabStopId] = (0, _react.useState)();
65
78
  const {
66
79
  isInSidebar
67
80
  } = (0, _react.useContext)(_drawer.DrawerSidebarContext);
@@ -69,7 +82,13 @@ const Tabs = ({
69
82
  const [tabsWarnings, setTabsWarnings] = (0, _react.useState)({});
70
83
  const [tabsInfos, setTabsInfos] = (0, _react.useState)({});
71
84
  (0, _react.useLayoutEffect)(() => {
72
- const selectedTab = selectedTabId || _react.default.Children.toArray(children)[0].props.tabId;
85
+ const selectedTab = selectedTabId || _react.Children.toArray(children)[0].props.tabId;
86
+
87
+ if (!tabIds().includes(selectedTabId)) {
88
+ setTabStopId(_react.default.Children.toArray(children)[0].props.tabId);
89
+ } else {
90
+ setTabStopId(selectedTab);
91
+ }
73
92
 
74
93
  setSelectedTabIdState(selectedTab); // eslint-disable-next-line react-hooks/exhaustive-deps
75
94
  }, []);
@@ -94,15 +113,25 @@ const Tabs = ({
94
113
  });
95
114
  }
96
115
  }, [tabsInfos]);
116
+ /** Returns true/false for if the given tab id is selected. */
117
+
118
+ const isTabSelected = (0, _react.useCallback)(tabId => tabId === selectedTabIdState, [selectedTabIdState]);
119
+ const hasTabStop = (0, _react.useCallback)(tabId => tabId === tabStopId, [tabStopId]);
97
120
  /** Updates the currently visible tab */
98
121
 
99
122
  const updateVisibleTab = (0, _react.useCallback)(tabid => {
100
- setSelectedTabIdState(tabid);
123
+ if (!isTabSelected(tabid)) {
124
+ setSelectedTabIdState(tabid);
125
+ }
126
+
127
+ if (!hasTabStop(tabid)) {
128
+ setTabStopId(tabid);
129
+ }
101
130
 
102
131
  if (onTabChange) {
103
132
  onTabChange(tabid);
104
133
  }
105
- }, [onTabChange]);
134
+ }, [onTabChange, isTabSelected, hasTabStop]);
106
135
  /** Determines if the tab titles are in a vertical format. */
107
136
 
108
137
  const isVertical = currentPosition => currentPosition === "left";
@@ -122,17 +151,7 @@ const Tabs = ({
122
151
  /** Focuses the tab for the reference specified */
123
152
 
124
153
 
125
- const focusTab = ref => ref.focus();
126
- /** The children nodes converted into an Array */
127
-
128
-
129
- const filteredChildren = _react.default.useMemo(() => _react.default.Children.toArray(children).filter(child => child), [children]);
130
- /** Array of the tabIds for the child nodes */
131
-
132
-
133
- const tabIds = () => {
134
- return filteredChildren.map(child => child.props.tabId);
135
- };
154
+ const focusTab = ref => ref.current.focus();
136
155
  /** Will trigger the tab at the given index. */
137
156
 
138
157
 
@@ -148,7 +167,7 @@ const Tabs = ({
148
167
  }
149
168
 
150
169
  const nextTabId = ids[newIndex];
151
- const nextRef = tabRefs.current[newIndex];
170
+ const nextRef = tabRefs[newIndex];
152
171
  updateVisibleTab(nextTabId);
153
172
  focusTab(nextRef);
154
173
  };
@@ -174,16 +193,6 @@ const Tabs = ({
174
193
  }
175
194
  };
176
195
  };
177
- /** Returns true/false for if the given tab id is selected. */
178
-
179
-
180
- const isTabSelected = tabId => tabId === selectedTabIdState;
181
-
182
- const addRef = ref => {
183
- if (ref && !tabRefs.current.includes(ref)) {
184
- tabRefs.current.push(ref);
185
- }
186
- };
187
196
  /** Build the headers for the tab component */
188
197
 
189
198
 
@@ -220,8 +229,8 @@ const Tabs = ({
220
229
  key: tabId,
221
230
  onClick: handleTabClick,
222
231
  onKeyDown: handleKeyDown(index),
223
- ref: node => addRef(node),
224
- tabIndex: isTabSelected(tabId) ? "0" : "-1",
232
+ ref: tabRefs[index],
233
+ tabIndex: isTabSelected(tabId) || hasTabStop(tabId) ? "0" : "-1",
225
234
  title: title,
226
235
  href: href,
227
236
  isTabSelected: isTabSelected(tabId),
@@ -239,7 +248,16 @@ const Tabs = ({
239
248
  noLeftBorder: ["no left side", "no sides"].includes(borders),
240
249
  noRightBorder: ["no right side", "no sides"].includes(borders),
241
250
  customLayout: customLayout,
242
- isInSidebar: isInSidebar
251
+ isInSidebar: isInSidebar,
252
+ onFocus: () => {
253
+ if (!hasTabStop(tabId)) {
254
+ setTabStopId(tabId);
255
+ }
256
+
257
+ if (!isTabSelected(tabId)) {
258
+ updateVisibleTab(tabId);
259
+ }
260
+ }
243
261
  });
244
262
 
245
263
  return tabTitle;
@@ -264,7 +282,7 @@ const Tabs = ({
264
282
  tab = child;
265
283
  }
266
284
  });
267
- return tab ? /*#__PURE__*/_react.default.cloneElement(tab, {
285
+ return tab ? /*#__PURE__*/(0, _react.cloneElement)(tab, {
268
286
  isTabSelected: isTabSelected(tab.props.tabId)
269
287
  }) : null;
270
288
  };
@@ -279,7 +297,7 @@ const Tabs = ({
279
297
  }
280
298
 
281
299
  const tabs = filteredChildren.map(child => {
282
- return /*#__PURE__*/_react.default.cloneElement(child, { ...child.props,
300
+ return /*#__PURE__*/(0, _react.cloneElement)(child, { ...child.props,
283
301
  role: "tabpanel",
284
302
  position,
285
303
  isTabSelected: isTabSelected(child.props.tabId),
@@ -190,9 +190,11 @@ let Textarea = /*#__PURE__*/function (_React$Component) {
190
190
  "data-component": dataComponent,
191
191
  "data-element": dataElement,
192
192
  "data-role": dataRole,
193
+ helpAriaLabel,
193
194
  ...props
194
195
  } = this.props;
195
196
  return /*#__PURE__*/_react.default.createElement(_tooltipProvider.TooltipProvider, {
197
+ helpAriaLabel: helpAriaLabel,
196
198
  tooltipPosition: tooltipPosition
197
199
  }, /*#__PURE__*/_react.default.createElement(_inputBehaviour.InputBehaviour, null, /*#__PURE__*/_react.default.createElement(_textarea.default, _extends({
198
200
  labelInline: labelInline,
@@ -374,7 +376,10 @@ Textarea.propTypes = { ...marginPropTypes,
374
376
  required: _propTypes.default.bool,
375
377
 
376
378
  /** Overrides the default tooltip position */
377
- tooltipPosition: _propTypes.default.oneOf(["top", "bottom", "left", "right"])
379
+ tooltipPosition: _propTypes.default.oneOf(["top", "bottom", "left", "right"]),
380
+
381
+ /** Aria label for rendered help component */
382
+ helpAriaLabel: _propTypes.default.string
378
383
  };
379
384
  Textarea.defaultProps = {
380
385
  labelWidth: 30,
@@ -70,6 +70,8 @@ export interface TextareaProps
70
70
  warnOverLimit?: boolean;
71
71
  /** Overrides the default tooltip position */
72
72
  tooltipPosition?: "top" | "bottom" | "left" | "right";
73
+ /** Aria label for rendered help component */
74
+ helpAriaLabel?: string;
73
75
  }
74
76
 
75
77
  declare class Textarea extends React.Component<TextareaProps> {}