@jetbrains/ring-ui 4.1.1 → 4.1.2

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 (314) hide show
  1. package/dist/_helpers/_rollupPluginBabelHelpers.js +34 -0
  2. package/dist/_helpers/anchor.js +32 -0
  3. package/dist/_helpers/badge.js +3 -0
  4. package/dist/_helpers/button-group.js +3 -0
  5. package/dist/_helpers/button-set.js +3 -0
  6. package/dist/_helpers/button-toolbar.js +3 -0
  7. package/dist/_helpers/button__classes.js +39 -0
  8. package/dist/_helpers/card.js +75 -0
  9. package/dist/_helpers/checkbox.js +3 -0
  10. package/dist/_helpers/date-picker.js +3 -0
  11. package/dist/_helpers/dialog__body-scroll-preventer.js +57 -0
  12. package/dist/_helpers/error-message.js +3 -0
  13. package/dist/_helpers/footer.js +121 -0
  14. package/dist/_helpers/grid.js +3 -0
  15. package/dist/_helpers/group.js +3 -0
  16. package/dist/_helpers/header.js +3 -0
  17. package/dist/_helpers/icon.js +3 -0
  18. package/dist/_helpers/inject-styles.js +22 -0
  19. package/dist/_helpers/input.js +3 -0
  20. package/dist/_helpers/island.js +3 -0
  21. package/dist/_helpers/link.js +3 -0
  22. package/dist/_helpers/list.js +3 -0
  23. package/dist/_helpers/loader-screen.js +3 -0
  24. package/dist/_helpers/panel.js +3 -0
  25. package/dist/_helpers/query-assist__suggestions.js +95 -0
  26. package/dist/_helpers/radio.js +3 -0
  27. package/dist/_helpers/select__filter.js +76 -0
  28. package/dist/_helpers/services-link.js +40 -0
  29. package/dist/_helpers/sidebar.js +125 -0
  30. package/dist/_helpers/table.js +3 -0
  31. package/dist/_helpers/tabs.js +3 -0
  32. package/dist/_helpers/title.js +99 -0
  33. package/dist/alert/alert.js +260 -0
  34. package/dist/alert/container.js +48 -0
  35. package/dist/alert-service/alert-service.js +170 -0
  36. package/dist/analytics/analytics.js +116 -0
  37. package/dist/analytics/analytics__custom-plugin.js +127 -0
  38. package/dist/analytics/analytics__fus-plugin.js +101 -0
  39. package/dist/analytics/analytics__ga-plugin.js +66 -0
  40. package/dist/analytics/analytics__plugin-utils.js +79 -0
  41. package/dist/analytics-ng/analytics-ng.js +94 -0
  42. package/dist/auth/auth.js +93 -0
  43. package/dist/auth/auth__core.js +1025 -0
  44. package/dist/auth/background-flow.js +122 -0
  45. package/dist/auth/down-notification.js +114 -0
  46. package/dist/auth/iframe-flow.js +150 -0
  47. package/dist/auth/landing-entry.js +5 -0
  48. package/dist/auth/landing.js +87 -0
  49. package/dist/auth/request-builder.js +75 -0
  50. package/dist/auth/response-parser.js +117 -0
  51. package/dist/auth/storage.js +280 -0
  52. package/dist/auth/token-validator.js +176 -0
  53. package/dist/auth/window-flow.js +133 -0
  54. package/dist/auth-dialog/auth-dialog.js +134 -0
  55. package/dist/auth-dialog-service/auth-dialog-service.js +68 -0
  56. package/dist/auth-ng/auth-ng.js +203 -0
  57. package/dist/auth-ng/auth-ng.mock.js +33 -0
  58. package/dist/autofocus-ng/autofocus-ng.js +50 -0
  59. package/dist/avatar/avatar-example-datauri.js +26 -0
  60. package/dist/avatar/avatar.js +161 -0
  61. package/dist/avatar/fallback-avatar.js +141 -0
  62. package/dist/avatar-editor-ng/avatar-editor-ng.js +164 -0
  63. package/dist/avatar-editor-ng/avatar-editor-ng__template.js +30 -0
  64. package/dist/avatar-ng/avatar-ng.js +18 -0
  65. package/dist/badge/badge.js +50 -0
  66. package/dist/badge-ng/badge-ng.js +16 -0
  67. package/dist/breadcrumb-ng/breadcrumb-ng.js +61 -0
  68. package/dist/button/button.js +123 -0
  69. package/dist/button/button__classes.js +5 -0
  70. package/dist/button-group/button-group.js +30 -0
  71. package/dist/button-group/caption.js +24 -0
  72. package/dist/button-group-ng/button-group-ng.js +38 -0
  73. package/dist/button-ng/button-ng.js +223 -0
  74. package/dist/button-set/button-set.js +26 -0
  75. package/dist/button-set-ng/button-set-ng.js +19 -0
  76. package/dist/button-toolbar/button-toolbar.js +29 -0
  77. package/dist/button-toolbar-ng/button-toolbar-ng.js +23 -0
  78. package/dist/caret/caret.js +264 -0
  79. package/dist/checkbox/checkbox.js +108 -0
  80. package/dist/checkbox-ng/checkbox-ng.js +55 -0
  81. package/dist/code/code.js +136 -0
  82. package/dist/compiler-ng/compiler-ng.js +53 -0
  83. package/dist/confirm/confirm.js +125 -0
  84. package/dist/confirm-ng/confirm-ng.js +66 -0
  85. package/dist/confirm-service/confirm-service.js +114 -0
  86. package/dist/content-layout/content-layout.js +65 -0
  87. package/dist/content-layout/sidebar.js +6 -0
  88. package/dist/contenteditable/contenteditable.js +78 -0
  89. package/dist/data-list/data-list.js +206 -0
  90. package/dist/data-list/data-list.mock.js +190 -0
  91. package/dist/data-list/item.js +227 -0
  92. package/dist/data-list/selection.js +101 -0
  93. package/dist/data-list/title.js +18 -0
  94. package/dist/data-list-ng/data-list-ng.js +59 -0
  95. package/dist/date-picker/consts.js +69 -0
  96. package/dist/date-picker/date-input.js +173 -0
  97. package/dist/date-picker/date-picker.js +365 -0
  98. package/dist/date-picker/date-popup.js +482 -0
  99. package/dist/date-picker/day.js +119 -0
  100. package/dist/date-picker/formats.js +3 -0
  101. package/dist/date-picker/month-names.js +99 -0
  102. package/dist/date-picker/month-slider.js +83 -0
  103. package/dist/date-picker/month.js +54 -0
  104. package/dist/date-picker/months.js +121 -0
  105. package/dist/date-picker/weekdays.js +32 -0
  106. package/dist/date-picker/years.js +109 -0
  107. package/dist/dialog/dialog.js +200 -0
  108. package/dist/dialog/dialog__body-scroll-preventer.js +2 -0
  109. package/dist/dialog-ng/dialog-ng.js +601 -0
  110. package/dist/dialog-ng/dialog-ng__template.js +71 -0
  111. package/dist/docked-panel-ng/docked-panel-ng.js +170 -0
  112. package/dist/dropdown/anchor.js +17 -0
  113. package/dist/dropdown/dropdown.js +234 -0
  114. package/dist/dropdown-menu/dropdown-menu.js +175 -0
  115. package/dist/error-bubble/error-bubble.js +57 -0
  116. package/dist/error-message/error-message.js +55 -0
  117. package/dist/error-message-ng/error-message-ng.js +53 -0
  118. package/dist/footer/footer.js +11 -0
  119. package/dist/footer-ng/footer-ng.js +75 -0
  120. package/dist/form-ng/form-ng.js +169 -0
  121. package/dist/global/angular-component-factory.js +82 -0
  122. package/dist/global/compose.js +9 -0
  123. package/dist/global/composeRefs.js +15 -0
  124. package/dist/global/conic-gradient.js +35 -0
  125. package/dist/global/create-stateful-context.js +54 -0
  126. package/dist/global/data-tests.js +22 -0
  127. package/dist/global/dom.js +124 -0
  128. package/dist/global/focus-sensor-hoc.js +145 -0
  129. package/dist/global/fuzzy-highlight.js +67 -0
  130. package/dist/global/get-event-key.js +111 -0
  131. package/dist/global/get-uid.js +15 -0
  132. package/dist/global/inject-styles.js +17 -0
  133. package/dist/global/linear-function.js +17 -0
  134. package/dist/global/listeners.js +42 -0
  135. package/dist/global/memoize.js +18 -0
  136. package/dist/global/normalize-indent.js +28 -0
  137. package/dist/global/promise-with-timeout.js +13 -0
  138. package/dist/global/radial-gradient-mask.js +49 -0
  139. package/dist/global/react-dom-renderer.js +45 -0
  140. package/dist/global/rerender-hoc.js +51 -0
  141. package/dist/global/ring-angular-component.js +24 -0
  142. package/dist/global/schedule-raf.js +31 -0
  143. package/dist/global/sniffer.js +6 -0
  144. package/dist/global/supports-css.js +20 -0
  145. package/dist/global/theme.js +54 -0
  146. package/dist/global/trivial-template-tag.js +15 -0
  147. package/dist/global/url.js +163 -0
  148. package/dist/global/variables_dark.js +57 -0
  149. package/dist/grid/col.js +60 -0
  150. package/dist/grid/grid.js +33 -0
  151. package/dist/grid/row.js +64 -0
  152. package/dist/group/group.js +31 -0
  153. package/dist/group-ng/group-ng.js +11 -0
  154. package/dist/header/header.js +147 -0
  155. package/dist/header/logo.js +38 -0
  156. package/dist/header/profile.js +217 -0
  157. package/dist/header/services-link.js +11 -0
  158. package/dist/header/services.js +136 -0
  159. package/dist/header/smart-profile.js +230 -0
  160. package/dist/header/smart-services.js +160 -0
  161. package/dist/header/tray-icon.js +45 -0
  162. package/dist/header/tray.js +31 -0
  163. package/dist/heading/heading.js +73 -0
  164. package/dist/http/http.js +216 -0
  165. package/dist/http/http.mock.js +65 -0
  166. package/dist/hub-source/hub-source.js +130 -0
  167. package/dist/hub-source/hub-source__user.js +28 -0
  168. package/dist/hub-source/hub-source__users-groups.js +62 -0
  169. package/dist/icon/icon.js +105 -0
  170. package/dist/icon/icon__constants.js +33 -0
  171. package/dist/icon/icon__svg.js +81 -0
  172. package/dist/icon/index.js +10 -0
  173. package/dist/icon-ng/icon-ng.js +89 -0
  174. package/dist/input/input.js +228 -0
  175. package/dist/input-ng/input-ng.js +166 -0
  176. package/dist/island/adaptive-island-hoc.js +47 -0
  177. package/dist/island/content.js +156 -0
  178. package/dist/island/header.js +83 -0
  179. package/dist/island/island.js +50 -0
  180. package/dist/island-legacy/content-legacy.js +26 -0
  181. package/dist/island-legacy/header-legacy.js +28 -0
  182. package/dist/island-legacy/island-legacy.js +28 -0
  183. package/dist/island-ng/island-content-ng.js +56 -0
  184. package/dist/island-ng/island-header-ng.js +32 -0
  185. package/dist/island-ng/island-ng-class-fixer.js +9 -0
  186. package/dist/island-ng/island-ng.js +31 -0
  187. package/dist/link/clickableLink.js +63 -0
  188. package/dist/link/link.js +114 -0
  189. package/dist/link-ng/link-ng.js +25 -0
  190. package/dist/list/consts.js +26 -0
  191. package/dist/list/list.js +812 -0
  192. package/dist/list/list__custom.js +85 -0
  193. package/dist/list/list__hint.js +26 -0
  194. package/dist/list/list__item.js +204 -0
  195. package/dist/list/list__link.js +64 -0
  196. package/dist/list/list__separator.js +30 -0
  197. package/dist/list/list__title.js +39 -0
  198. package/dist/list/list__users-groups-source.js +128 -0
  199. package/dist/loader/loader.js +70 -0
  200. package/dist/loader/loader__core.js +272 -0
  201. package/dist/loader-inline/inject-styles.js +11 -0
  202. package/dist/loader-inline/loader-inline.js +56 -0
  203. package/dist/loader-inline-ng/loader-inline-ng.js +42 -0
  204. package/dist/loader-ng/loader-ng.js +43 -0
  205. package/dist/loader-screen/loader-screen.js +43 -0
  206. package/dist/loader-screen-ng/loader-screen-ng.js +99 -0
  207. package/dist/login-dialog/login-dialog.js +186 -0
  208. package/dist/login-dialog/service.js +69 -0
  209. package/dist/markdown/code.js +30 -0
  210. package/dist/markdown/heading.js +23 -0
  211. package/dist/markdown/link.js +30 -0
  212. package/dist/markdown/markdown.js +73 -0
  213. package/dist/message/message.js +233 -0
  214. package/dist/message-bundle-ng/message-bundle-ng.js +111 -0
  215. package/dist/old-browsers-message/old-browsers-message.js +100 -0
  216. package/dist/old-browsers-message/old-browsers-message__stop.js +4 -0
  217. package/dist/old-browsers-message/white-list.js +33 -0
  218. package/dist/pager/pager.js +361 -0
  219. package/dist/pager-ng/pager-ng.js +96 -0
  220. package/dist/panel/panel.js +31 -0
  221. package/dist/panel-ng/panel-ng.js +16 -0
  222. package/dist/permissions/permissions.js +200 -0
  223. package/dist/permissions/permissions__cache.js +272 -0
  224. package/dist/permissions-ng/permissions-ng.js +274 -0
  225. package/dist/place-under-ng/place-under-ng.js +157 -0
  226. package/dist/popup/popup.consts.js +41 -0
  227. package/dist/popup/popup.js +389 -0
  228. package/dist/popup/popup.target.js +26 -0
  229. package/dist/popup/position.js +279 -0
  230. package/dist/popup-menu/popup-menu.js +115 -0
  231. package/dist/progress-bar/progress-bar.js +113 -0
  232. package/dist/progress-bar-ng/progress-bar-ng.js +15 -0
  233. package/dist/promised-click-ng/promised-click-ng.js +126 -0
  234. package/dist/proxy-attrs/proxy-attrs.js +19 -0
  235. package/dist/query-assist/query-assist.js +1092 -0
  236. package/dist/query-assist/query-assist__suggestions.js +47 -0
  237. package/dist/query-assist-ng/query-assist-ng.js +82 -0
  238. package/dist/radio/radio.js +41 -0
  239. package/dist/radio/radio__item.js +77 -0
  240. package/dist/radio-ng/radio-ng.js +63 -0
  241. package/dist/save-field-ng/save-field-ng.js +335 -0
  242. package/dist/save-field-ng/save-field-ng__template.js +34 -0
  243. package/dist/select/select.js +1336 -0
  244. package/dist/select/select__filter.js +54 -0
  245. package/dist/select/select__popup.js +546 -0
  246. package/dist/select-ng/select-ng.js +621 -0
  247. package/dist/select-ng/select-ng__lazy.js +150 -0
  248. package/dist/select-ng/select-ng__options.js +145 -0
  249. package/dist/shortcuts/core.js +245 -0
  250. package/dist/shortcuts/shortcut-title.js +51 -0
  251. package/dist/shortcuts/shortcuts-hoc.js +41 -0
  252. package/dist/shortcuts/shortcuts.js +72 -0
  253. package/dist/shortcuts-hint-ng/shortcuts-hint-ng.js +120 -0
  254. package/dist/shortcuts-hint-ng/shortcuts-hint-ng__template.js +50 -0
  255. package/dist/shortcuts-ng/shortcuts-ng.js +261 -0
  256. package/dist/sidebar-ng/sidebar-ng.js +111 -0
  257. package/dist/sidebar-ng/sidebar-ng__button-template.js +20 -0
  258. package/dist/sidebar-ng/sidebar-ng__template.js +12 -0
  259. package/dist/storage/storage.js +56 -0
  260. package/dist/storage/storage__fallback.js +214 -0
  261. package/dist/storage/storage__local.js +151 -0
  262. package/dist/style.css +1 -0
  263. package/dist/tab-trap/tab-trap.js +176 -0
  264. package/dist/table/cell.js +25 -0
  265. package/dist/table/disable-hover-hoc.js +53 -0
  266. package/dist/table/header-cell.js +90 -0
  267. package/dist/table/header.js +191 -0
  268. package/dist/table/multitable.js +140 -0
  269. package/dist/table/row-with-focus-sensor.js +81 -0
  270. package/dist/table/row.js +271 -0
  271. package/dist/table/selection-adapter.js +14 -0
  272. package/dist/table/selection-shortcuts-hoc.js +214 -0
  273. package/dist/table/selection.js +221 -0
  274. package/dist/table/smart-table.js +119 -0
  275. package/dist/table/table.js +404 -0
  276. package/dist/table-legacy-ng/table-legacy-ng.js +501 -0
  277. package/dist/table-legacy-ng/table-legacy-ng__pager.js +122 -0
  278. package/dist/table-legacy-ng/table-legacy-ng__selection-navigate-actions.js +123 -0
  279. package/dist/table-legacy-ng/table-legacy-ng__selection.js +179 -0
  280. package/dist/table-legacy-ng/table-legacy-ng__toolbar.js +56 -0
  281. package/dist/table-ng/smart-table-ng.js +65 -0
  282. package/dist/table-ng/table-ng.js +64 -0
  283. package/dist/tabs/collapsible-more.js +196 -0
  284. package/dist/tabs/collapsible-tab.js +90 -0
  285. package/dist/tabs/collapsible-tabs.js +360 -0
  286. package/dist/tabs/custom-item.js +13 -0
  287. package/dist/tabs/dumb-tabs.js +161 -0
  288. package/dist/tabs/smart-tabs.js +104 -0
  289. package/dist/tabs/tab-link.js +41 -0
  290. package/dist/tabs/tab.js +32 -0
  291. package/dist/tabs/tabs.js +69 -0
  292. package/dist/tabs-ng/tabs-ng.js +193 -0
  293. package/dist/tabs-ng/tabs-ng__template.js +40 -0
  294. package/dist/tag/tag.js +196 -0
  295. package/dist/tags-input/tags-input.js +478 -0
  296. package/dist/tags-input-ng/tags-input-ng.js +89 -0
  297. package/dist/tags-list/tags-list.js +93 -0
  298. package/dist/template-ng/template-ng.js +70 -0
  299. package/dist/text/text.js +36 -0
  300. package/dist/theme-ng/theme-ng.js +44 -0
  301. package/dist/title-ng/title-ng.js +114 -0
  302. package/dist/toggle/toggle.js +77 -0
  303. package/dist/toggle-ng/toggle-ng.js +16 -0
  304. package/dist/tooltip/tooltip.js +207 -0
  305. package/dist/tooltip-ng/tooltip-ng.js +98 -0
  306. package/dist/user-agreement/service.js +409 -0
  307. package/dist/user-agreement/toolbox.eula.js +162 -0
  308. package/dist/user-agreement/user-agreement.js +167 -0
  309. package/dist/user-card/card.js +17 -0
  310. package/dist/user-card/smart-user-card-tooltip.js +112 -0
  311. package/dist/user-card/tooltip.js +93 -0
  312. package/dist/user-card/user-card.js +49 -0
  313. package/dist/user-card-ng/user-card-ng.js +59 -0
  314. package/package.json +2 -2
@@ -0,0 +1,1092 @@
1
+ import { _ as _defineProperty } from '../_helpers/_rollupPluginBabelHelpers.js';
2
+ import React, { Component } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import debounce from 'just-debounce-it';
5
+ import classNames from 'classnames';
6
+ import deepEqual from 'deep-equal';
7
+ import searchIcon from '@jetbrains/icons/search';
8
+ import closeIcon from '@jetbrains/icons/close';
9
+ import getUID from '../global/get-uid.js';
10
+ import joinDataTestAttributes from '../global/data-tests.js';
11
+ import { preventDefault, getRect } from '../global/dom.js';
12
+ import Caret from '../caret/caret.js';
13
+ import ContentEditable from '../contenteditable/contenteditable.js';
14
+ import PopupMenu from '../popup-menu/popup-menu.js';
15
+ import LoaderInline from '../loader-inline/loader-inline.js';
16
+ import Shortcuts from '../shortcuts/shortcuts.js';
17
+ import rerenderHOC from '../global/rerender-hoc.js';
18
+ import Theme from '../global/theme.js';
19
+ import Button from '../button/button.js';
20
+ import { Q as QueryAssistSuggestions, m as modules_da7ab055 } from '../_helpers/query-assist__suggestions.js';
21
+ import 'react-dom/server';
22
+ import '../popup/popup.js';
23
+ import 'react-dom';
24
+ import '../global/schedule-raf.js';
25
+ import '../tab-trap/tab-trap.js';
26
+ import '../popup/position.js';
27
+ import '../popup/popup.consts.js';
28
+ import '../popup/popup.target.js';
29
+ import '../shortcuts/core.js';
30
+ import 'combokeys';
31
+ import '../global/sniffer.js';
32
+ import 'sniffr';
33
+ import '../list/list.js';
34
+ import 'react-virtualized/dist/es/List';
35
+ import 'react-virtualized/dist/es/AutoSizer';
36
+ import 'react-virtualized/dist/es/WindowScroller';
37
+ import 'react-virtualized/dist/es/CellMeasurer';
38
+ import 'util-deprecate';
39
+ import 'memoize-one';
40
+ import '../global/memoize.js';
41
+ import '../global/create-stateful-context.js';
42
+ import '../list/list__link.js';
43
+ import '../link/link.js';
44
+ import 'focus-visible';
45
+ import '../link/clickableLink.js';
46
+ import '../_helpers/link.js';
47
+ import '../_helpers/list.js';
48
+ import '../list/list__item.js';
49
+ import '../avatar/avatar.js';
50
+ import '../global/url.js';
51
+ import '../avatar/fallback-avatar.js';
52
+ import '../checkbox/checkbox.js';
53
+ import '@jetbrains/icons/checkmark';
54
+ import '@jetbrains/icons/remove-10px';
55
+ import '../icon/icon.js';
56
+ import '../icon/icon__constants.js';
57
+ import '../_helpers/icon.js';
58
+ import '../icon/icon__svg.js';
59
+ import '../_helpers/checkbox.js';
60
+ import '../list/list__custom.js';
61
+ import '../global/get-event-key.js';
62
+ import '../list/list__title.js';
63
+ import '../list/list__separator.js';
64
+ import '../list/list__hint.js';
65
+ import '../list/consts.js';
66
+ import '../_helpers/inject-styles.js';
67
+ import '../global/conic-gradient.js';
68
+ import 'conic-gradient';
69
+ import '../global/supports-css.js';
70
+ import '../global/inject-styles.js';
71
+ import '../global/radial-gradient-mask.js';
72
+ import '@jetbrains/icons/chevron-10px';
73
+ import '../_helpers/button__classes.js';
74
+
75
+ const POPUP_COMPENSATION = PopupMenu.ListProps.Dimension.ITEM_PADDING + PopupMenu.PopupProps.Dimension.BORDER_WIDTH;
76
+ const ngModelStateField = 'query';
77
+
78
+ function noop() {}
79
+
80
+ function cleanText(text) {
81
+ return text.replace(/([\n\r])+/g, ' ');
82
+ }
83
+ /**
84
+ * @name Query Assist
85
+ */
86
+
87
+ /**
88
+ * ## Data source function
89
+
90
+ Component class calls a data source function when user input happens and passes an object with fields \`caret\`, \`focus\` and \`query\` as the only argument.
91
+ The function must return an object with the fields described below. The object can be optionally wrapped in a Promise.
92
+
93
+ ### Return object fields
94
+
95
+ \`caret\` and \`query\` should just return server values provided to data source function.
96
+ These fields allow the Query Assist component to recognise and drop earlier responses from the server.
97
+
98
+ + __caret__ (\`string=0\`) Caret from request
99
+ + __query__ (\`string=''\`) Query from request
100
+ + __styleRanges__ (\`Array<suggestion>=\`) Array of \`styleRange\` objects, used to highlight the request in the input field
101
+ + __suggestions__ (\`Array<styleRange>\`) Array of \`suggestion\` objects to show.
102
+
103
+ ### **styleRange** object fields
104
+
105
+ start \`number\` Range start (in characters)
106
+ length \`number\` Range length (in characters)
107
+ style \`string\` Style of the range. Possible values: \`text\`, \`field_value\`, \`field_name\`, \`operator\`
108
+
109
+ ### **suggestion** object fields
110
+
111
+ + __prefix__ \`string=\` Suggestion option prefix
112
+ + __option__ \`string\` Suggestion option
113
+ + __suffix__ \`string=\` Suggestion option suffix
114
+ + __description__ \`string=\` Suggestion option description. Is not visible when a group is set
115
+ + __matchingStart__ \`number\` (required when matchingEnd is set) Start of the highlighted part of an option in the suggestions list (in characters)
116
+ + __matchingEnd__ \`number\` (required when matchingEnd is set) End of the highlighted part of an option in the suggestions list (in characters)
117
+ + __caret__ \`number\` Caret position after option completion (in characters)
118
+ + __completionStart__ \`number\` Where to start insertion (or replacement, when completing with the \`Tab\` key) of the completion option (in characters)
119
+ + __completionEnd__ \`number\` Where to end insertion of the completion option (in characters)
120
+ + __group__ \`string=\` Group title. Options with the same title are grouped under it
121
+ + __icon__ \`string=\` Icon URI, Data URI is possible
122
+ */
123
+
124
+
125
+ class QueryAssist extends Component {
126
+ constructor() {
127
+ var _this;
128
+
129
+ super(...arguments);
130
+ _this = this;
131
+
132
+ _defineProperty(this, "state", {
133
+ dirty: !this.props.query,
134
+ query: this.props.query,
135
+ placeholderEnabled: !this.props.query,
136
+ shortcuts: !!this.props.focus,
137
+ suggestions: [],
138
+ showPopup: false
139
+ });
140
+
141
+ _defineProperty(this, "ngModelStateField", ngModelStateField);
142
+
143
+ _defineProperty(this, "historyStack", []);
144
+
145
+ _defineProperty(this, "handleFocusChange", e => {
146
+ // otherwise it's blur and false
147
+ const focus = e.type === 'focus';
148
+ this.immediateState.focus = focus;
149
+
150
+ if (!focus) {
151
+ this.blurInput(); // Close popup on blur by keyboard (mostly shift+tab)
152
+
153
+ if (!this.mouseIsDownOnPopup) {
154
+ this.closePopup();
155
+ }
156
+ } else {
157
+ this.setCaretPosition();
158
+ }
159
+
160
+ if (!this.mouseIsDownOnPopup) {
161
+ this.props.onFocusChange({
162
+ focus
163
+ });
164
+ }
165
+
166
+ this.setState({
167
+ shortcuts: !!focus
168
+ });
169
+ });
170
+
171
+ _defineProperty(this, "nodeRef", node => {
172
+ this.node = node;
173
+ });
174
+
175
+ _defineProperty(this, "setCaretPosition", function () {
176
+ let params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
177
+ const queryLength = _this.immediateState.query != null && _this.immediateState.query.length;
178
+ const newCaretPosition = _this.immediateState.caret < queryLength ? _this.immediateState.caret : queryLength;
179
+
180
+ if (params.fromContentEditable) {
181
+ _this.immediateState.selection = _this.immediateState.selection ? _this.immediateState.selection : _this.state.query && _this.state.query.length;
182
+ }
183
+
184
+ if (_this.immediateState.focus && !_this.props.disabled) {
185
+ if (Number.isInteger(_this.immediateState.selection) && _this.immediateState.selection > -1) {
186
+ // Set to end of field value if newCaretPosition is inappropriate
187
+ _this.caret.setPosition(newCaretPosition >= 0 ? newCaretPosition : -1);
188
+
189
+ _this.scrollInput();
190
+ } else if (_this.immediateState.selection && _this.immediateState.selection.startOffset !== undefined) {
191
+ _this.caret.setPosition(_this.immediateState.selection);
192
+ } else if (!_this.immediateState.selection || params.forceSetCaret) {
193
+ _this.caret.setPosition(-1);
194
+ }
195
+ }
196
+ });
197
+
198
+ _defineProperty(this, "togglePlaceholder", () => {
199
+ const query = this.getQuery();
200
+ const currentQueryIsEmpty = this.immediateState.query === '';
201
+ const newQueryIsEmpty = query === '';
202
+
203
+ if (newQueryIsEmpty !== currentQueryIsEmpty) {
204
+ this.setState({
205
+ placeholderEnabled: newQueryIsEmpty
206
+ });
207
+ }
208
+ });
209
+
210
+ _defineProperty(this, "handleInput", e => {
211
+ this.togglePlaceholder();
212
+ const currentCaret = this.caret.getPosition();
213
+ const props = {
214
+ dirty: true,
215
+ query: this.getQuery(),
216
+ caret: Number.isInteger(currentCaret) ? currentCaret : currentCaret.position,
217
+ focus: true
218
+ };
219
+
220
+ if (this.immediateState.query === props.query && !this.isComposing) {
221
+ this.handleCaretMove(e);
222
+ return;
223
+ }
224
+
225
+ if (this.isComposing) {
226
+ return;
227
+ }
228
+
229
+ this.immediateState = props;
230
+ this.props.onChange(props);
231
+
232
+ if (props.query.length > 0) {
233
+ this.requestData();
234
+ }
235
+ });
236
+
237
+ _defineProperty(this, "handleEnter", e => {
238
+ if (e.key === 'Enter') {
239
+ preventDefault(e);
240
+ }
241
+ });
242
+
243
+ _defineProperty(this, "handleTab", e => {
244
+ const list = this._popup && this._popup.list;
245
+ const suggestion = list && (list.getSelected() || list.getFirst());
246
+
247
+ if (suggestion && this.state.showPopup) {
248
+ preventDefault(e);
249
+
250
+ if (this.getQuery() !== this.immediateState.suggestionsQuery) {
251
+ return false;
252
+ }
253
+
254
+ return this.handleComplete(suggestion, true);
255
+ }
256
+
257
+ if (this.state.loading) {
258
+ preventDefault(e);
259
+ return false;
260
+ }
261
+
262
+ return true;
263
+ });
264
+
265
+ _defineProperty(this, "setState", (state, resolve) => {
266
+ super.setState(state, () => {
267
+ this._pushHistory(state);
268
+
269
+ resolve === null || resolve === void 0 ? void 0 : resolve();
270
+ });
271
+ });
272
+
273
+ _defineProperty(this, "undo", e => {
274
+ // eslint-disable-next-line no-unused-vars
275
+ const [current, previous] = this.historyStack.splice(0, 2);
276
+
277
+ if (!previous) {
278
+ return;
279
+ }
280
+
281
+ this.setState({
282
+ query: previous.query
283
+ }, () => {
284
+ this.caret.setPosition(previous.caret);
285
+ this.handleInput(e);
286
+ });
287
+ });
288
+
289
+ _defineProperty(this, "handlePaste", e => {
290
+ const INSERT_COMMAND = 'insertText';
291
+
292
+ if (e.clipboardData && document.queryCommandSupported(INSERT_COMMAND)) {
293
+ preventDefault(e);
294
+ const text = cleanText(e.clipboardData.getData('text/plain'));
295
+ document.execCommand(INSERT_COMMAND, false, text);
296
+ this.handleInput(e);
297
+ }
298
+ });
299
+
300
+ _defineProperty(this, "handleCaretMove", e => {
301
+ if (this.isComposing) {
302
+ return;
303
+ }
304
+
305
+ const currentCaret = this.caret.getPosition();
306
+ const caret = Number.isInteger(currentCaret) ? currentCaret : currentCaret.position;
307
+ const popupHidden = !this.state.showPopup && e.type === 'click';
308
+
309
+ if (!this.props.disabled && (caret !== this.immediateState.caret || popupHidden)) {
310
+ this.immediateState.caret = caret;
311
+ this.scrollInput();
312
+
313
+ if (this.immediateState.query.length > 0) {
314
+ this.requestData();
315
+ }
316
+ }
317
+
318
+ if (this.immediateState.query.length < 1) {
319
+ this.setState({
320
+ showPopup: false
321
+ });
322
+ }
323
+ });
324
+
325
+ _defineProperty(this, "handleStyleRangesResponse", _ref => {
326
+ let {
327
+ suggestions,
328
+ ...restProps
329
+ } = _ref;
330
+ return this.handleResponse(restProps);
331
+ });
332
+
333
+ _defineProperty(this, "handleResponse", function (_ref2) {
334
+ let {
335
+ query = '',
336
+ caret = 0,
337
+ styleRanges,
338
+ suggestions = []
339
+ } = _ref2;
340
+ let afterCompletion = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
341
+ return new Promise((resolve, reject) => {
342
+ if (query === _this.getQuery() && (caret === _this.immediateState.caret || _this.immediateState.caret === undefined)) {
343
+ // Do not setState on unmounted component
344
+ if (!_this.node) {
345
+ return;
346
+ }
347
+
348
+ const state = {
349
+ dirty: _this.immediateState.dirty,
350
+ loading: false,
351
+ placeholderEnabled: !query,
352
+ query,
353
+ suggestions,
354
+ showPopup: !!suggestions.length && !afterCompletion
355
+ };
356
+ _this.immediateState.suggestionsQuery = query; // Do not update deep equal styleRanges to simplify shouldComponentUpdate check
357
+
358
+ if (!deepEqual(_this.state.styleRanges, styleRanges)) {
359
+ state.styleRanges = styleRanges;
360
+ }
361
+
362
+ _this.immediateState.selection = _this.caret.getPosition({
363
+ avoidFocus: true
364
+ });
365
+
366
+ _this.setState(state, resolve);
367
+ } else {
368
+ reject(new Error('Current and response queries mismatch'));
369
+ }
370
+ });
371
+ });
372
+
373
+ _defineProperty(this, "handleApply", () => {
374
+ this.closePopup();
375
+ this.immediateState.dirty = false; // Only set dirty to false when query is saved already
376
+
377
+ if (this.immediateState.query === this.state.query) {
378
+ this.setState({
379
+ dirty: false
380
+ });
381
+ }
382
+
383
+ return this.props.onApply(this.immediateState);
384
+ });
385
+
386
+ _defineProperty(this, "handleComplete", (data, replace) => {
387
+ if (!data || !data.data) {
388
+ this.handleApply();
389
+ return;
390
+ }
391
+
392
+ const query = this.getQuery();
393
+ const currentCaret = this.immediateState.caret;
394
+ const suggestion = data.data;
395
+ const prefix = suggestion.prefix || '';
396
+ const suffix = suggestion.suffix || '';
397
+ const state = {
398
+ caret: suggestion.caret,
399
+ selection: suggestion.caret,
400
+ query: query.substr(0, suggestion.completionStart) + prefix + suggestion.option + suffix
401
+ };
402
+
403
+ if (typeof replace === 'boolean' && replace) {
404
+ state.query += this.immediateState.query.substr(suggestion.completionEnd);
405
+ } else {
406
+ state.query += this.immediateState.query.substr(this.immediateState.caret);
407
+ }
408
+
409
+ this.props.onChange(state);
410
+ this.props.onApplySuggestion(data.data, state);
411
+ const focusState = {
412
+ focus: true
413
+ };
414
+ this.props.onFocusChange(focusState);
415
+
416
+ if (state.query !== this.immediateState.query) {
417
+ this.setState({
418
+ placeholderEnabled: !state.query,
419
+ query: state.query
420
+ });
421
+ }
422
+
423
+ this.immediateState = Object.assign(state, focusState);
424
+
425
+ if (this.immediateState.caret !== currentCaret) {
426
+ this.setCaretPosition();
427
+ }
428
+
429
+ this.closePopup();
430
+ this.requestData(true);
431
+ });
432
+
433
+ _defineProperty(this, "requestStyleRanges", () => {
434
+ const {
435
+ query,
436
+ caret
437
+ } = this.immediateState;
438
+
439
+ if (!query) {
440
+ return Promise.reject(new Error('Query is empty'));
441
+ }
442
+
443
+ return this.sendRequest({
444
+ query,
445
+ caret,
446
+ omitSuggestions: true
447
+ }).then(this.handleStyleRangesResponse).catch(noop);
448
+ });
449
+
450
+ _defineProperty(this, "requestHandler", function () {
451
+ let afterCompletion = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
452
+
453
+ if (_this.props.disabled) {
454
+ return Promise.reject(new Error('QueryAssist(@jetbrains/ring-ui): null exception'));
455
+ }
456
+
457
+ const {
458
+ query,
459
+ caret
460
+ } = _this.immediateState;
461
+ return _this.sendRequest({
462
+ query,
463
+ caret
464
+ }).then(data => _this.handleResponse(data, afterCompletion)).catch(noop);
465
+ });
466
+
467
+ _defineProperty(this, "handleCtrlSpace", e => {
468
+ preventDefault(e);
469
+
470
+ if (!this.state.showPopup) {
471
+ this.requestData();
472
+ }
473
+ });
474
+
475
+ _defineProperty(this, "trackPopupMouseState", e => {
476
+ this.mouseIsDownOnPopup = e.type === 'mousedown';
477
+ });
478
+
479
+ _defineProperty(this, "trackCompositionState", e => {
480
+ this.isComposing = e.type !== 'compositionend';
481
+ });
482
+
483
+ _defineProperty(this, "closePopup", () => {
484
+ if (this.node) {
485
+ this.setState({
486
+ showPopup: false
487
+ });
488
+ }
489
+ });
490
+
491
+ _defineProperty(this, "clearQuery", () => {
492
+ const state = {
493
+ dirty: false,
494
+ caret: 0,
495
+ query: '',
496
+ focus: true
497
+ };
498
+ this.props.onChange(state);
499
+ this.props.onClear();
500
+ this.immediateState = state;
501
+ this.setState({
502
+ dirty: false,
503
+ query: '',
504
+ placeholderEnabled: true,
505
+ loading: false
506
+ });
507
+ });
508
+
509
+ _defineProperty(this, "inputRef", node => {
510
+ if (!node) {
511
+ return;
512
+ }
513
+
514
+ this.input = node;
515
+ this.caret = new Caret(this.input);
516
+ });
517
+
518
+ _defineProperty(this, "popupRef", node => {
519
+ this._popup = node;
520
+ });
521
+
522
+ _defineProperty(this, "placeholderRef", node => {
523
+ this.placeholder = node;
524
+ });
525
+
526
+ _defineProperty(this, "glassRef", node => {
527
+ this.glass = node;
528
+ });
529
+
530
+ _defineProperty(this, "loaderRef", node => {
531
+ this.loader = node;
532
+ });
533
+
534
+ _defineProperty(this, "clearRef", node => {
535
+ this.clear = node;
536
+ });
537
+
538
+ _defineProperty(this, "shortcutsScope", getUID('ring-query-assist-'));
539
+
540
+ _defineProperty(this, "shortcutsMap", {
541
+ del: noop,
542
+ enter: this.handleComplete,
543
+ 'command+enter': this.handleComplete,
544
+ 'ctrl+enter': this.handleComplete,
545
+ 'ctrl+space': this.handleCtrlSpace,
546
+ tab: this.handleTab,
547
+ 'meta+z': this.undo,
548
+ right: noop,
549
+ left: noop,
550
+ space: noop,
551
+ home: noop,
552
+ end: noop
553
+ });
554
+ }
555
+
556
+ static getDerivedStateFromProps(_ref3, _ref4) {
557
+ let {
558
+ query
559
+ } = _ref3;
560
+ let {
561
+ prevQuery
562
+ } = _ref4;
563
+ const nextState = {
564
+ prevQuery: query
565
+ };
566
+
567
+ if (typeof query === 'string' && query !== prevQuery) {
568
+ nextState.query = query;
569
+ nextState.placeholderEnabled = !query;
570
+ }
571
+
572
+ return nextState;
573
+ }
574
+
575
+ componentDidMount() {
576
+ const query = this.props.query || '';
577
+ this.immediateState = {
578
+ query,
579
+ caret: Number.isFinite(this.props.caret) ? this.props.caret : query.length,
580
+ focus: Boolean(this.props.autoOpen || this.props.focus)
581
+ };
582
+ this.setupRequestHandler(this.props.delay);
583
+
584
+ if (this.props.autoOpen && query.length > 0) {
585
+ this.requestHandler().catch(noop);
586
+ } else {
587
+ this.requestStyleRanges().catch(noop);
588
+ }
589
+
590
+ this.setCaretPosition();
591
+
592
+ this._pushHistory(this.state);
593
+ }
594
+
595
+ shouldComponentUpdate(props, state) {
596
+ return state.query !== this.state.query || state.dirty !== this.state.dirty || state.loading !== this.state.loading || state.showPopup !== this.state.showPopup || state.suggestions !== this.state.suggestions || state.styleRanges !== this.state.styleRanges || state.placeholderEnabled !== this.state.placeholderEnabled || props.placeholder !== this.props.placeholder || props.disabled !== this.props.disabled || props.clear !== this.props.clear || props.focus !== this.props.focus || props.actions !== this.props.actions || props.loader !== this.props.loader || props.glass !== this.props.glass;
597
+ }
598
+
599
+ componentDidUpdate(prevProps) {
600
+ const {
601
+ caret,
602
+ delay,
603
+ query
604
+ } = this.props;
605
+ const queryChanged = query !== prevProps.query;
606
+ this.updateFocus(prevProps);
607
+ this.setupRequestHandler(delay);
608
+ const shouldSetCaret = typeof caret === 'number' && caret !== prevProps.caret;
609
+
610
+ if (shouldSetCaret) {
611
+ this.immediateState.caret = caret;
612
+ }
613
+
614
+ if (typeof query === 'string' && queryChanged && query !== this.immediateState.query) {
615
+ this.immediateState.query = query;
616
+
617
+ if (query && prevProps.autoOpen && query.length > 0) {
618
+ this.requestData();
619
+ } else if (query) {
620
+ this.requestStyleRanges();
621
+ }
622
+ }
623
+ }
624
+
625
+ updateFocus(_ref5) {
626
+ let {
627
+ focus,
628
+ caret
629
+ } = _ref5;
630
+ const isCaretChanged = caret !== this.props.caret;
631
+ const isFocusChanged = focus !== this.props.focus;
632
+
633
+ if (isFocusChanged || isCaretChanged) {
634
+ const focusValue = isFocusChanged ? this.props.focus : true;
635
+ this.setFocus(focusValue);
636
+ }
637
+ }
638
+
639
+ scrollInput() {
640
+ const caretOffset = this.caret.getOffset();
641
+
642
+ if (this.input.clientWidth !== this.input.scrollWidth && caretOffset > this.input.clientWidth) {
643
+ this.input.scrollLeft += caretOffset;
644
+ }
645
+ }
646
+
647
+ getQuery() {
648
+ return this.input.textContent.replace(/\s/g, ' ');
649
+ }
650
+
651
+ isRenderingGlassOrLoader() {
652
+ const renderLoader = this.props.loader !== false && this.state.loading;
653
+ return this.props.glass || renderLoader;
654
+ }
655
+
656
+ _pushHistory(state) {
657
+ var _this$historyStack$;
658
+
659
+ const queryIsSet = ('query' in state);
660
+ const queryIsSame = ((_this$historyStack$ = this.historyStack[0]) === null || _this$historyStack$ === void 0 ? void 0 : _this$historyStack$.query) === state.query;
661
+
662
+ if (queryIsSet && !queryIsSame) {
663
+ var _this$caret$getPositi, _this$caret;
664
+
665
+ this.historyStack.unshift({
666
+ query: state.query,
667
+ caret: (_this$caret$getPositi = (_this$caret = this.caret) === null || _this$caret === void 0 ? void 0 : _this$caret.getPosition({
668
+ avoidFocus: true
669
+ })) !== null && _this$caret$getPositi !== void 0 ? _this$caret$getPositi : -1
670
+ });
671
+ }
672
+ }
673
+
674
+ sendRequest(params) {
675
+ const value = this.props.dataSource(params);
676
+ const dataPromise = Promise.resolve(value);
677
+ const CLOSE_POPUP_TIMEOUT = 500; // Close popup after timeout between long requests
678
+
679
+ const timeout = window.setTimeout(() => {
680
+ if (this.node) {
681
+ this.setState({
682
+ loading: true
683
+ });
684
+ }
685
+
686
+ if (params.query === this.immediateState.query) {
687
+ this.closePopup();
688
+ }
689
+ }, CLOSE_POPUP_TIMEOUT);
690
+ dataPromise.then(() => window.clearTimeout(timeout)).catch(() => {
691
+ window.clearTimeout(timeout);
692
+ this.setState({
693
+ loading: false
694
+ });
695
+ });
696
+ return dataPromise;
697
+ }
698
+
699
+ getPopupOffset(suggestions) {
700
+ const ICON_SPACING = 12;
701
+ const minOffset = this.isRenderingGlassOrLoader() ? ICON_SPACING : 0;
702
+
703
+ if (!this.input) {
704
+ return minOffset;
705
+ } // First suggestion should be enough?
706
+
707
+
708
+ const suggestion = suggestions && suggestions[0]; // Check if suggestion begins not from the end
709
+
710
+ const completionStart = suggestion && suggestion.completionStart !== suggestion.completionEnd && suggestion.completionStart;
711
+ const inputChildren = this.input.firstChild && this.input.firstChild.children;
712
+ const completionStartNode = inputChildren && Number.isInteger(completionStart) && inputChildren[Math.min(completionStart, inputChildren.length - 1)];
713
+ let offset = completionStartNode && getRect(completionStartNode).right - getRect(this.input).left;
714
+
715
+ if (!offset) {
716
+ const caret = this.caret.getOffset(); // Do not compensate caret in the beginning of field
717
+
718
+ if (caret === 0) {
719
+ return minOffset;
720
+ } else {
721
+ offset = caret;
722
+ }
723
+ }
724
+
725
+ const result = offset - POPUP_COMPENSATION;
726
+ return result < minOffset ? minOffset : result;
727
+ }
728
+
729
+ blurInput() {
730
+ this.immediateState.selection = {};
731
+
732
+ if (!this.props.focus) {
733
+ this.caret.target.blur();
734
+ }
735
+ }
736
+ /**
737
+ * Optionally setup data request delay. For each component create a separate
738
+ * instance of the delayed function. This may help reduce the load on the server
739
+ * when the user quickly inputs data.
740
+ */
741
+
742
+
743
+ setupRequestHandler(delay) {
744
+ const needDelay = typeof delay === 'number';
745
+ const hasDelay = this.requestData !== this.requestHandler;
746
+
747
+ if (!this.requestData || hasDelay !== needDelay) {
748
+ if (needDelay) {
749
+ this.requestData = debounce(this.requestHandler, delay);
750
+ } else {
751
+ this.requestData = this.requestHandler;
752
+ }
753
+ }
754
+ }
755
+
756
+ _renderSuggestion(suggestion) {
757
+ const {
758
+ ITEM
759
+ } = PopupMenu.ListProps.Type;
760
+ const {
761
+ description,
762
+ icon,
763
+ group
764
+ } = suggestion;
765
+ const key = QueryAssistSuggestions.createKey(suggestion);
766
+ const label = QueryAssistSuggestions.renderLabel(suggestion);
767
+ return {
768
+ key,
769
+ icon,
770
+ label,
771
+ description,
772
+ group,
773
+ rgItemType: ITEM,
774
+ data: suggestion
775
+ };
776
+ }
777
+
778
+ renderSuggestions() {
779
+ const {
780
+ suggestions
781
+ } = this.state;
782
+
783
+ if (!suggestions || !suggestions.length) {
784
+ return [];
785
+ }
786
+
787
+ return QueryAssistSuggestions.renderList(suggestions, this._renderSuggestion);
788
+ }
789
+
790
+ renderQuery() {
791
+ const {
792
+ dirty,
793
+ styleRanges,
794
+ query
795
+ } = this.state;
796
+ const classes = [];
797
+ const LETTER_CLASS = 'letter';
798
+ const LETTER_DEFAULT_CLASS = modules_da7ab055.letterDefault;
799
+
800
+ if (styleRanges && styleRanges.length) {
801
+ styleRanges.forEach((item, index) => {
802
+ if (dirty && index === styleRanges.length - 1 && item.style === 'text') {
803
+ return;
804
+ }
805
+
806
+ const styleName = `${LETTER_CLASS}-${item.style.replace('_', '-')}`;
807
+
808
+ for (let i = item.start; i < item.start + item.length; i++) {
809
+ classes[i] = modules_da7ab055[styleName];
810
+ }
811
+ });
812
+ }
813
+
814
+ return Array.from(query).map((letter, index, letters) => {
815
+ const className = classNames(modules_da7ab055.letter, classes[index] || LETTER_DEFAULT_CLASS);
816
+ const dataTest = letters.length - 1 === index ? 'ring-query-assist-last-letter' : null; // \u00a0 === &nbsp;
817
+
818
+ return /*#__PURE__*/React.createElement("span", {
819
+ // eslint-disable-next-line react/no-array-index-key
820
+ key: index + letter,
821
+ className: className,
822
+ "data-test": dataTest
823
+ }, letter === ' ' ? '\u00a0' : letter);
824
+ });
825
+ }
826
+
827
+ setFocus(focus) {
828
+ this.setState({
829
+ shortcuts: !!focus
830
+ });
831
+ const isComponentFocused = Boolean(this.immediateState.focus);
832
+
833
+ if (focus === false && isComponentFocused) {
834
+ this.immediateState.focus = focus;
835
+ this.blurInput();
836
+ } else if (focus === true && !isComponentFocused) {
837
+ this.immediateState.focus = focus;
838
+ this.setCaretPosition({
839
+ forceSetCaret: true
840
+ });
841
+ }
842
+ }
843
+
844
+ renderActions() {
845
+ const actions = [].concat(this.props.actions || []);
846
+ const renderClear = this.props.clear && !!this.state.query;
847
+
848
+ if (renderClear) {
849
+ actions.push( /*#__PURE__*/React.createElement(Button, {
850
+ icon: closeIcon,
851
+ key: 'clearAction',
852
+ className: modules_da7ab055.icon,
853
+ iconClassName: modules_da7ab055.iconInner,
854
+ title: this.props.translations.clearTitle,
855
+ ref: this.clearRef,
856
+ onClick: this.clearQuery,
857
+ "data-test": "query-assist-clear-icon"
858
+ }));
859
+ }
860
+
861
+ return actions;
862
+ }
863
+
864
+ render() {
865
+ const {
866
+ theme,
867
+ glass,
868
+ 'data-test': dataTest,
869
+ className,
870
+ useCustomItemRender
871
+ } = this.props;
872
+ const renderPlaceholder = !!this.props.placeholder && this.state.placeholderEnabled;
873
+ const renderLoader = this.props.loader !== false && this.state.loading;
874
+ const renderGlass = glass && !renderLoader;
875
+ const renderUnderline = theme === Theme.DARK;
876
+ const actions = this.renderActions();
877
+ const inputClasses = classNames({
878
+ [`${modules_da7ab055.input} ring-js-shortcuts`]: true,
879
+ [modules_da7ab055.inputGap]: actions.length || this.isRenderingGlassOrLoader() && !glass,
880
+ [modules_da7ab055.inputGap2]: actions.length === 2,
881
+ // TODO: replace with flex-box layout
882
+ [modules_da7ab055.inputLeftGap]: this.isRenderingGlassOrLoader() && glass,
883
+ [modules_da7ab055.inputDisabled]: this.props.disabled
884
+ });
885
+ return /*#__PURE__*/React.createElement("div", {
886
+ "data-test": joinDataTestAttributes('ring-query-assist', dataTest),
887
+ className: classNames(className, modules_da7ab055.queryAssist, modules_da7ab055[theme]),
888
+ role: "presentation",
889
+ ref: this.nodeRef
890
+ }, this.state.shortcuts && /*#__PURE__*/React.createElement(Shortcuts, {
891
+ map: this.shortcutsMap,
892
+ scope: this.shortcutsScope
893
+ }), renderGlass && /*#__PURE__*/React.createElement(Button, {
894
+ icon: searchIcon,
895
+ className: modules_da7ab055.icon,
896
+ iconClassName: modules_da7ab055.iconInner,
897
+ title: this.props.translations.searchTitle,
898
+ ref: this.glassRef,
899
+ onClick: this.handleApply,
900
+ "data-test": "query-assist-search-icon"
901
+ }), renderLoader && /*#__PURE__*/React.createElement("div", {
902
+ className: classNames(modules_da7ab055.icon, modules_da7ab055.loader, {
903
+ [modules_da7ab055.loaderOnTheRight]: !glass
904
+ }),
905
+ ref: this.loaderRef
906
+ }, /*#__PURE__*/React.createElement(LoaderInline, {
907
+ theme: theme
908
+ })), /*#__PURE__*/React.createElement(ContentEditable, {
909
+ "aria-label": this.props.translations.searchTitle,
910
+ className: inputClasses,
911
+ "data-test": "ring-query-assist-input",
912
+ inputRef: this.inputRef,
913
+ disabled: this.props.disabled,
914
+ onComponentUpdate: () => this.setCaretPosition({
915
+ fromContentEditable: true
916
+ }),
917
+ onBlur: this.handleFocusChange,
918
+ onClick: this.handleCaretMove,
919
+ onCompositionStart: this.trackCompositionState,
920
+ onCompositionEnd: this.trackCompositionState,
921
+ onFocus: this.handleFocusChange,
922
+ onInput: this.handleInput // To support IE use the same method
923
+ ,
924
+ onKeyUp: this.handleInput // to handle input and key up
925
+ ,
926
+ onKeyDown: this.handleEnter,
927
+ onPaste: this.handlePaste,
928
+ spellCheck: "false"
929
+ }, this.state.query && /*#__PURE__*/React.createElement("span", null, this.renderQuery())), renderPlaceholder && /*#__PURE__*/React.createElement("button", {
930
+ type: "button",
931
+ className: classNames(modules_da7ab055.placeholder, {
932
+ [modules_da7ab055.placeholderSpaced]: glass
933
+ }),
934
+ ref: this.placeholderRef,
935
+ onClick: this.handleCaretMove,
936
+ "data-test": "query-assist-placeholder"
937
+ }, this.props.placeholder), renderUnderline && /*#__PURE__*/React.createElement("div", {
938
+ className: modules_da7ab055.focusUnderline
939
+ }), actions && /*#__PURE__*/React.createElement("div", {
940
+ "data-test": "ring-query-assist-actions",
941
+ className: modules_da7ab055.actions
942
+ }, actions), /*#__PURE__*/React.createElement(PopupMenu, {
943
+ hidden: !this.state.showPopup,
944
+ onCloseAttempt: this.closePopup,
945
+ ref: this.popupRef,
946
+ anchorElement: this.node,
947
+ keepMounted: true,
948
+ attached: true,
949
+ className: classNames(modules_da7ab055[theme], this.props.popupClassName),
950
+ directions: [PopupMenu.PopupProps.Directions.BOTTOM_RIGHT],
951
+ data: useCustomItemRender ? this.state.suggestions : this.renderSuggestions(),
952
+ "data-test": "ring-query-assist-popup",
953
+ hint: this.props.hint,
954
+ hintOnSelection: this.props.hintOnSelection,
955
+ left: this.getPopupOffset(this.state.suggestions),
956
+ maxHeight: PopupMenu.PopupProps.MaxHeight.SCREEN,
957
+ onMouseDown: this.trackPopupMouseState,
958
+ onMouseUp: this.trackPopupMouseState,
959
+ onSelect: this.handleComplete
960
+ }));
961
+ }
962
+
963
+ }
964
+
965
+ _defineProperty(QueryAssist, "propTypes", {
966
+ theme: PropTypes.string,
967
+
968
+ /**
969
+ * Open suggestions popup during the initial render
970
+ */
971
+ autoOpen: PropTypes.bool,
972
+
973
+ /**
974
+ * Initial caret position
975
+ */
976
+ caret: PropTypes.number,
977
+
978
+ /**
979
+ * Show clickable "cross" icon on the right which clears the query
980
+ */
981
+ clear: PropTypes.bool,
982
+
983
+ /**
984
+ * Additional class for the component
985
+ */
986
+ className: PropTypes.string,
987
+
988
+ /**
989
+ * Additional class for the popup
990
+ */
991
+ popupClassName: PropTypes.string,
992
+
993
+ /**
994
+ * Data source function
995
+ */
996
+ dataSource: PropTypes.func.isRequired,
997
+
998
+ /**
999
+ * Input debounce delay
1000
+ */
1001
+ delay: PropTypes.number,
1002
+
1003
+ /**
1004
+ * Disable the component
1005
+ */
1006
+ disabled: PropTypes.bool,
1007
+
1008
+ /**
1009
+ * Initial focus
1010
+ */
1011
+ focus: PropTypes.bool,
1012
+
1013
+ /**
1014
+ * Hint under the suggestions list
1015
+ */
1016
+ hint: PropTypes.string,
1017
+
1018
+ /**
1019
+ * Hint under the suggestions list visible when a suggestion is selected
1020
+ */
1021
+ hintOnSelection: PropTypes.string,
1022
+
1023
+ /**
1024
+ * Show clickable "glass" icon on the right which applies the query
1025
+ */
1026
+ glass: PropTypes.bool,
1027
+
1028
+ /**
1029
+ * Show loader when a data request is in process
1030
+ */
1031
+ loader: PropTypes.bool,
1032
+
1033
+ /**
1034
+ * Field placeholder value
1035
+ */
1036
+ placeholder: PropTypes.string,
1037
+
1038
+ /**
1039
+ * Called when the query is applied. An object with fields `caret`, `focus` and `query` is passed as an argument
1040
+ */
1041
+ onApply: PropTypes.func,
1042
+
1043
+ /**
1044
+ * Called when the query is changed. An object with fields `caret` and `query` is passed as an argument
1045
+ */
1046
+ onChange: PropTypes.func,
1047
+
1048
+ /**
1049
+ * Called when the query is cleared. Called without arguments
1050
+ */
1051
+ onClear: PropTypes.func,
1052
+
1053
+ /**
1054
+ * Called when the suggestion is applied
1055
+ */
1056
+ onApplySuggestion: PropTypes.func,
1057
+
1058
+ /**
1059
+ * Called when the focus status is changed. An object with fields `focus` is passed as an argument
1060
+ */
1061
+ onFocusChange: PropTypes.func,
1062
+
1063
+ /**
1064
+ * Initial query
1065
+ */
1066
+ query: PropTypes.string,
1067
+ useCustomItemRender: PropTypes.bool,
1068
+ translations: PropTypes.object,
1069
+ actions: PropTypes.array,
1070
+ 'data-test': PropTypes.string
1071
+ });
1072
+
1073
+ _defineProperty(QueryAssist, "defaultProps", {
1074
+ theme: Theme.LIGHT,
1075
+ onApply: noop,
1076
+ onChange: noop,
1077
+ onApplySuggestion: noop,
1078
+ onClear: noop,
1079
+ onFocusChange: noop,
1080
+ translations: {
1081
+ searchTitle: 'Search',
1082
+ clearTitle: 'Clear search input'
1083
+ }
1084
+ });
1085
+
1086
+ _defineProperty(QueryAssist, "ngModelStateField", ngModelStateField);
1087
+
1088
+ _defineProperty(QueryAssist, "Theme", Theme);
1089
+
1090
+ const RerenderableQueryAssist = rerenderHOC(QueryAssist);
1091
+
1092
+ export { RerenderableQueryAssist, QueryAssist as default };