@jetbrains/ring-ui 5.0.162 → 5.0.164

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.
@@ -1,8 +1,8 @@
1
1
  import Listeners, { Handler } from '../global/listeners';
2
2
  import HTTP, { HTTPAuth, RequestParams } from '../http/http';
3
3
  import AuthDialogService from '../auth-dialog-service/auth-dialog-service';
4
- import AuthStorage from './storage';
5
- import { AuthError } from './response-parser';
4
+ import AuthStorage, { AuthState } from './storage';
5
+ import { AuthError, AuthResponse } from './response-parser';
6
6
  import AuthRequestBuilder from './request-builder';
7
7
  import BackgroundFlow from './background-flow';
8
8
  import TokenValidator, { TokenValidationError, TokenValidatorConfig } from './token-validator';
@@ -197,6 +197,7 @@ export default class Auth implements HTTPAuth {
197
197
  */
198
198
  login(): Promise<void>;
199
199
  switchUser(): Promise<void>;
200
+ _makeStateFromResponse(authResponse: AuthResponse): AuthState;
200
201
  /**
201
202
  * Check if the hash contains an access token.
202
203
  * If it does, extract the state, compare with
@@ -691,6 +691,27 @@ export default class Auth {
691
691
  }
692
692
  await this._runEmbeddedLogin();
693
693
  }
694
+ _makeStateFromResponse(authResponse) {
695
+ const { state } = authResponse;
696
+ if (!state) {
697
+ return {};
698
+ }
699
+ const { scope: defaultScope } = this.config;
700
+ try {
701
+ const urlFromState = new URL(state); // checking if state contains valid URL on same origin, see HUB-11514
702
+ if (urlFromState.origin !== window.location.origin) {
703
+ return {};
704
+ }
705
+ return {
706
+ restoreLocation: state,
707
+ created: Date.now(),
708
+ scopes: defaultScope
709
+ };
710
+ }
711
+ catch (e) {
712
+ return {};
713
+ }
714
+ }
694
715
  /**
695
716
  * Check if the hash contains an access token.
696
717
  * If it does, extract the state, compare with
@@ -710,7 +731,8 @@ export default class Auth {
710
731
  return undefined;
711
732
  }
712
733
  const { state: stateId, scope, expiresIn, accessToken } = authResponse;
713
- const newState = await (stateId && this._storage?.getState(stateId)) || {};
734
+ const newState = await (stateId && this._storage?.getState(stateId)) ||
735
+ this._makeStateFromResponse(authResponse);
714
736
  const scopes = scope ? scope.split(' ') : newState.scopes || defaultScope || [];
715
737
  const effectiveExpiresIn = expiresIn ? parseInt(expiresIn, 10) : defaultExpiresIn;
716
738
  const expires = TokenValidator._epoch() + effectiveExpiresIn;
@@ -1,4 +1,4 @@
1
- import React, { ButtonHTMLAttributes, Component, CSSProperties, HTMLAttributes, ReactNode, Ref, RefCallback, SyntheticEvent } from 'react';
1
+ import React, { ButtonHTMLAttributes, Component, ComponentType, CSSProperties, HTMLAttributes, ReactNode, Ref, RefCallback, SyntheticEvent } from 'react';
2
2
  import { SelectHandlerParams } from '../list/list';
3
3
  import { Size } from '../input/input';
4
4
  import { LabelType } from '../control-label/control-label';
@@ -52,7 +52,8 @@ export type CustomAnchor = ((props: CustomAnchorProps) => ReactNode);
52
52
  export interface BaseSelectProps<T = unknown> {
53
53
  data: readonly SelectItem<T>[];
54
54
  filter: boolean | Filter<T>;
55
- filterRef: Ref<HTMLInputElement>;
55
+ filterIcon?: string | ComponentType | null | undefined;
56
+ filterRef?: Ref<HTMLInputElement>;
56
57
  clear: boolean;
57
58
  loading: boolean;
58
59
  disabled: boolean;
@@ -158,6 +159,7 @@ export default class Select<T = unknown> extends Component<SelectProps<T>, Selec
158
159
  static defaultProps: {
159
160
  data: never[];
160
161
  filter: boolean;
162
+ filterIcon: null;
161
163
  filterRef: typeof noop;
162
164
  multiple: boolean;
163
165
  clear: boolean;
@@ -182,6 +182,7 @@ export default class Select extends Component {
182
182
  static defaultProps = {
183
183
  data: [],
184
184
  filter: false,
185
+ filterIcon: null,
185
186
  filterRef: noop,
186
187
  multiple: false,
187
188
  clear: false,
@@ -437,7 +438,7 @@ export default class Select extends Component {
437
438
  message = this.props.notFoundMessage ?? translate('noOptionsFound');
438
439
  }
439
440
  return (<SelectPopup data={_shownData} message={message} toolbar={showPopup && this.getToolbar()} topbar={this.getTopbar()} loading={this.props.loading} activeIndex={this.state.selectedIndex} hidden={!showPopup} ref={this.popupRef} maxHeight={this.props.maxHeight} minWidth={this.props.minWidth} directions={this.props.directions} className={this.props.popupClassName} style={this.props.popupStyle} top={this.props.top} left={this.props.left} filter={this.isInputMode() ? false : this.props.filter} // disable popup filter in INPUT mode
440
- filterRef={this.props.filterRef} multiple={this.props.multiple} filterValue={this.state.filterValue} anchorElement={anchorElement} onCloseAttempt={this._onCloseAttempt} onOutsideClick={this.props.onOutsideClick} onSelect={this._listSelectHandler} onSelectAll={this._listSelectAllHandler} onFilter={this._filterChangeHandler} onClear={this.clearFilter} onLoadMore={this.props.onLoadMore} isInputMode={this.isInputMode()} selected={this.state.selected} tags={this.props.tags} compact={this.props.compact} renderOptimization={this.props.renderOptimization} ringPopupTarget={this.props.ringPopupTarget} disableMoveOverflow={this.props.disableMoveOverflow} disableScrollToActive={this.props.disableScrollToActive} dir={this.props.dir} onEmptyPopupEnter={this.onEmptyPopupEnter} listId={this.listId}/>);
441
+ filterIcon={this.props.filterIcon} filterRef={this.props.filterRef} multiple={this.props.multiple} filterValue={this.state.filterValue} anchorElement={anchorElement} onCloseAttempt={this._onCloseAttempt} onOutsideClick={this.props.onOutsideClick} onSelect={this._listSelectHandler} onSelectAll={this._listSelectAllHandler} onFilter={this._filterChangeHandler} onClear={this.clearFilter} onLoadMore={this.props.onLoadMore} isInputMode={this.isInputMode()} selected={this.state.selected} tags={this.props.tags} compact={this.props.compact} renderOptimization={this.props.renderOptimization} ringPopupTarget={this.props.ringPopupTarget} disableMoveOverflow={this.props.disableMoveOverflow} disableScrollToActive={this.props.disableScrollToActive} dir={this.props.dir} onEmptyPopupEnter={this.onEmptyPopupEnter} listId={this.listId}/>);
441
442
  }}
442
443
  </I18nContext.Consumer>);
443
444
  }
@@ -819,7 +820,7 @@ export default class Select extends Component {
819
820
  ...this.getShortcutsMap(),
820
821
  ...this._popup?.list?.shortcutsMap
821
822
  })
822
- : undefined} afterInput={this.props.type === Type.INPUT && iconsNode}/>
823
+ : undefined} icon={this.props.filterIcon} afterInput={this.props.type === Type.INPUT && iconsNode}/>
823
824
  {this._renderPopup()}
824
825
  </div>
825
826
  {this.props.error && (<div className={classNames(inputStyles.errorText, inputStyles[`size${this.props.size}`])}>
@@ -891,6 +892,7 @@ Select.propTypes = {
891
892
  multiple: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
892
893
  allowAny: PropTypes.bool,
893
894
  filter: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
895
+ filterIcon: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]),
894
896
  filterRef: PropTypes.oneOfType([
895
897
  PropTypes.func,
896
898
  refObject(PropTypes.instanceOf(HTMLInputElement))
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @description Displays a popup with select's options.
3
3
  */
4
- import React, { CSSProperties, PureComponent, ReactNode, Ref, SyntheticEvent } from 'react';
4
+ import React, { ComponentType, CSSProperties, PureComponent, ReactNode, Ref, SyntheticEvent } from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { IconType } from '../icon/icon';
7
7
  import Popup from '../popup/popup';
@@ -43,6 +43,7 @@ export interface SelectPopupProps<T = unknown> {
43
43
  toolbar: ReactNode;
44
44
  topbar: ReactNode;
45
45
  filter: boolean | Filter<T>;
46
+ filterIcon?: string | ComponentType | null | undefined;
46
47
  filterRef?: Ref<HTMLInputElement>;
47
48
  message: string | null;
48
49
  anchorElement: HTMLElement | null;
@@ -38,6 +38,7 @@ export default class SelectPopup extends PureComponent {
38
38
  toolbar: null,
39
39
  topbar: null,
40
40
  filter: false,
41
+ filterIcon: null,
41
42
  filterRef: noop,
42
43
  multiple: false,
43
44
  message: null,
@@ -183,7 +184,7 @@ export default class SelectPopup extends PureComponent {
183
184
  getFilter() {
184
185
  if (this.props.filter || this.props.tags) {
185
186
  return (<div className={styles.filterWrapper} data-test="ring-select-popup-filter">
186
- {!this.props.tags && (<Icon glyph={searchIcon} className={styles.filterIcon} data-test-custom="ring-select-popup-filter-icon"/>)}
187
+ {!this.props.tags && (<Icon glyph={this.props.filterIcon ?? searchIcon} className={styles.filterIcon} data-test-custom="ring-select-popup-filter-icon"/>)}
187
188
  <FilterWithShortcuts rgShortcutsOptions={this.state.popupFilterShortcutsOptions} rgShortcutsMap={this.popupFilterShortcutsMap} value={this.props.filterValue} inputRef={composeRefs(this.filterRef, this.props.filterRef)} onBlur={this.popupFilterOnBlur} onFocus={this.onFilterFocus} className="ring-js-shortcuts" inputClassName={classNames({ [styles.filterWithTagsInput]: this.props.tags })} placeholder={typeof this.props.filter === 'object'
188
189
  ? this.props.filter.placeholder
189
190
  : undefined} height={this.props.tags ? ControlsHeight.S : ControlsHeight.L} onChange={this.props.onFilter} onClick={this.onClickHandler} onClear={this.props.tags ? undefined : this.props.onClear} data-test-custom="ring-select-popup-filter-input" listId={this.props.listId} enableShortcuts={Object.keys(this.popupFilterShortcutsMap)}/>
@@ -367,6 +368,7 @@ SelectPopup.propTypes = {
367
368
  placeholder: PropTypes.string
368
369
  })]),
369
370
  filterValue: PropTypes.string,
371
+ filterIcon: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]),
370
372
  filterRef: PropTypes.oneOfType([
371
373
  PropTypes.func,
372
374
  refObject(PropTypes.instanceOf(HTMLInputElement))
@@ -79,8 +79,6 @@
79
79
  padding-top: unit;
80
80
  padding-bottom: 6px;
81
81
 
82
- text-transform: capitalize;
83
-
84
82
  color: var(--ring-text-color);
85
83
  border-bottom: none;
86
84
 
@@ -152,7 +152,10 @@ function _regeneratorRuntime() {
152
152
  if ("executing" === state) throw new Error("Generator is already running");
153
153
  if ("completed" === state) {
154
154
  if ("throw" === method) throw arg;
155
- return doneResult();
155
+ return {
156
+ value: void 0,
157
+ done: !0
158
+ };
156
159
  }
157
160
  for (context.method = method, context.arg = arg;;) {
158
161
  var delegate = context.delegate;
@@ -205,7 +208,7 @@ function _regeneratorRuntime() {
205
208
  }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
206
209
  }
207
210
  function values(iterable) {
208
- if (iterable) {
211
+ if (iterable || "" === iterable) {
209
212
  var iteratorMethod = iterable[iteratorSymbol];
210
213
  if (iteratorMethod) return iteratorMethod.call(iterable);
211
214
  if ("function" == typeof iterable.next) return iterable;
@@ -218,15 +221,7 @@ function _regeneratorRuntime() {
218
221
  return next.next = next;
219
222
  }
220
223
  }
221
- return {
222
- next: doneResult
223
- };
224
- }
225
- function doneResult() {
226
- return {
227
- value: undefined,
228
- done: !0
229
- };
224
+ throw new TypeError(typeof iterable + " is not iterable");
230
225
  }
231
226
  return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", {
232
227
  value: GeneratorFunctionPrototype,
package/dist/auth/auth.js CHANGED
@@ -80,6 +80,8 @@ import '../link/link.js';
80
80
  import '../_helpers/link.js';
81
81
  import '../group/group.js';
82
82
  import '../_helpers/group.js';
83
+ import 'core-js/modules/web.url.js';
84
+ import 'core-js/modules/web.url-search-params.js';
83
85
  import 'core-js/modules/es.parse-int.js';
84
86
  import 'core-js/modules/es.string.search.js';
85
87
  import '../global/listeners.js';
@@ -1,8 +1,8 @@
1
1
  import Listeners, { Handler } from '../global/listeners';
2
2
  import HTTP, { HTTPAuth, RequestParams } from '../http/http';
3
3
  import AuthDialogService from '../auth-dialog-service/auth-dialog-service';
4
- import AuthStorage from './storage';
5
- import { AuthError } from './response-parser';
4
+ import AuthStorage, { AuthState } from './storage';
5
+ import { AuthError, AuthResponse } from './response-parser';
6
6
  import AuthRequestBuilder from './request-builder';
7
7
  import BackgroundFlow from './background-flow';
8
8
  import TokenValidator, { TokenValidationError, TokenValidatorConfig } from './token-validator';
@@ -197,6 +197,7 @@ export default class Auth implements HTTPAuth {
197
197
  */
198
198
  login(): Promise<void>;
199
199
  switchUser(): Promise<void>;
200
+ _makeStateFromResponse(authResponse: AuthResponse): AuthState;
200
201
  /**
201
202
  * Check if the hash contains an access token.
202
203
  * If it does, extract the state, compare with
@@ -12,6 +12,8 @@ import 'core-js/modules/es.string.includes.js';
12
12
  import 'core-js/modules/es.regexp.exec.js';
13
13
  import 'core-js/modules/es.string.replace.js';
14
14
  import 'core-js/modules/es.regexp.to-string.js';
15
+ import 'core-js/modules/web.url.js';
16
+ import 'core-js/modules/web.url-search-params.js';
15
17
  import 'core-js/modules/es.parse-int.js';
16
18
  import 'core-js/modules/es.string.search.js';
17
19
  import { getAbsoluteBaseURL, fixUrl } from '../global/url.js';
@@ -1398,6 +1400,28 @@ var Auth = /*#__PURE__*/function () {
1398
1400
  }
1399
1401
  return switchUser;
1400
1402
  }()
1403
+ }, {
1404
+ key: "_makeStateFromResponse",
1405
+ value: function _makeStateFromResponse(authResponse) {
1406
+ var state = authResponse.state;
1407
+ if (!state) {
1408
+ return {};
1409
+ }
1410
+ var defaultScope = this.config.scope;
1411
+ try {
1412
+ var urlFromState = new URL(state); // checking if state contains valid URL on same origin, see HUB-11514
1413
+ if (urlFromState.origin !== window.location.origin) {
1414
+ return {};
1415
+ }
1416
+ return {
1417
+ restoreLocation: state,
1418
+ created: Date.now(),
1419
+ scopes: defaultScope
1420
+ };
1421
+ } catch (e) {
1422
+ return {};
1423
+ }
1424
+ }
1401
1425
  /**
1402
1426
  * Check if the hash contains an access token.
1403
1427
  * If it does, extract the state, compare with
@@ -1436,7 +1460,7 @@ var Auth = /*#__PURE__*/function () {
1436
1460
  _context20.next = 11;
1437
1461
  break;
1438
1462
  }
1439
- _context20.t0 = {};
1463
+ _context20.t0 = this._makeStateFromResponse(authResponse);
1440
1464
  case 11:
1441
1465
  newState = _context20.t0;
1442
1466
  scopes = scope ? scope.split(' ') : newState.scopes || defaultScope || [];
@@ -85,6 +85,8 @@ import '../link/link.js';
85
85
  import '../_helpers/link.js';
86
86
  import '../group/group.js';
87
87
  import '../_helpers/group.js';
88
+ import 'core-js/modules/web.url.js';
89
+ import 'core-js/modules/web.url-search-params.js';
88
90
  import 'core-js/modules/es.string.search.js';
89
91
  import '../global/listeners.js';
90
92
  import '../global/promise-with-timeout.js';
@@ -81,6 +81,8 @@ import '../link/link.js';
81
81
  import '../_helpers/link.js';
82
82
  import '../group/group.js';
83
83
  import '../_helpers/group.js';
84
+ import 'core-js/modules/web.url.js';
85
+ import 'core-js/modules/web.url-search-params.js';
84
86
  import 'core-js/modules/es.parse-int.js';
85
87
  import 'core-js/modules/es.string.search.js';
86
88
  import '../global/listeners.js';
@@ -125,6 +125,8 @@ import '../alert/container.js';
125
125
  import '../group/group.js';
126
126
  import '../_helpers/group.js';
127
127
  import '../auth/auth__core.js';
128
+ import 'core-js/modules/web.url.js';
129
+ import 'core-js/modules/web.url-search-params.js';
128
130
  import 'core-js/modules/es.parse-int.js';
129
131
  import 'core-js/modules/es.string.search.js';
130
132
  import '../global/listeners.js';
@@ -81,6 +81,8 @@ import '../_helpers/link.js';
81
81
  import '../group/group.js';
82
82
  import '../_helpers/group.js';
83
83
  import '../global/react-render-adapter.js';
84
+ import 'core-js/modules/web.url.js';
85
+ import 'core-js/modules/web.url-search-params.js';
84
86
  import 'core-js/modules/es.parse-int.js';
85
87
  import 'core-js/modules/es.string.search.js';
86
88
  import '../global/listeners.js';
@@ -82,6 +82,8 @@ import '../link/link.js';
82
82
  import '../_helpers/link.js';
83
83
  import '../group/group.js';
84
84
  import '../_helpers/group.js';
85
+ import 'core-js/modules/web.url.js';
86
+ import 'core-js/modules/web.url-search-params.js';
85
87
  import 'core-js/modules/es.parse-int.js';
86
88
  import 'core-js/modules/es.string.search.js';
87
89
  import '../global/listeners.js';
@@ -12,11 +12,11 @@ var MAJOR_VERSION_INDEX = 0;
12
12
  /**
13
13
  * SUPPORTED_BROWSERS are defined by Babel plugin, see babel config
14
14
  */
15
- if (!["and_chr 114", "and_uc 15.5", "chrome 114", "chrome 113", "chrome 109", "edge 114", "firefox 114", "ios_saf 16.5", "ios_saf 16.4", "ios_saf 16.3", "ios_saf 16.1", "opera 99", "safari 16.5", "samsung 21"]) {
15
+ if (!["and_chr 115", "and_uc 15.5", "chrome 114", "chrome 113", "chrome 109", "edge 114", "firefox 114", "ios_saf 16.5", "ios_saf 16.4", "ios_saf 16.3", "ios_saf 16.1", "opera 99", "safari 16.5", "samsung 21"]) {
16
16
  // eslint-disable-next-line no-console
17
17
  console.warn('Ring UI: no SUPPORTED_BROWSERS passed. Please check babel config.');
18
18
  }
19
- var SUPPORTED = ["and_chr 114", "and_uc 15.5", "chrome 114", "chrome 113", "chrome 109", "edge 114", "firefox 114", "ios_saf 16.5", "ios_saf 16.4", "ios_saf 16.3", "ios_saf 16.1", "opera 99", "safari 16.5", "samsung 21"] || [];
19
+ var SUPPORTED = ["and_chr 115", "and_uc 15.5", "chrome 114", "chrome 113", "chrome 109", "edge 114", "firefox 114", "ios_saf 16.5", "ios_saf 16.4", "ios_saf 16.3", "ios_saf 16.1", "opera 99", "safari 16.5", "samsung 21"] || [];
20
20
  var WHITE_LISTED_BROWSERS = ['chrome', 'firefox', 'safari', 'edge'];
21
21
  var WHITE_LIST = SUPPORTED.reduce(function (acc, item) {
22
22
  var _item$match;
@@ -84,6 +84,8 @@ import '../_helpers/link.js';
84
84
  import '../group/group.js';
85
85
  import '../_helpers/group.js';
86
86
  import '../auth/auth__core.js';
87
+ import 'core-js/modules/web.url.js';
88
+ import 'core-js/modules/web.url-search-params.js';
87
89
  import 'core-js/modules/es.parse-int.js';
88
90
  import 'core-js/modules/es.string.search.js';
89
91
  import '../global/listeners.js';
@@ -1,4 +1,4 @@
1
- import React, { ButtonHTMLAttributes, Component, CSSProperties, HTMLAttributes, ReactNode, Ref, RefCallback, SyntheticEvent } from 'react';
1
+ import React, { ButtonHTMLAttributes, Component, ComponentType, CSSProperties, HTMLAttributes, ReactNode, Ref, RefCallback, SyntheticEvent } from 'react';
2
2
  import { SelectHandlerParams } from '../list/list';
3
3
  import { Size } from '../input/input';
4
4
  import { LabelType } from '../control-label/control-label';
@@ -52,7 +52,8 @@ export type CustomAnchor = ((props: CustomAnchorProps) => ReactNode);
52
52
  export interface BaseSelectProps<T = unknown> {
53
53
  data: readonly SelectItem<T>[];
54
54
  filter: boolean | Filter<T>;
55
- filterRef: Ref<HTMLInputElement>;
55
+ filterIcon?: string | ComponentType | null | undefined;
56
+ filterRef?: Ref<HTMLInputElement>;
56
57
  clear: boolean;
57
58
  loading: boolean;
58
59
  disabled: boolean;
@@ -158,6 +159,7 @@ export default class Select<T = unknown> extends Component<SelectProps<T>, Selec
158
159
  static defaultProps: {
159
160
  data: never[];
160
161
  filter: boolean;
162
+ filterIcon: null;
161
163
  filterRef: typeof noop;
162
164
  multiple: boolean;
163
165
  clear: boolean;
@@ -735,6 +735,7 @@ var Select = /*#__PURE__*/function (_Component) {
735
735
  left: _this3.props.left,
736
736
  filter: _this3.isInputMode() ? false : _this3.props.filter // disable popup filter in INPUT mode
737
737
  ,
738
+ filterIcon: _this3.props.filterIcon,
738
739
  filterRef: _this3.props.filterRef,
739
740
  multiple: _this3.props.multiple,
740
741
  filterValue: _this3.state.filterValue,
@@ -1028,6 +1029,7 @@ var Select = /*#__PURE__*/function (_Component) {
1028
1029
  onKeyDown: this.props.onKeyDown,
1029
1030
  "data-test": "ring-select__focus",
1030
1031
  enableShortcuts: shortcutsEnabled ? Object.keys(_objectSpread2(_objectSpread2({}, this.getShortcutsMap()), (_this$_popup5 = this._popup) === null || _this$_popup5 === void 0 || (_this$_popup5 = _this$_popup5.list) === null || _this$_popup5 === void 0 ? void 0 : _this$_popup5.shortcutsMap)) : undefined,
1032
+ icon: this.props.filterIcon,
1031
1033
  afterInput: this.props.type === Type.INPUT && iconsNode
1032
1034
  })), this._renderPopup()), this.props.error && /*#__PURE__*/React.createElement("div", {
1033
1035
  className: classNames(modules_88cfaf40.errorText, modules_88cfaf40["size".concat(this.props.size)])
@@ -1175,6 +1177,7 @@ var Select = /*#__PURE__*/function (_Component) {
1175
1177
  _defineProperty(Select, "defaultProps", {
1176
1178
  data: [],
1177
1179
  filter: false,
1180
+ filterIcon: null,
1178
1181
  filterRef: noop,
1179
1182
  multiple: false,
1180
1183
  clear: false,
@@ -1224,6 +1227,7 @@ Select.propTypes = {
1224
1227
  multiple: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
1225
1228
  allowAny: PropTypes.bool,
1226
1229
  filter: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
1230
+ filterIcon: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]),
1227
1231
  filterRef: PropTypes.oneOfType([PropTypes.func, refObject(PropTypes.instanceOf(HTMLInputElement))]),
1228
1232
  getInitial: PropTypes.func,
1229
1233
  onClose: PropTypes.func,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @description Displays a popup with select's options.
3
3
  */
4
- import React, { CSSProperties, PureComponent, ReactNode, Ref, SyntheticEvent } from 'react';
4
+ import React, { ComponentType, CSSProperties, PureComponent, ReactNode, Ref, SyntheticEvent } from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { IconType } from '../icon/icon';
7
7
  import Popup from '../popup/popup';
@@ -43,6 +43,7 @@ export interface SelectPopupProps<T = unknown> {
43
43
  toolbar: ReactNode;
44
44
  topbar: ReactNode;
45
45
  filter: boolean | Filter<T>;
46
+ filterIcon?: string | ComponentType | null | undefined;
46
47
  filterRef?: Ref<HTMLInputElement>;
47
48
  message: string | null;
48
49
  anchorElement: HTMLElement | null;
@@ -388,11 +388,12 @@ var SelectPopup = /*#__PURE__*/function (_PureComponent) {
388
388
  key: "getFilter",
389
389
  value: function getFilter() {
390
390
  if (this.props.filter || this.props.tags) {
391
+ var _this$props$filterIco;
391
392
  return /*#__PURE__*/React.createElement("div", {
392
393
  className: modules_b607bec2.filterWrapper,
393
394
  "data-test": "ring-select-popup-filter"
394
395
  }, !this.props.tags && /*#__PURE__*/React.createElement(Icon, {
395
- glyph: searchIcon,
396
+ glyph: (_this$props$filterIco = this.props.filterIcon) !== null && _this$props$filterIco !== void 0 ? _this$props$filterIco : searchIcon,
396
397
  className: modules_b607bec2.filterIcon,
397
398
  "data-test-custom": "ring-select-popup-filter-icon"
398
399
  }), /*#__PURE__*/React.createElement(FilterWithShortcuts, {
@@ -558,6 +559,7 @@ _defineProperty(SelectPopup, "defaultProps", {
558
559
  toolbar: null,
559
560
  topbar: null,
560
561
  filter: false,
562
+ filterIcon: null,
561
563
  filterRef: noop,
562
564
  multiple: false,
563
565
  message: null,
@@ -593,6 +595,7 @@ SelectPopup.propTypes = {
593
595
  placeholder: PropTypes.string
594
596
  })]),
595
597
  filterValue: PropTypes.string,
598
+ filterIcon: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]),
596
599
  filterRef: PropTypes.oneOfType([PropTypes.func, refObject(PropTypes.instanceOf(HTMLInputElement))]),
597
600
  hidden: PropTypes.bool,
598
601
  isInputMode: PropTypes.bool,