carbon-react 101.3.1 → 101.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/lib/__internal__/checkable-input/checkable-input.component.js +26 -8
  2. package/lib/__internal__/checkable-input/checkable-input.d.ts +2 -0
  3. package/lib/__internal__/checkable-input/hidden-checkable-input.component.js +1 -20
  4. package/lib/__internal__/checkable-input/hidden-checkable-input.d.ts +0 -8
  5. package/lib/__internal__/date/date.js +5 -9
  6. package/lib/__internal__/form-field/form-field.component.js +3 -3
  7. package/lib/__internal__/form-field/form-field.d.ts +2 -2
  8. package/lib/__internal__/input-icon-toggle/input-icon-toggle.component.js +7 -3
  9. package/lib/__internal__/input-icon-toggle/input-icon-toggle.d.ts +1 -0
  10. package/lib/__internal__/label/label.component.js +5 -5
  11. package/lib/__internal__/label/label.d.ts +2 -2
  12. package/lib/__internal__/validations/validation-icon.component.js +5 -0
  13. package/lib/__internal__/validations/validation-icon.d.ts +2 -0
  14. package/lib/components/date/date.component.js +19 -27
  15. package/lib/components/help/help.component.js +6 -1
  16. package/lib/components/help/help.d.ts +2 -0
  17. package/lib/components/icon/icon.component.js +5 -0
  18. package/lib/components/icon/icon.d.ts +2 -0
  19. package/lib/components/link/link.component.js +5 -1
  20. package/lib/components/search/search.component.js +7 -2
  21. package/lib/components/search/search.d.ts +2 -0
  22. package/lib/components/textarea/textarea.component.js +23 -1
  23. package/lib/components/textbox/textbox.component.js +24 -2
  24. package/lib/hooks/__internal__/useInputAccessibility/index.d.ts +24 -0
  25. package/lib/hooks/__internal__/useInputAccessibility/index.js +15 -0
  26. package/lib/hooks/__internal__/useInputAccessibility/useInputAccessibility.js +29 -0
  27. package/lib/locales/en-gb.js +3 -0
  28. package/lib/locales/pl-pl.js +3 -0
  29. package/package.json +12 -12
@@ -19,6 +19,8 @@ var _hiddenCheckableInput = _interopRequireDefault(require("./hidden-checkable-i
19
19
 
20
20
  var _guid = _interopRequireDefault(require("../utils/helpers/guid"));
21
21
 
22
+ var _useInputAccessibility = _interopRequireDefault(require("../../hooks/__internal__/useInputAccessibility"));
23
+
22
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
25
 
24
26
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -26,6 +28,7 @@ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return
26
28
  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; }
27
29
 
28
30
  const CheckableInput = ({
31
+ ariaLabelledBy: externalAriaLabelledBy,
29
32
  autoFocus,
30
33
  checked,
31
34
  children,
@@ -58,16 +61,28 @@ const CheckableInput = ({
58
61
  const {
59
62
  current: id
60
63
  } = (0, _react.useRef)(inputId || (0, _guid.default)());
61
- const labelId = label ? `${id}-label` : undefined;
62
- const helpId = [error, warning, info, labelHelp].filter(validation => typeof validation === "string").length ? `${id}-help` : undefined;
63
- const fieldHelpId = fieldHelp ? `${id}-field-help` : undefined;
64
+ const {
65
+ labelId,
66
+ tooltipId,
67
+ fieldHelpId,
68
+ ariaDescribedBy,
69
+ ariaLabelledBy
70
+ } = (0, _useInputAccessibility.default)({
71
+ id,
72
+ error,
73
+ warning,
74
+ info,
75
+ label,
76
+ labelHelp,
77
+ fieldHelp
78
+ });
64
79
  const isRadio = type === "radio";
65
80
  const formFieldProps = {
66
81
  disabled,
67
82
  error,
68
83
  fieldHelp,
69
84
  fieldHelpInline,
70
- helpId,
85
+ tooltipId,
71
86
  fieldHelpId,
72
87
  id,
73
88
  info,
@@ -87,16 +102,16 @@ const CheckableInput = ({
87
102
  useValidationIcon: validationOnLabel
88
103
  };
89
104
  const inputProps = {
105
+ "aria-describedby": ariaDescribedBy,
106
+ "aria-labelledby": externalAriaLabelledBy || ariaLabelledBy,
107
+ "aria-invalid": !!error,
90
108
  autoFocus,
91
109
  checked,
92
110
  disabled,
93
- helpId,
94
- fieldHelpId,
95
111
  id,
96
112
  inputRef,
97
113
  type,
98
114
  value,
99
- labelId,
100
115
  name,
101
116
  onBlur,
102
117
  onChange,
@@ -202,7 +217,10 @@ CheckableInput.propTypes = {
202
217
  })]),
203
218
 
204
219
  /** When true, displays validation icon on label */
205
- validationOnLabel: _propTypes.default.bool
220
+ validationOnLabel: _propTypes.default.bool,
221
+
222
+ /** The id of the element that labels the input */
223
+ ariaLabelledBy: _propTypes.default.string
206
224
  };
207
225
  CheckableInput.defaultProps = {
208
226
  reverse: false,
@@ -33,6 +33,8 @@ export interface CommonCheckableInputProps
33
33
  reverse?: boolean;
34
34
  /** Size of the component */
35
35
  size?: "small" | "large";
36
+ /** The id of the element that labels the input */
37
+ ariaLabelledBy?: string;
36
38
  }
37
39
 
38
40
  export interface CheckableInputProps extends CommonCheckableInputProps {
@@ -22,9 +22,6 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
22
22
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
23
23
 
24
24
  const HiddenCheckableInput = ({
25
- helpId,
26
- fieldHelpId,
27
- labelId,
28
25
  name,
29
26
  checked,
30
27
  type,
@@ -32,7 +29,6 @@ const HiddenCheckableInput = ({
32
29
  inputRef,
33
30
  onChange,
34
31
  autoFocus,
35
- ariaLabelledBy,
36
32
  ...props
37
33
  }) => {
38
34
  const {
@@ -72,13 +68,10 @@ const HiddenCheckableInput = ({
72
68
  if (onMouseLeaveGroup) onMouseLeaveGroup(ev);
73
69
  };
74
70
 
75
- const ariaDescribedBy = [fieldHelpId, helpId].filter(Boolean).join(" ");
76
71
  return /*#__PURE__*/_react.default.createElement(_hiddenCheckableInput.default, _extends({
77
72
  autoFocus: autoFocus,
78
73
  "aria-checked": checked,
79
74
  checked: checked,
80
- "aria-labelledby": ariaLabelledBy || labelId,
81
- "aria-describedby": ariaDescribedBy,
82
75
  name: name,
83
76
  role: type,
84
77
  type: type,
@@ -100,12 +93,6 @@ HiddenCheckableInput.propTypes = {
100
93
  /** Checked state of the input */
101
94
  checked: _propTypes.default.bool,
102
95
 
103
- /** Element id for aria-describedby */
104
- helpId: _propTypes.default.string,
105
-
106
- /** Element id for aria-describedby */
107
- fieldHelpId: _propTypes.default.string,
108
-
109
96
  /** Input name */
110
97
  name: _propTypes.default.string,
111
98
 
@@ -124,9 +111,6 @@ HiddenCheckableInput.propTypes = {
124
111
  /** OnMouseEnter event handler */
125
112
  onMouseEnter: _propTypes.default.func,
126
113
 
127
- /** Element id for aria-labelledby */
128
- labelId: _propTypes.default.string,
129
-
130
114
  /** HTML type attribute of the input */
131
115
  type: _propTypes.default.string.isRequired,
132
116
 
@@ -136,10 +120,7 @@ HiddenCheckableInput.propTypes = {
136
120
  /** A callback to retrieve the input reference */
137
121
  inputRef: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.shape({
138
122
  current: _propTypes.default.instanceOf(Element)
139
- })]),
140
-
141
- /** The id of the element that labels the input */
142
- ariaLabelledBy: _propTypes.default.string
123
+ })])
143
124
  };
144
125
 
145
126
  var _default = /*#__PURE__*/_react.default.memo(HiddenCheckableInput);
@@ -31,14 +31,6 @@ export interface HiddenCheckableInputProps
31
31
  extends CommonHiddenCheckableInputProps {
32
32
  /** HTML type attribute of the input */
33
33
  type: string;
34
- /** Element id for aria-describedby */
35
- helpId?: string;
36
- /** Element id for aria-describedby */
37
- fieldHelpId?: string;
38
- /** Element id for aria-labelledby */
39
- labelId?: string;
40
- /** The id of the element that labels the input */
41
- ariaLabelledBy?: string;
42
34
  }
43
35
 
44
36
  declare function HiddenCheckableInput(
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
 
8
8
  var _moment = _interopRequireDefault(require("moment"));
9
9
 
10
+ require("moment/min/locales");
11
+
10
12
  var _lodash = require("lodash");
11
13
 
12
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -161,14 +163,12 @@ const DateHelper = {
161
163
  * formats - given accepted formats
162
164
  * locale - current locale
163
165
  * strict - moment js strict mode
164
- * sanitize - should value be sanitized before parsing
165
166
  */
166
167
  _defaultMomentOptions: (locale, formats) => {
167
168
  return {
168
169
  locale,
169
170
  formats,
170
- strict: true,
171
- sanitize: true
171
+ strict: true
172
172
  };
173
173
  },
174
174
 
@@ -185,7 +185,7 @@ const DateHelper = {
185
185
  value,
186
186
  options,
187
187
  locale,
188
- formats,
188
+ formats = [],
189
189
  format
190
190
  }) {
191
191
  const opts = (0, _lodash.merge)(DateHelper._defaultMomentOptions(locale, formats), options, {
@@ -193,8 +193,7 @@ const DateHelper = {
193
193
  formats,
194
194
  format
195
195
  });
196
- const val = opts.sanitize ? DateHelper.sanitizeDateInput(value) : value;
197
- return (0, _moment.default)(val, [format, ...opts.formats], opts.locale, opts.strict);
196
+ return (0, _moment.default)(value, [format, isoDateFormat, ...opts.formats], opts.locale, opts.strict);
198
197
  },
199
198
 
200
199
  formatDateToCurrentLocale({
@@ -206,9 +205,6 @@ const DateHelper = {
206
205
  return DateHelper.formatValue({
207
206
  value,
208
207
  formatTo: format,
209
- options: {
210
- formats: [format]
211
- },
212
208
  locale,
213
209
  formats,
214
210
  format
@@ -43,7 +43,7 @@ const FormField = ({
43
43
  error,
44
44
  warning,
45
45
  info,
46
- helpId,
46
+ tooltipId,
47
47
  fieldHelpId,
48
48
  helpTabIndex,
49
49
  label,
@@ -93,7 +93,7 @@ const FormField = ({
93
93
  warning: warning,
94
94
  info: info,
95
95
  help: labelHelp,
96
- helpId: helpId,
96
+ tooltipId: tooltipId,
97
97
  helpTabIndex: helpTabIndex,
98
98
  htmlFor: id,
99
99
  helpIcon: labelHelpIcon,
@@ -128,7 +128,7 @@ FormField.propTypes = {
128
128
  error: errorPropType,
129
129
  warning: errorPropType,
130
130
  info: errorPropType,
131
- helpId: _propTypes.default.string,
131
+ tooltipId: _propTypes.default.string,
132
132
  fieldHelpId: _propTypes.default.string,
133
133
  helpTabIndex: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
134
134
  id: _propTypes.default.string.isRequired,
@@ -9,8 +9,8 @@ export interface CommonFormFieldPropTypes
9
9
  disabled?: boolean;
10
10
  /** Help content to be displayed under an input */
11
11
  fieldHelp?: React.ReactNode;
12
- /** The unique id of the Help component */
13
- helpId?: string;
12
+ /** The unique id of the Help component tooltip, used for accessibility */
13
+ tooltipId?: string;
14
14
  /** The unique id of the FieldHelp component */
15
15
  fieldHelpId?: string;
16
16
  /** Overrides the default tabindex of the Help component */
@@ -40,7 +40,8 @@ const InputIconToggle = ({
40
40
  info,
41
41
  useValidationIcon,
42
42
  align,
43
- iconTabIndex
43
+ iconTabIndex,
44
+ tooltipId
44
45
  }) => {
45
46
  if (useValidationIcon && !disabled && shouldDisplayValidationIcon({
46
47
  error,
@@ -59,6 +60,7 @@ const InputIconToggle = ({
59
60
  onBlur: onBlur,
60
61
  isPartOfInput: true,
61
62
  tabIndex: iconTabIndex,
63
+ tooltipId: tooltipId,
62
64
  tooltipPosition: align === "right" ? "left" : "right"
63
65
  }));
64
66
  }
@@ -72,7 +74,8 @@ const InputIconToggle = ({
72
74
  onMouseDown: onMouseDown,
73
75
  tabIndex: iconTabIndex
74
76
  }, /*#__PURE__*/_react.default.createElement(_icon.default, {
75
- type: type
77
+ type: type,
78
+ tooltipId: tooltipId
76
79
  }));
77
80
  }
78
81
 
@@ -93,7 +96,8 @@ InputIconToggle.propTypes = {
93
96
  size: _propTypes.default.oneOf(["small", "medium", "large"]),
94
97
  align: _propTypes.default.oneOf(["left", "right"]),
95
98
  useValidationIcon: _propTypes.default.bool,
96
- iconTabIndex: _propTypes.default.number
99
+ iconTabIndex: _propTypes.default.number,
100
+ tooltipId: _propTypes.default.string
97
101
  };
98
102
  var _default = InputIconToggle;
99
103
  exports.default = _default;
@@ -15,6 +15,7 @@ export interface InputIconToggleProps {
15
15
  align?: "left" | "right";
16
16
  useValidationIcon?: boolean;
17
17
  iconTabIndex?: number;
18
+ tooltipId?: string;
18
19
  }
19
20
  declare function InputIconToggle(props: InputIconToggleProps): JSX.Element;
20
21
 
@@ -51,7 +51,7 @@ const Label = ({
51
51
  width,
52
52
  optional,
53
53
  labelId,
54
- helpId,
54
+ tooltipId,
55
55
  children,
56
56
  error,
57
57
  warning,
@@ -104,7 +104,7 @@ const Label = ({
104
104
  inline
105
105
  });
106
106
  return /*#__PURE__*/_react.default.createElement(_iconWrapper.default, null, /*#__PURE__*/_react.default.createElement(_validationIcon.default, {
107
- iconId: helpId,
107
+ tooltipId: tooltipId,
108
108
  error: error,
109
109
  warning: warning,
110
110
  info: info,
@@ -114,7 +114,7 @@ const Label = ({
114
114
  }
115
115
 
116
116
  return help && /*#__PURE__*/_react.default.createElement(_iconWrapper.default, wrapperProps, /*#__PURE__*/_react.default.createElement(_help.default, {
117
- helpId: helpId,
117
+ tooltipId: tooltipId,
118
118
  tabIndex: helpTabIndex,
119
119
  type: helpIcon,
120
120
  isFocused: isFocused
@@ -158,8 +158,8 @@ Label.propTypes = {
158
158
  /** The unique id of the label element */
159
159
  labelId: _propTypes.default.string,
160
160
 
161
- /** The unique id of the Help component */
162
- helpId: _propTypes.default.string,
161
+ /** The unique id of the Help component tooltip, used for accessibility */
162
+ tooltipId: _propTypes.default.string,
163
163
 
164
164
  /** Children elements */
165
165
  children: _propTypes.default.node,
@@ -16,8 +16,8 @@ export interface LabelPropTypes extends ValidationPropTypes {
16
16
  optional?: boolean;
17
17
  /** The unique id of the label element */
18
18
  labelId?: string;
19
- /** The unique id of the Help component */
20
- helpId?: string;
19
+ /** The unique id of the Help component tooltip, used for accessibility */
20
+ tooltipId?: string;
21
21
  /** Children elements */
22
22
  children?: React.ReactNode;
23
23
  /** A message that the Help component will display */
@@ -48,6 +48,7 @@ const ValidationIcon = ({
48
48
  onFocus,
49
49
  onBlur,
50
50
  iconId,
51
+ tooltipId,
51
52
  isPartOfInput,
52
53
  tabIndex,
53
54
  onClick,
@@ -95,6 +96,7 @@ const ValidationIcon = ({
95
96
  key: `${validationType}-icon`,
96
97
  type: validationType,
97
98
  tabIndex: tabIndex,
99
+ tooltipId: tooltipId,
98
100
  tooltipMessage: validationMessage,
99
101
  tooltipPosition: tooltipPosition,
100
102
  tooltipVisible: hasFocus || hasMouseOver || groupHasFocus || groupHasMouseOver || triggeredByIcon,
@@ -130,6 +132,9 @@ ValidationIcon.propTypes = { ...marginPropTypes,
130
132
  `The \`${propName}\` prop supplied to \`${componentName}\` must be an array containing some or all of ["top", "bottom", "left", "right"].`);
131
133
  },
132
134
 
135
+ /** Id passed to the tooltip container, used for accessibility purposes. */
136
+ tooltipId: _propTypes.default.string,
137
+
133
138
  /** An onClick handler */
134
139
  onClick: _propTypes.default.func,
135
140
 
@@ -15,6 +15,8 @@ export interface ValidationIconProps extends ValidationPropTypes {
15
15
  * (see https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements)
16
16
  */
17
17
  tooltipFlipOverrides?: ["top" | "bottom" | "left" | "right"];
18
+ /** Id passed to the tooltip container, used for accessibility purposes */
19
+ tooltipId?: string;
18
20
  /** An onClick handler */
19
21
  onClick?: (ev: React.MouseEvent<HTMLElement>) => void;
20
22
  /** An onBlur handler */
@@ -167,13 +167,11 @@ let BaseDateInput = /*#__PURE__*/function (_React$Component) {
167
167
  _this.reformatVisibleDate();
168
168
 
169
169
  if (_this.props.onBlur && !_this.state.isDatePickerOpen) {
170
- const dateWithSlashes = _date.default.sanitizeDateInput(_this.state.visibleValue);
171
-
172
170
  const event = _this.buildCustomEvent({
173
171
  target: _this.input,
174
172
  type: "blur"
175
173
  }, _date.default.formatValue({
176
- value: dateWithSlashes,
174
+ value: _this.state.visibleValue,
177
175
  ..._this.localeData
178
176
  }));
179
177
 
@@ -365,10 +363,8 @@ let BaseDateInput = /*#__PURE__*/function (_React$Component) {
365
363
  } = _this.props;
366
364
  const value = ev.target.value.formattedValue || ev.target.value;
367
365
 
368
- const dateWithSlashes = _date.default.sanitizeDateInput(value);
369
-
370
366
  const isValidDate = _date.default.isValidDate({
371
- value: dateWithSlashes,
367
+ value,
372
368
  ..._this.localeData
373
369
  });
374
370
 
@@ -378,7 +374,7 @@ let BaseDateInput = /*#__PURE__*/function (_React$Component) {
378
374
 
379
375
  if (isValidDate || _this.canBeEmptyValues(value)) {
380
376
  isoDateString = _date.default.formatValue({
381
- value: dateWithSlashes,
377
+ value,
382
378
  ..._this.localeData
383
379
  });
384
380
 
@@ -440,9 +436,6 @@ let BaseDateInput = /*#__PURE__*/function (_React$Component) {
440
436
  });
441
437
 
442
438
  _defineProperty(_assertThisInitialized(_this), "buildCustomEvent", (ev, isoFormattedValue) => {
443
- const {
444
- type
445
- } = ev;
446
439
  const {
447
440
  id,
448
441
  name,
@@ -477,7 +470,7 @@ let BaseDateInput = /*#__PURE__*/function (_React$Component) {
477
470
  ...(validRawValue && {
478
471
  rawValue: isoFormattedValue
479
472
  }),
480
- ...(type === "blur" && {
473
+ ...(!validRawValue && {
481
474
  formattedValue: value,
482
475
  rawValue: value
483
476
  })
@@ -488,15 +481,19 @@ let BaseDateInput = /*#__PURE__*/function (_React$Component) {
488
481
 
489
482
  _defineProperty(_assertThisInitialized(_this), "renderDatePicker", dateRangeProps => {
490
483
  if (!_this.state.isDatePickerOpen) return null;
491
- let {
484
+ const {
492
485
  visibleValue
493
486
  } = _this.state;
487
+ let isoValue = "";
494
488
 
495
- if (!_date.default.isValidDate({
489
+ if (_date.default.isValidDate({
496
490
  value: visibleValue,
497
491
  ..._this.localeData
498
492
  })) {
499
- visibleValue = "";
493
+ isoValue = _date.default.formatValue({
494
+ value: visibleValue,
495
+ ..._this.localeData
496
+ });
500
497
  }
501
498
 
502
499
  return /*#__PURE__*/_react.default.createElement("div", {
@@ -506,7 +503,7 @@ let BaseDateInput = /*#__PURE__*/function (_React$Component) {
506
503
  inputElement: _this.inputPresentationRef,
507
504
  selectedDate: _this.state.selectedDate,
508
505
  handleDateSelect: _this.handleDateSelect,
509
- inputDate: visibleValue,
506
+ inputDate: isoValue,
510
507
  disablePortal: _this.props.disablePortal
511
508
  }, dateRangeProps)));
512
509
  });
@@ -642,7 +639,7 @@ function generateAdjustedValue({
642
639
  formats,
643
640
  format
644
641
  }) {
645
- if (value !== undefined && canReturnValue(value, allowEmptyValue, locale, formats, format)) {
642
+ if (value !== undefined && canReturnValue(value, allowEmptyValue)) {
646
643
  return _date.default.formatDateToCurrentLocale({
647
644
  value,
648
645
  locale,
@@ -651,7 +648,7 @@ function generateAdjustedValue({
651
648
  });
652
649
  }
653
650
 
654
- if (canReturnValue(defaultValue, allowEmptyValue, locale, formats, format)) {
651
+ if (canReturnValue(defaultValue, allowEmptyValue)) {
655
652
  return _date.default.formatDateToCurrentLocale({
656
653
  value: defaultValue,
657
654
  locale,
@@ -668,25 +665,20 @@ function generateAdjustedValue({
668
665
  });
669
666
  }
670
667
 
671
- function isValidInitialFormat(value, locale, formats, format) {
668
+ function isValidInitialFormat(value) {
672
669
  return _date.default.isValidDate({
673
670
  value,
674
- options: {
675
- defaultValue: hiddenDateFormat
676
- },
677
- locale,
678
- formats,
679
- format
671
+ format: hiddenDateFormat
680
672
  });
681
673
  }
682
674
 
683
- function canReturnValue(value, allowEmptyValue, locale, formats, format) {
675
+ function canReturnValue(value, allowEmptyValue) {
684
676
  if (!allowEmptyValue && value && value.length) {
685
677
  const message = "The Date component must be initialised with a value in the iso (YYYY-MM-DD) format";
686
- (0, _invariant.default)(isValidInitialFormat(value, locale, formats, format), message);
678
+ (0, _invariant.default)(isValidInitialFormat(value), message);
687
679
  }
688
680
 
689
- return isValidInitialFormat(value, locale, formats, format) || allowEmptyValue && !value;
681
+ return isValidInitialFormat(value) || allowEmptyValue && !value;
690
682
  }
691
683
 
692
684
  const DateInput = (0, _withUniqueIdProps.default)(BaseDateInput);
@@ -45,6 +45,7 @@ const Help = ({
45
45
  tooltipPosition,
46
46
  isFocused,
47
47
  type,
48
+ tooltipId,
48
49
  tooltipBgColor,
49
50
  tooltipFontColor,
50
51
  tooltipFlipOverrides,
@@ -107,6 +108,7 @@ const Help = ({
107
108
  tooltipFontColor: tooltipFontColor,
108
109
  tooltipFlipOverrides: tooltipFlipOverrides,
109
110
  focusable: false,
111
+ tooltipId: tooltipId,
110
112
  "aria-hidden": "true"
111
113
  }, href && {
112
114
  role: "tooltip",
@@ -122,7 +124,7 @@ Help.propTypes = { ...marginPropTypes,
122
124
  /** Message to display in tooltip */
123
125
  children: _propTypes.default.node,
124
126
 
125
- /** The unique id of the component (used with aria-describedby for accessibility) */
127
+ /** The unique id of the component */
126
128
  helpId: _propTypes.default.string,
127
129
 
128
130
  /** Overrides the default tabindex of the component */
@@ -166,6 +168,9 @@ Help.propTypes = { ...marginPropTypes,
166
168
  `The \`${propName}\` prop supplied to \`${componentName}\` must be an array containing some or all of ["top", "bottom", "left", "right"].`);
167
169
  },
168
170
 
171
+ /** Id passed to the tooltip container, used for accessibility purposes. */
172
+ tooltipId: _propTypes.default.string,
173
+
169
174
  /** Aria label */
170
175
  ariaLabel: _propTypes.default.string
171
176
  };
@@ -28,6 +28,8 @@ export interface HelpProps extends MarginProps {
28
28
  tooltipFlipOverrides?: ["top" | "bottom" | "left" | "right"];
29
29
  /** Position of tooltip relative to target */
30
30
  tooltipPosition?: "top" | "bottom" | "left" | "right";
31
+ /** Id passed to the tooltip container, used for accessibility purposes */
32
+ tooltipId?: string;
31
33
  /** Help Icon type */
32
34
  type?: IconType;
33
35
  /** Aria label */
@@ -48,6 +48,7 @@ const Icon = /*#__PURE__*/_react.default.forwardRef(({
48
48
  tooltipBgColor,
49
49
  tooltipFontColor,
50
50
  tooltipFlipOverrides,
51
+ tooltipId,
51
52
  tabIndex,
52
53
  isPartOfInput,
53
54
  inputSize,
@@ -122,6 +123,7 @@ const Icon = /*#__PURE__*/_react.default.forwardRef(({
122
123
  message: tooltipMessage,
123
124
  position: tooltipPositionFromContext || tooltipPosition,
124
125
  type: type,
126
+ id: tooltipId,
125
127
  isVisible: visible,
126
128
  isPartOfInput: isPartOfInput,
127
129
  inputSize: inputSize,
@@ -186,6 +188,9 @@ Icon.propTypes = { ...marginPropTypes,
186
188
  /** Override font color of the Tooltip, provide any color from palette or any valid css color value. */
187
189
  tooltipFontColor: _propTypes.default.string,
188
190
 
191
+ /** Id passed to the tooltip container, used for accessibility purposes. */
192
+ tooltipId: _propTypes.default.string,
193
+
189
194
  /** Overrides the default flip behaviour of the Tooltip, must be an array containing some or all of ["top", "bottom", "left", "right"].
190
195
  *
191
196
  * See the Popper [documentation](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) for more information
@@ -233,6 +233,8 @@ export interface IconProps extends MarginProps {
233
233
  tooltipFontColor?: string;
234
234
  /** Overrides the default flip behaviour of the Tooltip */
235
235
  tooltipFlipOverrides?: TooltipPositions[];
236
+ /** Id passed to the tooltip container, used for accessibility purposes */
237
+ tooltipId?: string;
236
238
  }
237
239
 
238
240
  declare function Icon(
@@ -21,6 +21,8 @@ var _tags = _interopRequireDefault(require("../../__internal__/utils/helpers/tag
21
21
 
22
22
  var _themes = require("../../style/themes");
23
23
 
24
+ var _useLocale = _interopRequireDefault(require("../../hooks/__internal__/useLocale"));
25
+
24
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
27
 
26
28
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -48,6 +50,8 @@ const Link = /*#__PURE__*/_react.default.forwardRef(({
48
50
  target,
49
51
  ...rest
50
52
  }, ref) => {
53
+ const l = (0, _useLocale.default)();
54
+
51
55
  const theme = (0, _react.useContext)(_styledComponents.ThemeContext) || _themes.baseTheme;
52
56
 
53
57
  const tabIndex = tabbable && !disabled ? "0" : "-1";
@@ -110,7 +114,7 @@ const Link = /*#__PURE__*/_react.default.forwardRef(({
110
114
  ...(type === "button" && {
111
115
  role: "link"
112
116
  })
113
- }, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderLinkIcon(), /*#__PURE__*/_react.default.createElement(_link.StyledContent, null, isSkipLink ? "Skip to main content" : children), renderLinkIcon("right")));
117
+ }, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, renderLinkIcon(), /*#__PURE__*/_react.default.createElement(_link.StyledContent, null, isSkipLink ? l.link.skipLinkLabel() : children), renderLinkIcon("right")));
114
118
  };
115
119
 
116
120
  return /*#__PURE__*/_react.default.createElement(_link.StyledLink, _extends({
@@ -54,6 +54,7 @@ const Search = ({
54
54
  variant = "default",
55
55
  "aria-label": ariaLabel = "search",
56
56
  inputRef,
57
+ tabIndex,
57
58
  ...rest
58
59
  }) => {
59
60
  const isControlled = value !== undefined;
@@ -173,7 +174,8 @@ const Search = ({
173
174
  onBlur: onBlur,
174
175
  onChange: onChange,
175
176
  onKeyDown: onKeyDown,
176
- inputRef: assignInput
177
+ inputRef: assignInput,
178
+ tabIndex: tabIndex
177
179
  }), searchButton && /*#__PURE__*/_react.default.createElement(_search.StyledSearchButton, null, Boolean(isFocused || (!isControlled ? searchValue.length : value.length)) && /*#__PURE__*/_react.default.createElement(_button.default, _extends({
178
180
  tabIndex: iconTabIndex,
179
181
  size: "medium",
@@ -249,7 +251,10 @@ Search.propTypes = {
249
251
  */
250
252
  inputRef: _propTypes.default.shape({
251
253
  current: _propTypes.default.instanceOf(Element)
252
- })
254
+ }),
255
+
256
+ /** Input tabindex */
257
+ tabIndex: _propTypes.default.number
253
258
  };
254
259
  var _default = Search;
255
260
  exports.default = _default;
@@ -40,6 +40,8 @@ export interface SearchProps extends MarginProps {
40
40
  variant?: string;
41
41
  /** A callback to retrieve the input reference */
42
42
  inputRef?: React.RefObject<HTMLInputElement>;
43
+ /** Input tabindex */
44
+ tabIndex?: number;
43
45
  }
44
46
 
45
47
  declare function Search(props: SearchProps): JSX.Element;
@@ -33,6 +33,8 @@ var _i18nContext = _interopRequireDefault(require("../../__internal__/i18n-conte
33
33
 
34
34
  var _tooltipProvider = require("../../__internal__/tooltip-provider");
35
35
 
36
+ var _useInputAccessibility = _interopRequireDefault(require("../../hooks/__internal__/useInputAccessibility"));
37
+
36
38
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
39
 
38
40
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -101,6 +103,21 @@ const Textarea = ({
101
103
  }
102
104
  };
103
105
 
106
+ const {
107
+ labelId,
108
+ tooltipId,
109
+ fieldHelpId,
110
+ ariaDescribedBy,
111
+ ariaLabelledBy
112
+ } = (0, _useInputAccessibility.default)({
113
+ id,
114
+ error,
115
+ warning,
116
+ info,
117
+ label,
118
+ labelHelp,
119
+ fieldHelp
120
+ });
104
121
  (0, _react.useEffect)(() => {
105
122
  if (expandable) {
106
123
  expandTextarea();
@@ -146,10 +163,12 @@ const Textarea = ({
146
163
  "data-element": dataElement
147
164
  }, (0, _utils.filterStyledSystemMarginProps)(props)), /*#__PURE__*/_react.default.createElement(_formField.default, {
148
165
  fieldHelp: fieldHelp,
166
+ fieldHelpId: fieldHelpId,
149
167
  error: error,
150
168
  warning: warning,
151
169
  info: info,
152
170
  label: label,
171
+ labelId: labelId,
153
172
  disabled: disabled,
154
173
  id: id,
155
174
  labelInline: labelInline,
@@ -157,6 +176,7 @@ const Textarea = ({
157
176
  labelWidth: labelWidth,
158
177
  labelHelp: labelHelp,
159
178
  labelSpacing: labelSpacing,
179
+ tooltipId: tooltipId,
160
180
  isRequired: props.required,
161
181
  useValidationIcon: validationOnLabel,
162
182
  adaptiveLabelBreakpoint: adaptiveLabelBreakpoint
@@ -169,9 +189,11 @@ const Textarea = ({
169
189
  warning: warning,
170
190
  info: info
171
191
  }, /*#__PURE__*/_react.default.createElement(_input2.default, _extends({
192
+ "aria-invalid": !!error,
193
+ "aria-labelledby": ariaLabelledBy,
194
+ "aria-describedby": ariaDescribedBy,
172
195
  autoFocus: autoFocus,
173
196
  name: name,
174
- "aria-invalid": !!error,
175
197
  ref: inputRef,
176
198
  maxLength: enforceCharacterLimit && characterLimit ? characterLimit : undefined,
177
199
  onChange: onChange,
@@ -29,6 +29,8 @@ var _tooltipProvider = require("../../__internal__/tooltip-provider");
29
29
 
30
30
  var _useCharacterCount = _interopRequireDefault(require("../../hooks/__internal__/useCharacterCount"));
31
31
 
32
+ var _useInputAccessibility = _interopRequireDefault(require("../../hooks/__internal__/useInputAccessibility/useInputAccessibility"));
33
+
32
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
35
 
34
36
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
@@ -42,7 +44,7 @@ const Textbox = ({
42
44
  disabled,
43
45
  inputIcon,
44
46
  leftChildren,
45
- labelId,
47
+ labelId: externalLabelId,
46
48
  label,
47
49
  labelAlign,
48
50
  labelHelp,
@@ -90,12 +92,29 @@ const Textbox = ({
90
92
  ...props
91
93
  }) => {
92
94
  const [maxLength, characterCount] = (0, _useCharacterCount.default)(value, characterLimit, warnOverLimit, enforceCharacterLimit);
95
+ const {
96
+ labelId: internalLabelId,
97
+ tooltipId,
98
+ fieldHelpId,
99
+ ariaDescribedBy
100
+ } = (0, _useInputAccessibility.default)({
101
+ id,
102
+ error,
103
+ warning,
104
+ info,
105
+ label,
106
+ labelHelp,
107
+ fieldHelp
108
+ });
109
+ const labelId = externalLabelId || internalLabelId;
93
110
  return /*#__PURE__*/_react.default.createElement(_tooltipProvider.TooltipProvider, {
94
111
  helpAriaLabel: helpAriaLabel,
95
112
  tooltipPosition: tooltipPosition
96
113
  }, /*#__PURE__*/_react.default.createElement(_inputBehaviour.InputBehaviour, null, /*#__PURE__*/_react.default.createElement(_formField.default, _extends({
114
+ tooltipId: tooltipId,
97
115
  disabled: disabled,
98
116
  fieldHelp: fieldHelp,
117
+ fieldHelpId: fieldHelpId,
99
118
  error: error,
100
119
  warning: warning,
101
120
  info: info,
@@ -132,6 +151,8 @@ const Textbox = ({
132
151
  }, {
133
152
  align: align,
134
153
  "aria-invalid": !!error,
154
+ "aria-labelledby": labelId,
155
+ "aria-describedby": ariaDescribedBy,
135
156
  autoFocus: autoFocus,
136
157
  deferTimeout: deferTimeout,
137
158
  disabled: disabled,
@@ -160,7 +181,8 @@ const Textbox = ({
160
181
  readOnly: readOnly,
161
182
  size: size,
162
183
  useValidationIcon: !validationOnLabel,
163
- warning: warning
184
+ warning: warning,
185
+ tooltipId: tooltipId
164
186
  }))), characterCount));
165
187
  };
166
188
 
@@ -0,0 +1,24 @@
1
+ interface InputAccessibilityProperties {
2
+ labelId?: string;
3
+ tooltipId?: string;
4
+ fieldHelpId?: string;
5
+ ariaDescribedBy?: string;
6
+ ariaLabelledBy?: string;
7
+ }
8
+
9
+ export default function useInputAccessibility(
10
+ /** Input id - */
11
+ id: string,
12
+ /** Error validation message */
13
+ error?: string,
14
+ /** Warning validation message */
15
+ warning?: string,
16
+ /** Info validation message */
17
+ info?: string,
18
+ /** Label */
19
+ label?: string,
20
+ /** labelHelp message */
21
+ labelHelp?: string,
22
+ /** fieldHelp message */
23
+ fieldHelp?: string
24
+ ): void;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _useInputAccessibility.default;
10
+ }
11
+ });
12
+
13
+ var _useInputAccessibility = _interopRequireDefault(require("./useInputAccessibility"));
14
+
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = useInputAccessibility;
7
+
8
+ function useInputAccessibility({
9
+ id,
10
+ error,
11
+ warning,
12
+ info,
13
+ label,
14
+ labelHelp,
15
+ fieldHelp
16
+ }) {
17
+ const labelId = label ? `${id}-label` : undefined;
18
+ const tooltipId = [error, warning, info, labelHelp].filter(validation => typeof validation === "string").length ? `${id}-tooltip` : undefined;
19
+ const fieldHelpId = fieldHelp ? `${id}-field-help` : undefined;
20
+ const ariaDescribedBy = [fieldHelpId, tooltipId].filter(Boolean).join(" ");
21
+ const ariaLabelledBy = labelId;
22
+ return {
23
+ labelId,
24
+ tooltipId,
25
+ fieldHelpId,
26
+ ariaDescribedBy,
27
+ ariaLabelledBy
28
+ };
29
+ }
@@ -83,6 +83,9 @@ var _default = {
83
83
  placeholder: () => "Please Select...",
84
84
  noResultsForTerm: term => `No results for "${term}"`
85
85
  },
86
+ link: {
87
+ skipLinkLabel: () => "Skip to main content"
88
+ },
86
89
  switch: {
87
90
  on: () => "ON",
88
91
  off: () => "OFF"
@@ -75,6 +75,9 @@ var _default = {
75
75
  placeholder: () => "Proszę wybierz...",
76
76
  noResultsForTerm: term => `Brak wyników dla "${term}"`
77
77
  },
78
+ link: {
79
+ skipLinkLabel: () => "Przejdź do treści"
80
+ },
78
81
  switch: {
79
82
  on: () => "WŁ",
80
83
  off: () => "WYŁ"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "101.3.1",
3
+ "version": "101.4.1",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "engineStrict": true,
6
6
  "engines": {
@@ -62,18 +62,18 @@
62
62
  "@semantic-release/changelog": "^6.0.1",
63
63
  "@semantic-release/exec": "^6.0.2",
64
64
  "@semantic-release/git": "^10.0.1",
65
- "@storybook/addon-a11y": "^6.3.6",
66
- "@storybook/addon-actions": "^6.3.6",
67
- "@storybook/addon-controls": "^6.3.7",
68
- "@storybook/addon-docs": "^6.3.6",
65
+ "@storybook/addon-a11y": "^6.3.12",
66
+ "@storybook/addon-actions": "^6.3.12",
67
+ "@storybook/addon-controls": "^6.3.12",
68
+ "@storybook/addon-docs": "^6.3.12",
69
69
  "@storybook/addon-google-analytics": "^6.2.9",
70
- "@storybook/addon-links": "^6.3.6",
71
- "@storybook/addon-toolbars": "^6.3.8",
72
- "@storybook/addon-viewport": "^6.3.6",
73
- "@storybook/addons": "^6.3.6",
74
- "@storybook/components": "^6.3.6",
75
- "@storybook/react": "^6.3.6",
76
- "@storybook/theming": "^6.3.6",
70
+ "@storybook/addon-links": "^6.3.12",
71
+ "@storybook/addon-toolbars": "^6.3.12",
72
+ "@storybook/addon-viewport": "^6.3.12",
73
+ "@storybook/addons": "^6.3.12",
74
+ "@storybook/components": "^6.3.12",
75
+ "@storybook/react": "^6.3.12",
76
+ "@storybook/theming": "^6.3.12",
77
77
  "@types/enzyme": "^3.10.3",
78
78
  "@types/enzyme-adapter-react-16": "^1.0.5",
79
79
  "@types/jest": "^26.0.19",