carbon-react 128.4.1 → 129.0.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 (33) hide show
  1. package/esm/components/link/link.style.js +17 -17
  2. package/esm/components/menu/__internal__/submenu/submenu.style.js +23 -14
  3. package/esm/components/menu/menu-full-screen/menu-full-screen.component.js +0 -17
  4. package/esm/components/menu/menu-full-screen/menu-full-screen.style.js +12 -26
  5. package/esm/components/menu/menu-item/menu-item.component.js +7 -7
  6. package/esm/components/menu/menu-item/menu-item.style.js +9 -7
  7. package/esm/components/menu/menu.style.js +4 -1
  8. package/esm/components/search/index.d.ts +1 -1
  9. package/esm/components/search/search-button.style.js +8 -3
  10. package/esm/components/search/search.component.d.ts +10 -7
  11. package/esm/components/search/search.component.js +35 -42
  12. package/esm/components/search/search.style.d.ts +0 -1
  13. package/esm/components/search/search.style.js +64 -52
  14. package/esm/locales/__internal__/es-es.js +3 -0
  15. package/esm/locales/en-gb.js +3 -0
  16. package/esm/locales/locale.d.ts +3 -0
  17. package/lib/components/link/link.style.js +17 -17
  18. package/lib/components/menu/__internal__/submenu/submenu.style.js +23 -14
  19. package/lib/components/menu/menu-full-screen/menu-full-screen.component.js +0 -17
  20. package/lib/components/menu/menu-full-screen/menu-full-screen.style.js +12 -26
  21. package/lib/components/menu/menu-item/menu-item.component.js +7 -7
  22. package/lib/components/menu/menu-item/menu-item.style.js +9 -7
  23. package/lib/components/menu/menu.style.js +4 -1
  24. package/lib/components/search/index.d.ts +1 -1
  25. package/lib/components/search/search-button.style.js +8 -3
  26. package/lib/components/search/search.component.d.ts +10 -7
  27. package/lib/components/search/search.component.js +34 -41
  28. package/lib/components/search/search.style.d.ts +0 -1
  29. package/lib/components/search/search.style.js +64 -52
  30. package/lib/locales/__internal__/es-es.js +3 -0
  31. package/lib/locales/en-gb.js +3 -0
  32. package/lib/locales/locale.d.ts +3 -0
  33. package/package.json +1 -1
@@ -55,14 +55,14 @@ const StyledLink = styled.span`
55
55
  ${isSkipLink && css`
56
56
  a {
57
57
  position: absolute;
58
- padding-left: 24px;
59
- padding-right: 24px;
58
+ padding-left: var(--spacing300);
59
+ padding-right: var(--spacing300);
60
60
  line-height: 36px;
61
61
  left: -999em;
62
62
  z-index: ${theme.zIndex.aboveAll};
63
- box-shadow: inset 0 0 0 2px var(--colorsActionMajor500);
64
- border: 2px solid var(--colorsUtilityYang100);
65
- font-size: 16px;
63
+ box-shadow: inset 0 0 0 var(--spacing025) var(--colorsActionMajor500);
64
+ border: var(--spacing025) solid var(--colorsUtilityYang100);
65
+ font-size: var(--fontSizes200);
66
66
  color: var(--colorsUtilityYin090);
67
67
 
68
68
  &:hover {
@@ -80,15 +80,15 @@ const StyledLink = styled.span`
80
80
  }
81
81
 
82
82
  a:focus {
83
- top: 8px;
84
- left: 8px;
83
+ top: var(--spacing100);
84
+ left: var(--spacing100);
85
85
  }
86
86
  `}
87
87
 
88
88
  ${!isSkipLink && css`
89
- a,
90
- button {
91
- font-size: 14px;
89
+ > a,
90
+ > button {
91
+ font-size: var(--fontSizes100);
92
92
 
93
93
  ${!disabled && css`
94
94
  color: ${color};
@@ -99,7 +99,7 @@ const StyledLink = styled.span`
99
99
  &:hover {
100
100
  color: ${hoverColor};
101
101
 
102
- ${StyledIcon} {
102
+ > ${StyledIcon} {
103
103
  color: ${hoverColor};
104
104
  }
105
105
  }
@@ -120,8 +120,8 @@ const StyledLink = styled.span`
120
120
  }
121
121
  `}
122
122
 
123
- a,
124
- button {
123
+ > a,
124
+ > button {
125
125
  text-decoration: ${hasContent ? "underline" : "none"};
126
126
  ${isMenuItem && "display: inline-block;"}
127
127
 
@@ -160,20 +160,20 @@ const StyledLink = styled.span`
160
160
  }
161
161
 
162
162
  ${!isSkipLink && !disabled && !theme.focusRedesignOptOut && hasFocus && css`
163
- a,
164
- button {
163
+ > a,
164
+ > button {
165
165
  outline: none;
166
166
  text-decoration: none;
167
167
  border-bottom-left-radius: var(--borderRadius000);
168
168
  border-bottom-right-radius: var(--borderRadius000);
169
169
  }
170
170
  max-width: fit-content;
171
- box-shadow: 0 4px 0 0 var(--colorsUtilityYin090);
171
+ box-shadow: 0 var(--spacing050) 0 0 var(--colorsUtilityYin090);
172
172
  border-bottom-left-radius: var(--borderRadius025);
173
173
  border-bottom-right-radius: var(--borderRadius025);
174
174
  `}
175
175
 
176
- button {
176
+ > button {
177
177
  background-color: transparent;
178
178
  border: none;
179
179
  padding: 0;
@@ -3,7 +3,7 @@ import { baseTheme } from "../../../../style/themes";
3
3
  import { StyledLink } from "../../../link/link.style";
4
4
  import { StyledMenuItem } from "../../menu.style";
5
5
  import StyledMenuItemWrapper from "../../menu-item/menu-item.style";
6
- import StyledSearch from "../../../search/search.style";
6
+ import StyledIcon from "../../../icon/icon.style";
7
7
  import menuConfigVariants from "../../menu.config";
8
8
  const StyledSubmenuWrapper = styled.div`
9
9
  position: relative;
@@ -94,17 +94,17 @@ const StyledSubmenu = styled.ul`
94
94
  ${!inFullscreenView && menuType && css`
95
95
  background-color: ${menuConfigVariants[menuType].submenuItemBackground};
96
96
 
97
- a:focus,
98
- button:focus {
97
+ > a:focus,
98
+ > button:focus {
99
99
  background-color: ${menuConfigVariants[menuType].submenuItemBackground};
100
100
  }
101
101
 
102
- a:hover,
103
- button:hover {
102
+ > a:hover,
103
+ > button:hover {
104
104
  background-color: transparent;
105
105
  color: var(--colorsComponentsMenuYang100);
106
106
 
107
- [data-component="icon"] {
107
+ > [data-component="icon"] {
108
108
  color: var(--colorsComponentsMenuYang100);
109
109
  }
110
110
  }
@@ -114,17 +114,26 @@ const StyledSubmenu = styled.ul`
114
114
  text-decoration: none;
115
115
  }
116
116
 
117
- ${StyledSearch} span > [data-component="icon"] {
118
- color: var(--colorsUtilityMajor200);
117
+ > ${StyledIcon} {
118
+ width: 16px;
119
+ height: 16px;
120
+ margin-right: 5px;
121
+ }
122
+ }
119
123
 
120
- &:hover {
121
- color: var(--colorsUtilityMajor150);
122
- }
124
+ [data-component="icon"] {
125
+ line-height: 20px;
126
+
127
+ &:before {
128
+ line-height: unset;
123
129
  }
124
130
 
125
- ${StyledSearch} {
126
- :hover {
127
- border-bottom-color: var(--colorsUtilityMajor150);
131
+ span {
132
+ vertical-align: middle;
133
+
134
+ svg {
135
+ height: 16px;
136
+ width: 16px;
128
137
  }
129
138
  }
130
139
  }
@@ -34,22 +34,6 @@ export const MenuFullscreen = ({
34
34
  const isDarkVariant = ["dark", "black"].includes(menuType);
35
35
  const transitionDuration = 200;
36
36
  const locale = useLocale();
37
-
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();
51
- }
52
- };
53
37
  const flattenedChildren = React.Children.toArray(children);
54
38
  const childArray = React.Children.toArray(flattenedChildren.map((child, index) => {
55
39
  if (index < flattenedChildren.length - 1) {
@@ -88,7 +72,6 @@ export const MenuFullscreen = ({
88
72
  "data-element": dataElement,
89
73
  "data-role": dataRole,
90
74
  menuType: menuType,
91
- onKeyDown: ev => Events.isTabKey(ev) && !Events.isShiftKey(ev) && handleFocusedSearchButton(ev),
92
75
  ref: modalRef,
93
76
  role: "dialog",
94
77
  tabIndex: -1
@@ -7,6 +7,7 @@ import StyledIcon from "../../icon/icon.style";
7
7
  import StyledButton from "../../button/button.style";
8
8
  import menuConfigVariants from "../menu.config";
9
9
  import addFocusStyling from "../../../style/utils/add-focus-styling";
10
+ import { StyledLink } from "../../link/link.style";
10
11
  const oldFocusStyling = `
11
12
  outline: solid 3px var(--colorsSemanticFocus500);
12
13
  box-shadow: none;
@@ -54,10 +55,16 @@ const StyledMenuModal = styled.div`
54
55
  width: 100vw;
55
56
  outline: none;
56
57
 
57
- a,
58
- button,
59
- div {
60
- font-size: 16px;
58
+ && {
59
+ ${StyledLink} {
60
+ max-width: 100vw;
61
+ }
62
+
63
+ ${StyledLink} > a,
64
+ ${StyledLink} > button,
65
+ > div {
66
+ font-size: var(--fontSizes200);
67
+ }
61
68
  }
62
69
 
63
70
  ${({
@@ -67,30 +74,9 @@ const StyledMenuModal = styled.div`
67
74
  background-color: ${menuConfigVariants[menuType].background};
68
75
 
69
76
  && {
70
- ${menuType === "dark" && css`
71
- ${StyledSearch} span > [data-component="icon"] {
72
- color: var(--colorsUtilityMajor200);
73
-
74
- &:hover {
75
- color: var(--colorsUtilityMajor150);
76
- }
77
- }
78
- `}
79
-
80
- ${menuType === "light" && css`
81
- ${StyledSearch} span > [data-component="icon"] {
82
- color: var(--colorsUtilityMajor200);
83
-
84
- &:hover {
85
- color: var(--colorsUtilityMajor400);
86
- }
87
- }
88
- `}
89
-
90
- ${StyledSearch} {
77
+ ${StyledSearch} {
91
78
  ${StyledIcon} {
92
79
  display: inline-flex;
93
- margin-right: 0;
94
80
  bottom: auto;
95
81
  }
96
82
 
@@ -55,8 +55,6 @@ export const MenuItem = ({
55
55
  const focusFromMenu = focusId === menuItemId.current;
56
56
  const focusFromSubmenu = submenuFocusId ? submenuFocusId === menuItemId.current : undefined;
57
57
  const inputRef = useRef(null);
58
- const inputIcon = useRef(null);
59
- inputIcon.current = ref.current ? ref.current.querySelector("[data-element='input-icon-toggle']") : null;
60
58
  inputRef.current = ref.current ? ref.current.querySelector("[data-element='input']") : null;
61
59
  const focusRef = inputRef.current ? inputRef : ref;
62
60
  useEffect(() => {
@@ -71,18 +69,19 @@ export const MenuItem = ({
71
69
  };
72
70
  }, [registerItem, unregisterItem]);
73
71
  useEffect(() => {
72
+ const inputIcon = ref.current?.querySelector("[data-element='input-icon-toggle']");
74
73
  if (!openSubmenuId && focusFromSubmenu === undefined && focusFromMenu) {
75
74
  /* istanbul ignore else */
76
75
  if (focusRef.current) {
77
76
  focusRef.current?.focus();
78
77
  }
79
- } else if (focusFromSubmenu && !(shiftTabPressed && inputIcon.current?.getAttribute("tabindex") === "0")) {
78
+ } else if (focusFromSubmenu && !(shiftTabPressed && inputIcon?.getAttribute("tabindex") === "0")) {
80
79
  /* istanbul ignore else */
81
80
  if (focusRef.current) {
82
81
  focusRef.current?.focus();
83
82
  }
84
83
  }
85
- }, [openSubmenuId, focusFromMenu, focusFromSubmenu, inputIcon, shiftTabPressed, focusRef]);
84
+ }, [openSubmenuId, focusFromMenu, focusFromSubmenu, shiftTabPressed, focusRef]);
86
85
  const updateFocusOnClick = useCallback(() => {
87
86
  if (updateSubmenuFocusId) {
88
87
  updateSubmenuFocusId(menuItemId.current);
@@ -95,16 +94,17 @@ export const MenuItem = ({
95
94
  if (ref.current && Events.isEscKey(event)) {
96
95
  ref.current?.focus();
97
96
  }
98
- const shouldFocusIcon = inputIcon.current?.getAttribute("tabindex") === "0" && document.activeElement === inputRef.current && inputRef.current?.value;
97
+ const inputIcon = ref.current?.querySelector("[data-element='input-icon-toggle']");
98
+ const shouldFocusIcon = inputIcon?.getAttribute("tabindex") === "0" && document.activeElement === inputRef.current && inputRef.current?.value;
99
99
 
100
100
  // let natural tab order move focus if input icon is tabbable or input with button exists
101
- if (Events.isTabKey(event) && (!Events.isShiftKey(event) && shouldFocusIcon || Events.isShiftKey(event) && document.activeElement === inputIcon.current)) {
101
+ if (Events.isTabKey(event) && (!Events.isShiftKey(event) && shouldFocusIcon || Events.isShiftKey(event) && document.activeElement === inputIcon)) {
102
102
  return;
103
103
  }
104
104
  if (handleSubmenuKeyDown) {
105
105
  handleSubmenuKeyDown(event);
106
106
  }
107
- }, [onKeyDown, handleSubmenuKeyDown, inputIcon]);
107
+ }, [onKeyDown, handleSubmenuKeyDown]);
108
108
  const elementProps = {
109
109
  className: href || onClick ? "carbon-menu-item--has-link" : "",
110
110
  href,
@@ -149,9 +149,11 @@ const StyledMenuItemWrapper = styled.a.attrs({
149
149
  ${!hasInput && `color: ${menuConfigVariants[menuType].color};`}
150
150
  }
151
151
 
152
- ${StyledIcon} {
153
- display: inline-block;
154
- }
152
+ ${!inFullscreenView && css`
153
+ a > ${StyledIcon}, button > ${StyledIcon} {
154
+ display: inline-block;
155
+ }
156
+ `}
155
157
  }
156
158
 
157
159
  ${selected && css`
@@ -313,10 +315,10 @@ const StyledMenuItemWrapper = styled.a.attrs({
313
315
  }
314
316
 
315
317
  && {
316
- a:focus,
317
- a:hover,
318
- button:focus,
319
- button:hover {
318
+ > a:focus,
319
+ > a:hover,
320
+ > button:focus,
321
+ > button:hover {
320
322
  background-color: var(--colorsComponentsMenuAutumnStandard600);
321
323
  color: var(--colorsComponentsMenuYang100);
322
324
 
@@ -4,6 +4,7 @@ import menuConfigVariants from "./menu.config";
4
4
  import { StyledVerticalWrapper, StyledDivider } from "../vertical-divider/vertical-divider.style";
5
5
  import { StyledLink } from "../link/link.style";
6
6
  import { baseTheme } from "../../style/themes";
7
+ import StyledMenuItemWrapper from "./menu-item/menu-item.style";
7
8
  const StyledMenuWrapper = styled.ul`
8
9
  line-height: 40px;
9
10
  list-style: none;
@@ -66,7 +67,9 @@ const StyledMenuItem = styled.li`
66
67
  }
67
68
  `}
68
69
 
69
- ${padding}
70
+ ${StyledMenuItemWrapper} {
71
+ ${padding}
72
+ }
70
73
  `;
71
74
  StyledMenuItem.defaultProps = {
72
75
  theme: baseTheme
@@ -1,2 +1,2 @@
1
1
  export { default } from "./search.component";
2
- export type { SearchProps, SearchEvent } from "./search.component";
2
+ export type { SearchProps, SearchEvent, SearchHandle, } from "./search.component";
@@ -13,7 +13,7 @@ const StyledSearchButton = styled.div`
13
13
  border-bottom: none;
14
14
 
15
15
  & ${StyledButton} {
16
- background-color: var(--colorsActionMajor500);
16
+ color: var(--colorsActionMajorYang100);
17
17
  border-color: var(--colorsActionMajorTransparent);
18
18
  border-bottom-left-radius: var(--borderRadius000);
19
19
  border-top-left-radius: var(--borderRadius000);
@@ -21,13 +21,18 @@ const StyledSearchButton = styled.div`
21
21
  border-top-right-radius: var(--borderRadius050);
22
22
 
23
23
  :hover {
24
- background: var(--colorsActionMajor600);
25
24
  border-color: var(--colorsActionMajorTransparent);
26
25
  }
27
26
 
28
- width: 40px;
27
+ width: fit-content;
28
+
29
+ ${StyledIcon}${StyledIcon} {
30
+ color: var(--colorsActionMajorYang100);
31
+ }
32
+
29
33
  margin: 0px 0px;
30
34
  padding-bottom: 3px;
35
+
31
36
  :focus {
32
37
  z-index: ${({
33
38
  theme
@@ -17,8 +17,6 @@ export interface SearchProps extends ValidationProps, MarginProps {
17
17
  defaultValue?: string;
18
18
  /** Prop for `id` */
19
19
  id?: string;
20
- /** A callback to retrieve the input reference */
21
- inputRef?: React.MutableRefObject<HTMLInputElement | null>;
22
20
  /** Prop for `name` */
23
21
  name?: string;
24
22
  /** Prop for `onBlur` events */
@@ -35,8 +33,11 @@ export interface SearchProps extends ValidationProps, MarginProps {
35
33
  onKeyDown?: (ev: React.KeyboardEvent<HTMLInputElement>) => void;
36
34
  /** Prop for a placeholder */
37
35
  placeholder?: string;
38
- /** Prop boolean to state whether the `search` icon renders */
39
- searchButton?: boolean;
36
+ /**
37
+ * Pass a boolean to render a search Button with default text.
38
+ * Pass a string to override the text in the search Button
39
+ * */
40
+ searchButton?: boolean | string;
40
41
  /**
41
42
  * Prop for specifying an input width length.
42
43
  * Leaving the `searchWidth` prop with no value will default the width to '100%'
@@ -47,8 +48,6 @@ export interface SearchProps extends ValidationProps, MarginProps {
47
48
  * Leaving the `maxWidth` prop with no value will default the width to '100%'
48
49
  */
49
50
  maxWidth?: string;
50
- /** Prop for active search threshold. This must be a positive number */
51
- threshold?: number;
52
51
  /** Prop for `controlled` use */
53
52
  value?: string;
54
53
  /** Prop to specify the styling of the search component */
@@ -58,5 +57,9 @@ export interface SearchProps extends ValidationProps, MarginProps {
58
57
  /** Overrides the default tooltip position */
59
58
  tooltipPosition?: "top" | "bottom" | "left" | "right";
60
59
  }
61
- export declare const Search: React.ForwardRefExoticComponent<SearchProps & React.RefAttributes<HTMLInputElement>>;
60
+ export declare type SearchHandle = {
61
+ /** Programmatically focus on root container of Dialog. */
62
+ focus: () => void;
63
+ } | null;
64
+ export declare const Search: React.ForwardRefExoticComponent<SearchProps & React.RefAttributes<SearchHandle>>;
62
65
  export default Search;
@@ -1,16 +1,16 @@
1
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, { useState, useMemo, useEffect } from "react";
2
+ import React, { useState, useRef, useImperativeHandle } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import invariant from "invariant";
5
5
  import { filterStyledSystemMarginProps } from "../../style/utils";
6
6
  import tagComponent from "../../__internal__/utils/helpers/tags/tags";
7
7
  import StyledSearch from "./search.style";
8
- import StyledSearchButton, { StyledButtonIcon } from "./search-button.style";
8
+ import StyledSearchButton from "./search-button.style";
9
9
  import Icon from "../icon";
10
10
  import Textbox from "../textbox";
11
11
  import Button from "../button";
12
12
  import Logger from "../../__internal__/utils/logger";
13
- let deprecateInputRefWarnTriggered = false;
13
+ import useLocale from "../../hooks/__internal__/useLocale";
14
14
  let deprecateUncontrolledWarnTriggered = false;
15
15
  const Search = /*#__PURE__*/React.forwardRef(({
16
16
  defaultValue,
@@ -22,7 +22,6 @@ const Search = /*#__PURE__*/React.forwardRef(({
22
22
  value,
23
23
  id,
24
24
  name,
25
- threshold = 3,
26
25
  searchWidth,
27
26
  maxWidth,
28
27
  searchButton,
@@ -30,7 +29,6 @@ const Search = /*#__PURE__*/React.forwardRef(({
30
29
  placeholder,
31
30
  variant = "default",
32
31
  "aria-label": ariaLabel = "search",
33
- inputRef,
34
32
  tabIndex,
35
33
  error,
36
34
  warning,
@@ -40,33 +38,22 @@ const Search = /*#__PURE__*/React.forwardRef(({
40
38
  }, ref) => {
41
39
  const isControlled = value !== undefined;
42
40
  const initialValue = isControlled ? value : defaultValue;
43
- if (!deprecateInputRefWarnTriggered && inputRef) {
44
- deprecateInputRefWarnTriggered = true;
45
- Logger.deprecate("The `inputRef` prop in `Search` component is deprecated and will soon be removed. Please use `ref` instead.");
46
- }
41
+ const locale = useLocale();
42
+ const searchRef = useRef(null);
43
+ const inputRef = useRef(null);
44
+ useImperativeHandle(ref, () => ({
45
+ focus() {
46
+ inputRef.current?.focus();
47
+ }
48
+ }), []);
47
49
  if (!deprecateUncontrolledWarnTriggered && !isControlled) {
48
50
  deprecateUncontrolledWarnTriggered = true;
49
51
  Logger.deprecate("Uncontrolled behaviour in `Search` is deprecated and support will soon be removed. Please make sure all your inputs are controlled.");
50
52
  }
51
53
  !(typeof initialValue === "string") ? process.env.NODE_ENV !== "production" ? invariant(false, "This component has no initial value") : invariant(false) : void 0;
52
- !(threshold === undefined || typeof threshold === "number" && threshold > 0) ? process.env.NODE_ENV !== "production" ? invariant(false, "Threshold must be a positive number") : invariant(false) : void 0;
53
54
  const [searchValue, setSearchValue] = useState(initialValue);
54
55
  const [isFocused, setIsFocused] = useState(false);
55
- const [searchIsActive, setSearchIsActive] = useState(initialValue.length >= threshold);
56
- useEffect(() => {
57
- setSearchIsActive(!isControlled ? searchValue.length >= threshold : value.length >= threshold);
58
- }, [isControlled, searchValue, threshold, value]);
59
- const [iconType, iconTabIndex] = useMemo(() => {
60
- const isSearchValueEmpty = !isControlled ? searchValue.length === 0 : value.length === 0;
61
- const isFocusedOrActive = isFocused || searchIsActive || inputRef?.current === document.activeElement;
62
- if (!isSearchValueEmpty) {
63
- return ["cross", 0];
64
- }
65
- if (!isFocusedOrActive || threshold === 0 || !searchButton && isSearchValueEmpty) {
66
- return ["search", -1];
67
- }
68
- return [undefined, -1];
69
- }, [isControlled, searchValue, value, isFocused, searchIsActive, threshold, searchButton, inputRef]);
56
+ const isSearchValueEmpty = !isControlled ? searchValue.length === 0 : value.length === 0;
70
57
  let buttonProps = {};
71
58
  const handleChange = event => {
72
59
  if (onChange) {
@@ -110,12 +97,15 @@ const Search = /*#__PURE__*/React.forwardRef(({
110
97
  }
111
98
  });
112
99
  }
100
+ inputRef.current?.focus();
113
101
  };
114
102
  const handleMouseDown = event => {
115
103
  event.preventDefault();
116
104
  };
117
105
  const handleBlur = event => {
118
106
  setIsFocused(false);
107
+
108
+ /* istanbul ignore else */
119
109
  if (onBlur) {
120
110
  onBlur(event);
121
111
  }
@@ -128,14 +118,15 @@ const Search = /*#__PURE__*/React.forwardRef(({
128
118
  onKeyDown(event);
129
119
  }
130
120
  };
131
- const isSearchTyped = isFocused || (!isControlled ? !!searchValue.length : !!value.length);
121
+ const searchButtonText = typeof searchButton === "string" ? searchButton : locale.search.searchButtonText();
122
+ const searchHasValue = !isControlled ? !!searchValue?.length : !!value?.length;
132
123
  return /*#__PURE__*/React.createElement(StyledSearch, _extends({
124
+ ref: searchRef,
133
125
  isFocused: isFocused,
134
126
  searchWidth: searchWidth,
135
127
  maxWidth: maxWidth,
136
- searchIsActive: searchIsActive,
137
- searchHasValue: !isControlled ? !!searchValue?.length : !!value?.length,
138
- showSearchButton: searchButton,
128
+ searchHasValue: searchHasValue,
129
+ showSearchButton: !!searchButton,
139
130
  variant: variant,
140
131
  mb: 0
141
132
  }, filterStyledSystemMarginProps(rest), tagComponent("search", rest), {
@@ -144,8 +135,8 @@ const Search = /*#__PURE__*/React.forwardRef(({
144
135
  }, rest), /*#__PURE__*/React.createElement(Textbox, {
145
136
  placeholder: placeholder,
146
137
  value: !isControlled ? searchValue : value,
147
- inputIcon: iconType,
148
- iconTabIndex: iconTabIndex,
138
+ inputIcon: !isSearchValueEmpty ? "cross" : undefined,
139
+ iconTabIndex: !isSearchValueEmpty ? 0 : -1,
149
140
  iconOnClick: handleIconClick,
150
141
  iconOnMouseDown: handleMouseDown,
151
142
  "aria-label": ariaLabel,
@@ -153,30 +144,33 @@ const Search = /*#__PURE__*/React.forwardRef(({
153
144
  onBlur: handleBlur,
154
145
  onChange: handleChange,
155
146
  onKeyDown: handleKeyDown,
156
- ref: ref || inputRef,
147
+ ref: inputRef,
157
148
  tabIndex: tabIndex,
158
149
  error: error,
159
150
  warning: warning,
160
151
  info: info,
152
+ leftChildren: !searchButton ? /*#__PURE__*/React.createElement(Icon, {
153
+ type: "search",
154
+ ml: 1
155
+ }) : undefined,
161
156
  tooltipPosition: tooltipPosition
162
- }), searchButton && /*#__PURE__*/React.createElement(StyledSearchButton, null, isSearchTyped && /*#__PURE__*/React.createElement(Button, _extends({
157
+ }), searchButton && /*#__PURE__*/React.createElement(StyledSearchButton, null, /*#__PURE__*/React.createElement(Button, _extends({
163
158
  "aria-label": searchButtonAriaLabel,
164
159
  size: "medium",
165
- px: "16px"
166
- }, buttonProps), /*#__PURE__*/React.createElement(StyledButtonIcon, null, /*#__PURE__*/React.createElement(Icon, {
167
- type: "search"
168
- })))));
160
+ px: 2,
161
+ buttonType: "primary",
162
+ iconPosition: "before",
163
+ iconType: "search"
164
+ }, buttonProps), searchButtonText)));
169
165
  });
170
166
  if (process.env.NODE_ENV !== "production") {
171
167
  Search.propTypes = {
172
168
  "aria-label": PropTypes.string,
169
+ "children": PropTypes.node,
173
170
  "defaultValue": PropTypes.string,
174
171
  "error": PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
175
172
  "id": PropTypes.string,
176
173
  "info": PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
177
- "inputRef": PropTypes.shape({
178
- "current": PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.object]).isRequired
179
- }),
180
174
  "m": PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.number, PropTypes.shape({
181
175
  "__@toStringTag": PropTypes.string.isRequired,
182
176
  "description": PropTypes.string,
@@ -339,11 +333,10 @@ if (process.env.NODE_ENV !== "production") {
339
333
  "onFocus": PropTypes.func,
340
334
  "onKeyDown": PropTypes.func,
341
335
  "placeholder": PropTypes.string,
342
- "searchButton": PropTypes.bool,
336
+ "searchButton": PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
343
337
  "searchButtonAriaLabel": PropTypes.string,
344
338
  "searchWidth": PropTypes.string,
345
339
  "tabIndex": PropTypes.number,
346
- "threshold": PropTypes.number,
347
340
  "tooltipPosition": PropTypes.oneOf(["bottom", "left", "right", "top"]),
348
341
  "value": PropTypes.string,
349
342
  "variant": PropTypes.oneOf(["dark", "default"]),
@@ -2,7 +2,6 @@ interface StyledSearchProps {
2
2
  name?: string;
3
3
  isFocused?: boolean;
4
4
  searchHasValue?: boolean;
5
- searchIsActive?: boolean;
6
5
  searchWidth?: string;
7
6
  maxWidth?: string;
8
7
  showSearchButton?: boolean;