@atlaskit/link-picker 1.18.2 → 1.18.4

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/link-picker
2
2
 
3
+ ## 1.18.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`2e01c9c74b5`](https://bitbucket.org/atlassian/atlassian-frontend/commits/2e01c9c74b5) - DUMMY remove before merging to master; dupe adf-schema via adf-utils
8
+ - Updated dependencies
9
+
10
+ ## 1.18.3
11
+
12
+ ### Patch Changes
13
+
14
+ - [`ee4573b4721`](https://bitbucket.org/atlassian/atlassian-frontend/commits/ee4573b4721) - [ux] Handle keyboard navigation as a listbox
15
+ Updates focus style of link picker listbox
16
+
3
17
  ## 1.18.2
4
18
 
5
19
  ### Patch Changes
@@ -152,68 +152,16 @@ function LinkPicker(_ref) {
152
152
  displayText: e.currentTarget.value
153
153
  });
154
154
  }, [dispatch]);
155
- var handleKeyDown = (0, _react.useCallback)(function (event) {
156
- var key = event.key;
157
- var KEY_ARROW_DOWN = 'ArrowDown';
158
- var KEY_ARROW_UP = 'ArrowUp';
159
- if (!items || !items.length) {
160
- return;
161
- }
162
- var updatedIndex = activeIndex;
163
- switch (key) {
164
- case KEY_ARROW_DOWN:
165
- // down
166
- event.preventDefault();
167
- updatedIndex = (activeIndex + 1) % items.length;
168
- break;
169
- case KEY_ARROW_UP:
170
- // up
171
- event.preventDefault();
172
- updatedIndex = activeIndex > 0 ? activeIndex - 1 : items.length - 1;
173
- break;
174
- }
175
- var item = items[updatedIndex];
176
- if ([KEY_ARROW_DOWN, KEY_ARROW_UP].includes(key) && item) {
177
- /**
178
- * Manually track that the url has been updated using searchResult method
179
- */
180
- trackAttribute('linkFieldContent', getLinkFieldContent(item.url));
181
- trackAttribute('linkFieldContentInputMethod', 'searchResult');
182
- trackAttribute('linkFieldContentInputSource', (0, _utils.getDataSource)(item, activePlugin));
183
- dispatch({
184
- activeIndex: updatedIndex,
185
- selectedIndex: updatedIndex,
186
- url: item.url,
187
- invalidUrl: false
188
- });
189
- }
190
- }, [dispatch, activeIndex, items, trackAttribute, activePlugin]);
191
155
  var handleClear = (0, _react.useCallback)(function (field) {
192
- dispatch((0, _defineProperty2.default)({}, field, ''));
156
+ dispatch((0, _defineProperty2.default)({
157
+ activeIndex: -1,
158
+ selectedIndex: -1
159
+ }, field, ''));
193
160
  }, [dispatch]);
194
161
  var handleUrlClear = (0, _react.useCallback)(function () {
195
162
  trackAttribute('linkFieldContentInputSource', null);
196
163
  handleClear('url');
197
164
  }, [trackAttribute, handleClear]);
198
- var handleMouseEnterResultItem = (0, _react.useCallback)(function (objectId) {
199
- var index = items === null || items === void 0 ? void 0 : items.findIndex(function (item) {
200
- return item.objectId === objectId;
201
- });
202
- dispatch({
203
- activeIndex: index !== null && index !== void 0 ? index : -1
204
- });
205
- }, [dispatch, items]);
206
- var handleMouseLeaveResultItem = (0, _react.useCallback)(function (objectId) {
207
- var index = items === null || items === void 0 ? void 0 : items.findIndex(function (item) {
208
- return item.objectId === objectId;
209
- });
210
- // This is to avoid updating index that was set by other mouseenter event
211
- if (activeIndex === index) {
212
- dispatch({
213
- activeIndex: -1
214
- });
215
- }
216
- }, [dispatch, activeIndex, items]);
217
165
  var handleInsert = (0, _react.useCallback)(function (url, title, inputType) {
218
166
  var event = createAnalyticsEvent((0, _analytics.default)('ui.form.submitted.linkPicker', {}));
219
167
 
@@ -256,7 +204,7 @@ function LinkPicker(_ref) {
256
204
  }
257
205
  }, [handleInsert, trackAttribute, items, activePlugin]);
258
206
  var handleSubmit = (0, _react.useCallback)(function (event) {
259
- event.preventDefault();
207
+ event === null || event === void 0 ? void 0 : event.preventDefault();
260
208
  if (isSelectedItem && selectedItem) {
261
209
  return handleInsert(selectedItem.url, selectedItem.name, 'typeAhead');
262
210
  }
@@ -282,6 +230,60 @@ function LinkPicker(_ref) {
282
230
  });
283
231
  trackAttribute('tab', (_plugins$activeTab$ta = plugins === null || plugins === void 0 ? void 0 : (_plugins$activeTab = plugins[activeTab]) === null || _plugins$activeTab === void 0 ? void 0 : _plugins$activeTab.tabKey) !== null && _plugins$activeTab$ta !== void 0 ? _plugins$activeTab$ta : null);
284
232
  }, [dispatch, plugins, trackAttribute]);
233
+ var handleSearchListOnChange = function handleSearchListOnChange(id) {
234
+ var index = items === null || items === void 0 ? void 0 : items.findIndex(function (item) {
235
+ return item.objectId === id;
236
+ });
237
+ if (typeof index === 'number') {
238
+ var item = items === null || items === void 0 ? void 0 : items[index];
239
+ if (item) {
240
+ /**
241
+ * Manually track that the url has been updated using searchResult method
242
+ */
243
+ trackAttribute('linkFieldContent', getLinkFieldContent(item.url));
244
+ trackAttribute('linkFieldContentInputMethod', 'searchResult');
245
+ trackAttribute('linkFieldContentInputSource', (0, _utils.getDataSource)(item, activePlugin));
246
+ dispatch({
247
+ activeIndex: index,
248
+ selectedIndex: index,
249
+ url: item.url,
250
+ invalidUrl: false
251
+ });
252
+ }
253
+ }
254
+ };
255
+ var handleKeyDown = (0, _react.useCallback)(function (event) {
256
+ if (!(items !== null && items !== void 0 && items.length)) {
257
+ return;
258
+ }
259
+ var updatedIndex = activeIndex;
260
+ if (event.key === 'Enter') {
261
+ event.preventDefault();
262
+ if (selectedItem) {
263
+ handleSelected(selectedItem.objectId);
264
+ } else {
265
+ // triggers validation error message
266
+ handleSubmit();
267
+ }
268
+ } else {
269
+ updatedIndex = (0, _utils.handleNavKeyDown)(event, items.length, activeIndex);
270
+ }
271
+ var item = items[updatedIndex];
272
+ if (['Enter', 'ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key) && item) {
273
+ /**
274
+ * Manually track that the url has been updated using searchResult method
275
+ */
276
+ trackAttribute('linkFieldContent', getLinkFieldContent(item.url));
277
+ trackAttribute('linkFieldContentInputMethod', 'searchResult');
278
+ trackAttribute('linkFieldContentInputSource', (0, _utils.getDataSource)(item, activePlugin));
279
+ dispatch({
280
+ activeIndex: updatedIndex,
281
+ selectedIndex: updatedIndex,
282
+ url: item.url,
283
+ invalidUrl: false
284
+ });
285
+ }
286
+ }, [items, activeIndex, selectedItem, handleSelected, handleSubmit, trackAttribute, activePlugin]);
285
287
  var messages = isActivePlugin ? _messages.searchMessages : _messages.linkMessages;
286
288
  var screenReaderDescriptionId = 'search-recent-links-field-description';
287
289
  var linkSearchListId = 'link-picker-search-list';
@@ -345,7 +347,6 @@ function LinkPicker(_ref) {
345
347
  clearLabel: intl.formatMessage(_messages.linkTextMessages.clearLinkText),
346
348
  "aria-label": intl.formatMessage(_messages.linkTextMessages.linkTextAriaLabel),
347
349
  onClear: handleClear,
348
- onKeyDown: handleKeyDown,
349
350
  onChange: handleChangeText
350
351
  }), isActivePlugin && !!queryState && (0, _react2.jsx)(_react.Fragment, null, tabs.length > 0 && (0, _react2.jsx)("div", {
351
352
  css: _styled.tabsWrapperStyles
@@ -366,8 +367,8 @@ function LinkPicker(_ref) {
366
367
  selectedIndex: selectedIndex,
367
368
  activeIndex: activeIndex,
368
369
  onSelect: handleSelected,
369
- onMouseEnter: handleMouseEnterResultItem,
370
- onMouseLeave: handleMouseLeaveResultItem,
370
+ onChange: handleSearchListOnChange,
371
+ onKeyDown: handleKeyDown,
371
372
  hasSearchTerm: !!(queryState !== null && queryState !== void 0 && queryState.query.length)
372
373
  }), error && ((_errorFallback = errorFallback === null || errorFallback === void 0 ? void 0 : errorFallback(error, retry)) !== null && _errorFallback !== void 0 ? _errorFallback : (0, _react2.jsx)(_linkSearchError.default, null)))), (0, _react2.jsx)(_formFooter.default, {
373
374
  error: error,
@@ -18,7 +18,8 @@ var _listItem = _interopRequireDefault(require("../list-item"));
18
18
  var _styled = require("./styled");
19
19
  var _linkSearchNoResults = _interopRequireWildcard(require("./link-search-no-results"));
20
20
  var _useTrackResultsShown = require("./use-track-results-shown");
21
- var _excluded = ["onSelect", "onMouseEnter", "onMouseLeave", "items", "activeIndex", "selectedIndex", "isLoading", "ariaControls", "ariaLabelledBy", "role", "id", "hasSearchTerm"];
21
+ var _utils = require("../utils");
22
+ var _excluded = ["onChange", "onSelect", "onKeyDown", "items", "activeIndex", "selectedIndex", "isLoading", "ariaControls", "ariaLabelledBy", "role", "id", "hasSearchTerm"];
22
23
  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); }
23
24
  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; }
24
25
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
@@ -49,9 +50,9 @@ var testIds = _objectSpread(_objectSpread({}, _linkSearchNoResults.testIds), {},
49
50
  });
50
51
  exports.testIds = testIds;
51
52
  var LinkSearchList = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
52
- var onSelect = _ref.onSelect,
53
- onMouseEnter = _ref.onMouseEnter,
54
- onMouseLeave = _ref.onMouseLeave,
53
+ var onChange = _ref.onChange,
54
+ onSelect = _ref.onSelect,
55
+ onKeyDown = _ref.onKeyDown,
55
56
  items = _ref.items,
56
57
  activeIndex = _ref.activeIndex,
57
58
  selectedIndex = _ref.selectedIndex,
@@ -66,6 +67,47 @@ var LinkSearchList = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
66
67
  var loadingContent;
67
68
  var linkListTitle = hasSearchTerm ? messages.titleResults : messages.titleRecentlyViewed;
68
69
  (0, _useTrackResultsShown.useTrackResultsShown)(isLoading, items, hasSearchTerm);
70
+ var itemRefs = (0, _react.useRef)({});
71
+ var itemRefCallback = (0, _react.useCallback)(function (el, id) {
72
+ if (el === null) {
73
+ delete itemRefs.current[id];
74
+ } else {
75
+ itemRefs.current[id] = el;
76
+ }
77
+ }, []);
78
+ var getTabIndex = (0, _react.useCallback)(function (index) {
79
+ if (selectedIndex > -1) {
80
+ return selectedIndex === index ? 0 : -1;
81
+ }
82
+ if (index === 0) {
83
+ return 0;
84
+ }
85
+ return -1;
86
+ }, [selectedIndex]);
87
+ var handleOnFocus = function handleOnFocus() {
88
+ if (items && items.length > 0 && selectedIndex === -1) {
89
+ var item = items[0];
90
+ onChange(item.objectId);
91
+ }
92
+ };
93
+ var handleKeyDown = (0, _react.useCallback)(function (event) {
94
+ var updatedIndex = activeIndex;
95
+ if (onKeyDown) {
96
+ onKeyDown(event);
97
+ }
98
+ if (!(items !== null && items !== void 0 && items.length)) {
99
+ return;
100
+ }
101
+ updatedIndex = (0, _utils.handleNavKeyDown)(event, items.length, activeIndex);
102
+ var item = items === null || items === void 0 ? void 0 : items[updatedIndex];
103
+ if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key) && item) {
104
+ onChange(item.objectId);
105
+ if (itemRefs.current) {
106
+ var _itemRefs$current$ite;
107
+ (_itemRefs$current$ite = itemRefs.current[item.objectId]) === null || _itemRefs$current$ite === void 0 ? void 0 : _itemRefs$current$ite.focus();
108
+ }
109
+ }
110
+ }, [activeIndex, items, onChange, onKeyDown]);
69
111
  if ((items === null || items === void 0 ? void 0 : items.length) === 0) {
70
112
  return (0, _react2.jsx)(_linkSearchNoResults.default, null);
71
113
  }
@@ -96,10 +138,14 @@ var LinkSearchList = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
96
138
  item: item,
97
139
  selected: selectedIndex === index,
98
140
  active: activeIndex === index,
99
- onMouseEnter: onMouseEnter,
100
- onMouseLeave: onMouseLeave,
141
+ onFocus: handleOnFocus,
142
+ onKeyDown: handleKeyDown,
101
143
  onSelect: onSelect,
102
- key: item.objectId
144
+ key: item.objectId,
145
+ tabIndex: getTabIndex(index),
146
+ ref: function ref(el) {
147
+ return itemRefCallback(el, item.objectId);
148
+ }
103
149
  });
104
150
  })));
105
151
  }
@@ -6,42 +6,39 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _react = require("react");
8
8
  var _react2 = require("@emotion/react");
9
- var _reactIntlNext = require("react-intl-next");
10
9
  var _transformTimeStamp = require("../transformTimeStamp");
11
10
  var _styled = require("./styled");
12
11
  var _ = require("..");
12
+ var _reactIntlNext = require("react-intl-next");
13
13
  /** @jsx jsx */
14
14
 
15
- var LinkSearchListItem = function LinkSearchListItem(_ref) {
15
+ var LinkSearchListItem = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
16
16
  var item = _ref.item,
17
17
  selected = _ref.selected,
18
18
  active = _ref.active,
19
19
  id = _ref.id,
20
20
  role = _ref.role,
21
- intl = _ref.intl,
22
21
  onSelect = _ref.onSelect,
23
- onMouseEnter = _ref.onMouseEnter,
24
- onMouseLeave = _ref.onMouseLeave;
22
+ tabIndex = _ref.tabIndex,
23
+ onKeyDown = _ref.onKeyDown,
24
+ onFocus = _ref.onFocus;
25
+ var intl = (0, _reactIntlNext.useIntl)();
25
26
  var handleSelect = function handleSelect() {
26
27
  return onSelect(item.objectId);
27
28
  };
28
- var handleMouseEnter = function handleMouseEnter() {
29
- return onMouseEnter(item.objectId);
30
- };
31
- var handleMouseLeave = function handleMouseLeave() {
32
- return onMouseLeave(item.objectId);
33
- };
34
29
  var container = item.container || null;
35
30
  var date = (0, _transformTimeStamp.transformTimeStamp)(intl, item.lastViewedDate, item.lastUpdatedDate);
36
31
  return (0, _react2.jsx)("div", {
37
- css: (0, _styled.composeListItemStyles)(active, selected),
32
+ css: (0, _styled.composeListItemStyles)(selected),
38
33
  role: role,
39
34
  id: id,
40
35
  "aria-selected": selected,
41
36
  "data-testid": _.testIds.searchResultItem,
42
- onMouseEnter: handleMouseEnter,
43
- onMouseLeave: handleMouseLeave,
44
- onClick: handleSelect
37
+ onKeyDown: onKeyDown,
38
+ onClick: handleSelect,
39
+ onFocus: onFocus,
40
+ tabIndex: tabIndex,
41
+ ref: ref
45
42
  }, (0, _react2.jsx)(ListItemIcon, {
46
43
  item: item,
47
44
  intl: intl
@@ -60,8 +57,8 @@ var LinkSearchListItem = function LinkSearchListItem(_ref) {
60
57
  }, container)), date && (0, _react2.jsx)("div", {
61
58
  css: _styled.listItemContainerInnerStyles
62
59
  }, container && (0, _react2.jsx)(_react.Fragment, null, "\xA0 \u2022\xA0 "), (0, _react2.jsx)(_react.Fragment, null, formatDate(date))))));
63
- };
64
- var _default = (0, _reactIntlNext.injectIntl)(LinkSearchListItem);
60
+ });
61
+ var _default = LinkSearchListItem;
65
62
  exports.default = _default;
66
63
  var formatDate = function formatDate(date) {
67
64
  return [date.pageAction, date.dateString, date.timeSince].filter(Boolean).join(' ');
@@ -9,7 +9,7 @@ var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/hel
9
9
  var _react = require("@emotion/react");
10
10
  var _colors = require("@atlaskit/theme/colors");
11
11
  var _theme = require("@atlaskit/theme");
12
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12; // AFP-2532 TODO: Fix automatic suppressions below
12
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13; // AFP-2532 TODO: Fix automatic suppressions below
13
13
  // eslint-disable-next-line @atlassian/tangerine/import/entry-points
14
14
  var relativeFontSizeToBase16 = function relativeFontSizeToBase16(px) {
15
15
  if (typeof px === 'string') {
@@ -22,27 +22,26 @@ var relativeFontSizeToBase16 = function relativeFontSizeToBase16(px) {
22
22
  };
23
23
  exports.relativeFontSizeToBase16 = relativeFontSizeToBase16;
24
24
  var listItemBaseStyles = (0, _react.css)(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n padding: ", " ", ";\n margin: 0 calc(-1 * ", ");\n cursor: pointer;\n"])), "var(--ds-space-100, 8px)", "var(--ds-space-200, 16px)", "var(--ds-space-200, 16px)");
25
- var listItemBoxShadow = (0, _react.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n box-shadow: inset 2px 0px 0px ", ";\n"])), "var(--ds-border-selected, ".concat(_colors.B400, ")"));
26
- var listItemActive = (0, _react.css)(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2.default)(["\n background-color: ", ";\n"])), "var(--ds-background-neutral-subtle-hovered, ".concat(_colors.N20, ")"));
27
- var listItemSelected = (0, _react.css)(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2.default)(["\n background-color: ", ";\n"])), "var(--ds-background-selected, ".concat(_colors.B50, ")"));
25
+ var listItemFocusStyles = (0, _react.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n &:focus {\n outline: none;\n box-shadow: 0 0 0 2px ", " inset;\n text-decoration: none;\n }\n"])), "var(--ds-border-focused, ".concat(_colors.B100, ")"));
26
+ var listItemBoxShadow = (0, _react.css)(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2.default)(["\n box-shadow: inset 2px 0px 0px ", ";\n"])), "var(--ds-border-selected, ".concat(_colors.B400, ")"));
27
+ var listItemActive = (0, _react.css)(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2.default)(["\n &:hover {\n background-color: ", ";\n ", ";\n }\n"])), "var(--ds-background-neutral-subtle-hovered, ".concat(_colors.N20, ")"), listItemBoxShadow);
28
+ var listItemSelected = (0, _react.css)(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2.default)(["\n background-color: ", ";\n ", ";\n"])), "var(--ds-background-selected, ".concat(_colors.B50, ")"), listItemBoxShadow);
28
29
  var composeListItemStyles = function composeListItemStyles() {
29
- var active = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
30
- var selected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
31
- var hasShadow = active || selected;
32
- return (0, _react.css)(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2.default)(["\n ", ";\n ", ";\n ", ";\n ", ";\n "])), listItemBaseStyles, active && listItemActive, selected && listItemSelected, hasShadow && listItemBoxShadow);
30
+ var selected = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
31
+ return (0, _react.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2.default)(["\n ", ";\n ", ";\n ", ";\n ", ";\n "])), listItemBaseStyles, !selected && listItemActive, selected && listItemSelected, listItemFocusStyles);
33
32
  };
34
33
  exports.composeListItemStyles = composeListItemStyles;
35
- var itemNameStyles = (0, _react.css)(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2.default)(["\n overflow: hidden;\n"])));
34
+ var itemNameStyles = (0, _react.css)(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2.default)(["\n overflow: hidden;\n"])));
36
35
  exports.itemNameStyles = itemNameStyles;
37
- var listItemNameStyles = (0, _react.css)(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2.default)(["\n color: ", ";\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n line-height: 20px;\n"])), "var(--ds-text, ".concat(_colors.N800, ")"));
36
+ var listItemNameStyles = (0, _react.css)(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2.default)(["\n color: ", ";\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n line-height: 20px;\n"])), "var(--ds-text, ".concat(_colors.N800, ")"));
38
37
  exports.listItemNameStyles = listItemNameStyles;
39
- var listItemContextStyles = (0, _react.css)(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2.default)(["\n color: ", ";\n font-size: ", ";\n line-height: ", "px;\n display: flex;\n"])), "var(--ds-text, ".concat(_colors.N300, ")"), relativeFontSizeToBase16((0, _theme.fontSizeSmall)()), (0, _theme.fontSize)());
38
+ var listItemContextStyles = (0, _react.css)(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2.default)(["\n color: ", ";\n font-size: ", ";\n line-height: ", "px;\n display: flex;\n"])), "var(--ds-text, ".concat(_colors.N300, ")"), relativeFontSizeToBase16((0, _theme.fontSizeSmall)()), (0, _theme.fontSize)());
40
39
  exports.listItemContextStyles = listItemContextStyles;
41
- var listItemContainerStyles = (0, _react.css)(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2.default)(["\n overflow: hidden;\n text-overflow: ellipsis;\n"])));
40
+ var listItemContainerStyles = (0, _react.css)(_templateObject10 || (_templateObject10 = (0, _taggedTemplateLiteral2.default)(["\n overflow: hidden;\n text-overflow: ellipsis;\n"])));
42
41
  exports.listItemContainerStyles = listItemContainerStyles;
43
- var listItemContainerInnerStyles = (0, _react.css)(_templateObject10 || (_templateObject10 = (0, _taggedTemplateLiteral2.default)(["\n white-space: nowrap;\n"])));
42
+ var listItemContainerInnerStyles = (0, _react.css)(_templateObject11 || (_templateObject11 = (0, _taggedTemplateLiteral2.default)(["\n white-space: nowrap;\n"])));
44
43
  exports.listItemContainerInnerStyles = listItemContainerInnerStyles;
45
- var itemIconStyles = (0, _react.css)(_templateObject11 || (_templateObject11 = (0, _taggedTemplateLiteral2.default)(["\n min-width: ", ";\n margin-top: 3px;\n margin-right: ", ";\n"])), "var(--ds-space-200, 16px)", "var(--ds-space-150, 12px)");
44
+ var itemIconStyles = (0, _react.css)(_templateObject12 || (_templateObject12 = (0, _taggedTemplateLiteral2.default)(["\n min-width: ", ";\n margin-top: 3px;\n margin-right: ", ";\n"])), "var(--ds-space-200, 16px)", "var(--ds-space-150, 12px)");
46
45
  exports.itemIconStyles = itemIconStyles;
47
- var imgStyles = (0, _react.css)(_templateObject12 || (_templateObject12 = (0, _taggedTemplateLiteral2.default)(["\n max-width: ", ";\n"])), "var(--ds-space-200, 16px)");
46
+ var imgStyles = (0, _react.css)(_templateObject13 || (_templateObject13 = (0, _taggedTemplateLiteral2.default)(["\n max-width: ", ";\n"])), "var(--ds-space-200, 16px)");
48
47
  exports.imgStyles = imgStyles;
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getDataSource = void 0;
7
7
  exports.getScreenReaderText = getScreenReaderText;
8
- exports.isUndoEvent = exports.isRedoEvent = void 0;
8
+ exports.isUndoEvent = exports.isRedoEvent = exports.handleNavKeyDown = void 0;
9
9
  var _userAgent = require("@atlaskit/linking-common/user-agent");
10
10
  var _transformTimeStamp = require("./transformTimeStamp");
11
11
  var KeyZCode = 90;
@@ -49,4 +49,27 @@ function getScreenReaderText(items, selectedIndex, intl) {
49
49
  var formattedDate = [date === null || date === void 0 ? void 0 : date.pageAction, date === null || date === void 0 ? void 0 : date.dateString, date === null || date === void 0 ? void 0 : date.timeSince].filter(Boolean).join(' ');
50
50
  return [name, container, formattedDate].filter(Boolean).join(', ');
51
51
  }
52
- }
52
+ }
53
+ var handleNavKeyDown = function handleNavKeyDown(event, itemsLength, activeIndex) {
54
+ var updatedIndex = activeIndex;
55
+ switch (event.key) {
56
+ case 'ArrowDown':
57
+ event.preventDefault();
58
+ updatedIndex = (activeIndex + 1) % itemsLength;
59
+ break;
60
+ case 'ArrowUp':
61
+ event.preventDefault();
62
+ updatedIndex = activeIndex > 0 ? activeIndex - 1 : itemsLength - 1;
63
+ break;
64
+ case 'Home':
65
+ event.preventDefault();
66
+ updatedIndex = 0;
67
+ break;
68
+ case 'End':
69
+ event.preventDefault();
70
+ updatedIndex = itemsLength - 1;
71
+ break;
72
+ }
73
+ return updatedIndex;
74
+ };
75
+ exports.handleNavKeyDown = handleNavKeyDown;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-picker",
3
- "version": "1.18.2",
3
+ "version": "1.18.4",
4
4
  "sideEffects": false
5
5
  }
@@ -23,7 +23,7 @@ import ScrollingTabList from '../scrolling-tabs';
23
23
  import LinkSearchList, { testIds as listTestIds } from './link-search-list';
24
24
  import LinkSearchError, { testIds as searchErrorTestIds } from './link-search-error';
25
25
  import FormFooter, { testIds as formFooterTestIds } from './form-footer';
26
- import { getDataSource, getScreenReaderText } from './utils';
26
+ import { getDataSource, getScreenReaderText, handleNavKeyDown } from './utils';
27
27
  import TrackTabViewed from './track-tab-viewed';
28
28
  import TrackMount from './track-mount';
29
29
  export const RECENT_SEARCH_LIST_SIZE = 5;
@@ -146,46 +146,10 @@ function LinkPicker({
146
146
  displayText: e.currentTarget.value
147
147
  });
148
148
  }, [dispatch]);
149
- const handleKeyDown = useCallback(event => {
150
- const {
151
- key
152
- } = event;
153
- const KEY_ARROW_DOWN = 'ArrowDown';
154
- const KEY_ARROW_UP = 'ArrowUp';
155
- if (!items || !items.length) {
156
- return;
157
- }
158
- let updatedIndex = activeIndex;
159
- switch (key) {
160
- case KEY_ARROW_DOWN:
161
- // down
162
- event.preventDefault();
163
- updatedIndex = (activeIndex + 1) % items.length;
164
- break;
165
- case KEY_ARROW_UP:
166
- // up
167
- event.preventDefault();
168
- updatedIndex = activeIndex > 0 ? activeIndex - 1 : items.length - 1;
169
- break;
170
- }
171
- const item = items[updatedIndex];
172
- if ([KEY_ARROW_DOWN, KEY_ARROW_UP].includes(key) && item) {
173
- /**
174
- * Manually track that the url has been updated using searchResult method
175
- */
176
- trackAttribute('linkFieldContent', getLinkFieldContent(item.url));
177
- trackAttribute('linkFieldContentInputMethod', 'searchResult');
178
- trackAttribute('linkFieldContentInputSource', getDataSource(item, activePlugin));
179
- dispatch({
180
- activeIndex: updatedIndex,
181
- selectedIndex: updatedIndex,
182
- url: item.url,
183
- invalidUrl: false
184
- });
185
- }
186
- }, [dispatch, activeIndex, items, trackAttribute, activePlugin]);
187
149
  const handleClear = useCallback(field => {
188
150
  dispatch({
151
+ activeIndex: -1,
152
+ selectedIndex: -1,
189
153
  [field]: ''
190
154
  });
191
155
  }, [dispatch]);
@@ -193,21 +157,6 @@ function LinkPicker({
193
157
  trackAttribute('linkFieldContentInputSource', null);
194
158
  handleClear('url');
195
159
  }, [trackAttribute, handleClear]);
196
- const handleMouseEnterResultItem = useCallback(objectId => {
197
- const index = items === null || items === void 0 ? void 0 : items.findIndex(item => item.objectId === objectId);
198
- dispatch({
199
- activeIndex: index !== null && index !== void 0 ? index : -1
200
- });
201
- }, [dispatch, items]);
202
- const handleMouseLeaveResultItem = useCallback(objectId => {
203
- const index = items === null || items === void 0 ? void 0 : items.findIndex(item => item.objectId === objectId);
204
- // This is to avoid updating index that was set by other mouseenter event
205
- if (activeIndex === index) {
206
- dispatch({
207
- activeIndex: -1
208
- });
209
- }
210
- }, [dispatch, activeIndex, items]);
211
160
  const handleInsert = useCallback((url, title, inputType) => {
212
161
  const event = createAnalyticsEvent(createEventPayload('ui.form.submitted.linkPicker', {}));
213
162
 
@@ -251,7 +200,7 @@ function LinkPicker({
251
200
  }
252
201
  }, [handleInsert, trackAttribute, items, activePlugin]);
253
202
  const handleSubmit = useCallback(event => {
254
- event.preventDefault();
203
+ event === null || event === void 0 ? void 0 : event.preventDefault();
255
204
  if (isSelectedItem && selectedItem) {
256
205
  return handleInsert(selectedItem.url, selectedItem.name, 'typeAhead');
257
206
  }
@@ -277,6 +226,58 @@ function LinkPicker({
277
226
  });
278
227
  trackAttribute('tab', (_plugins$activeTab$ta = plugins === null || plugins === void 0 ? void 0 : (_plugins$activeTab = plugins[activeTab]) === null || _plugins$activeTab === void 0 ? void 0 : _plugins$activeTab.tabKey) !== null && _plugins$activeTab$ta !== void 0 ? _plugins$activeTab$ta : null);
279
228
  }, [dispatch, plugins, trackAttribute]);
229
+ const handleSearchListOnChange = id => {
230
+ const index = items === null || items === void 0 ? void 0 : items.findIndex(item => item.objectId === id);
231
+ if (typeof index === 'number') {
232
+ const item = items === null || items === void 0 ? void 0 : items[index];
233
+ if (item) {
234
+ /**
235
+ * Manually track that the url has been updated using searchResult method
236
+ */
237
+ trackAttribute('linkFieldContent', getLinkFieldContent(item.url));
238
+ trackAttribute('linkFieldContentInputMethod', 'searchResult');
239
+ trackAttribute('linkFieldContentInputSource', getDataSource(item, activePlugin));
240
+ dispatch({
241
+ activeIndex: index,
242
+ selectedIndex: index,
243
+ url: item.url,
244
+ invalidUrl: false
245
+ });
246
+ }
247
+ }
248
+ };
249
+ const handleKeyDown = useCallback(event => {
250
+ if (!(items !== null && items !== void 0 && items.length)) {
251
+ return;
252
+ }
253
+ let updatedIndex = activeIndex;
254
+ if (event.key === 'Enter') {
255
+ event.preventDefault();
256
+ if (selectedItem) {
257
+ handleSelected(selectedItem.objectId);
258
+ } else {
259
+ // triggers validation error message
260
+ handleSubmit();
261
+ }
262
+ } else {
263
+ updatedIndex = handleNavKeyDown(event, items.length, activeIndex);
264
+ }
265
+ const item = items[updatedIndex];
266
+ if (['Enter', 'ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key) && item) {
267
+ /**
268
+ * Manually track that the url has been updated using searchResult method
269
+ */
270
+ trackAttribute('linkFieldContent', getLinkFieldContent(item.url));
271
+ trackAttribute('linkFieldContentInputMethod', 'searchResult');
272
+ trackAttribute('linkFieldContentInputSource', getDataSource(item, activePlugin));
273
+ dispatch({
274
+ activeIndex: updatedIndex,
275
+ selectedIndex: updatedIndex,
276
+ url: item.url,
277
+ invalidUrl: false
278
+ });
279
+ }
280
+ }, [items, activeIndex, selectedItem, handleSelected, handleSubmit, trackAttribute, activePlugin]);
280
281
  const messages = isActivePlugin ? searchMessages : linkMessages;
281
282
  const screenReaderDescriptionId = 'search-recent-links-field-description';
282
283
  const linkSearchListId = 'link-picker-search-list';
@@ -338,7 +339,6 @@ function LinkPicker({
338
339
  clearLabel: intl.formatMessage(linkTextMessages.clearLinkText),
339
340
  "aria-label": intl.formatMessage(linkTextMessages.linkTextAriaLabel),
340
341
  onClear: handleClear,
341
- onKeyDown: handleKeyDown,
342
342
  onChange: handleChangeText
343
343
  }), isActivePlugin && !!queryState && jsx(Fragment, null, tabs.length > 0 && jsx("div", {
344
344
  css: tabsWrapperStyles
@@ -359,8 +359,8 @@ function LinkPicker({
359
359
  selectedIndex: selectedIndex,
360
360
  activeIndex: activeIndex,
361
361
  onSelect: handleSelected,
362
- onMouseEnter: handleMouseEnterResultItem,
363
- onMouseLeave: handleMouseLeaveResultItem,
362
+ onChange: handleSearchListOnChange,
363
+ onKeyDown: handleKeyDown,
364
364
  hasSearchTerm: !!(queryState !== null && queryState !== void 0 && queryState.query.length)
365
365
  }), error && ((_errorFallback = errorFallback === null || errorFallback === void 0 ? void 0 : errorFallback(error, retry)) !== null && _errorFallback !== void 0 ? _errorFallback : jsx(LinkSearchError, null)))), jsx(FormFooter, {
366
366
  error: error,