@atlaskit/quick-search 8.0.9

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 (77) hide show
  1. package/CHANGELOG.md +763 -0
  2. package/LICENSE +13 -0
  3. package/build/tsconfig.json +17 -0
  4. package/dist/cjs/components/QuickSearch.js +447 -0
  5. package/dist/cjs/components/ResultItem/ResultItem.js +87 -0
  6. package/dist/cjs/components/ResultItem/ResultItemGroup.js +57 -0
  7. package/dist/cjs/components/ResultItem/styled.js +53 -0
  8. package/dist/cjs/components/Results/ContainerResult.js +93 -0
  9. package/dist/cjs/components/Results/ObjectResult.js +108 -0
  10. package/dist/cjs/components/Results/PersonResult.js +99 -0
  11. package/dist/cjs/components/Results/ResultBase.js +206 -0
  12. package/dist/cjs/components/Results/index.js +39 -0
  13. package/dist/cjs/components/Results/types.js +5 -0
  14. package/dist/cjs/components/Search/Search.js +124 -0
  15. package/dist/cjs/components/Search/styled.js +61 -0
  16. package/dist/cjs/components/constants.js +20 -0
  17. package/dist/cjs/components/context.js +29 -0
  18. package/dist/cjs/components/decorateWithAnalyticsData.js +80 -0
  19. package/dist/cjs/components/isReactElement.js +19 -0
  20. package/dist/cjs/index.js +94 -0
  21. package/dist/cjs/version.json +4 -0
  22. package/dist/es2019/components/QuickSearch.js +417 -0
  23. package/dist/es2019/components/ResultItem/ResultItem.js +41 -0
  24. package/dist/es2019/components/ResultItem/ResultItemGroup.js +16 -0
  25. package/dist/es2019/components/ResultItem/styled.js +54 -0
  26. package/dist/es2019/components/Results/ContainerResult.js +45 -0
  27. package/dist/es2019/components/Results/ObjectResult.js +60 -0
  28. package/dist/es2019/components/Results/PersonResult.js +50 -0
  29. package/dist/es2019/components/Results/ResultBase.js +149 -0
  30. package/dist/es2019/components/Results/index.js +4 -0
  31. package/dist/es2019/components/Results/types.js +1 -0
  32. package/dist/es2019/components/Search/Search.js +80 -0
  33. package/dist/es2019/components/Search/styled.js +76 -0
  34. package/dist/es2019/components/constants.js +7 -0
  35. package/dist/es2019/components/context.js +11 -0
  36. package/dist/es2019/components/decorateWithAnalyticsData.js +33 -0
  37. package/dist/es2019/components/isReactElement.js +10 -0
  38. package/dist/es2019/index.js +23 -0
  39. package/dist/es2019/version.json +4 -0
  40. package/dist/esm/components/QuickSearch.js +442 -0
  41. package/dist/esm/components/ResultItem/ResultItem.js +65 -0
  42. package/dist/esm/components/ResultItem/ResultItemGroup.js +42 -0
  43. package/dist/esm/components/ResultItem/styled.js +18 -0
  44. package/dist/esm/components/Results/ContainerResult.js +78 -0
  45. package/dist/esm/components/Results/ObjectResult.js +93 -0
  46. package/dist/esm/components/Results/PersonResult.js +86 -0
  47. package/dist/esm/components/Results/ResultBase.js +189 -0
  48. package/dist/esm/components/Results/index.js +4 -0
  49. package/dist/esm/components/Results/types.js +1 -0
  50. package/dist/esm/components/Search/Search.js +108 -0
  51. package/dist/esm/components/Search/styled.js +20 -0
  52. package/dist/esm/components/constants.js +7 -0
  53. package/dist/esm/components/context.js +13 -0
  54. package/dist/esm/components/decorateWithAnalyticsData.js +64 -0
  55. package/dist/esm/components/isReactElement.js +10 -0
  56. package/dist/esm/index.js +23 -0
  57. package/dist/esm/version.json +4 -0
  58. package/dist/types/components/QuickSearch.d.ts +122 -0
  59. package/dist/types/components/ResultItem/ResultItem.d.ts +38 -0
  60. package/dist/types/components/ResultItem/ResultItemGroup.d.ts +11 -0
  61. package/dist/types/components/ResultItem/styled.d.ts +13 -0
  62. package/dist/types/components/Results/ContainerResult.d.ts +19 -0
  63. package/dist/types/components/Results/ObjectResult.d.ts +22 -0
  64. package/dist/types/components/Results/PersonResult.d.ts +20 -0
  65. package/dist/types/components/Results/ResultBase.d.ts +37 -0
  66. package/dist/types/components/Results/index.d.ts +4 -0
  67. package/dist/types/components/Results/types.d.ts +34 -0
  68. package/dist/types/components/Search/Search.d.ts +31 -0
  69. package/dist/types/components/Search/styled.d.ts +10 -0
  70. package/dist/types/components/constants.d.ts +6 -0
  71. package/dist/types/components/context.d.ts +22 -0
  72. package/dist/types/components/decorateWithAnalyticsData.d.ts +3 -0
  73. package/dist/types/components/isReactElement.d.ts +6 -0
  74. package/dist/types/index.d.ts +17 -0
  75. package/docs/0-intro.tsx +53 -0
  76. package/package.json +52 -0
  77. package/tsconfig.json +11 -0
@@ -0,0 +1,76 @@
1
+ import styled, { css } from 'styled-components';
2
+ import { gridSize } from '@atlaskit/theme/constants';
3
+ import { N0, N500, B200, placeholderText, N50 } from '@atlaskit/theme/colors';
4
+ const inputRightPadding = gridSize() * 2;
5
+ export const SearchBox = styled.div`
6
+ position: sticky;
7
+ top: 0;
8
+ z-index: 1; /* required to keep the search box on top of icons in results when sticky */
9
+ background-color: ${N0};
10
+ color: ${N500};
11
+ display: flex;
12
+ height: 36px;
13
+ z-index: 10;
14
+ `;
15
+ export const SearchFieldBaseOuter = styled.div`
16
+ display: flex;
17
+ flex: 1;
18
+ margin-right: auto;
19
+ padding-bottom: 2px;
20
+ border-bottom: 2px solid ${B200};
21
+ `;
22
+ export const SearchFieldBaseInner = styled.div`
23
+ position: relative;
24
+ align-items: center;
25
+ padding-right: ${inputRightPadding}px; /* pad search text from FieldBase's isLoading spinner */
26
+ display: flex;
27
+ flex-grow: 1;
28
+ `;
29
+ export const SearchInner = styled.div`
30
+ padding-right: ${gridSize() * 3}px;
31
+ `;
32
+ export const getPlaceholderStyle = style => css`
33
+ &::-webkit-input-placeholder {
34
+ ${style};
35
+ }
36
+ &::-moz-placeholder {
37
+ /* Mozilla Firefox 19+ */
38
+ ${style} opacity: 1;
39
+ }
40
+ &::-ms-input-placeholder {
41
+ /* Microsoft Edge */
42
+ ${style};
43
+ }
44
+ &:-moz-placeholder {
45
+ /* Mozilla Firefox 4 to 18 */
46
+ ${style} opacity: 1;
47
+ }
48
+ &:-ms-input-placeholder {
49
+ /* Internet Explorer 10-11 */
50
+ ${style};
51
+ }
52
+ `;
53
+ export const getPlaceholderColor = css`
54
+ color: ${placeholderText};
55
+ `;
56
+ export const SearchInput = styled.input`
57
+ background-color: transparent;
58
+ border: 0;
59
+ color: ${N500};
60
+ flex-grow: 1;
61
+ font-size: 1.4em;
62
+ outline: 0;
63
+ // Safari adds 2px margin-left
64
+ margin-left: 0;
65
+ ${getPlaceholderStyle(getPlaceholderColor)};
66
+ `;
67
+ export const SearchInputTypeAhead = styled(SearchInput)`
68
+ color: ${N50};
69
+ position: absolute;
70
+ width: calc(100% - ${inputRightPadding}px);
71
+ z-index: -1;
72
+ `;
73
+ export const SearchInputControlsContainer = styled.span`
74
+ padding-left: ${gridSize() * 3}px;
75
+ `;
76
+ SearchInputControlsContainer.displayName = 'SearchInputControlsContainer'; // required for testing
@@ -0,0 +1,7 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ export const ATLASKIT_QUICKSEARCH_NS = 'atlaskit.navigation.quick-search';
3
+ export const QS_ANALYTICS_EV_CLOSE = `${ATLASKIT_QUICKSEARCH_NS}.close`;
4
+ export const QS_ANALYTICS_EV_KB_CTRLS_USED = `${ATLASKIT_QUICKSEARCH_NS}.keyboard-controls-used`;
5
+ export const QS_ANALYTICS_EV_OPEN = `${ATLASKIT_QUICKSEARCH_NS}.open`;
6
+ export const QS_ANALYTICS_EV_QUERY_ENTERED = `${ATLASKIT_QUICKSEARCH_NS}.query-entered`;
7
+ export const QS_ANALYTICS_EV_SUBMIT = `${ATLASKIT_QUICKSEARCH_NS}.submit`;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ const defaultState = {
3
+ sendAnalytics: () => {},
4
+ onMouseEnter: () => {},
5
+ onMouseLeave: () => {},
6
+ registerResult: () => {},
7
+ unregisterResult: () => {},
8
+ getIndex: n => Number(n)
9
+ };
10
+ export const ResultContext = /*#__PURE__*/React.createContext(defaultState);
11
+ export const SelectedResultIdContext = /*#__PURE__*/React.createContext(null);
@@ -0,0 +1,33 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import React from 'react';
3
+ import { AnalyticsDecorator } from '@atlaskit/analytics';
4
+ import isReactElement from './isReactElement';
5
+ import { QS_ANALYTICS_EV_SUBMIT } from './constants';
6
+ export default function decorateWithAnalyticsData(WrappedQuickSearch) {
7
+ var _class, _temp;
8
+
9
+ return _temp = _class = class DecorateWithAnalyticsData extends React.Component {
10
+ constructor(...args) {
11
+ super(...args);
12
+
13
+ _defineProperty(this, "countChildren", () => {
14
+ return React.Children.toArray(this.props.children).reduce((total, group) => isReactElement(group) ? total + React.Children.count(group.props.children) : total, 0);
15
+ });
16
+ }
17
+
18
+ render() {
19
+ return /*#__PURE__*/React.createElement(AnalyticsDecorator, {
20
+ matchPrivate: true,
21
+ match: QS_ANALYTICS_EV_SUBMIT,
22
+ data: {
23
+ resultCount: this.countChildren(),
24
+ queryLength: this.props.value.length
25
+ }
26
+ }, /*#__PURE__*/React.createElement(WrappedQuickSearch, this.props));
27
+ }
28
+
29
+ }, _defineProperty(_class, "defaultProps", {
30
+ children: [],
31
+ value: ''
32
+ }), _temp;
33
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Heuristically check whether an element is a react element or not.
3
+ * React elements have constructors for their type property but native elements use strings.
4
+ */
5
+ export default (element => {
6
+ const type = element && element.type;
7
+ const hasFunctionAsType = !!type && typeof type === 'function';
8
+ const hasProps = element && element.props;
9
+ return hasFunctionAsType && hasProps;
10
+ });
@@ -0,0 +1,23 @@
1
+ import * as resultTypes from './components/Results';
2
+ /*
3
+ This component is exported in two different ways.
4
+
5
+ v0: A legacy, backwards compatible API from when quick-search was living inside @atlaskit/navigation. This API
6
+ is deprecated and will be removed in the next major version.
7
+
8
+ v1: An API tailored to a stand-alone quick-search component.
9
+ */
10
+ // API v0 Exports:
11
+
12
+ export { default as AkNavigationItemGroup } from './components/ResultItem/ResultItemGroup';
13
+ export { default as AkNavigationItem } from './components/ResultItem/ResultItem';
14
+ export { default as AkQuickSearch } from './components/QuickSearch';
15
+ export { default as AkSearch } from './components/Search/Search';
16
+ export { resultTypes as quickSearchResultTypes }; // API v1 Exports:
17
+
18
+ export { default as QuickSearch } from './components/QuickSearch';
19
+ export { default as ResultItemGroup } from './components/ResultItem/ResultItemGroup';
20
+ export { default as ObjectResult } from './components/Results/ObjectResult';
21
+ export { default as PersonResult } from './components/Results/PersonResult';
22
+ export { default as ContainerResult } from './components/Results/ContainerResult';
23
+ export { default as ResultBase } from './components/Results/ResultBase'; // types
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@atlaskit/quick-search",
3
+ "version": "8.0.9"
4
+ }
@@ -0,0 +1,442 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
4
+ import _inherits from "@babel/runtime/helpers/inherits";
5
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
6
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
7
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
8
+
9
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
10
+
11
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
12
+
13
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
14
+
15
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
16
+
17
+ import React from 'react';
18
+ import keycode from 'keycode';
19
+ import { withAnalytics } from '@atlaskit/analytics';
20
+ import AkSearch from './Search/Search';
21
+ import { ResultContext, SelectedResultIdContext } from './context';
22
+ import decorateWithAnalyticsData from './decorateWithAnalyticsData';
23
+ import { QS_ANALYTICS_EV_CLOSE, QS_ANALYTICS_EV_KB_CTRLS_USED, QS_ANALYTICS_EV_OPEN, QS_ANALYTICS_EV_QUERY_ENTERED, QS_ANALYTICS_EV_SUBMIT } from './constants';
24
+
25
+ /**
26
+ * Get the result ID of a result by its index in the flatResults array
27
+ * Returns null for a failed index or if resultId is empty|undefined
28
+ */
29
+ var getResultIdByIndex = function getResultIdByIndex(array, index) {
30
+ if (array && index !== null && array[index] && array[index].props && array[index].props.resultId) {
31
+ return array[index].props.resultId;
32
+ }
33
+
34
+ return null;
35
+ };
36
+ /**
37
+ * Find a result in the flatResults array by its ID
38
+ * Returns the result object or null
39
+ */
40
+
41
+
42
+ var getResultById = function getResultById(array, id) {
43
+ return array && array.find(function (result) {
44
+ return result.props && result.props.resultId === id;
45
+ }) || null;
46
+ };
47
+ /**
48
+ * Get a result's index in the flatResults array by its ID
49
+ * Returns a numeric index or null
50
+ */
51
+
52
+
53
+ var getResultIndexById = function getResultIndexById(array, id) {
54
+ if (!array) {
55
+ return null;
56
+ }
57
+
58
+ var result = getResultById(array, id);
59
+
60
+ if (!result) {
61
+ return null;
62
+ }
63
+
64
+ var index = array.indexOf(result);
65
+ return index >= 0 ? index : null;
66
+ };
67
+
68
+ var adjustIndex = function adjustIndex(arrayLength, currentIndex, adjustment) {
69
+ if (arrayLength === 0) {
70
+ return null;
71
+ }
72
+
73
+ if (adjustment === 0) {
74
+ return currentIndex;
75
+ } // If nothing is selected, select the element on the end
76
+
77
+
78
+ if (currentIndex === null) {
79
+ return adjustment > 0 ? 0 : arrayLength - 1;
80
+ } // Adjust current index, wrapping around if necessary
81
+
82
+
83
+ var adjustedIndex = (currentIndex + adjustment) % arrayLength; // Correct for negative indices
84
+
85
+ return adjustedIndex >= 0 ? adjustedIndex : adjustedIndex + arrayLength;
86
+ };
87
+
88
+ export var QuickSearch = /*#__PURE__*/function (_React$Component) {
89
+ _inherits(QuickSearch, _React$Component);
90
+
91
+ var _super = _createSuper(QuickSearch);
92
+
93
+ function QuickSearch(props) {
94
+ var _this;
95
+
96
+ _classCallCheck(this, QuickSearch);
97
+
98
+ _this = _super.call(this, props);
99
+
100
+ _defineProperty(_assertThisInitialized(_this), "flatResults", []);
101
+
102
+ _defineProperty(_assertThisInitialized(_this), "hasSearchQueryEventFired", false);
103
+
104
+ _defineProperty(_assertThisInitialized(_this), "hasKeyDownEventFired", false);
105
+
106
+ _defineProperty(_assertThisInitialized(_this), "lastKeyPressed", '');
107
+
108
+ _defineProperty(_assertThisInitialized(_this), "adjustSelectedResultIndex", function (adjustment) {
109
+ var currentIndex = getResultIndexById(_this.flatResults, _this.state.selectedResultId);
110
+ var newIndex = adjustIndex(_this.flatResults.length, currentIndex, adjustment);
111
+ var selectedResultId = getResultIdByIndex(_this.flatResults, newIndex);
112
+
113
+ _this.setState({
114
+ selectedResultId: selectedResultId
115
+ });
116
+
117
+ if (selectedResultId) {
118
+ _this.fireKeyboardControlEvent(selectedResultId);
119
+ }
120
+
121
+ if (_this.props.onSelectedResultIdChanged) {
122
+ _this.props.onSelectedResultIdChanged(selectedResultId);
123
+ }
124
+ });
125
+
126
+ _defineProperty(_assertThisInitialized(_this), "selectNext", function () {
127
+ _this.adjustSelectedResultIndex(+1);
128
+ });
129
+
130
+ _defineProperty(_assertThisInitialized(_this), "selectPrevious", function () {
131
+ _this.adjustSelectedResultIndex(-1);
132
+ });
133
+
134
+ _defineProperty(_assertThisInitialized(_this), "handleRegisterResult", function (result) {
135
+ if (!getResultById(_this.flatResults, result.props.resultId)) {
136
+ _this.flatResults.push(result);
137
+ }
138
+ });
139
+
140
+ _defineProperty(_assertThisInitialized(_this), "handleUnregisterResult", function (result) {
141
+ var resultIndex = getResultIndexById(_this.flatResults, result.props.resultId);
142
+
143
+ if (resultIndex !== null && +resultIndex >= 0) {
144
+ _this.flatResults.splice(resultIndex, 1);
145
+ }
146
+ });
147
+
148
+ _defineProperty(_assertThisInitialized(_this), "handleResultMouseEnter", function (resultData) {
149
+ _this.setState({
150
+ selectedResultId: resultData && resultData.resultId
151
+ });
152
+ });
153
+
154
+ _defineProperty(_assertThisInitialized(_this), "handleResultMouseLeave", function () {
155
+ _this.setState({
156
+ selectedResultId: null
157
+ });
158
+ });
159
+
160
+ _defineProperty(_assertThisInitialized(_this), "handleSearchBlur", function (event) {
161
+ _this.props.onSearchBlur(event);
162
+
163
+ _this.setState({
164
+ selectedResultId: null
165
+ });
166
+ });
167
+
168
+ _defineProperty(_assertThisInitialized(_this), "onInput", function (event) {
169
+ var onSearchInput = _this.props.onSearchInput;
170
+
171
+ _this.setState({
172
+ value: event.currentTarget.value
173
+ });
174
+
175
+ if (onSearchInput) {
176
+ onSearchInput(event);
177
+ }
178
+ });
179
+
180
+ _defineProperty(_assertThisInitialized(_this), "handleSearchKeyDown", function (event) {
181
+ var firePrivateAnalyticsEvent = _this.props.firePrivateAnalyticsEvent;
182
+
183
+ _this.props.onSearchKeyDown(event);
184
+
185
+ _this.lastKeyPressed = event.key; // Need to check for keyCode for up/down/enter in case user is composing using an IME
186
+ // fixes https://ecosystem.atlassian.net/browse/DS-6518
187
+
188
+ if (event.key === 'ArrowUp' && event.keyCode === keycode('up')) {
189
+ event.preventDefault(); // Don't move cursor around in search input field
190
+
191
+ _this.selectPrevious();
192
+ } else if (event.key === 'ArrowDown' && event.keyCode === keycode('down')) {
193
+ event.preventDefault(); // Don't move cursor around in search input field
194
+
195
+ _this.selectNext();
196
+ } else if (event.key === 'Enter' && event.keyCode === keycode('enter')) {
197
+ // shift key pressed or no result selected
198
+ if (event.shiftKey || !_this.state.selectedResultId) {
199
+ if (firePrivateAnalyticsEvent) {
200
+ firePrivateAnalyticsEvent(QS_ANALYTICS_EV_SUBMIT, {
201
+ newTab: false,
202
+ // enter always open in the same tab
203
+ resultCount: _this.flatResults.length,
204
+ method: 'shortcut'
205
+ });
206
+ }
207
+
208
+ _this.props.onSearchSubmit(event);
209
+ } else {
210
+ event.preventDefault(); // Don't fire submit event from input
211
+
212
+ var result = getResultById(_this.flatResults, _this.state.selectedResultId);
213
+
214
+ if (!result || !result.props) {
215
+ return;
216
+ } // Capture when users are using the keyboard to submit
217
+
218
+
219
+ if (typeof firePrivateAnalyticsEvent === 'function') {
220
+ _this.fireKeyboardControlEvent(_this.state.selectedResultId);
221
+
222
+ firePrivateAnalyticsEvent(QS_ANALYTICS_EV_SUBMIT, _objectSpread(_objectSpread({}, result.getAnalyticsData()), {}, {
223
+ method: 'returnKey',
224
+ newTab: false,
225
+ // enter always open in the same tab
226
+ resultCount: _this.flatResults.length
227
+ }));
228
+ }
229
+
230
+ var _preventDefault = false;
231
+
232
+ if (result.props.onClick) {
233
+ result.props.onClick({
234
+ resultId: result.props.resultId,
235
+ type: result.props.type,
236
+ event: Object.assign({}, event, {
237
+ preventDefault: function preventDefault() {
238
+ _preventDefault = true;
239
+ },
240
+ stopPropagation: function stopPropagation() {}
241
+ })
242
+ });
243
+ }
244
+
245
+ if (result.props.href && !_preventDefault) {
246
+ window.location.assign(result.props.href);
247
+ }
248
+ }
249
+ } else if (event.key === 'Tab' || event.key === 'ArrowRight') {
250
+ var autocompleteText = _this.props.autocompleteText;
251
+
252
+ if (autocompleteText && autocompleteText.length > 0 && // multiple Tab or ArrowRight
253
+ autocompleteText.slice(-1) !== ' ') {
254
+ _this.acceptAutocomplete(event, autocompleteText);
255
+
256
+ event.preventDefault();
257
+ }
258
+ }
259
+ });
260
+
261
+ _defineProperty(_assertThisInitialized(_this), "acceptAutocomplete", function (event, text) {
262
+ var onSearchInput = _this.props.onSearchInput;
263
+ var newValue = "".concat(text, " ");
264
+
265
+ if (_this.inputSearchRef) {
266
+ _this.setState({
267
+ value: newValue
268
+ }); // @ts-ignore unchecked
269
+
270
+
271
+ _this.inputSearchRef.value = newValue;
272
+ }
273
+
274
+ if (onSearchInput) {
275
+ onSearchInput(event, true);
276
+ }
277
+ });
278
+
279
+ _defineProperty(_assertThisInitialized(_this), "setSearchInputRef", function (refs) {
280
+ if (refs && refs.inputRef) {
281
+ _this.inputSearchRef = refs.inputRef;
282
+ }
283
+ });
284
+
285
+ _defineProperty(_assertThisInitialized(_this), "focusSearchInput", function () {
286
+ if (_this.inputSearchRef && // @ts-ignore unchecked
287
+ typeof _this.inputSearchRef.focus === 'function') {
288
+ // @ts-ignore unchecked
289
+ _this.inputSearchRef.focus();
290
+ }
291
+ });
292
+
293
+ _this.state = {
294
+ /** Select first result by default if `selectedResultId` prop is not provided */
295
+ selectedResultId: _this.props.selectedResultId || null,
296
+ context: {
297
+ registerResult: _this.handleRegisterResult,
298
+ unregisterResult: _this.handleUnregisterResult,
299
+ onMouseEnter: _this.handleResultMouseEnter,
300
+ onMouseLeave: _this.handleResultMouseLeave,
301
+ sendAnalytics: _this.props.firePrivateAnalyticsEvent,
302
+ getIndex: function getIndex(resultId) {
303
+ return getResultIndexById(_this.flatResults, resultId);
304
+ },
305
+ linkComponent: _this.props.linkComponent
306
+ },
307
+ value: props.value
308
+ };
309
+ return _this;
310
+ }
311
+
312
+ _createClass(QuickSearch, [{
313
+ key: "componentDidMount",
314
+ value: function componentDidMount() {
315
+ var firePrivateAnalyticsEvent = this.props.firePrivateAnalyticsEvent;
316
+
317
+ if (firePrivateAnalyticsEvent) {
318
+ firePrivateAnalyticsEvent(QS_ANALYTICS_EV_OPEN, {});
319
+ }
320
+ }
321
+ }, {
322
+ key: "componentWillUnmount",
323
+ value: function componentWillUnmount() {
324
+ var firePrivateAnalyticsEvent = this.props.firePrivateAnalyticsEvent;
325
+
326
+ if (firePrivateAnalyticsEvent) {
327
+ firePrivateAnalyticsEvent(QS_ANALYTICS_EV_CLOSE, {});
328
+ }
329
+ }
330
+ }, {
331
+ key: "UNSAFE_componentWillReceiveProps",
332
+ value: function UNSAFE_componentWillReceiveProps(nextProps) {
333
+ if (nextProps.children !== this.props.children) {
334
+ this.setState({
335
+ selectedResultId: nextProps.selectedResultId || null
336
+ });
337
+ } else if (nextProps.selectedResultId !== this.props.selectedResultId && nextProps.selectedResultId !== this.state.selectedResultId) {
338
+ this.setState({
339
+ selectedResultId: nextProps.selectedResultId || null
340
+ });
341
+ } // keep context state in sync
342
+
343
+
344
+ var _this$state$context = this.state.context,
345
+ sendAnalytics = _this$state$context.sendAnalytics,
346
+ linkComponent = _this$state$context.linkComponent;
347
+
348
+ if (sendAnalytics !== nextProps.firePrivateAnalyticsEvent || linkComponent !== nextProps.linkComponent) {
349
+ this.setState({
350
+ context: _objectSpread(_objectSpread({}, this.state.context), {}, {
351
+ sendAnalytics: nextProps.firePrivateAnalyticsEvent,
352
+ linkComponent: nextProps.linkComponent
353
+ })
354
+ });
355
+ }
356
+ /**
357
+ * Capture whether user needed to query in order to find their target result.
358
+ * Only fire once per mount. Only fire when a search term is entered and the previous search
359
+ * term was empty.
360
+ */
361
+
362
+
363
+ if (!this.hasSearchQueryEventFired && !this.props.value && nextProps.value) {
364
+ this.hasSearchQueryEventFired = true;
365
+ var firePrivateAnalyticsEvent = this.props.firePrivateAnalyticsEvent;
366
+
367
+ if (firePrivateAnalyticsEvent) {
368
+ firePrivateAnalyticsEvent(QS_ANALYTICS_EV_QUERY_ENTERED, {});
369
+ }
370
+ }
371
+ }
372
+ }, {
373
+ key: "fireKeyboardControlEvent",
374
+ value: function fireKeyboardControlEvent(selectedResultId) {
375
+ var firePrivateAnalyticsEvent = this.props.firePrivateAnalyticsEvent;
376
+
377
+ if (firePrivateAnalyticsEvent) {
378
+ var result = getResultById(this.flatResults, selectedResultId);
379
+
380
+ if (result) {
381
+ firePrivateAnalyticsEvent(QS_ANALYTICS_EV_KB_CTRLS_USED, _objectSpread(_objectSpread({}, result.getAnalyticsData()), {}, {
382
+ key: this.lastKeyPressed,
383
+ resultCount: this.flatResults.length
384
+ }));
385
+ }
386
+ }
387
+
388
+ this.lastKeyPressed = '';
389
+ }
390
+ /**
391
+ * Uses the virtual list, this.flatResults, to move the selection across grouped results as if
392
+ * results were in a single, circular list.
393
+ *
394
+ * Process:
395
+ * 1. Finds the index of the selected result in the flatResults array,
396
+ * 2. Increments or decrements this index by the supplied adjustment amount,
397
+ * 3. Sets the new selectedResultId based on the modifed index
398
+ */
399
+
400
+ }, {
401
+ key: "render",
402
+ value: function render() {
403
+ return /*#__PURE__*/React.createElement(AkSearch, {
404
+ isLoading: this.props.isLoading,
405
+ inputControls: this.props.inputControls,
406
+ onBlur: this.handleSearchBlur,
407
+ onInput: this.onInput,
408
+ onKeyDown: this.handleSearchKeyDown,
409
+ placeholder: this.props.placeholder,
410
+ value: this.state.value,
411
+ autocompleteText: this.props.autocompleteText,
412
+ ref: this.setSearchInputRef
413
+ }, /*#__PURE__*/React.createElement(ResultContext.Provider, {
414
+ value: this.state.context
415
+ }, /*#__PURE__*/React.createElement(SelectedResultIdContext.Provider, {
416
+ value: this.state.selectedResultId
417
+ }, this.props.children)));
418
+ }
419
+ }]);
420
+
421
+ return QuickSearch;
422
+ }(React.Component);
423
+ /**
424
+ * HOCs:
425
+ * `decorateWithAnalyticsData` - Wrapper that decorates analytics events with additional data.
426
+ * `withAnalytics` - Injects analytics firing methods that are picked up by
427
+ * @atlaskit/analytics/AnalyticsListener.
428
+ */
429
+
430
+ _defineProperty(QuickSearch, "defaultProps", {
431
+ children: [],
432
+ firePrivateAnalyticsEvent: function firePrivateAnalyticsEvent(_) {},
433
+ isLoading: false,
434
+ onSearchBlur: function onSearchBlur(_) {},
435
+ onSearchKeyDown: function onSearchKeyDown(_) {},
436
+ onSearchSubmit: function onSearchSubmit(_) {},
437
+ placeholder: 'Search',
438
+ value: ''
439
+ });
440
+
441
+ export default decorateWithAnalyticsData( // @ts-ignore
442
+ withAnalytics(QuickSearch, {}, {}));