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