@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.
- package/CHANGELOG.md +763 -0
- package/LICENSE +13 -0
- package/build/tsconfig.json +17 -0
- package/dist/cjs/components/QuickSearch.js +447 -0
- package/dist/cjs/components/ResultItem/ResultItem.js +87 -0
- package/dist/cjs/components/ResultItem/ResultItemGroup.js +57 -0
- package/dist/cjs/components/ResultItem/styled.js +53 -0
- package/dist/cjs/components/Results/ContainerResult.js +93 -0
- package/dist/cjs/components/Results/ObjectResult.js +108 -0
- package/dist/cjs/components/Results/PersonResult.js +99 -0
- package/dist/cjs/components/Results/ResultBase.js +206 -0
- package/dist/cjs/components/Results/index.js +39 -0
- package/dist/cjs/components/Results/types.js +5 -0
- package/dist/cjs/components/Search/Search.js +124 -0
- package/dist/cjs/components/Search/styled.js +61 -0
- package/dist/cjs/components/constants.js +20 -0
- package/dist/cjs/components/context.js +29 -0
- package/dist/cjs/components/decorateWithAnalyticsData.js +80 -0
- package/dist/cjs/components/isReactElement.js +19 -0
- package/dist/cjs/index.js +94 -0
- package/dist/cjs/version.json +4 -0
- package/dist/es2019/components/QuickSearch.js +417 -0
- package/dist/es2019/components/ResultItem/ResultItem.js +41 -0
- package/dist/es2019/components/ResultItem/ResultItemGroup.js +16 -0
- package/dist/es2019/components/ResultItem/styled.js +54 -0
- package/dist/es2019/components/Results/ContainerResult.js +45 -0
- package/dist/es2019/components/Results/ObjectResult.js +60 -0
- package/dist/es2019/components/Results/PersonResult.js +50 -0
- package/dist/es2019/components/Results/ResultBase.js +149 -0
- package/dist/es2019/components/Results/index.js +4 -0
- package/dist/es2019/components/Results/types.js +1 -0
- package/dist/es2019/components/Search/Search.js +80 -0
- package/dist/es2019/components/Search/styled.js +76 -0
- package/dist/es2019/components/constants.js +7 -0
- package/dist/es2019/components/context.js +11 -0
- package/dist/es2019/components/decorateWithAnalyticsData.js +33 -0
- package/dist/es2019/components/isReactElement.js +10 -0
- package/dist/es2019/index.js +23 -0
- package/dist/es2019/version.json +4 -0
- package/dist/esm/components/QuickSearch.js +442 -0
- package/dist/esm/components/ResultItem/ResultItem.js +65 -0
- package/dist/esm/components/ResultItem/ResultItemGroup.js +42 -0
- package/dist/esm/components/ResultItem/styled.js +18 -0
- package/dist/esm/components/Results/ContainerResult.js +78 -0
- package/dist/esm/components/Results/ObjectResult.js +93 -0
- package/dist/esm/components/Results/PersonResult.js +86 -0
- package/dist/esm/components/Results/ResultBase.js +189 -0
- package/dist/esm/components/Results/index.js +4 -0
- package/dist/esm/components/Results/types.js +1 -0
- package/dist/esm/components/Search/Search.js +108 -0
- package/dist/esm/components/Search/styled.js +20 -0
- package/dist/esm/components/constants.js +7 -0
- package/dist/esm/components/context.js +13 -0
- package/dist/esm/components/decorateWithAnalyticsData.js +64 -0
- package/dist/esm/components/isReactElement.js +10 -0
- package/dist/esm/index.js +23 -0
- package/dist/esm/version.json +4 -0
- package/dist/types/components/QuickSearch.d.ts +122 -0
- package/dist/types/components/ResultItem/ResultItem.d.ts +38 -0
- package/dist/types/components/ResultItem/ResultItemGroup.d.ts +11 -0
- package/dist/types/components/ResultItem/styled.d.ts +13 -0
- package/dist/types/components/Results/ContainerResult.d.ts +19 -0
- package/dist/types/components/Results/ObjectResult.d.ts +22 -0
- package/dist/types/components/Results/PersonResult.d.ts +20 -0
- package/dist/types/components/Results/ResultBase.d.ts +37 -0
- package/dist/types/components/Results/index.d.ts +4 -0
- package/dist/types/components/Results/types.d.ts +34 -0
- package/dist/types/components/Search/Search.d.ts +31 -0
- package/dist/types/components/Search/styled.d.ts +10 -0
- package/dist/types/components/constants.d.ts +6 -0
- package/dist/types/components/context.d.ts +22 -0
- package/dist/types/components/decorateWithAnalyticsData.d.ts +3 -0
- package/dist/types/components/isReactElement.d.ts +6 -0
- package/dist/types/index.d.ts +17 -0
- package/docs/0-intro.tsx +53 -0
- package/package.json +52 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.SelectedResultIdContext = exports.ResultContext = void 0;
|
|
9
|
+
|
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
|
11
|
+
|
|
12
|
+
var defaultState = {
|
|
13
|
+
sendAnalytics: function sendAnalytics() {},
|
|
14
|
+
onMouseEnter: function onMouseEnter() {},
|
|
15
|
+
onMouseLeave: function onMouseLeave() {},
|
|
16
|
+
registerResult: function registerResult() {},
|
|
17
|
+
unregisterResult: function unregisterResult() {},
|
|
18
|
+
getIndex: function getIndex(n) {
|
|
19
|
+
return Number(n);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
var ResultContext = /*#__PURE__*/_react.default.createContext(defaultState);
|
|
24
|
+
|
|
25
|
+
exports.ResultContext = ResultContext;
|
|
26
|
+
|
|
27
|
+
var SelectedResultIdContext = /*#__PURE__*/_react.default.createContext(null);
|
|
28
|
+
|
|
29
|
+
exports.SelectedResultIdContext = SelectedResultIdContext;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = decorateWithAnalyticsData;
|
|
9
|
+
|
|
10
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
11
|
+
|
|
12
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
13
|
+
|
|
14
|
+
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
|
|
15
|
+
|
|
16
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
17
|
+
|
|
18
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
19
|
+
|
|
20
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
|
|
21
|
+
|
|
22
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
23
|
+
|
|
24
|
+
var _react = _interopRequireDefault(require("react"));
|
|
25
|
+
|
|
26
|
+
var _analytics = require("@atlaskit/analytics");
|
|
27
|
+
|
|
28
|
+
var _isReactElement = _interopRequireDefault(require("./isReactElement"));
|
|
29
|
+
|
|
30
|
+
var _constants = require("./constants");
|
|
31
|
+
|
|
32
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
|
|
33
|
+
|
|
34
|
+
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; } }
|
|
35
|
+
|
|
36
|
+
function decorateWithAnalyticsData(WrappedQuickSearch) {
|
|
37
|
+
var _class, _temp;
|
|
38
|
+
|
|
39
|
+
return _temp = _class = /*#__PURE__*/function (_React$Component) {
|
|
40
|
+
(0, _inherits2.default)(DecorateWithAnalyticsData, _React$Component);
|
|
41
|
+
|
|
42
|
+
var _super = _createSuper(DecorateWithAnalyticsData);
|
|
43
|
+
|
|
44
|
+
function DecorateWithAnalyticsData() {
|
|
45
|
+
var _this;
|
|
46
|
+
|
|
47
|
+
(0, _classCallCheck2.default)(this, DecorateWithAnalyticsData);
|
|
48
|
+
|
|
49
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
50
|
+
args[_key] = arguments[_key];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_this = _super.call.apply(_super, [this].concat(args));
|
|
54
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "countChildren", function () {
|
|
55
|
+
return _react.default.Children.toArray(_this.props.children).reduce(function (total, group) {
|
|
56
|
+
return (0, _isReactElement.default)(group) ? total + _react.default.Children.count(group.props.children) : total;
|
|
57
|
+
}, 0);
|
|
58
|
+
});
|
|
59
|
+
return _this;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
(0, _createClass2.default)(DecorateWithAnalyticsData, [{
|
|
63
|
+
key: "render",
|
|
64
|
+
value: function render() {
|
|
65
|
+
return /*#__PURE__*/_react.default.createElement(_analytics.AnalyticsDecorator, {
|
|
66
|
+
matchPrivate: true,
|
|
67
|
+
match: _constants.QS_ANALYTICS_EV_SUBMIT,
|
|
68
|
+
data: {
|
|
69
|
+
resultCount: this.countChildren(),
|
|
70
|
+
queryLength: this.props.value.length
|
|
71
|
+
}
|
|
72
|
+
}, /*#__PURE__*/_react.default.createElement(WrappedQuickSearch, this.props));
|
|
73
|
+
}
|
|
74
|
+
}]);
|
|
75
|
+
return DecorateWithAnalyticsData;
|
|
76
|
+
}(_react.default.Component), (0, _defineProperty2.default)(_class, "defaultProps", {
|
|
77
|
+
children: [],
|
|
78
|
+
value: ''
|
|
79
|
+
}), _temp;
|
|
80
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Heuristically check whether an element is a react element or not.
|
|
10
|
+
* React elements have constructors for their type property but native elements use strings.
|
|
11
|
+
*/
|
|
12
|
+
var _default = function _default(element) {
|
|
13
|
+
var type = element && element.type;
|
|
14
|
+
var hasFunctionAsType = !!type && typeof type === 'function';
|
|
15
|
+
var hasProps = element && element.props;
|
|
16
|
+
return hasFunctionAsType && hasProps;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
exports.default = _default;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8
|
+
value: true
|
|
9
|
+
});
|
|
10
|
+
Object.defineProperty(exports, "AkNavigationItemGroup", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function get() {
|
|
13
|
+
return _ResultItemGroup.default;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "ResultItemGroup", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function get() {
|
|
19
|
+
return _ResultItemGroup.default;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(exports, "AkNavigationItem", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function get() {
|
|
25
|
+
return _ResultItem.default;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports, "AkQuickSearch", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function get() {
|
|
31
|
+
return _QuickSearch.default;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(exports, "QuickSearch", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function get() {
|
|
37
|
+
return _QuickSearch.default;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
Object.defineProperty(exports, "AkSearch", {
|
|
41
|
+
enumerable: true,
|
|
42
|
+
get: function get() {
|
|
43
|
+
return _Search.default;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
Object.defineProperty(exports, "ObjectResult", {
|
|
47
|
+
enumerable: true,
|
|
48
|
+
get: function get() {
|
|
49
|
+
return _ObjectResult.default;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
Object.defineProperty(exports, "PersonResult", {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
get: function get() {
|
|
55
|
+
return _PersonResult.default;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
Object.defineProperty(exports, "ContainerResult", {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
get: function get() {
|
|
61
|
+
return _ContainerResult.default;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(exports, "ResultBase", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
get: function get() {
|
|
67
|
+
return _ResultBase.default;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
exports.quickSearchResultTypes = void 0;
|
|
71
|
+
|
|
72
|
+
var resultTypes = _interopRequireWildcard(require("./components/Results"));
|
|
73
|
+
|
|
74
|
+
exports.quickSearchResultTypes = resultTypes;
|
|
75
|
+
|
|
76
|
+
var _ResultItemGroup = _interopRequireDefault(require("./components/ResultItem/ResultItemGroup"));
|
|
77
|
+
|
|
78
|
+
var _ResultItem = _interopRequireDefault(require("./components/ResultItem/ResultItem"));
|
|
79
|
+
|
|
80
|
+
var _QuickSearch = _interopRequireDefault(require("./components/QuickSearch"));
|
|
81
|
+
|
|
82
|
+
var _Search = _interopRequireDefault(require("./components/Search/Search"));
|
|
83
|
+
|
|
84
|
+
var _ObjectResult = _interopRequireDefault(require("./components/Results/ObjectResult"));
|
|
85
|
+
|
|
86
|
+
var _PersonResult = _interopRequireDefault(require("./components/Results/PersonResult"));
|
|
87
|
+
|
|
88
|
+
var _ContainerResult = _interopRequireDefault(require("./components/Results/ContainerResult"));
|
|
89
|
+
|
|
90
|
+
var _ResultBase = _interopRequireDefault(require("./components/Results/ResultBase"));
|
|
91
|
+
|
|
92
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
93
|
+
|
|
94
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import keycode from 'keycode';
|
|
4
|
+
import { withAnalytics } from '@atlaskit/analytics';
|
|
5
|
+
import AkSearch from './Search/Search';
|
|
6
|
+
import { ResultContext, SelectedResultIdContext } from './context';
|
|
7
|
+
import decorateWithAnalyticsData from './decorateWithAnalyticsData';
|
|
8
|
+
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';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get the result ID of a result by its index in the flatResults array
|
|
12
|
+
* Returns null for a failed index or if resultId is empty|undefined
|
|
13
|
+
*/
|
|
14
|
+
const getResultIdByIndex = (array, index) => {
|
|
15
|
+
if (array && index !== null && array[index] && array[index].props && array[index].props.resultId) {
|
|
16
|
+
return array[index].props.resultId;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return null;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Find a result in the flatResults array by its ID
|
|
23
|
+
* Returns the result object or null
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
const getResultById = (array, id) => array && array.find(result => result.props && result.props.resultId === id) || null;
|
|
28
|
+
/**
|
|
29
|
+
* Get a result's index in the flatResults array by its ID
|
|
30
|
+
* Returns a numeric index or null
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
const getResultIndexById = (array, id) => {
|
|
35
|
+
if (!array) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const result = getResultById(array, id);
|
|
40
|
+
|
|
41
|
+
if (!result) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const index = array.indexOf(result);
|
|
46
|
+
return index >= 0 ? index : null;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const adjustIndex = (arrayLength, currentIndex, adjustment) => {
|
|
50
|
+
if (arrayLength === 0) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (adjustment === 0) {
|
|
55
|
+
return currentIndex;
|
|
56
|
+
} // If nothing is selected, select the element on the end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if (currentIndex === null) {
|
|
60
|
+
return adjustment > 0 ? 0 : arrayLength - 1;
|
|
61
|
+
} // Adjust current index, wrapping around if necessary
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
const adjustedIndex = (currentIndex + adjustment) % arrayLength; // Correct for negative indices
|
|
65
|
+
|
|
66
|
+
return adjustedIndex >= 0 ? adjustedIndex : adjustedIndex + arrayLength;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export class QuickSearch extends React.Component {
|
|
70
|
+
constructor(props) {
|
|
71
|
+
super(props);
|
|
72
|
+
|
|
73
|
+
_defineProperty(this, "flatResults", []);
|
|
74
|
+
|
|
75
|
+
_defineProperty(this, "hasSearchQueryEventFired", false);
|
|
76
|
+
|
|
77
|
+
_defineProperty(this, "hasKeyDownEventFired", false);
|
|
78
|
+
|
|
79
|
+
_defineProperty(this, "lastKeyPressed", '');
|
|
80
|
+
|
|
81
|
+
_defineProperty(this, "adjustSelectedResultIndex", adjustment => {
|
|
82
|
+
const currentIndex = getResultIndexById(this.flatResults, this.state.selectedResultId);
|
|
83
|
+
const newIndex = adjustIndex(this.flatResults.length, currentIndex, adjustment);
|
|
84
|
+
const selectedResultId = getResultIdByIndex(this.flatResults, newIndex);
|
|
85
|
+
this.setState({
|
|
86
|
+
selectedResultId
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
if (selectedResultId) {
|
|
90
|
+
this.fireKeyboardControlEvent(selectedResultId);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (this.props.onSelectedResultIdChanged) {
|
|
94
|
+
this.props.onSelectedResultIdChanged(selectedResultId);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
_defineProperty(this, "selectNext", () => {
|
|
99
|
+
this.adjustSelectedResultIndex(+1);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
_defineProperty(this, "selectPrevious", () => {
|
|
103
|
+
this.adjustSelectedResultIndex(-1);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
_defineProperty(this, "handleRegisterResult", result => {
|
|
107
|
+
if (!getResultById(this.flatResults, result.props.resultId)) {
|
|
108
|
+
this.flatResults.push(result);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
_defineProperty(this, "handleUnregisterResult", result => {
|
|
113
|
+
const resultIndex = getResultIndexById(this.flatResults, result.props.resultId);
|
|
114
|
+
|
|
115
|
+
if (resultIndex !== null && +resultIndex >= 0) {
|
|
116
|
+
this.flatResults.splice(resultIndex, 1);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
_defineProperty(this, "handleResultMouseEnter", resultData => {
|
|
121
|
+
this.setState({
|
|
122
|
+
selectedResultId: resultData && resultData.resultId
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
_defineProperty(this, "handleResultMouseLeave", () => {
|
|
127
|
+
this.setState({
|
|
128
|
+
selectedResultId: null
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
_defineProperty(this, "handleSearchBlur", event => {
|
|
133
|
+
this.props.onSearchBlur(event);
|
|
134
|
+
this.setState({
|
|
135
|
+
selectedResultId: null
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
_defineProperty(this, "onInput", event => {
|
|
140
|
+
const {
|
|
141
|
+
onSearchInput
|
|
142
|
+
} = this.props;
|
|
143
|
+
this.setState({
|
|
144
|
+
value: event.currentTarget.value
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
if (onSearchInput) {
|
|
148
|
+
onSearchInput(event);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
_defineProperty(this, "handleSearchKeyDown", event => {
|
|
153
|
+
const {
|
|
154
|
+
firePrivateAnalyticsEvent
|
|
155
|
+
} = this.props;
|
|
156
|
+
this.props.onSearchKeyDown(event);
|
|
157
|
+
this.lastKeyPressed = event.key; // Need to check for keyCode for up/down/enter in case user is composing using an IME
|
|
158
|
+
// fixes https://ecosystem.atlassian.net/browse/DS-6518
|
|
159
|
+
|
|
160
|
+
if (event.key === 'ArrowUp' && event.keyCode === keycode('up')) {
|
|
161
|
+
event.preventDefault(); // Don't move cursor around in search input field
|
|
162
|
+
|
|
163
|
+
this.selectPrevious();
|
|
164
|
+
} else if (event.key === 'ArrowDown' && event.keyCode === keycode('down')) {
|
|
165
|
+
event.preventDefault(); // Don't move cursor around in search input field
|
|
166
|
+
|
|
167
|
+
this.selectNext();
|
|
168
|
+
} else if (event.key === 'Enter' && event.keyCode === keycode('enter')) {
|
|
169
|
+
// shift key pressed or no result selected
|
|
170
|
+
if (event.shiftKey || !this.state.selectedResultId) {
|
|
171
|
+
if (firePrivateAnalyticsEvent) {
|
|
172
|
+
firePrivateAnalyticsEvent(QS_ANALYTICS_EV_SUBMIT, {
|
|
173
|
+
newTab: false,
|
|
174
|
+
// enter always open in the same tab
|
|
175
|
+
resultCount: this.flatResults.length,
|
|
176
|
+
method: 'shortcut'
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
this.props.onSearchSubmit(event);
|
|
181
|
+
} else {
|
|
182
|
+
event.preventDefault(); // Don't fire submit event from input
|
|
183
|
+
|
|
184
|
+
const result = getResultById(this.flatResults, this.state.selectedResultId);
|
|
185
|
+
|
|
186
|
+
if (!result || !result.props) {
|
|
187
|
+
return;
|
|
188
|
+
} // Capture when users are using the keyboard to submit
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
if (typeof firePrivateAnalyticsEvent === 'function') {
|
|
192
|
+
this.fireKeyboardControlEvent(this.state.selectedResultId);
|
|
193
|
+
firePrivateAnalyticsEvent(QS_ANALYTICS_EV_SUBMIT, { ...result.getAnalyticsData(),
|
|
194
|
+
method: 'returnKey',
|
|
195
|
+
newTab: false,
|
|
196
|
+
// enter always open in the same tab
|
|
197
|
+
resultCount: this.flatResults.length
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
let preventDefault = false;
|
|
202
|
+
|
|
203
|
+
if (result.props.onClick) {
|
|
204
|
+
result.props.onClick({
|
|
205
|
+
resultId: result.props.resultId,
|
|
206
|
+
type: result.props.type,
|
|
207
|
+
event: Object.assign({}, event, {
|
|
208
|
+
preventDefault() {
|
|
209
|
+
preventDefault = true;
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
stopPropagation() {}
|
|
213
|
+
|
|
214
|
+
})
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (result.props.href && !preventDefault) {
|
|
219
|
+
window.location.assign(result.props.href);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
} else if (event.key === 'Tab' || event.key === 'ArrowRight') {
|
|
223
|
+
const {
|
|
224
|
+
autocompleteText
|
|
225
|
+
} = this.props;
|
|
226
|
+
|
|
227
|
+
if (autocompleteText && autocompleteText.length > 0 && // multiple Tab or ArrowRight
|
|
228
|
+
autocompleteText.slice(-1) !== ' ') {
|
|
229
|
+
this.acceptAutocomplete(event, autocompleteText);
|
|
230
|
+
event.preventDefault();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
_defineProperty(this, "acceptAutocomplete", (event, text) => {
|
|
236
|
+
const {
|
|
237
|
+
onSearchInput
|
|
238
|
+
} = this.props;
|
|
239
|
+
const newValue = `${text} `;
|
|
240
|
+
|
|
241
|
+
if (this.inputSearchRef) {
|
|
242
|
+
this.setState({
|
|
243
|
+
value: newValue
|
|
244
|
+
}); // @ts-ignore unchecked
|
|
245
|
+
|
|
246
|
+
this.inputSearchRef.value = newValue;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (onSearchInput) {
|
|
250
|
+
onSearchInput(event, true);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
_defineProperty(this, "setSearchInputRef", refs => {
|
|
255
|
+
if (refs && refs.inputRef) {
|
|
256
|
+
this.inputSearchRef = refs.inputRef;
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
_defineProperty(this, "focusSearchInput", () => {
|
|
261
|
+
if (this.inputSearchRef && // @ts-ignore unchecked
|
|
262
|
+
typeof this.inputSearchRef.focus === 'function') {
|
|
263
|
+
// @ts-ignore unchecked
|
|
264
|
+
this.inputSearchRef.focus();
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
this.state = {
|
|
269
|
+
/** Select first result by default if `selectedResultId` prop is not provided */
|
|
270
|
+
selectedResultId: this.props.selectedResultId || null,
|
|
271
|
+
context: {
|
|
272
|
+
registerResult: this.handleRegisterResult,
|
|
273
|
+
unregisterResult: this.handleUnregisterResult,
|
|
274
|
+
onMouseEnter: this.handleResultMouseEnter,
|
|
275
|
+
onMouseLeave: this.handleResultMouseLeave,
|
|
276
|
+
sendAnalytics: this.props.firePrivateAnalyticsEvent,
|
|
277
|
+
getIndex: resultId => {
|
|
278
|
+
return getResultIndexById(this.flatResults, resultId);
|
|
279
|
+
},
|
|
280
|
+
linkComponent: this.props.linkComponent
|
|
281
|
+
},
|
|
282
|
+
value: props.value
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
componentDidMount() {
|
|
287
|
+
const {
|
|
288
|
+
firePrivateAnalyticsEvent
|
|
289
|
+
} = this.props;
|
|
290
|
+
|
|
291
|
+
if (firePrivateAnalyticsEvent) {
|
|
292
|
+
firePrivateAnalyticsEvent(QS_ANALYTICS_EV_OPEN, {});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
componentWillUnmount() {
|
|
297
|
+
const {
|
|
298
|
+
firePrivateAnalyticsEvent
|
|
299
|
+
} = this.props;
|
|
300
|
+
|
|
301
|
+
if (firePrivateAnalyticsEvent) {
|
|
302
|
+
firePrivateAnalyticsEvent(QS_ANALYTICS_EV_CLOSE, {});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
307
|
+
if (nextProps.children !== this.props.children) {
|
|
308
|
+
this.setState({
|
|
309
|
+
selectedResultId: nextProps.selectedResultId || null
|
|
310
|
+
});
|
|
311
|
+
} else if (nextProps.selectedResultId !== this.props.selectedResultId && nextProps.selectedResultId !== this.state.selectedResultId) {
|
|
312
|
+
this.setState({
|
|
313
|
+
selectedResultId: nextProps.selectedResultId || null
|
|
314
|
+
});
|
|
315
|
+
} // keep context state in sync
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
const {
|
|
319
|
+
sendAnalytics,
|
|
320
|
+
linkComponent
|
|
321
|
+
} = this.state.context;
|
|
322
|
+
|
|
323
|
+
if (sendAnalytics !== nextProps.firePrivateAnalyticsEvent || linkComponent !== nextProps.linkComponent) {
|
|
324
|
+
this.setState({
|
|
325
|
+
context: { ...this.state.context,
|
|
326
|
+
sendAnalytics: nextProps.firePrivateAnalyticsEvent,
|
|
327
|
+
linkComponent: nextProps.linkComponent
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Capture whether user needed to query in order to find their target result.
|
|
333
|
+
* Only fire once per mount. Only fire when a search term is entered and the previous search
|
|
334
|
+
* term was empty.
|
|
335
|
+
*/
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
if (!this.hasSearchQueryEventFired && !this.props.value && nextProps.value) {
|
|
339
|
+
this.hasSearchQueryEventFired = true;
|
|
340
|
+
const {
|
|
341
|
+
firePrivateAnalyticsEvent
|
|
342
|
+
} = this.props;
|
|
343
|
+
|
|
344
|
+
if (firePrivateAnalyticsEvent) {
|
|
345
|
+
firePrivateAnalyticsEvent(QS_ANALYTICS_EV_QUERY_ENTERED, {});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
fireKeyboardControlEvent(selectedResultId) {
|
|
351
|
+
const {
|
|
352
|
+
firePrivateAnalyticsEvent
|
|
353
|
+
} = this.props;
|
|
354
|
+
|
|
355
|
+
if (firePrivateAnalyticsEvent) {
|
|
356
|
+
const result = getResultById(this.flatResults, selectedResultId);
|
|
357
|
+
|
|
358
|
+
if (result) {
|
|
359
|
+
firePrivateAnalyticsEvent(QS_ANALYTICS_EV_KB_CTRLS_USED, { ...result.getAnalyticsData(),
|
|
360
|
+
key: this.lastKeyPressed,
|
|
361
|
+
resultCount: this.flatResults.length
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
this.lastKeyPressed = '';
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Uses the virtual list, this.flatResults, to move the selection across grouped results as if
|
|
370
|
+
* results were in a single, circular list.
|
|
371
|
+
*
|
|
372
|
+
* Process:
|
|
373
|
+
* 1. Finds the index of the selected result in the flatResults array,
|
|
374
|
+
* 2. Increments or decrements this index by the supplied adjustment amount,
|
|
375
|
+
* 3. Sets the new selectedResultId based on the modifed index
|
|
376
|
+
*/
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
render() {
|
|
380
|
+
return /*#__PURE__*/React.createElement(AkSearch, {
|
|
381
|
+
isLoading: this.props.isLoading,
|
|
382
|
+
inputControls: this.props.inputControls,
|
|
383
|
+
onBlur: this.handleSearchBlur,
|
|
384
|
+
onInput: this.onInput,
|
|
385
|
+
onKeyDown: this.handleSearchKeyDown,
|
|
386
|
+
placeholder: this.props.placeholder,
|
|
387
|
+
value: this.state.value,
|
|
388
|
+
autocompleteText: this.props.autocompleteText,
|
|
389
|
+
ref: this.setSearchInputRef
|
|
390
|
+
}, /*#__PURE__*/React.createElement(ResultContext.Provider, {
|
|
391
|
+
value: this.state.context
|
|
392
|
+
}, /*#__PURE__*/React.createElement(SelectedResultIdContext.Provider, {
|
|
393
|
+
value: this.state.selectedResultId
|
|
394
|
+
}, this.props.children)));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* HOCs:
|
|
400
|
+
* `decorateWithAnalyticsData` - Wrapper that decorates analytics events with additional data.
|
|
401
|
+
* `withAnalytics` - Injects analytics firing methods that are picked up by
|
|
402
|
+
* @atlaskit/analytics/AnalyticsListener.
|
|
403
|
+
*/
|
|
404
|
+
|
|
405
|
+
_defineProperty(QuickSearch, "defaultProps", {
|
|
406
|
+
children: [],
|
|
407
|
+
firePrivateAnalyticsEvent: _ => {},
|
|
408
|
+
isLoading: false,
|
|
409
|
+
onSearchBlur: _ => {},
|
|
410
|
+
onSearchKeyDown: _ => {},
|
|
411
|
+
onSearchSubmit: _ => {},
|
|
412
|
+
placeholder: 'Search',
|
|
413
|
+
value: ''
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
export default decorateWithAnalyticsData( // @ts-ignore
|
|
417
|
+
withAnalytics(QuickSearch, {}, {}));
|