@jetbrains/ring-ui-built 7.0.66 → 7.0.70

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 (231) hide show
  1. package/components/_helpers/anchor.js +12 -17
  2. package/components/_helpers/avatar-info.js +4 -5
  3. package/components/_helpers/button.classes.js +20 -21
  4. package/components/_helpers/caption.js +3 -3
  5. package/components/_helpers/card.js +26 -32
  6. package/components/_helpers/dialog-body-scroll-preventer.js +1 -2
  7. package/components/_helpers/icon-svg.js +9 -12
  8. package/components/_helpers/input.js +78 -86
  9. package/components/_helpers/loader-core.js +260 -0
  10. package/components/_helpers/query-assist-suggestions.js +0 -1
  11. package/components/_helpers/select-filter.js +19 -26
  12. package/components/_helpers/services-link.js +9 -12
  13. package/components/_helpers/sidebar.js +36 -44
  14. package/components/_helpers/tab-link.js +9 -11
  15. package/components/_helpers/theme.js +20 -24
  16. package/components/_helpers/title.js +12 -17
  17. package/components/alert/alert.js +41 -49
  18. package/components/alert/container.js +9 -12
  19. package/components/alert-service/alert-service.js +23 -32
  20. package/components/analytics/analytics-custom-plugin.js +12 -17
  21. package/components/analytics/analytics.js +1 -3
  22. package/components/auth/auth-core.js +128 -170
  23. package/components/auth/auth.js +3 -10
  24. package/components/auth/background-flow.js +5 -8
  25. package/components/auth/down-notification.js +9 -17
  26. package/components/auth/iframe-flow.js +13 -19
  27. package/components/auth/request-builder.js +4 -9
  28. package/components/auth/response-parser.js +9 -12
  29. package/components/auth/storage.js +12 -18
  30. package/components/auth/token-validator.js +19 -30
  31. package/components/auth/window-flow.js +22 -27
  32. package/components/auth-dialog/auth-dialog.js +40 -48
  33. package/components/auth-dialog-service/auth-dialog-service.js +10 -13
  34. package/components/avatar/avatar.figma.js +6 -6
  35. package/components/avatar/avatar.js +58 -59
  36. package/components/avatar/fallback-avatar.js +8 -11
  37. package/components/avatar-stack/avatar-stack.figma.js +10 -11
  38. package/components/avatar-stack/avatar-stack.js +25 -31
  39. package/components/banner/banner.js +0 -6
  40. package/components/breadcrumbs/breadcrumbs.figma.js +8 -6
  41. package/components/breadcrumbs/breadcrumbs.js +4 -5
  42. package/components/button/button.figma.js +15 -10
  43. package/components/button/button.js +59 -64
  44. package/components/button-group/button-group.js +11 -15
  45. package/components/button-group/caption.js +0 -1
  46. package/components/button-set/button-set.js +9 -12
  47. package/components/button-toolbar/button-toolbar.js +8 -11
  48. package/components/caret/caret.js +20 -28
  49. package/components/checkbox/checkbox-group.figma.js +8 -10
  50. package/components/checkbox/checkbox.figma.js +5 -5
  51. package/components/checkbox/checkbox.js +27 -35
  52. package/components/clipboard/clipboard-fallback.js +3 -3
  53. package/components/clipboard/clipboard.js +3 -16
  54. package/components/code/code.js +8 -14
  55. package/components/collapse/collapse-content.js +10 -15
  56. package/components/collapse/collapse-control.js +5 -7
  57. package/components/collapse/collapse.js +9 -11
  58. package/components/collapse/utils.js +1 -1
  59. package/components/confirm/confirm.js +17 -26
  60. package/components/confirm-service/confirm-service.js +30 -31
  61. package/components/content-layout/content-layout.js +21 -28
  62. package/components/content-layout/sidebar.js +0 -2
  63. package/components/contenteditable/contenteditable.js +23 -28
  64. package/components/control-help/control-help.js +8 -10
  65. package/components/control-label/control-label.js +12 -17
  66. package/components/data-list/data-list.js +57 -65
  67. package/components/data-list/data-list.mock.js +0 -4
  68. package/components/data-list/item.js +65 -72
  69. package/components/data-list/selection.js +11 -19
  70. package/components/data-list/title.js +0 -4
  71. package/components/date-picker/consts.js +3 -4
  72. package/components/date-picker/date-input.js +25 -33
  73. package/components/date-picker/date-picker.js +179 -193
  74. package/components/date-picker/date-popup.js +135 -127
  75. package/components/date-picker/day.d.ts +1 -1
  76. package/components/date-picker/day.js +24 -30
  77. package/components/date-picker/month-names.js +7 -12
  78. package/components/date-picker/month-slider.js +16 -22
  79. package/components/date-picker/month.js +3 -5
  80. package/components/date-picker/months.js +6 -6
  81. package/components/date-picker/weekdays.js +0 -1
  82. package/components/date-picker/years.js +20 -26
  83. package/components/dialog/dialog-body-scroll-preventer.js +0 -1
  84. package/components/dialog/dialog.js +73 -83
  85. package/components/dropdown/anchor.js +0 -4
  86. package/components/dropdown/dropdown.js +98 -114
  87. package/components/dropdown-menu/dropdown-menu.js +80 -79
  88. package/components/editable-heading/editable-heading.js +48 -54
  89. package/components/error-bubble/error-bubble.figma.js +4 -4
  90. package/components/error-bubble/error-bubble.js +9 -13
  91. package/components/error-message/error-message.js +1 -6
  92. package/components/footer/footer.js +11 -15
  93. package/components/global/compose-refs.js +1 -4
  94. package/components/global/compose.js +1 -4
  95. package/components/global/configuration.js +3 -3
  96. package/components/global/controls-height.js +0 -1
  97. package/components/global/create-stateful-context.js +10 -14
  98. package/components/global/data-tests.js +2 -10
  99. package/components/global/dom.js +6 -19
  100. package/components/global/focus-sensor-hoc.js +74 -87
  101. package/components/global/fuzzy-highlight.js +3 -8
  102. package/components/global/get-uid.js +1 -1
  103. package/components/global/inject-styles.js +5 -6
  104. package/components/global/listeners.js +2 -11
  105. package/components/global/memoize.js +0 -2
  106. package/components/global/normalize-indent.js +2 -6
  107. package/components/global/promise-with-timeout.js +4 -5
  108. package/components/global/react-dom-renderer.js +4 -9
  109. package/components/global/rerender-hoc.js +8 -11
  110. package/components/global/schedule-raf.js +1 -2
  111. package/components/global/theme.js +0 -5
  112. package/components/global/trivial-template-tag.js +1 -6
  113. package/components/global/url.js +2 -6
  114. package/components/global/use-event-callback.js +2 -3
  115. package/components/grid/col.js +7 -18
  116. package/components/grid/grid.js +9 -14
  117. package/components/grid/row.js +7 -11
  118. package/components/group/group.js +9 -12
  119. package/components/header/header-icon.js +8 -13
  120. package/components/header/header.js +16 -27
  121. package/components/header/links.js +7 -10
  122. package/components/header/logo.js +12 -16
  123. package/components/header/profile.js +73 -83
  124. package/components/header/services-link.js +0 -2
  125. package/components/header/services.js +32 -43
  126. package/components/header/smart-profile.js +44 -59
  127. package/components/header/smart-services.js +33 -45
  128. package/components/header/tray.js +8 -10
  129. package/components/heading/heading.js +27 -27
  130. package/components/http/http.js +120 -125
  131. package/components/http/http.mock.js +6 -10
  132. package/components/hub-source/hub-source-user.js +6 -13
  133. package/components/hub-source/hub-source-users-groups.js +8 -12
  134. package/components/hub-source/hub-source.js +8 -10
  135. package/components/i18n/i18n-context.js +4 -7
  136. package/components/i18n/i18n.js +5 -5
  137. package/components/icon/icon-svg.js +0 -4
  138. package/components/icon/icon.js +28 -32
  139. package/components/icon/index.js +0 -4
  140. package/components/input/input.figma.js +8 -8
  141. package/components/input/input.js +0 -4
  142. package/components/island/adaptive-island-hoc.js +19 -23
  143. package/components/island/content.js +70 -75
  144. package/components/island/header.js +21 -21
  145. package/components/island/island.js +11 -14
  146. package/components/link/clickable-link.js +30 -37
  147. package/components/link/link.js +27 -29
  148. package/components/list/list-custom.js +6 -11
  149. package/components/list/list-item.js +49 -56
  150. package/components/list/list-separator.js +0 -1
  151. package/components/list/list-title.js +0 -1
  152. package/components/list/list-users-groups-source.js +14 -22
  153. package/components/list/list.classes.js +8 -9
  154. package/components/list/list.js +387 -404
  155. package/components/loader/loader-core.js +2 -265
  156. package/components/loader/loader.d.ts +8 -0
  157. package/components/loader/loader.js +43 -29
  158. package/components/loader-inline/loader-inline.js +9 -12
  159. package/components/loader-screen/loader-screen.js +10 -14
  160. package/components/login-dialog/login-dialog.js +46 -54
  161. package/components/login-dialog/service.js +13 -15
  162. package/components/message/message.js +65 -79
  163. package/components/old-browsers-message/old-browsers-message-stop.js +0 -3
  164. package/components/old-browsers-message/old-browsers-message.js +1 -4
  165. package/components/old-browsers-message/white-list.js +5 -7
  166. package/components/pager/pager.js +73 -88
  167. package/components/panel/panel.js +9 -12
  168. package/components/permissions/permissions-cache.js +6 -8
  169. package/components/permissions/permissions.js +19 -21
  170. package/components/popup/popup.js +136 -145
  171. package/components/popup/popup.target.js +8 -10
  172. package/components/popup/position-css.js +19 -27
  173. package/components/popup/position.js +22 -28
  174. package/components/popup-menu/popup-menu.js +27 -37
  175. package/components/progress-bar/progress-bar.js +26 -32
  176. package/components/query-assist/query-assist-suggestions.js +0 -6
  177. package/components/query-assist/query-assist.js +432 -468
  178. package/components/radio/radio-item.js +30 -40
  179. package/components/radio/radio.js +6 -10
  180. package/components/scrollable-section/scrollable-section.js +7 -10
  181. package/components/select/select-filter.js +0 -6
  182. package/components/select/select-popup.js +155 -174
  183. package/components/select/select.js +464 -479
  184. package/components/shortcuts/core.js +40 -45
  185. package/components/shortcuts/shortcut-title.js +0 -1
  186. package/components/shortcuts/shortcuts-hoc.js +9 -15
  187. package/components/shortcuts/shortcuts.js +3 -5
  188. package/components/slider/slider.js +53 -66
  189. package/components/slider/slider.utils.js +1 -4
  190. package/components/storage/storage-local.js +2 -8
  191. package/components/storage/storage.js +0 -5
  192. package/components/style.css +1 -1
  193. package/components/tab-trap/tab-trap.js +21 -30
  194. package/components/table/cell.js +3 -4
  195. package/components/table/disable-hover-hoc.js +24 -28
  196. package/components/table/header-cell.js +30 -38
  197. package/components/table/header.js +20 -28
  198. package/components/table/multitable.js +81 -101
  199. package/components/table/row-with-focus-sensor.js +17 -28
  200. package/components/table/row.js +89 -99
  201. package/components/table/selection-adapter.js +0 -2
  202. package/components/table/selection-shortcuts-hoc.js +159 -161
  203. package/components/table/selection.js +23 -31
  204. package/components/table/simple-table.js +16 -22
  205. package/components/table/smart-table.js +19 -26
  206. package/components/table/table.js +137 -146
  207. package/components/tabs/collapsible-more.js +34 -47
  208. package/components/tabs/collapsible-tab.js +28 -33
  209. package/components/tabs/collapsible-tabs.js +16 -24
  210. package/components/tabs/custom-item.js +3 -6
  211. package/components/tabs/dumb-tabs.js +48 -64
  212. package/components/tabs/smart-tabs.js +14 -23
  213. package/components/tabs/tab-link.js +0 -2
  214. package/components/tabs/tab.js +0 -1
  215. package/components/tabs/tabs.js +0 -7
  216. package/components/tag/tag.js +30 -35
  217. package/components/tags-input/tags-input.js +192 -218
  218. package/components/tags-list/tags-list.js +26 -31
  219. package/components/text/text.js +16 -19
  220. package/components/toggle/toggle.js +19 -23
  221. package/components/tooltip/tooltip.js +110 -121
  222. package/components/upload/upload.js +19 -28
  223. package/components/user-agreement/service.js +247 -252
  224. package/components/user-agreement/toolbox.eula.js +160 -1
  225. package/components/user-agreement/user-agreement.js +23 -32
  226. package/components/user-card/card.js +0 -5
  227. package/components/user-card/smart-user-card-tooltip.js +41 -50
  228. package/components/user-card/tooltip.js +32 -38
  229. package/components/user-card/user-card.js +0 -5
  230. package/package.json +9 -3
  231. package/components/_helpers/_rollupPluginBabelHelpers.js +0 -72
@@ -1,15 +1,12 @@
1
- import { _ as _defineProperty, b as _objectSpread2, a as _objectWithoutProperties, d as _toPropertyKey } from '../_helpers/_rollupPluginBabelHelpers.js';
2
- import 'core-js/modules/es.regexp.exec.js';
3
- import 'core-js/modules/es.string.replace.js';
4
- import 'core-js/modules/es.string.trim.js';
5
- import 'core-js/modules/web.dom-collections.iterator.js';
6
1
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
7
2
  import { Component, Fragment } from 'react';
8
3
  import classNames from 'classnames';
9
4
  import chevronDownIcon from '@jetbrains/icons/chevron-down';
10
5
  import closeIcon from '@jetbrains/icons/close-12px';
11
6
  import { dequal } from 'dequal';
12
- import '../dropdown/dropdown.js';
7
+ import joinDataTestAttributes from '../global/data-tests.js';
8
+ import { isArray } from '../global/typescript-utils.js';
9
+ import { A as Anchor } from '../_helpers/anchor.js';
13
10
  import Avatar from '../avatar/avatar.js';
14
11
  import Popup from '../popup/popup.js';
15
12
  import List, { ActiveItemContext } from '../list/list.js';
@@ -17,26 +14,17 @@ import { S as Size, I as Input, i as inputStyles } from '../_helpers/input.js';
17
14
  import { ControlLabel } from '../control-label/control-label.js';
18
15
  import Shortcuts from '../shortcuts/shortcuts.js';
19
16
  import { Button } from '../button/button.js';
20
- import joinDataTestAttributes from '../global/data-tests.js';
21
17
  import getUID from '../global/get-uid.js';
22
18
  import rerenderHOC from '../global/rerender-hoc.js';
23
19
  import fuzzyHighlight from '../global/fuzzy-highlight.js';
24
20
  import memoize from '../global/memoize.js';
25
21
  import { I18nContext } from '../i18n/i18n-context.js';
26
22
  import { createComposedRef } from '../global/compose-refs.js';
27
- import { isArray } from '../global/typescript-utils.js';
28
23
  import { ControlsHeightContext } from '../global/controls-height.js';
29
24
  import SelectPopup from './select-popup.js';
30
25
  import { ControlsHeight } from '../global/configuration.js';
31
26
  import { Size as Size$1 } from '../avatar/avatar-size.js';
32
- import { A as Anchor } from '../_helpers/anchor.js';
33
- import '@jetbrains/icons/chevron-12px-down';
34
27
  import 'util-deprecate';
35
- import '../icon/icon.js';
36
- import '../icon/icon.constants.js';
37
- import '../_helpers/icon-svg.js';
38
- import '../link/clickable-link.js';
39
- import '../_helpers/button.classes.js';
40
28
  import '../global/url.js';
41
29
  import '../global/dom.js';
42
30
  import '../_helpers/avatar-info.js';
@@ -45,7 +33,6 @@ import 'react-dom';
45
33
  import '../global/schedule-raf.js';
46
34
  import '../tab-trap/tab-trap.js';
47
35
  import '../popup/position.js';
48
- import 'core-js/modules/es.array.sort.js';
49
36
  import '../popup/popup.consts.js';
50
37
  import '../popup/popup.target.js';
51
38
  import '../popup/position-css.js';
@@ -53,7 +40,6 @@ import '../shortcuts/core.js';
53
40
  import 'combokeys';
54
41
  import '../global/sniffer.js';
55
42
  import 'sniffr';
56
- import 'core-js/modules/es.symbol.description.js';
57
43
  import 'react-virtualized/dist/es/List';
58
44
  import 'react-virtualized/dist/es/AutoSizer';
59
45
  import 'react-virtualized/dist/es/WindowScroller';
@@ -64,8 +50,12 @@ import '../list/list-item.js';
64
50
  import '../checkbox/checkbox.js';
65
51
  import '@jetbrains/icons/checkmark-12px';
66
52
  import '@jetbrains/icons/remove-12px';
53
+ import '../icon/icon.js';
54
+ import '../icon/icon.constants.js';
55
+ import '../_helpers/icon-svg.js';
67
56
  import '../control-help/control-help.js';
68
57
  import '../link/link.js';
58
+ import '../link/clickable-link.js';
69
59
  import '../_helpers/link.js';
70
60
  import '../_helpers/list.js';
71
61
  import '../list/consts.js';
@@ -75,6 +65,8 @@ import '../global/get-event-key.js';
75
65
  import '../list/list-title.js';
76
66
  import '../list/list-separator.js';
77
67
  import '../list/list-hint.js';
68
+ import '@jetbrains/icons/chevron-12px-down';
69
+ import '../_helpers/button.classes.js';
78
70
  import '../i18n/i18n.js';
79
71
  import '@jetbrains/icons/search';
80
72
  import '../loader-inline/loader-inline.js';
@@ -139,8 +131,7 @@ function buildMultipleMap(selected) {
139
131
  }, {});
140
132
  }
141
133
  // eslint-disable-next-line complexity
142
- function getListItems(props, state, rawFilterString) {
143
- let data = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : props.data;
134
+ function getListItems(props, state, rawFilterString, data = props.data) {
144
135
  let filterString = rawFilterString.trim();
145
136
  if (isInputMode(props.type) && !props.allowAny && state.selected && !Array.isArray(state.selected) && filterString === state.selected.label) {
146
137
  filterString = ''; // ignore multiple if it is exactly the selected item
@@ -150,19 +141,19 @@ function getListItems(props, state, rawFilterString) {
150
141
  let exactMatch = false;
151
142
  const check = getFilterFn(props.filter);
152
143
  for (let i = 0; i < data.length; i++) {
153
- const item = _objectSpread2({}, data[i]);
144
+ const item = {
145
+ ...data[i]
146
+ };
154
147
  if (check(item, lowerCaseString, data)) {
155
- var _state$multipleMap2;
156
148
  exactMatch = item.label === filterString;
157
149
  if (props.multiple && !(typeof props.multiple === 'object' && props.multiple.removeSelectedItems)) {
158
- var _state$multipleMap;
159
- item.checkbox = !!((_state$multipleMap = state.multipleMap) !== null && _state$multipleMap !== void 0 && _state$multipleMap[item.key]);
150
+ item.checkbox = !!state.multipleMap?.[item.key];
160
151
  }
161
152
  if (props.multiple && typeof props.multiple === 'object' && props.multiple.limit && Array.isArray(state.selected)) {
162
153
  item.disabled = props.multiple.limit === state.selected.length && !state.selected.find(selectedItem => selectedItem.key === item.key);
163
154
  }
164
155
  // Ignore item if it's multiple and is already selected
165
- if (!(props.multiple && typeof props.multiple === 'object' && props.multiple.removeSelectedItems && (_state$multipleMap2 = state.multipleMap) !== null && _state$multipleMap2 !== void 0 && _state$multipleMap2[item.key])) {
156
+ if (!(props.multiple && typeof props.multiple === 'object' && props.multiple.removeSelectedItems && state.multipleMap?.[item.key])) {
166
157
  filteredData.push(item);
167
158
  }
168
159
  }
@@ -192,11 +183,10 @@ function getListItems(props, state, rawFilterString) {
192
183
  addButton
193
184
  };
194
185
  }
195
- const getItemLabel = _ref => {
196
- let {
197
- selectedLabel,
198
- label
199
- } = _ref;
186
+ const getItemLabel = ({
187
+ selectedLabel,
188
+ label
189
+ }) => {
200
190
  if (selectedLabel !== null && selectedLabel !== undefined) {
201
191
  return selectedLabel;
202
192
  }
@@ -212,360 +202,71 @@ const getValueForFilter = (selected, type, filterValue) => selected && !isArray(
212
202
  * Displays a select.
213
203
  */
214
204
  class Select extends Component {
215
- constructor() {
216
- var _this;
217
- super(...arguments);
218
- _this = this;
219
- _defineProperty(this, "state", {
220
- data: [],
221
- shownData: [],
222
- selected: this.props.multiple ? [] : null,
223
- lastInteractedKey: null,
224
- filterValue: this.props.filter && typeof this.props.filter === 'object' && this.props.filter.value || '',
225
- shortcutsEnabled: false,
226
- popupShortcuts: false,
227
- showPopup: this.props.showPopup,
228
- prevData: [],
229
- prevSelected: null,
230
- prevMultiple: this.props.multiple,
231
- multipleMap: {},
232
- addButton: null
233
- });
234
- _defineProperty(this, "id", getUID('select-'));
235
- _defineProperty(this, "shortcutsScope", this.id);
236
- _defineProperty(this, "listId", "".concat(this.id, ":list"));
237
- _defineProperty(this, "_focusHandler", e => {
238
- this.props.onFocus(e);
239
- this.setState({
240
- shortcutsEnabled: true,
241
- focused: true
242
- });
243
- });
244
- _defineProperty(this, "isClickingSelect", false);
245
- _defineProperty(this, "mouseDownHandler", () => {
246
- this.isClickingSelect = true;
247
- });
248
- _defineProperty(this, "mouseUpHandler", () => {
249
- this.isClickingSelect = false;
250
- });
251
- _defineProperty(this, "_blurHandler", () => {
252
- var _this$_popup;
253
- this.props.onBlur();
254
- if (this._popup && this._popup.isVisible() && !this._popup.isClickingPopup && !this.isClickingSelect) {
255
- window.setTimeout(() => {
256
- this.setState({
257
- showPopup: false
258
- });
259
- });
260
- }
261
- if (!((_this$_popup = this._popup) !== null && _this$_popup !== void 0 && _this$_popup.isClickingPopup)) {
262
- this.setState({
263
- shortcutsEnabled: false,
264
- focused: false
265
- });
266
- }
267
- });
268
- _defineProperty(this, "node", void 0);
269
- _defineProperty(this, "nodeRef", el => {
270
- this.node = el;
271
- });
272
- _defineProperty(this, "_popup", null);
273
- _defineProperty(this, "onEmptyPopupEnter", () => {
274
- if (this.state.addButton) {
275
- this.addHandler();
276
- }
277
- });
278
- _defineProperty(this, "focus", () => {
279
- var _this$node;
280
- const focusableSelectExists = (_this$node = this.node) === null || _this$node === void 0 ? void 0 : _this$node.querySelector('[data-test~=ring-select__focus]');
281
- const restoreFocusNode = this.props.targetElement || focusableSelectExists;
282
- restoreFocusNode === null || restoreFocusNode === void 0 || restoreFocusNode.focus();
283
- });
284
- _defineProperty(this, "_onEnter", () => {
285
- var _this$_popup2;
286
- if (this.state.addButton && this.state.shownData.length === 0) {
287
- this.addHandler();
288
- }
289
- this.props.onDone();
290
- if (!((_this$_popup2 = this._popup) !== null && _this$_popup2 !== void 0 && _this$_popup2.isVisible()) && this.props.allowAny) {
291
- return true;
292
- }
293
- return undefined;
294
- });
295
- _defineProperty(this, "_onEsc", event => {
296
- var _this$_popup3;
297
- if (!((_this$_popup3 = this._popup) !== null && _this$_popup3 !== void 0 && _this$_popup3.isVisible())) {
298
- return true;
299
- }
300
- if (this.props.multiple || !this.props.getInitial) {
301
- return false;
302
- }
303
- const selected = {
304
- key: Math.random(),
305
- label: this.props.getInitial()
306
- };
307
- this.setState({
308
- selected,
309
- filterValue: this.getValueForFilter(selected)
310
- }, () => {
311
- this.props.onChange(selected, event);
312
- this.props.onReset();
313
- });
314
- return undefined;
315
- });
316
- _defineProperty(this, "_inputShortcutHandler", () => {
317
- if (this.state.focused && this._popup && !this._popup.isVisible()) {
318
- this._clickHandler();
319
- }
320
- });
321
- _defineProperty(this, "popupRef", el => {
322
- this._popup = el;
323
- });
324
- _defineProperty(this, "_showPopup", () => {
325
- if (!this.node) {
326
- return;
327
- }
328
- const shownData = this.getListItems(this.filterValue());
329
- this.setState({
330
- showPopup: true,
331
- shownData
332
- });
333
- });
334
- _defineProperty(this, "_hidePopup", tryFocusAnchor => {
335
- if (this.node && this.state.showPopup) {
336
- this.setState(prevState => ({
337
- showPopup: false,
338
- filterValue: this.props.allowAny ? prevState.filterValue : '',
339
- lastInteractedKey: null
340
- }));
341
- if (tryFocusAnchor) {
342
- this.focus();
343
- }
344
- }
345
- });
346
- _defineProperty(this, "addHandler", () => {
347
- const value = this.filterValue();
348
- this._hidePopup();
349
- this.props.onAdd(value);
350
- });
351
- _defineProperty(this, "getLowerCaseLabel", getLowerCaseLabel);
352
- _defineProperty(this, "doesLabelMatch", doesLabelMatch);
353
- _defineProperty(this, "_clickHandler", () => {
354
- if (!this.props.disabled) {
355
- if (this.state.showPopup) {
356
- this._hidePopup();
357
- } else {
358
- this.props.onBeforeOpen();
359
- this._showPopup();
360
- }
361
- }
362
- });
363
- _defineProperty(this, "_openPopupIfClosed", () => {
364
- if (this.props.disabled || this.state.showPopup) {
365
- return;
366
- }
367
- this.props.onBeforeOpen();
368
- this._showPopup();
369
- });
370
- _defineProperty(this, "_filterChangeHandler", e => {
371
- this._setFilter(e.currentTarget.value, e);
372
- });
373
- _defineProperty(this, "_setFilter", (value, event) => {
374
- var _this$_popup4;
375
- if (this.isInputMode() && !this.state.focused) {
376
- return;
377
- }
378
- if (value === this.state.filterValue) {
379
- return;
380
- }
381
- const filterValue = value.replace(/^\s+/g, '');
382
- this.props.onFilter(filterValue);
383
- if (this.props.allowAny) {
384
- const fakeSelected = {
385
- key: Math.random(),
386
- label: filterValue
387
- };
388
- this.setState({
389
- selected: filterValue === '' ? null : fakeSelected
390
- }, () => {
391
- this.props.onSelect(fakeSelected, event);
392
- this.props.onChange(fakeSelected, event);
393
- });
394
- }
395
- if (!((_this$_popup4 = this._popup) !== null && _this$_popup4 !== void 0 && _this$_popup4.isVisible())) {
396
- this.props.onBeforeOpen();
397
- }
398
- this.setState({
399
- filterValue
400
- }, () => {
401
- this._showPopup();
402
- });
403
- });
404
- _defineProperty(this, "_redrawPopup", () => {
405
- if (this.props.multiple) {
406
- setTimeout(() => {
407
- //setTimeout solves events order and bubbling issue
408
- if (this.isInputMode()) {
409
- this.clearFilter();
410
- }
411
- this._showPopup();
412
- }, 0);
413
- }
414
- });
415
- _defineProperty(this, "_listSelectHandler", function (selected, event) {
416
- var _selected$key, _this$props$tryKeepOp;
417
- let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
418
- const isItem = item => List.isItemType(List.ListProps.Type.ITEM, item);
419
- const isCustomItem = item => List.isItemType(List.ListProps.Type.CUSTOM, item);
420
- const isSelectItemEvent = event && (event.type === 'select' || event.type === 'keydown');
421
- if (isSelectItemEvent) {
422
- event.preventDefault();
423
- }
424
- if (!isItem(selected) && !isCustomItem(selected) || selected.disabled || selected.isResetItem) {
425
- return;
426
- }
427
- const lastInteractedKey = (_selected$key = selected === null || selected === void 0 ? void 0 : selected.key) !== null && _selected$key !== void 0 ? _selected$key : null;
428
- const tryKeepOpen = (_this$props$tryKeepOp = _this.props.tryKeepOpen) !== null && _this$props$tryKeepOp !== void 0 ? _this$props$tryKeepOp : opts.tryKeepOpen;
429
- if (!_this.props.multiple) {
430
- var _selected$key2;
431
- if (!tryKeepOpen) {
432
- _this._hidePopup(isSelectItemEvent);
433
- }
434
- _this.setState({
435
- selected,
436
- lastInteractedKey: (_selected$key2 = selected === null || selected === void 0 ? void 0 : selected.key) !== null && _selected$key2 !== void 0 ? _selected$key2 : null
437
- }, () => {
438
- const newFilterValue = _this.isInputMode() && !_this.props.hideSelected ? getItemLabel(selected) : '';
439
- _this.filterValue(newFilterValue);
440
- _this.props.onFilter(newFilterValue);
441
- _this.props.onSelect(selected, event);
442
- _this.props.onChange(selected, event);
443
- });
444
- } else {
445
- if (!tryKeepOpen) {
446
- _this._hidePopup(isSelectItemEvent);
447
- }
448
- if (selected.key === null || selected.key === undefined) {
449
- throw new Error('Multiple selection requires each item to have the "key" property');
450
- }
451
- _this.setState(prevState => {
452
- const currentSelection = prevState.selected;
453
- let nextSelection;
454
- if (!prevState.multipleMap[selected.key]) {
455
- nextSelection = currentSelection.concat(selected);
456
- } else {
457
- nextSelection = currentSelection.filter(item => item.key !== selected.key);
458
- }
459
- const nextState = {
460
- filterValue: '',
461
- selected: nextSelection,
462
- lastInteractedKey: tryKeepOpen ? lastInteractedKey : null
463
- };
464
- if (typeof _this.props.multiple === 'object' && _this.props.multiple.limit && nextSelection.length === _this.props.multiple.limit) {
465
- nextState.shownData = prevState.shownData.map(item => nextSelection.find(selectedItem => selectedItem.key === item.key) ? item : _objectSpread2(_objectSpread2({}, item), {}, {
466
- disabled: true
467
- }));
468
- }
469
- if (!prevState.multipleMap[selected.key]) {
470
- nextState.multipleMap = _objectSpread2(_objectSpread2({}, prevState.multipleMap), {}, {
471
- [selected.key]: true
472
- });
473
- } else {
474
- const _prevState$multipleMa = prevState.multipleMap,
475
- _selected$key3 = selected.key,
476
- {
477
- [_selected$key3]: _
478
- } = _prevState$multipleMa,
479
- restMultipleMap = _objectWithoutProperties(_prevState$multipleMa, [_selected$key3].map(_toPropertyKey));
480
- nextState.multipleMap = restMultipleMap;
481
- }
482
- return _objectSpread2(_objectSpread2({}, prevState), nextState);
483
- }, () => {
484
- if (_this.state.multipleMap[selected.key]) {
485
- var _this$props$onSelect, _this$props;
486
- (_this$props$onSelect = (_this$props = _this.props).onSelect) === null || _this$props$onSelect === void 0 || _this$props$onSelect.call(_this$props, selected, event);
487
- } else {
488
- var _this$props$onDeselec, _this$props2;
489
- (_this$props$onDeselec = (_this$props2 = _this.props).onDeselect) === null || _this$props$onDeselec === void 0 || _this$props$onDeselec.call(_this$props2, selected);
490
- }
491
- _this.props.onChange(_this.state.selected, event);
492
- if (tryKeepOpen) {
493
- _this._redrawPopup();
494
- }
495
- });
496
- }
497
- });
498
- _defineProperty(this, "_listSelectAllHandler", function () {
499
- let isSelectAll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
500
- const isItem = item => List.isItemType(List.ListProps.Type.ITEM, item);
501
- const isCustomItem = item => List.isItemType(List.ListProps.Type.CUSTOM, item);
502
- _this.setState(prevState => {
503
- const currentSelection = prevState.selected;
504
- let nextSelection;
505
- if (isSelectAll) {
506
- nextSelection = _this.props.data.filter(item => (isItem(item) || isCustomItem(item)) && !item.disabled);
507
- nextSelection.filter(item => !_this.props.selected.find(selectedItem => item.key === selectedItem.key)).forEach(item => {
508
- var _this$props$onSelect2, _this$props3;
509
- (_this$props$onSelect2 = (_this$props3 = _this.props).onSelect) === null || _this$props$onSelect2 === void 0 || _this$props$onSelect2.call(_this$props3, item);
510
- });
511
- } else {
512
- nextSelection = [];
513
- currentSelection.forEach(item => {
514
- var _this$props$onDeselec2, _this$props4;
515
- (_this$props$onDeselec2 = (_this$props4 = _this.props).onDeselect) === null || _this$props$onDeselec2 === void 0 || _this$props$onDeselec2.call(_this$props4, item);
516
- });
517
- }
518
- _this.props.onChange(nextSelection, event);
519
- return {
520
- filterValue: '',
521
- selected: nextSelection,
522
- shownData: prevState.shownData.map(item => _objectSpread2(_objectSpread2({}, item), {}, {
523
- checkbox: isSelectAll
524
- })),
525
- multipleMap: isSelectAll ? buildMultipleMap(_this.props.data.filter(item => !item.disabled)) : {}
526
- };
527
- }, _this._redrawPopup);
528
- });
529
- _defineProperty(this, "_onCloseAttempt", (event, isEsc) => {
530
- if (this.isInputMode()) {
531
- if (!this.props.allowAny) {
532
- if (this.props.hideSelected || !this.state.selected || this.props.multiple) {
533
- this.clearFilter();
534
- } else if (this.state.selected && !Array.isArray(this.state.selected)) {
535
- this.filterValue(getItemLabel(this.state.selected));
536
- }
537
- }
538
- }
539
- const isTagRemoved = this.props.tags && event && event.target && event.target instanceof Element && event.target.matches('[data-test="ring-tag-remove"]');
540
- if (!isTagRemoved) {
541
- this._hidePopup(isEsc);
542
- }
543
- });
544
- _defineProperty(this, "clearFilter", e => {
545
- this._setFilter('', e);
546
- });
547
- _defineProperty(this, "clear", event => {
548
- if (event) {
549
- event.stopPropagation();
550
- }
551
- const empty = this.props.multiple ? [] : null;
552
- this.setState({
553
- selected: empty,
554
- lastInteractedKey: null,
555
- filterValue: ''
556
- }, () => {
557
- if (this.props.onChange) {
558
- this.props.onChange(empty, event);
559
- }
560
- });
561
- return false;
562
- });
563
- _defineProperty(this, "filter", void 0);
564
- _defineProperty(this, "filterRef", el => {
565
- this.filter = el;
566
- });
567
- _defineProperty(this, "composedFilterRef", createComposedRef());
568
- }
205
+ static defaultProps = {
206
+ data: [],
207
+ filter: false,
208
+ // enable filter (not in INPUT modes)
209
+ filterIcon: null,
210
+ filterRef: noop,
211
+ multiple: false,
212
+ // multiple can be an object - see demo for more information
213
+ clear: false,
214
+ // enable clear button that clears the "selected" state
215
+ loading: false,
216
+ // show a loading indicator while data is loading
217
+ disabled: false,
218
+ // disable select
219
+ type: Type.BUTTON,
220
+ size: Size.M,
221
+ targetElement: null,
222
+ // element to bind the popup to (select BUTTON or INPUT by default)
223
+ hideSelected: false,
224
+ // INPUT mode: clears the input after an option is selected (useful when the selection is displayed in some custom way elsewhere)
225
+ allowAny: false,
226
+ // INPUT mode: allows any value to be entered
227
+ hideArrow: false,
228
+ // hide dropdown arrow icon
229
+ showPopup: false,
230
+ maxHeight: 600,
231
+ // height of the options list, including the filter and the 'Add' button
232
+ directions: [Popup.PopupProps.Directions.BOTTOM_RIGHT, Popup.PopupProps.Directions.BOTTOM_LEFT, Popup.PopupProps.Directions.TOP_LEFT, Popup.PopupProps.Directions.TOP_RIGHT],
233
+ selected: null,
234
+ // current selection (item / array of items)
235
+ label: null,
236
+ // BUTTON or INPUT label (nothing selected)
237
+ selectedLabel: null,
238
+ // BUTTON or INPUT label (something selected)
239
+ inputPlaceholder: '',
240
+ // Placeholder for input modes
241
+ hint: null,
242
+ // hint text to display under the list
243
+ shortcutsEnabled: false,
244
+ onBeforeOpen: noop,
245
+ onLoadMore: noop,
246
+ onOpen: noop,
247
+ onClose: noop,
248
+ onFilter: noop,
249
+ // search string as first argument
250
+ onFocus: noop,
251
+ onBlur: noop,
252
+ onKeyDown: noop,
253
+ onSelect: noop,
254
+ // single + multi
255
+ onDeselect: noop,
256
+ // multi
257
+ onOutsideClick: noop,
258
+ // multi
259
+ onChange: noop,
260
+ // multi
261
+ onAdd: noop,
262
+ // search string as first argument
263
+ onDone: noop,
264
+ onReset: noop,
265
+ tags: null,
266
+ ringPopupTarget: null,
267
+ dir: 'ltr',
268
+ offset: 4
269
+ };
569
270
  static getDerivedStateFromProps(nextProps, prevState) {
570
271
  const {
571
272
  multiple,
@@ -613,7 +314,10 @@ class Select extends Component {
613
314
  }
614
315
  const {
615
316
  selected
616
- } = _objectSpread2(_objectSpread2({}, prevState), nextState);
317
+ } = {
318
+ ...prevState,
319
+ ...nextState
320
+ };
617
321
  if (selected && Array.isArray(selected)) {
618
322
  nextState.multipleMap = buildMultipleMap(selected);
619
323
  const {
@@ -631,6 +335,21 @@ class Select extends Component {
631
335
  }
632
336
  return nextState;
633
337
  }
338
+ state = {
339
+ data: [],
340
+ shownData: [],
341
+ selected: this.props.multiple ? [] : null,
342
+ lastInteractedKey: null,
343
+ filterValue: this.props.filter && typeof this.props.filter === 'object' && this.props.filter.value || '',
344
+ shortcutsEnabled: false,
345
+ popupShortcuts: false,
346
+ showPopup: this.props.showPopup,
347
+ prevData: [],
348
+ prevSelected: null,
349
+ prevMultiple: this.props.multiple,
350
+ multipleMap: {},
351
+ addButton: null
352
+ };
634
353
  componentDidUpdate(prevProps, prevState) {
635
354
  const {
636
355
  showPopup,
@@ -651,6 +370,92 @@ class Select extends Component {
651
370
  onChange(selected);
652
371
  }
653
372
  }
373
+ static contextType = ControlsHeightContext;
374
+ static Type = Type;
375
+ static Size = Size;
376
+ id = getUID('select-');
377
+ shortcutsScope = this.id;
378
+ listId = `${this.id}:list`;
379
+ _focusHandler = e => {
380
+ this.props.onFocus(e);
381
+ this.setState({
382
+ shortcutsEnabled: true,
383
+ focused: true
384
+ });
385
+ };
386
+ isClickingSelect = false;
387
+ mouseDownHandler = () => {
388
+ this.isClickingSelect = true;
389
+ };
390
+ mouseUpHandler = () => {
391
+ this.isClickingSelect = false;
392
+ };
393
+ _blurHandler = () => {
394
+ this.props.onBlur();
395
+ if (this._popup && this._popup.isVisible() && !this._popup.isClickingPopup && !this.isClickingSelect) {
396
+ window.setTimeout(() => {
397
+ this.setState({
398
+ showPopup: false
399
+ });
400
+ });
401
+ }
402
+ if (!this._popup?.isClickingPopup) {
403
+ this.setState({
404
+ shortcutsEnabled: false,
405
+ focused: false
406
+ });
407
+ }
408
+ };
409
+ node;
410
+ nodeRef = el => {
411
+ this.node = el;
412
+ };
413
+ _popup = null;
414
+ onEmptyPopupEnter = () => {
415
+ if (this.state.addButton) {
416
+ this.addHandler();
417
+ }
418
+ };
419
+ focus = () => {
420
+ const focusableSelectExists = this.node?.querySelector('[data-test~=ring-select__focus]');
421
+ const restoreFocusNode = this.props.targetElement || focusableSelectExists;
422
+ restoreFocusNode?.focus();
423
+ };
424
+ _onEnter = () => {
425
+ if (this.state.addButton && this.state.shownData.length === 0) {
426
+ this.addHandler();
427
+ }
428
+ this.props.onDone();
429
+ if (!this._popup?.isVisible() && this.props.allowAny) {
430
+ return true;
431
+ }
432
+ return undefined;
433
+ };
434
+ _onEsc = event => {
435
+ if (!this._popup?.isVisible()) {
436
+ return true;
437
+ }
438
+ if (this.props.multiple || !this.props.getInitial) {
439
+ return false;
440
+ }
441
+ const selected = {
442
+ key: Math.random(),
443
+ label: this.props.getInitial()
444
+ };
445
+ this.setState({
446
+ selected,
447
+ filterValue: this.getValueForFilter(selected)
448
+ }, () => {
449
+ this.props.onChange(selected, event);
450
+ this.props.onReset();
451
+ });
452
+ return undefined;
453
+ };
454
+ _inputShortcutHandler = () => {
455
+ if (this.state.focused && this._popup && !this._popup.isVisible()) {
456
+ this._clickHandler();
457
+ }
458
+ };
654
459
  getValueForFilter(selected) {
655
460
  return getValueForFilter(selected, this.props.type, this.state.filterValue);
656
461
  }
@@ -677,6 +482,9 @@ class Select extends Component {
677
482
  }
678
483
  return items.findIndex(item => !isNonOptionItem(item));
679
484
  }
485
+ popupRef = el => {
486
+ this._popup = el;
487
+ };
680
488
  _getResetOption() {
681
489
  const isOptionsSelected = Array.isArray(this.state.selected) && this.state.selected.length;
682
490
  const reset = this.props.tags && typeof this.props.tags === 'object' ? this.props.tags.reset : null;
@@ -732,10 +540,9 @@ class Select extends Component {
732
540
  const _shownData = this._prependResetOption(shownData);
733
541
  const activeIndex = this._getActiveIndex(_shownData);
734
542
  return jsx(I18nContext.Consumer, {
735
- children: _ref2 => {
736
- let {
737
- translate
738
- } = _ref2;
543
+ children: ({
544
+ translate
545
+ }) => {
739
546
  let message;
740
547
  if (this.props.loading) {
741
548
  var _this$props$loadingMe;
@@ -790,6 +597,33 @@ class Select extends Component {
790
597
  }
791
598
  });
792
599
  }
600
+ _showPopup = () => {
601
+ if (!this.node) {
602
+ return;
603
+ }
604
+ const shownData = this.getListItems(this.filterValue());
605
+ this.setState({
606
+ showPopup: true,
607
+ shownData
608
+ });
609
+ };
610
+ _hidePopup = tryFocusAnchor => {
611
+ if (this.node && this.state.showPopup) {
612
+ this.setState(prevState => ({
613
+ showPopup: false,
614
+ filterValue: this.props.allowAny ? prevState.filterValue : '',
615
+ lastInteractedKey: null
616
+ }));
617
+ if (tryFocusAnchor) {
618
+ this.focus();
619
+ }
620
+ }
621
+ };
622
+ addHandler = () => {
623
+ const value = this.filterValue();
624
+ this._hidePopup();
625
+ this.props.onAdd(value);
626
+ };
793
627
  getToolbar() {
794
628
  const {
795
629
  hint,
@@ -815,7 +649,7 @@ class Select extends Component {
815
649
  className: classNames(styles.button, styles.buttonSpaced),
816
650
  onClick: this.addHandler,
817
651
  "data-test": 'ring-select-toolbar-button',
818
- children: prefix ? "".concat(prefix, " ").concat(label) : label
652
+ children: prefix ? `${prefix} ${label}` : label
819
653
  }), hint && jsx(List.ListHint, {
820
654
  label: hint,
821
655
  "data-test": 'ring-select-toolbar-hint'
@@ -823,9 +657,10 @@ class Select extends Component {
823
657
  });
824
658
  }
825
659
  getTopbar() {
826
- var _this$props$renderTop, _this$props5;
827
- return (_this$props$renderTop = (_this$props5 = this.props).renderTopToolbar) === null || _this$props$renderTop === void 0 ? void 0 : _this$props$renderTop.call(_this$props5);
660
+ return this.props.renderTopToolbar?.();
828
661
  }
662
+ getLowerCaseLabel = getLowerCaseLabel;
663
+ doesLabelMatch = doesLabelMatch;
829
664
  getFilterFn() {
830
665
  return getFilterFn(this.props.filter);
831
666
  }
@@ -851,6 +686,56 @@ class Select extends Component {
851
686
  isInputMode() {
852
687
  return isInputMode(this.props.type);
853
688
  }
689
+ _clickHandler = () => {
690
+ if (!this.props.disabled) {
691
+ if (this.state.showPopup) {
692
+ this._hidePopup();
693
+ } else {
694
+ this.props.onBeforeOpen();
695
+ this._showPopup();
696
+ }
697
+ }
698
+ };
699
+ _openPopupIfClosed = () => {
700
+ if (this.props.disabled || this.state.showPopup) {
701
+ return;
702
+ }
703
+ this.props.onBeforeOpen();
704
+ this._showPopup();
705
+ };
706
+ _filterChangeHandler = e => {
707
+ this._setFilter(e.currentTarget.value, e);
708
+ };
709
+ _setFilter = (value, event) => {
710
+ if (this.isInputMode() && !this.state.focused) {
711
+ return;
712
+ }
713
+ if (value === this.state.filterValue) {
714
+ return;
715
+ }
716
+ const filterValue = value.replace(/^\s+/g, '');
717
+ this.props.onFilter(filterValue);
718
+ if (this.props.allowAny) {
719
+ const fakeSelected = {
720
+ key: Math.random(),
721
+ label: filterValue
722
+ };
723
+ this.setState({
724
+ selected: filterValue === '' ? null : fakeSelected
725
+ }, () => {
726
+ this.props.onSelect(fakeSelected, event);
727
+ this.props.onChange(fakeSelected, event);
728
+ });
729
+ }
730
+ if (!this._popup?.isVisible()) {
731
+ this.props.onBeforeOpen();
732
+ }
733
+ this.setState({
734
+ filterValue
735
+ }, () => {
736
+ this._showPopup();
737
+ });
738
+ };
854
739
  _rebuildMultipleMap(selected) {
855
740
  if (Array.isArray(selected)) {
856
741
  this.setState({
@@ -858,12 +743,169 @@ class Select extends Component {
858
743
  });
859
744
  }
860
745
  }
746
+ _redrawPopup = () => {
747
+ if (this.props.multiple) {
748
+ setTimeout(() => {
749
+ //setTimeout solves events order and bubbling issue
750
+ if (this.isInputMode()) {
751
+ this.clearFilter();
752
+ }
753
+ this._showPopup();
754
+ }, 0);
755
+ }
756
+ };
757
+ _listSelectHandler = (selected, event, opts = {}) => {
758
+ var _selected$key, _this$props$tryKeepOp;
759
+ const isItem = item => List.isItemType(List.ListProps.Type.ITEM, item);
760
+ const isCustomItem = item => List.isItemType(List.ListProps.Type.CUSTOM, item);
761
+ const isSelectItemEvent = event && (event.type === 'select' || event.type === 'keydown');
762
+ if (isSelectItemEvent) {
763
+ event.preventDefault();
764
+ }
765
+ if (!isItem(selected) && !isCustomItem(selected) || selected.disabled || selected.isResetItem) {
766
+ return;
767
+ }
768
+ const lastInteractedKey = (_selected$key = selected?.key) !== null && _selected$key !== void 0 ? _selected$key : null;
769
+ const tryKeepOpen = (_this$props$tryKeepOp = this.props.tryKeepOpen) !== null && _this$props$tryKeepOp !== void 0 ? _this$props$tryKeepOp : opts.tryKeepOpen;
770
+ if (!this.props.multiple) {
771
+ var _selected$key2;
772
+ if (!tryKeepOpen) {
773
+ this._hidePopup(isSelectItemEvent);
774
+ }
775
+ this.setState({
776
+ selected,
777
+ lastInteractedKey: (_selected$key2 = selected?.key) !== null && _selected$key2 !== void 0 ? _selected$key2 : null
778
+ }, () => {
779
+ const newFilterValue = this.isInputMode() && !this.props.hideSelected ? getItemLabel(selected) : '';
780
+ this.filterValue(newFilterValue);
781
+ this.props.onFilter(newFilterValue);
782
+ this.props.onSelect(selected, event);
783
+ this.props.onChange(selected, event);
784
+ });
785
+ } else {
786
+ if (!tryKeepOpen) {
787
+ this._hidePopup(isSelectItemEvent);
788
+ }
789
+ if (selected.key === null || selected.key === undefined) {
790
+ throw new Error('Multiple selection requires each item to have the "key" property');
791
+ }
792
+ this.setState(prevState => {
793
+ const currentSelection = prevState.selected;
794
+ let nextSelection;
795
+ if (!prevState.multipleMap[selected.key]) {
796
+ nextSelection = currentSelection.concat(selected);
797
+ } else {
798
+ nextSelection = currentSelection.filter(item => item.key !== selected.key);
799
+ }
800
+ const nextState = {
801
+ filterValue: '',
802
+ selected: nextSelection,
803
+ lastInteractedKey: tryKeepOpen ? lastInteractedKey : null
804
+ };
805
+ if (typeof this.props.multiple === 'object' && this.props.multiple.limit && nextSelection.length === this.props.multiple.limit) {
806
+ nextState.shownData = prevState.shownData.map(item => nextSelection.find(selectedItem => selectedItem.key === item.key) ? item : {
807
+ ...item,
808
+ disabled: true
809
+ });
810
+ }
811
+ if (!prevState.multipleMap[selected.key]) {
812
+ nextState.multipleMap = {
813
+ ...prevState.multipleMap,
814
+ [selected.key]: true
815
+ };
816
+ } else {
817
+ const {
818
+ [selected.key]: _,
819
+ ...restMultipleMap
820
+ } = prevState.multipleMap;
821
+ nextState.multipleMap = restMultipleMap;
822
+ }
823
+ return {
824
+ ...prevState,
825
+ ...nextState
826
+ };
827
+ }, () => {
828
+ if (this.state.multipleMap[selected.key]) {
829
+ this.props.onSelect?.(selected, event);
830
+ } else {
831
+ this.props.onDeselect?.(selected);
832
+ }
833
+ this.props.onChange(this.state.selected, event);
834
+ if (tryKeepOpen) {
835
+ this._redrawPopup();
836
+ }
837
+ });
838
+ }
839
+ };
840
+ _listSelectAllHandler = (isSelectAll = true) => {
841
+ const isItem = item => List.isItemType(List.ListProps.Type.ITEM, item);
842
+ const isCustomItem = item => List.isItemType(List.ListProps.Type.CUSTOM, item);
843
+ this.setState(prevState => {
844
+ const currentSelection = prevState.selected;
845
+ let nextSelection;
846
+ if (isSelectAll) {
847
+ nextSelection = this.props.data.filter(item => (isItem(item) || isCustomItem(item)) && !item.disabled);
848
+ nextSelection.filter(item => !this.props.selected.find(selectedItem => item.key === selectedItem.key)).forEach(item => {
849
+ this.props.onSelect?.(item);
850
+ });
851
+ } else {
852
+ nextSelection = [];
853
+ currentSelection.forEach(item => {
854
+ this.props.onDeselect?.(item);
855
+ });
856
+ }
857
+ this.props.onChange(nextSelection, event);
858
+ return {
859
+ filterValue: '',
860
+ selected: nextSelection,
861
+ shownData: prevState.shownData.map(item => ({
862
+ ...item,
863
+ checkbox: isSelectAll
864
+ })),
865
+ multipleMap: isSelectAll ? buildMultipleMap(this.props.data.filter(item => !item.disabled)) : {}
866
+ };
867
+ }, this._redrawPopup);
868
+ };
869
+ _onCloseAttempt = (event, isEsc) => {
870
+ if (this.isInputMode()) {
871
+ if (!this.props.allowAny) {
872
+ if (this.props.hideSelected || !this.state.selected || this.props.multiple) {
873
+ this.clearFilter();
874
+ } else if (this.state.selected && !Array.isArray(this.state.selected)) {
875
+ this.filterValue(getItemLabel(this.state.selected));
876
+ }
877
+ }
878
+ }
879
+ const isTagRemoved = this.props.tags && event && event.target && event.target instanceof Element && event.target.matches('[data-test="ring-tag-remove"]');
880
+ if (!isTagRemoved) {
881
+ this._hidePopup(isEsc);
882
+ }
883
+ };
884
+ clearFilter = e => {
885
+ this._setFilter('', e);
886
+ };
887
+ clear = event => {
888
+ if (event) {
889
+ event.stopPropagation();
890
+ }
891
+ const empty = this.props.multiple ? [] : null;
892
+ this.setState({
893
+ selected: empty,
894
+ lastInteractedKey: null,
895
+ filterValue: ''
896
+ }, () => {
897
+ if (this.props.onChange) {
898
+ this.props.onChange(empty, event);
899
+ }
900
+ });
901
+ return false;
902
+ };
861
903
  _selectionIsEmpty() {
862
904
  return Array.isArray(this.state.selected) && !this.state.selected.length || !this.state.selected;
863
905
  }
864
906
  _getLabel() {
865
- var _ref3, _this$props$label;
866
- return (_ref3 = (_this$props$label = this.props.label) !== null && _this$props$label !== void 0 ? _this$props$label : this.props.selectedLabel) !== null && _ref3 !== void 0 ? _ref3 : 'Select an option';
907
+ var _ref, _this$props$label;
908
+ return (_ref = (_this$props$label = this.props.label) !== null && _this$props$label !== void 0 ? _this$props$label : this.props.selectedLabel) !== null && _ref !== void 0 ? _ref : 'Select an option';
867
909
  }
868
910
  _getPlaceholder() {
869
911
  if (this._selectionIsEmpty()) {
@@ -896,7 +938,7 @@ class Select extends Component {
896
938
  } = this.props;
897
939
  const icons = [];
898
940
  const height = this.getHeight();
899
- if (!Array.isArray(selected) && selected !== null && selected !== void 0 && selected.icon) {
941
+ if (!Array.isArray(selected) && selected?.icon) {
900
942
  icons.push(jsx("button", {
901
943
  title: 'Toggle options popup',
902
944
  type: 'button',
@@ -904,7 +946,7 @@ class Select extends Component {
904
946
  disabled: this.props.disabled,
905
947
  onClick: this._clickHandler,
906
948
  style: {
907
- backgroundImage: "url(".concat(selected.icon, ")")
949
+ backgroundImage: `url(${selected.icon})`
908
950
  }
909
951
  }, 'selected'));
910
952
  }
@@ -933,14 +975,18 @@ class Select extends Component {
933
975
  return icons;
934
976
  }
935
977
  _getAvatar() {
936
- var _this$state$selected, _this$state$selected2;
937
- return !Array.isArray(this.state.selected) && (((_this$state$selected = this.state.selected) === null || _this$state$selected === void 0 ? void 0 : _this$state$selected.avatar) || ((_this$state$selected2 = this.state.selected) === null || _this$state$selected2 === void 0 ? void 0 : _this$state$selected2.showGeneratedAvatar)) && jsx(Avatar, {
978
+ return !Array.isArray(this.state.selected) && (this.state.selected?.avatar || this.state.selected?.showGeneratedAvatar) && jsx(Avatar, {
938
979
  className: styles.avatar,
939
980
  url: this.state.selected.avatar,
940
981
  username: this.state.selected.username,
941
982
  size: Size$1.Size20
942
983
  });
943
984
  }
985
+ filter;
986
+ filterRef = el => {
987
+ this.filter = el;
988
+ };
989
+ composedFilterRef = createComposedRef();
944
990
  getShortcutsMap() {
945
991
  return {
946
992
  enter: this._onEnter,
@@ -956,7 +1002,7 @@ class Select extends Component {
956
1002
  }
957
1003
  // eslint-disable-next-line complexity
958
1004
  renderSelect(activeItemId) {
959
- var _ref4, _this$props$label3, _this$_popup5, _this$props$buttonCla;
1005
+ var _ref2, _this$props$label3, _this$props$buttonCla;
960
1006
  const dataTest = this.props['data-test'];
961
1007
  const {
962
1008
  selectedLabel
@@ -964,8 +1010,8 @@ class Select extends Component {
964
1010
  const {
965
1011
  shortcutsEnabled
966
1012
  } = this.state;
967
- const classes = classNames(styles.select, 'ring-js-shortcuts', this.props.className, styles["height".concat(this.getHeight())], {
968
- [styles["size".concat(this.props.size)]]: this.props.type !== Type.INLINE,
1013
+ const classes = classNames(styles.select, 'ring-js-shortcuts', this.props.className, styles[`height${this.getHeight()}`], {
1014
+ [styles[`size${this.props.size}`]]: this.props.type !== Type.INLINE,
969
1015
  [styles.disabled]: this.props.disabled
970
1016
  });
971
1017
  let style;
@@ -983,7 +1029,7 @@ class Select extends Component {
983
1029
  'aria-expanded': this.state.showPopup,
984
1030
  'aria-controls': this.listId,
985
1031
  'aria-activedescendant': this.state.showPopup ? activeItemId : undefined,
986
- 'aria-label': (_ref4 = (_this$props$label3 = this.props.label) !== null && _this$props$label3 !== void 0 ? _this$props$label3 : this._getPlaceholder()) !== null && _ref4 !== void 0 ? _ref4 : undefined
1032
+ 'aria-label': (_ref2 = (_this$props$label3 = this.props.label) !== null && _this$props$label3 !== void 0 ? _this$props$label3 : this._getPlaceholder()) !== null && _ref2 !== void 0 ? _ref2 : undefined
987
1033
  };
988
1034
  switch (this.props.type) {
989
1035
  case Type.INPUT_WITHOUT_CONTROLS:
@@ -1000,7 +1046,8 @@ class Select extends Component {
1000
1046
  children: [shortcutsEnabled && jsx(Shortcuts, {
1001
1047
  map: this.getShortcutsMap(),
1002
1048
  scope: this.shortcutsScope
1003
- }), jsx(Input, _objectSpread2(_objectSpread2({}, ariaProps), {}, {
1049
+ }), jsx(Input, {
1050
+ ...ariaProps,
1004
1051
  height: this.props.height,
1005
1052
  autoComplete: 'off',
1006
1053
  id: this.props.id,
@@ -1020,12 +1067,15 @@ class Select extends Component {
1020
1067
  placeholder: this.props.inputPlaceholder,
1021
1068
  onKeyDown: this.props.onKeyDown,
1022
1069
  "data-test": 'ring-select__focus',
1023
- 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,
1070
+ enableShortcuts: shortcutsEnabled ? Object.keys({
1071
+ ...this.getShortcutsMap(),
1072
+ ...this._popup?.list?.shortcutsMap
1073
+ }) : undefined,
1024
1074
  icon: this.props.filterIcon,
1025
1075
  afterInput: iconsNode
1026
- })), this._renderPopup()]
1076
+ }), this._renderPopup()]
1027
1077
  }), this.props.error && jsx("div", {
1028
- className: classNames(inputStyles.errorText, inputStyles["size".concat(this.props.size)]),
1078
+ className: classNames(inputStyles.errorText, inputStyles[`size${this.props.size}`]),
1029
1079
  children: this.props.error
1030
1080
  })]
1031
1081
  });
@@ -1044,7 +1094,8 @@ class Select extends Component {
1044
1094
  scope: this.shortcutsScope
1045
1095
  }), jsxs("div", {
1046
1096
  className: styles.buttonContainer,
1047
- children: [jsxs(Button, _objectSpread2(_objectSpread2({}, ariaProps), {}, {
1097
+ children: [jsxs(Button, {
1098
+ ...ariaProps,
1048
1099
  height: this.props.height,
1049
1100
  id: this.props.id,
1050
1101
  onClick: this._clickHandler,
@@ -1056,7 +1107,7 @@ class Select extends Component {
1056
1107
  style: style,
1057
1108
  "data-test": 'ring-select__button ring-select__focus',
1058
1109
  children: [this._getAvatar(), this._getPlaceholder()]
1059
- })), iconsNode]
1110
+ }), iconsNode]
1060
1111
  }), this._renderPopup()]
1061
1112
  });
1062
1113
  case Type.INLINE:
@@ -1067,7 +1118,8 @@ class Select extends Component {
1067
1118
  children: [shortcutsEnabled && jsx(Shortcuts, {
1068
1119
  map: this.getShortcutsMap(),
1069
1120
  scope: this.shortcutsScope
1070
- }), jsx(Anchor, _objectSpread2(_objectSpread2({}, ariaProps), {}, {
1121
+ }), jsx(Anchor, {
1122
+ ...ariaProps,
1071
1123
  className: (_this$props$buttonCla = this.props.buttonClassName) !== null && _this$props$buttonCla !== void 0 ? _this$props$buttonCla : undefined,
1072
1124
  id: this.props.id,
1073
1125
  onClick: this._clickHandler,
@@ -1075,7 +1127,7 @@ class Select extends Component {
1075
1127
  disabled: this.props.disabled,
1076
1128
  active: this.state.showPopup,
1077
1129
  children: this._getPlaceholder()
1078
- })), this._renderPopup()]
1130
+ }), this._renderPopup()]
1079
1131
  });
1080
1132
  default:
1081
1133
  if (this.props.customAnchor) {
@@ -1088,13 +1140,14 @@ class Select extends Component {
1088
1140
  ref: this.nodeRef,
1089
1141
  'data-test': joinDataTestAttributes('ring-select', dataTest)
1090
1142
  },
1091
- buttonProps: _objectSpread2(_objectSpread2({}, ariaProps), {}, {
1143
+ buttonProps: {
1144
+ ...ariaProps,
1092
1145
  id: this.props.id,
1093
1146
  onClick: this._clickHandler,
1094
1147
  disabled: this.props.disabled,
1095
1148
  children: this._getPlaceholder(),
1096
1149
  'data-test': 'ring-select__focus'
1097
- }),
1150
+ },
1098
1151
  popup: this._renderPopup()
1099
1152
  })]
1100
1153
  });
@@ -1116,74 +1169,6 @@ class Select extends Component {
1116
1169
  }
1117
1170
  }
1118
1171
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1119
- _defineProperty(Select, "defaultProps", {
1120
- data: [],
1121
- filter: false,
1122
- // enable filter (not in INPUT modes)
1123
- filterIcon: null,
1124
- filterRef: noop,
1125
- multiple: false,
1126
- // multiple can be an object - see demo for more information
1127
- clear: false,
1128
- // enable clear button that clears the "selected" state
1129
- loading: false,
1130
- // show a loading indicator while data is loading
1131
- disabled: false,
1132
- // disable select
1133
- type: Type.BUTTON,
1134
- size: Size.M,
1135
- targetElement: null,
1136
- // element to bind the popup to (select BUTTON or INPUT by default)
1137
- hideSelected: false,
1138
- // INPUT mode: clears the input after an option is selected (useful when the selection is displayed in some custom way elsewhere)
1139
- allowAny: false,
1140
- // INPUT mode: allows any value to be entered
1141
- hideArrow: false,
1142
- // hide dropdown arrow icon
1143
- showPopup: false,
1144
- maxHeight: 600,
1145
- // height of the options list, including the filter and the 'Add' button
1146
- directions: [Popup.PopupProps.Directions.BOTTOM_RIGHT, Popup.PopupProps.Directions.BOTTOM_LEFT, Popup.PopupProps.Directions.TOP_LEFT, Popup.PopupProps.Directions.TOP_RIGHT],
1147
- selected: null,
1148
- // current selection (item / array of items)
1149
- label: null,
1150
- // BUTTON or INPUT label (nothing selected)
1151
- selectedLabel: null,
1152
- // BUTTON or INPUT label (something selected)
1153
- inputPlaceholder: '',
1154
- // Placeholder for input modes
1155
- hint: null,
1156
- // hint text to display under the list
1157
- shortcutsEnabled: false,
1158
- onBeforeOpen: noop,
1159
- onLoadMore: noop,
1160
- onOpen: noop,
1161
- onClose: noop,
1162
- onFilter: noop,
1163
- // search string as first argument
1164
- onFocus: noop,
1165
- onBlur: noop,
1166
- onKeyDown: noop,
1167
- onSelect: noop,
1168
- // single + multi
1169
- onDeselect: noop,
1170
- // multi
1171
- onOutsideClick: noop,
1172
- // multi
1173
- onChange: noop,
1174
- // multi
1175
- onAdd: noop,
1176
- // search string as first argument
1177
- onDone: noop,
1178
- onReset: noop,
1179
- tags: null,
1180
- ringPopupTarget: null,
1181
- dir: 'ltr',
1182
- offset: 4
1183
- });
1184
- _defineProperty(Select, "contextType", ControlsHeightContext);
1185
- _defineProperty(Select, "Type", Type);
1186
- _defineProperty(Select, "Size", Size);
1187
1172
  const RerenderableSelect = rerenderHOC(Select);
1188
1173
 
1189
1174
  export { RerenderableSelect, Type, Select as default };