@jetbrains/ring-ui 6.0.6-beta.0 → 6.0.6

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