carbon-react 128.1.2 → 128.3.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 (112) hide show
  1. package/esm/__internal__/checkable-input/checkable-input.component.d.ts +2 -0
  2. package/esm/__internal__/checkable-input/checkable-input.component.js +4 -2
  3. package/esm/__internal__/fieldset/fieldset.style.js +7 -6
  4. package/esm/__internal__/form-field/form-field.component.d.ts +1 -1
  5. package/esm/__internal__/form-field/form-field.component.js +1 -0
  6. package/esm/__internal__/label/label.style.js +6 -5
  7. package/esm/components/checkbox/checkbox-group/checkbox-group.component.d.ts +2 -0
  8. package/esm/components/checkbox/checkbox-group/checkbox-group.component.js +5 -2
  9. package/esm/components/checkbox/checkbox.component.js +3 -0
  10. package/esm/components/date-range/date-range.component.d.ts +5 -1
  11. package/esm/components/date-range/date-range.component.js +5 -1
  12. package/esm/components/decimal/decimal.component.d.ts +0 -2
  13. package/esm/components/decimal/decimal.component.js +1 -2
  14. package/esm/components/fieldset/fieldset.component.d.ts +8 -3
  15. package/esm/components/fieldset/fieldset.component.js +16 -2
  16. package/esm/components/fieldset/fieldset.style.d.ts +4 -0
  17. package/esm/components/fieldset/fieldset.style.js +29 -2
  18. package/esm/components/file-input/file-input.component.d.ts +4 -0
  19. package/esm/components/file-input/file-input.component.js +3 -0
  20. package/esm/components/form/index.d.ts +1 -0
  21. package/esm/components/form/index.js +2 -1
  22. package/esm/components/form/required-fields-indicator/index.d.ts +1 -0
  23. package/esm/components/form/required-fields-indicator/index.js +1 -0
  24. package/esm/components/form/required-fields-indicator/required-fields-indicator.component.d.ts +7 -0
  25. package/esm/components/form/required-fields-indicator/required-fields-indicator.component.js +20 -0
  26. package/esm/components/inline-inputs/inline-inputs.component.d.ts +3 -1
  27. package/esm/components/inline-inputs/inline-inputs.component.js +13 -3
  28. package/esm/components/menu/menu-full-screen/menu-full-screen.component.d.ts +8 -4
  29. package/esm/components/menu/menu-full-screen/menu-full-screen.component.js +70 -43
  30. package/esm/components/menu/menu-full-screen/menu-full-screen.style.d.ts +10 -6
  31. package/esm/components/menu/menu-full-screen/menu-full-screen.style.js +43 -20
  32. package/esm/components/numeral-date/numeral-date.component.d.ts +3 -1
  33. package/esm/components/numeral-date/numeral-date.component.js +4 -3
  34. package/esm/components/radio-button/radio-button-group/radio-button-group.component.d.ts +2 -0
  35. package/esm/components/radio-button/radio-button-group/radio-button-group.component.js +5 -3
  36. package/esm/components/radio-button/radio-button.component.d.ts +1 -2
  37. package/esm/components/radio-button/radio-button.component.js +1 -3
  38. package/esm/components/select/filterable-select/filterable-select.component.d.ts +4 -0
  39. package/esm/components/select/filterable-select/filterable-select.component.js +5 -0
  40. package/esm/components/select/multi-select/multi-select.component.d.ts +2 -0
  41. package/esm/components/select/multi-select/multi-select.component.js +5 -0
  42. package/esm/components/select/select-textbox/select-textbox.component.d.ts +2 -0
  43. package/esm/components/select/select-textbox/select-textbox.component.js +3 -0
  44. package/esm/components/select/simple-select/simple-select.component.d.ts +4 -0
  45. package/esm/components/select/simple-select/simple-select.component.js +6 -0
  46. package/esm/components/switch/switch.component.js +1 -0
  47. package/esm/components/text-editor/text-editor.component.d.ts +3 -1
  48. package/esm/components/text-editor/text-editor.component.js +16 -2
  49. package/esm/components/textarea/textarea.component.d.ts +2 -2
  50. package/esm/components/textarea/textarea.component.js +7 -2
  51. package/esm/components/textbox/textbox.component.d.ts +2 -2
  52. package/esm/components/tile-select/tile-select.style.d.ts +1 -1
  53. package/esm/locales/__internal__/es-es.js +5 -0
  54. package/esm/locales/en-gb.js +5 -0
  55. package/esm/locales/locale.d.ts +5 -0
  56. package/lib/__internal__/checkable-input/checkable-input.component.d.ts +2 -0
  57. package/lib/__internal__/checkable-input/checkable-input.component.js +4 -2
  58. package/lib/__internal__/fieldset/fieldset.style.js +7 -6
  59. package/lib/__internal__/form-field/form-field.component.d.ts +1 -1
  60. package/lib/__internal__/form-field/form-field.component.js +1 -0
  61. package/lib/__internal__/label/label.style.js +6 -5
  62. package/lib/components/checkbox/checkbox-group/checkbox-group.component.d.ts +2 -0
  63. package/lib/components/checkbox/checkbox-group/checkbox-group.component.js +5 -2
  64. package/lib/components/checkbox/checkbox.component.js +3 -0
  65. package/lib/components/date-range/date-range.component.d.ts +5 -1
  66. package/lib/components/date-range/date-range.component.js +5 -1
  67. package/lib/components/decimal/decimal.component.d.ts +0 -2
  68. package/lib/components/decimal/decimal.component.js +1 -2
  69. package/lib/components/fieldset/fieldset.component.d.ts +8 -3
  70. package/lib/components/fieldset/fieldset.component.js +18 -2
  71. package/lib/components/fieldset/fieldset.style.d.ts +4 -0
  72. package/lib/components/fieldset/fieldset.style.js +31 -2
  73. package/lib/components/file-input/file-input.component.d.ts +4 -0
  74. package/lib/components/file-input/file-input.component.js +3 -0
  75. package/lib/components/form/index.d.ts +1 -0
  76. package/lib/components/form/index.js +7 -0
  77. package/lib/components/form/required-fields-indicator/index.d.ts +1 -0
  78. package/lib/components/form/required-fields-indicator/index.js +13 -0
  79. package/lib/components/form/required-fields-indicator/package.json +6 -0
  80. package/lib/components/form/required-fields-indicator/required-fields-indicator.component.d.ts +7 -0
  81. package/lib/components/form/required-fields-indicator/required-fields-indicator.component.js +28 -0
  82. package/lib/components/inline-inputs/inline-inputs.component.d.ts +3 -1
  83. package/lib/components/inline-inputs/inline-inputs.component.js +14 -4
  84. package/lib/components/menu/menu-full-screen/menu-full-screen.component.d.ts +8 -4
  85. package/lib/components/menu/menu-full-screen/menu-full-screen.component.js +68 -41
  86. package/lib/components/menu/menu-full-screen/menu-full-screen.style.d.ts +10 -6
  87. package/lib/components/menu/menu-full-screen/menu-full-screen.style.js +43 -20
  88. package/lib/components/numeral-date/numeral-date.component.d.ts +3 -1
  89. package/lib/components/numeral-date/numeral-date.component.js +4 -3
  90. package/lib/components/radio-button/radio-button-group/radio-button-group.component.d.ts +2 -0
  91. package/lib/components/radio-button/radio-button-group/radio-button-group.component.js +5 -3
  92. package/lib/components/radio-button/radio-button.component.d.ts +1 -2
  93. package/lib/components/radio-button/radio-button.component.js +1 -3
  94. package/lib/components/select/filterable-select/filterable-select.component.d.ts +4 -0
  95. package/lib/components/select/filterable-select/filterable-select.component.js +5 -0
  96. package/lib/components/select/multi-select/multi-select.component.d.ts +2 -0
  97. package/lib/components/select/multi-select/multi-select.component.js +5 -0
  98. package/lib/components/select/select-textbox/select-textbox.component.d.ts +2 -0
  99. package/lib/components/select/select-textbox/select-textbox.component.js +3 -0
  100. package/lib/components/select/simple-select/simple-select.component.d.ts +4 -0
  101. package/lib/components/select/simple-select/simple-select.component.js +6 -0
  102. package/lib/components/switch/switch.component.js +1 -0
  103. package/lib/components/text-editor/text-editor.component.d.ts +3 -1
  104. package/lib/components/text-editor/text-editor.component.js +16 -2
  105. package/lib/components/textarea/textarea.component.d.ts +2 -2
  106. package/lib/components/textarea/textarea.component.js +7 -2
  107. package/lib/components/textbox/textbox.component.d.ts +2 -2
  108. package/lib/components/tile-select/tile-select.style.d.ts +1 -1
  109. package/lib/locales/__internal__/es-es.js +5 -0
  110. package/lib/locales/en-gb.js +5 -0
  111. package/lib/locales/locale.d.ts +5 -0
  112. package/package.json +1 -1
@@ -1,48 +1,53 @@
1
- function _extends() { _extends = Object.assign ? Object.assign.bind() : 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); }
2
- import React, { useContext, useRef } from "react";
1
+ import React, { useCallback, useContext, useRef } from "react";
3
2
  import PropTypes from "prop-types";
4
- import { StyledMenuFullscreen, StyledMenuFullscreenHeader } from "./menu-full-screen.style";
3
+ import { CSSTransition } from "react-transition-group";
4
+ import { StyledMenuFullscreen, StyledMenuModal, StyledMenuFullscreenHeader } from "./menu-full-screen.style";
5
5
  import { StyledMenuWrapper } from "../menu.style";
6
6
  import MenuContext from "../menu.context";
7
- import FocusTrap from "../../../__internal__/focus-trap";
8
7
  import Events from "../../../__internal__/utils/helpers/events";
9
8
  import Box from "../../box";
10
9
  import IconButton from "../../icon-button";
11
10
  import Icon from "../../icon";
12
11
  import Portal from "../../portal";
12
+ import FocusTrap from "../../../__internal__/focus-trap";
13
13
  import MenuDivider from "../menu-divider/menu-divider.component";
14
- import tagComponent from "../../../__internal__/utils/helpers/tags";
14
+ import useLocale from "../../../hooks/__internal__/useLocale";
15
+ import useModalAria from "../../../hooks/__internal__/useModalAria";
16
+ import useModalManager from "../../../hooks/__internal__/useModalManager";
15
17
  export const MenuFullscreen = ({
18
+ "aria-label": ariaLabel = "Fullscreen menu",
19
+ "data-element": dataElement,
20
+ "data-role": dataRole,
16
21
  children,
17
- isOpen,
18
- startPosition = "left",
22
+ isOpen = false,
19
23
  onClose,
20
- ...rest
24
+ startPosition = "left",
25
+ topModalOverride
21
26
  }) => {
22
- const menuWrapperRef = useRef(null);
23
- const menuContentRef = useRef(null);
27
+ const menuRef = useRef(null);
28
+ const modalRef = useRef(null);
29
+ const contentRef = useRef(null);
30
+ const isTopModal = useModalAria(modalRef);
24
31
  const {
25
32
  menuType
26
33
  } = useContext(MenuContext);
27
34
  const isDarkVariant = ["dark", "black"].includes(menuType);
28
- const handleKeyDown = ev => {
29
- /* istanbul ignore else */
30
- if (Events.isEscKey(ev)) {
31
- onClose(ev);
32
- }
33
- if (Events.isTabKey(ev) && !Events.isShiftKey(ev)) {
34
- const search = menuWrapperRef.current?.querySelector('[data-component="search"');
35
- const searchInput = search?.querySelector("input");
36
- const searchButton = search?.querySelector("button");
35
+ const transitionDuration = 200;
36
+ const locale = useLocale();
37
37
 
38
- // if there is no value in the search input the button disappears when the input blurs
39
- // this means we need to programatically set focus to the next menu item
40
- if (searchButton && searchInput && !searchInput.value && searchInput === document.activeElement) {
41
- ev.preventDefault();
42
- const elements = Array.from(menuWrapperRef.current?.querySelectorAll("a, input, button"));
43
- const index = elements.indexOf(searchInput);
44
- elements[index + 2]?.focus();
45
- }
38
+ // TODO: Remove this temporary event handler as part of FE-6078
39
+ const handleFocusedSearchButton = ev => {
40
+ const search = modalRef.current?.querySelector('[data-component="search"]');
41
+ const searchInput = search?.querySelector("input");
42
+ const searchButton = search?.querySelector("button");
43
+
44
+ // if there is no value in the search input the button disappears when the input blurs
45
+ // this means we need to programmatically set focus to the next menu item
46
+ if (searchButton && searchInput && !searchInput.value && searchInput === document.activeElement) {
47
+ ev.preventDefault();
48
+ const elements = Array.from(modalRef.current?.querySelectorAll("a, input, button"));
49
+ const index = elements.indexOf(searchInput);
50
+ elements[index + 2]?.focus();
46
51
  }
47
52
  };
48
53
  const flattenedChildren = React.Children.toArray(children);
@@ -52,23 +57,45 @@ export const MenuFullscreen = ({
52
57
  }
53
58
  return child;
54
59
  }));
55
- return /*#__PURE__*/React.createElement("li", {
56
- "aria-label": "menu-fullscreen"
57
- }, /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement(FocusTrap, {
58
- wrapperRef: menuWrapperRef,
59
- isOpen: isOpen
60
- }, /*#__PURE__*/React.createElement(StyledMenuFullscreen, _extends({
61
- ref: menuWrapperRef,
62
- isOpen: isOpen,
63
- menuType: menuType,
60
+ const closeModal = useCallback(ev => {
61
+ if (onClose && Events.isEscKey(ev)) {
62
+ ev.stopImmediatePropagation();
63
+ onClose(ev);
64
+ }
65
+ }, [onClose]);
66
+ useModalManager({
67
+ open: isOpen,
68
+ closeModal,
69
+ modalRef: menuRef,
70
+ topModalOverride
71
+ });
72
+ return /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement(CSSTransition, {
73
+ nodeRef: menuRef,
74
+ in: isOpen,
75
+ timeout: transitionDuration,
76
+ unmountOnExit: true
77
+ }, /*#__PURE__*/React.createElement(StyledMenuFullscreen, {
78
+ ref: menuRef,
64
79
  startPosition: startPosition,
65
- onKeyDown: handleKeyDown
66
- }, rest, tagComponent("menu-fullscreen", rest)), /*#__PURE__*/React.createElement(StyledMenuFullscreenHeader, {
67
- isOpen: isOpen,
80
+ transitionDuration: transitionDuration
81
+ }, /*#__PURE__*/React.createElement(FocusTrap, {
82
+ wrapperRef: modalRef,
83
+ isOpen: isOpen
84
+ }, /*#__PURE__*/React.createElement(StyledMenuModal, {
85
+ "aria-label": ariaLabel,
86
+ "aria-modal": isTopModal ? true : undefined,
87
+ "data-component": "menu-fullscreen",
88
+ "data-element": dataElement,
89
+ "data-role": dataRole,
68
90
  menuType: menuType,
69
- startPosition: startPosition
91
+ onKeyDown: ev => Events.isTabKey(ev) && !Events.isShiftKey(ev) && handleFocusedSearchButton(ev),
92
+ ref: modalRef,
93
+ role: "dialog",
94
+ tabIndex: -1
95
+ }, /*#__PURE__*/React.createElement(StyledMenuFullscreenHeader, {
96
+ menuType: menuType
70
97
  }, /*#__PURE__*/React.createElement(IconButton, {
71
- "aria-label": "menu fullscreen close button",
98
+ "aria-label": locale.menuFullscreen.ariaLabels.closeButton(),
72
99
  onClick: onClose,
73
100
  "data-element": "close"
74
101
  }, /*#__PURE__*/React.createElement(Icon, {
@@ -82,7 +109,7 @@ export const MenuFullscreen = ({
82
109
  }, /*#__PURE__*/React.createElement(StyledMenuWrapper, {
83
110
  "data-component": "menu",
84
111
  menuType: menuType,
85
- ref: menuContentRef,
112
+ ref: contentRef,
86
113
  display: "flex",
87
114
  flexDirection: "column",
88
115
  role: "list",
@@ -95,6 +122,6 @@ export const MenuFullscreen = ({
95
122
  openSubmenuId: null,
96
123
  setOpenSubmenuId: /* istanbul ignore next */() => {}
97
124
  }
98
- }, childArray)))))));
125
+ }, childArray)))))))));
99
126
  };
100
127
  export default MenuFullscreen;
@@ -1,8 +1,12 @@
1
- import { MenuFullscreenProps } from "./menu-full-screen.component";
2
1
  import { MenuType } from "../menu.context";
3
- interface StyledMenuFullScreenProps extends Pick<MenuFullscreenProps, "isOpen" | "startPosition"> {
2
+ declare const StyledMenuFullscreen: import("styled-components").StyledComponent<"div", any, {
3
+ transitionDuration: number;
4
+ startPosition: "left" | "right";
5
+ }, never>;
6
+ declare const StyledMenuModal: import("styled-components").StyledComponent<"div", any, {
4
7
  menuType: MenuType;
5
- }
6
- declare const StyledMenuFullscreen: import("styled-components").StyledComponent<"div", any, StyledMenuFullScreenProps, never>;
7
- declare const StyledMenuFullscreenHeader: import("styled-components").StyledComponent<"div", any, StyledMenuFullScreenProps, never>;
8
- export { StyledMenuFullscreen, StyledMenuFullscreenHeader };
8
+ }, never>;
9
+ declare const StyledMenuFullscreenHeader: import("styled-components").StyledComponent<"div", any, {
10
+ menuType: MenuType;
11
+ }, never>;
12
+ export { StyledMenuModal, StyledMenuFullscreen, StyledMenuFullscreenHeader };
@@ -8,15 +8,50 @@ import StyledButton from "../../button/button.style";
8
8
  import menuConfigVariants from "../menu.config";
9
9
  import addFocusStyling from "../../../style/utils/add-focus-styling";
10
10
  const oldFocusStyling = `
11
- outline: solid 3px var(--colorsSemanticFocus500);
12
- box-shadow: none;
11
+ outline: solid 3px var(--colorsSemanticFocus500);
12
+ box-shadow: none;
13
13
  `;
14
14
  const StyledMenuFullscreen = styled.div`
15
15
  position: fixed;
16
16
  top: 0;
17
17
  bottom: 0;
18
+
19
+ ${({
20
+ theme
21
+ }) => css`
22
+ z-index: ${theme.zIndex.fullScreenModal};
23
+ `}
24
+
25
+ ${({
26
+ startPosition,
27
+ transitionDuration
28
+ }) => css`
29
+ &.enter {
30
+ visibility: hidden;
31
+ ${startPosition}: -100%;
32
+ }
33
+
34
+ &.enter-active {
35
+ visibility: visible;
36
+ ${startPosition}: 0;
37
+ transition: all ${transitionDuration}ms ease;
38
+ }
39
+
40
+ &.exit {
41
+ visibility: visible;
42
+ ${startPosition}: 0;
43
+ }
44
+
45
+ &.exit-active {
46
+ visibility: hidden;
47
+ ${startPosition}: -100%;
48
+ transition: all ${transitionDuration}ms ease;
49
+ }
50
+ `}
51
+ `;
52
+ const StyledMenuModal = styled.div`
18
53
  height: 100vh;
19
- width: 100%;
54
+ width: 100vw;
20
55
  outline: none;
21
56
 
22
57
  a,
@@ -26,13 +61,10 @@ const StyledMenuFullscreen = styled.div`
26
61
  }
27
62
 
28
63
  ${({
29
- isOpen,
30
64
  menuType,
31
- startPosition,
32
65
  theme
33
66
  }) => css`
34
67
  background-color: ${menuConfigVariants[menuType].background};
35
- z-index: ${theme.zIndex.fullScreenModal};
36
68
 
37
69
  && {
38
70
  ${menuType === "dark" && css`
@@ -55,7 +87,7 @@ const StyledMenuFullscreen = styled.div`
55
87
  }
56
88
  `}
57
89
 
58
- ${StyledSearch} {
90
+ ${StyledSearch} {
59
91
  ${StyledIcon} {
60
92
  display: inline-flex;
61
93
  margin-right: 0;
@@ -76,18 +108,6 @@ const StyledMenuFullscreen = styled.div`
76
108
  }
77
109
  }
78
110
  }
79
-
80
- ${isOpen && css`
81
- visibility: visible;
82
- ${startPosition}: 0;
83
- transition: all 0.3s ease;
84
- `}
85
-
86
- ${!isOpen && css`
87
- visibility: hidden;
88
- ${startPosition}: -100%;
89
- transition: all 0.3s ease;
90
- `}
91
111
  `}
92
112
 
93
113
  ${StyledBox} {
@@ -115,4 +135,7 @@ const StyledMenuFullscreenHeader = styled.div`
115
135
  StyledMenuFullscreen.defaultProps = {
116
136
  theme: baseTheme
117
137
  };
118
- export { StyledMenuFullscreen, StyledMenuFullscreenHeader };
138
+ StyledMenuModal.defaultProps = {
139
+ theme: baseTheme
140
+ };
141
+ export { StyledMenuModal, StyledMenuFullscreen, StyledMenuFullscreenHeader };
@@ -87,7 +87,9 @@ export interface NumeralDateProps<DateType extends NumeralDateObject = FullDate>
87
87
  * A React ref to pass to the input corresponding to the year
88
88
  */
89
89
  yearRef?: React.ForwardedRef<HTMLInputElement>;
90
+ /** Flag to configure component as optional. */
91
+ isOptional?: boolean;
90
92
  }
91
93
  export declare type ValidDateFormat = typeof ALLOWED_DATE_FORMATS[number];
92
- export declare const NumeralDate: <DateType extends NumeralDateObject = FullDate>({ dateFormat, defaultValue, disabled, error, warning, "data-component": dataComponent, "data-element": dataElement, "data-role": dataRole, info, id, name, onBlur, onChange, value, validationOnLabel, label, labelInline, labelWidth, labelAlign, labelHelp, labelSpacing, fieldHelp, adaptiveLabelBreakpoint, required, readOnly, size, enableInternalError, enableInternalWarning, tooltipPosition, helpAriaLabel, dayRef, monthRef, yearRef, ...rest }: NumeralDateProps<DateType>) => React.JSX.Element;
94
+ export declare const NumeralDate: <DateType extends NumeralDateObject = FullDate>({ dateFormat, defaultValue, disabled, error, warning, "data-component": dataComponent, "data-element": dataElement, "data-role": dataRole, info, id, name, onBlur, onChange, value, validationOnLabel, label, labelInline, labelWidth, labelAlign, labelHelp, labelSpacing, fieldHelp, adaptiveLabelBreakpoint, required, isOptional, readOnly, size, enableInternalError, enableInternalWarning, tooltipPosition, helpAriaLabel, dayRef, monthRef, yearRef, ...rest }: NumeralDateProps<DateType>) => React.JSX.Element;
93
95
  export default NumeralDate;
@@ -103,6 +103,7 @@ export const NumeralDate = ({
103
103
  fieldHelp,
104
104
  adaptiveLabelBreakpoint,
105
105
  required,
106
+ isOptional,
106
107
  readOnly,
107
108
  size,
108
109
  enableInternalError,
@@ -215,6 +216,7 @@ export const NumeralDate = ({
215
216
  fieldHelp: fieldHelp,
216
217
  adaptiveLabelBreakpoint: adaptiveLabelBreakpoint,
217
218
  isRequired: required,
219
+ isOptional: isOptional,
218
220
  validationRedesignOptIn: validationRedesignOptIn
219
221
  }, filterStyledSystemMarginProps(rest)), validationRedesignOptIn && labelHelp && /*#__PURE__*/React.createElement(StyledHintText, null, labelHelp), /*#__PURE__*/React.createElement(Box, {
220
222
  position: "relative"
@@ -285,8 +287,6 @@ export const NumeralDate = ({
285
287
  error: !!internalError,
286
288
  warning: !!internalWarning,
287
289
  info: !!info
288
- }, required && {
289
- required
290
290
  }, isEnd && !validationRedesignOptIn && !validationOnLabel && {
291
291
  error: internalError,
292
292
  warning: internalWarning,
@@ -294,7 +294,8 @@ export const NumeralDate = ({
294
294
  }, {
295
295
  size: size,
296
296
  tooltipPosition: tooltipPosition,
297
- "aria-labelledby": labelId
297
+ "aria-labelledby": labelId,
298
+ required: required
298
299
  })))));
299
300
  }))))));
300
301
  };
@@ -32,6 +32,8 @@ export interface RadioButtonGroupProps extends ValidationProps, MarginProps {
32
32
  onChange?: (ev: React.ChangeEvent<HTMLInputElement>) => void;
33
33
  /** Flag to configure component as mandatory */
34
34
  required?: boolean;
35
+ /** Flag to configure component as optional. */
36
+ isOptional?: boolean;
35
37
  /** value of the selected RadioButton */
36
38
  value?: string;
37
39
  /** Overrides the default tooltip position */
@@ -35,6 +35,7 @@ export const RadioButtonGroup = props => {
35
35
  adaptiveLegendBreakpoint,
36
36
  adaptiveSpacingBreakpoint,
37
37
  required,
38
+ isOptional,
38
39
  tooltipPosition
39
40
  } = props;
40
41
  const {
@@ -64,7 +65,8 @@ export const RadioButtonGroup = props => {
64
65
  legendWidth: legendWidth,
65
66
  legendAlign: legendAlign,
66
67
  legendSpacing: legendSpacing,
67
- isRequired: required
68
+ isRequired: required,
69
+ isOptional: isOptional
68
70
  }, tagComponent("radiogroup", props), marginProps, {
69
71
  ml: marginLeft,
70
72
  blockGroupBehaviour: !(error || warning)
@@ -110,7 +112,8 @@ export const RadioButtonGroup = props => {
110
112
  legendWidth: legendWidth,
111
113
  legendAlign: legendAlign,
112
114
  legendSpacing: legendSpacing,
113
- isRequired: required
115
+ isRequired: required,
116
+ isOptional: isOptional
114
117
  }, tagComponent("radiogroup", props), marginProps, {
115
118
  ml: marginLeft,
116
119
  blockGroupBehaviour: !(error || warning || info)
@@ -134,7 +137,6 @@ export const RadioButtonGroup = props => {
134
137
  error: !!error,
135
138
  warning: !!warning,
136
139
  info: !!info,
137
- required,
138
140
  ...child.props
139
141
  });
140
142
  }))))));
@@ -3,9 +3,8 @@ import { MarginProps } from "styled-system";
3
3
  import { CommonCheckableInputProps } from "../../__internal__/checkable-input";
4
4
  interface InternalRadioButtonProps {
5
5
  inline?: boolean;
6
- required?: boolean;
7
6
  }
8
- export interface RadioButtonProps extends CommonCheckableInputProps, MarginProps {
7
+ export interface RadioButtonProps extends Omit<CommonCheckableInputProps, "required" | "IsOptional">, MarginProps {
9
8
  /** Identifier used for testing purposes, applied to the root element of the component. */
10
9
  "data-component"?: string;
11
10
  /** Identifier used for testing purposes, applied to the root element of the component. */
@@ -29,7 +29,6 @@ const RadioButton = /*#__PURE__*/React.forwardRef(({
29
29
  onFocus,
30
30
  value,
31
31
  reverse = false,
32
- required,
33
32
  size,
34
33
  error,
35
34
  warning,
@@ -97,7 +96,6 @@ const RadioButton = /*#__PURE__*/React.forwardRef(({
97
96
  * opposite way around by default)
98
97
  */
99
98
  reverse: !reverse,
100
- required,
101
99
  ref: ref || inputRef,
102
100
  ...props
103
101
  };
@@ -225,6 +223,7 @@ if (process.env.NODE_ENV !== "production") {
225
223
  })]),
226
224
  "inputWidth": PropTypes.number,
227
225
  "is": PropTypes.string,
226
+ "isOptional": PropTypes.bool,
228
227
  "itemID": PropTypes.string,
229
228
  "itemProp": PropTypes.string,
230
229
  "itemRef": PropTypes.string,
@@ -565,7 +564,6 @@ if (process.env.NODE_ENV !== "production") {
565
564
  "radioGroup": PropTypes.string,
566
565
  "readOnly": PropTypes.bool,
567
566
  "rel": PropTypes.string,
568
- "required": PropTypes.bool,
569
567
  "resource": PropTypes.string,
570
568
  "results": PropTypes.number,
571
569
  "rev": PropTypes.string,
@@ -61,6 +61,10 @@ export interface FilterableSelectProps extends Omit<FormInputPropTypes, "default
61
61
  /** Boolean to disable automatic filtering and highlighting of options.
62
62
  * This allows custom filtering and option styling to be performed outside of the component when the filter text changes. */
63
63
  disableDefaultFiltering?: boolean;
64
+ /** Flag to configure component as optional. */
65
+ isOptional?: boolean;
66
+ /** Flag to configure component as mandatory */
67
+ required?: boolean;
64
68
  }
65
69
  export declare const FilterableSelect: React.ForwardRefExoticComponent<FilterableSelectProps & React.RefAttributes<unknown>>;
66
70
  export default FilterableSelect;
@@ -54,6 +54,8 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
54
54
  enableVirtualScroll,
55
55
  virtualScrollOverscan,
56
56
  disableDefaultFiltering = false,
57
+ isOptional,
58
+ required,
57
59
  ...textboxProps
58
60
  }, ref) => {
59
61
  const [activeDescendantId, setActiveDescendantId] = useState();
@@ -397,6 +399,8 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
397
399
  onMouseDown: handleTextboxMouseDown,
398
400
  tooltipPosition,
399
401
  inputRef,
402
+ required,
403
+ isOptional,
400
404
  ...filterOutStyledSystemSpacingProps(textboxProps)
401
405
  };
402
406
  }
@@ -565,6 +569,7 @@ if (process.env.NODE_ENV !== "production") {
565
569
  "inputWidth": PropTypes.number,
566
570
  "is": PropTypes.string,
567
571
  "isLoading": PropTypes.bool,
572
+ "isOptional": PropTypes.bool,
568
573
  "itemID": PropTypes.string,
569
574
  "itemProp": PropTypes.string,
570
575
  "itemRef": PropTypes.string,
@@ -55,6 +55,8 @@ export interface MultiSelectProps extends Omit<FormInputPropTypes, "defaultValue
55
55
  * Higher values make for smoother scrolling but may impact performance.
56
56
  * Only used if the `enableVirtualScroll` prop is set. */
57
57
  virtualScrollOverscan?: number;
58
+ /** Flag to configure component as optional. */
59
+ isOptional?: boolean;
58
60
  }
59
61
  export declare const MultiSelect: React.ForwardRefExoticComponent<MultiSelectProps & React.RefAttributes<unknown>>;
60
62
  export default MultiSelect;
@@ -55,6 +55,8 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
55
55
  inputRef,
56
56
  enableVirtualScroll,
57
57
  virtualScrollOverscan,
58
+ isOptional,
59
+ required,
58
60
  ...textboxProps
59
61
  }, ref) => {
60
62
  const [activeDescendantId, setActiveDescendantId] = useState();
@@ -404,6 +406,8 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
404
406
  onChange: handleTextboxChange,
405
407
  tooltipPosition,
406
408
  size,
409
+ required,
410
+ isOptional,
407
411
  inputRef,
408
412
  ...filterOutStyledSystemSpacingProps(textboxProps)
409
413
  };
@@ -574,6 +578,7 @@ if (process.env.NODE_ENV !== "production") {
574
578
  "inputWidth": PropTypes.number,
575
579
  "is": PropTypes.string,
576
580
  "isLoading": PropTypes.bool,
581
+ "isOptional": PropTypes.bool,
577
582
  "itemID": PropTypes.string,
578
583
  "itemProp": PropTypes.string,
579
584
  "itemRef": PropTypes.string,
@@ -59,6 +59,8 @@ export interface FormInputPropTypes extends ValidationProps, Omit<CommonTextboxP
59
59
  *
60
60
  */
61
61
  labelId?: string;
62
+ /** Flag to configure component as optional in Form */
63
+ isOptional?: boolean;
62
64
  }
63
65
  export interface SelectTextboxProps extends FormInputPropTypes {
64
66
  /** Id attribute of the select list */
@@ -37,6 +37,7 @@ const SelectTextbox = /*#__PURE__*/React.forwardRef(({
37
37
  onChange,
38
38
  selectedValue,
39
39
  required,
40
+ isOptional,
40
41
  textboxRef,
41
42
  hasTextCursor,
42
43
  transparent,
@@ -80,6 +81,7 @@ const SelectTextbox = /*#__PURE__*/React.forwardRef(({
80
81
  id,
81
82
  readOnly,
82
83
  required,
84
+ isOptional,
83
85
  onClick: handleTextboxClick,
84
86
  onFocus: handleTextboxFocus,
85
87
  onBlur: handleTextboxBlur,
@@ -234,6 +236,7 @@ if (process.env.NODE_ENV !== "production") {
234
236
  "inputWidth": PropTypes.number,
235
237
  "is": PropTypes.string,
236
238
  "isOpen": PropTypes.bool,
239
+ "isOptional": PropTypes.bool,
237
240
  "itemID": PropTypes.string,
238
241
  "itemProp": PropTypes.string,
239
242
  "itemRef": PropTypes.string,
@@ -61,6 +61,10 @@ export interface SimpleSelectProps extends Omit<FormInputPropTypes, "defaultValu
61
61
  * Higher values make for smoother scrolling but may impact performance.
62
62
  * Only used if the `enableVirtualScroll` prop is set. */
63
63
  virtualScrollOverscan?: number;
64
+ /** Flag to configure component as optional in Form */
65
+ isOptional?: boolean;
66
+ /** Flag to configure component as mandatory */
67
+ isRequired?: boolean;
64
68
  }
65
69
  export declare const SimpleSelect: React.ForwardRefExoticComponent<SimpleSelectProps & React.RefAttributes<unknown>>;
66
70
  export default SimpleSelect;
@@ -48,6 +48,8 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
48
48
  inputRef,
49
49
  enableVirtualScroll,
50
50
  virtualScrollOverscan,
51
+ isOptional,
52
+ required,
51
53
  ...props
52
54
  }, ref) => {
53
55
  const selectListId = useRef(guid());
@@ -314,6 +316,8 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
314
316
  onKeyDown: handleTextboxKeydown,
315
317
  onBlur: handleTextboxBlur,
316
318
  tooltipPosition,
319
+ required,
320
+ isOptional,
317
321
  transparent,
318
322
  inputRef,
319
323
  ...filterOutStyledSystemSpacingProps(props)
@@ -476,6 +480,8 @@ if (process.env.NODE_ENV !== "production") {
476
480
  "inputWidth": PropTypes.number,
477
481
  "is": PropTypes.string,
478
482
  "isLoading": PropTypes.bool,
483
+ "isOptional": PropTypes.bool,
484
+ "isRequired": PropTypes.bool,
479
485
  "itemID": PropTypes.string,
480
486
  "itemProp": PropTypes.string,
481
487
  "itemRef": PropTypes.string,
@@ -275,6 +275,7 @@ if (process.env.NODE_ENV !== "production") {
275
275
  })]),
276
276
  "inputWidth": PropTypes.number,
277
277
  "is": PropTypes.string,
278
+ "isOptional": PropTypes.bool,
278
279
  "itemID": PropTypes.string,
279
280
  "itemProp": PropTypes.string,
280
281
  "itemRef": PropTypes.string,
@@ -16,8 +16,10 @@ export interface TextEditorProps extends MarginProps {
16
16
  toolbarElements?: React.ReactNode;
17
17
  /** The value of the input, this is an EditorState immutable object */
18
18
  value: EditorState;
19
- /** Flag to configure component as mandatory */
19
+ /** Flag to configure component as mandatory. */
20
20
  required?: boolean;
21
+ /** Flag to configure component as optional. */
22
+ isOptional?: boolean;
21
23
  /** Message to be displayed when there is an error */
22
24
  error?: string;
23
25
  /** Message to be displayed when there is a warning */
@@ -1,3 +1,4 @@
1
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : 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); }
1
2
  import React, { useCallback, useEffect, useRef, useState, useContext } from "react";
2
3
  import PropTypes from "prop-types";
3
4
  import { ContentState, EditorState, RichUtils, getDefaultKeyBinding, Modifier, Editor } from "draft-js";
@@ -33,6 +34,7 @@ const TextEditor = /*#__PURE__*/React.forwardRef(({
33
34
  previews,
34
35
  onLinkAdded,
35
36
  inputHint,
37
+ isOptional,
36
38
  ...rest
37
39
  }, ref) => {
38
40
  const {
@@ -43,6 +45,7 @@ const TextEditor = /*#__PURE__*/React.forwardRef(({
43
45
  const [activeInlines, setActiveInlines] = useState({});
44
46
  const [focusToolbar, setFocusToolbar] = useState(false);
45
47
  const editorRef = useRef(null);
48
+ const wrapper = useRef(null);
46
49
  const editor = ref || editorRef;
47
50
  const contentLength = getContent(value).getPlainText("").length;
48
51
  const moveCursor = useRef(contentLength > 0);
@@ -242,16 +245,26 @@ const TextEditor = /*#__PURE__*/React.forwardRef(({
242
245
  editor.current?.focus();
243
246
  }
244
247
  };
248
+ useEffect(() => {
249
+ if (required) {
250
+ const editableElement = wrapper.current?.querySelector("div[contenteditable='true']");
251
+ editableElement?.setAttribute("required", "");
252
+ editableElement?.setAttribute("aria-required", "true");
253
+ }
254
+ }, [required]);
245
255
  return /*#__PURE__*/React.createElement(EditorContext.Provider, {
246
256
  value: {
247
257
  onLinkAdded,
248
258
  editMode: true
249
259
  }
250
- }, /*#__PURE__*/React.createElement(StyledEditorWrapper, rest, /*#__PURE__*/React.createElement(LabelWrapper, {
260
+ }, /*#__PURE__*/React.createElement(StyledEditorWrapper, _extends({
261
+ ref: wrapper
262
+ }, rest), /*#__PURE__*/React.createElement(LabelWrapper, {
251
263
  onClick: () => handleEditorFocus(true)
252
264
  }, /*#__PURE__*/React.createElement(Label, {
253
265
  labelId: labelId,
254
- isRequired: required
266
+ isRequired: required,
267
+ optional: isOptional
255
268
  }, labelText)), inputHint && /*#__PURE__*/React.createElement(StyledHintText, {
256
269
  id: inputHintId.current
257
270
  }, inputHint), /*#__PURE__*/React.createElement(Box, {
@@ -313,6 +326,7 @@ if (process.env.NODE_ENV !== "production") {
313
326
  "error": PropTypes.string,
314
327
  "info": PropTypes.string,
315
328
  "inputHint": PropTypes.string,
329
+ "isOptional": PropTypes.bool,
316
330
  "labelText": PropTypes.string.isRequired,
317
331
  "m": PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.number, PropTypes.shape({
318
332
  "__@toStringTag": PropTypes.string.isRequired,
@@ -79,8 +79,8 @@ export interface TextareaProps extends ValidationProps, MarginProps, Omit<Common
79
79
  placeholder?: string;
80
80
  /** Adds readOnly property */
81
81
  readOnly?: boolean;
82
- /** Flag to configure component as mandatory */
83
- required?: boolean;
82
+ /** Flag to configure component as optional */
83
+ isOptional?: boolean;
84
84
  /** The number of visible text lines for the control */
85
85
  rows?: number;
86
86
  /** One of type of size to apply to the textarea */