@atlaskit/link-picker 1.3.0 → 1.5.0

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.
@@ -7,23 +7,11 @@ var _typeof = require("@babel/runtime/helpers/typeof");
7
7
  Object.defineProperty(exports, "__esModule", {
8
8
  value: true
9
9
  });
10
- exports.default = exports.RECENT_SEARCH_LIST_SIZE = void 0;
10
+ exports.testIds = exports.default = exports.RECENT_SEARCH_LIST_SIZE = void 0;
11
11
 
12
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
12
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
13
13
 
14
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
15
-
16
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
17
-
18
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
19
-
20
- var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
21
-
22
- var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
23
-
24
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
25
-
26
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
27
15
 
28
16
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
29
17
 
@@ -39,7 +27,7 @@ var _textInput = _interopRequireDefault(require("./text-input"));
39
27
 
40
28
  var _linkSearchList = _interopRequireDefault(require("./link-search-list"));
41
29
 
42
- var _url = require("./url");
30
+ var _url2 = require("./url");
43
31
 
44
32
  var _styled = require("./styled");
45
33
 
@@ -55,10 +43,14 @@ var _form = require("@atlaskit/form");
55
43
 
56
44
  var _search = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/search"));
57
45
 
46
+ var _tabs = _interopRequireWildcard(require("@atlaskit/tabs"));
47
+
58
48
  var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden"));
59
49
 
60
50
  var _linkSearchNoResults = _interopRequireDefault(require("./link-search-no-results"));
61
51
 
52
+ var _usePlugins2 = require("../../services/use-plugins");
53
+
62
54
  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); }
63
55
 
64
56
  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; }
@@ -67,523 +59,317 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
67
59
 
68
60
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
69
61
 
70
- 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); }; }
71
-
72
- 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; } }
73
-
74
62
  var RECENT_SEARCH_LIST_SIZE = 5;
75
63
  exports.RECENT_SEARCH_LIST_SIZE = RECENT_SEARCH_LIST_SIZE;
64
+ var testIds = {
65
+ linkPicker: 'link-picker',
66
+ urlInputField: 'link-url',
67
+ textInputField: 'link-text',
68
+ searchIcon: 'link-picker-search-icon',
69
+ insertButton: 'link-picker-insert-button',
70
+ cancelButton: 'link-picker-cancel-button',
71
+ clearUrlButton: 'clear-text',
72
+ resultListTitle: 'link-picker-list-title',
73
+ emptyResultPage: 'link-search-no-results',
74
+ searchResultList: 'link-search-list',
75
+ searchResultItem: 'link-search-list-item',
76
+ searchResultLoadingIndicator: 'link-picker.results-loading-indicator',
77
+ urlError: 'link-error',
78
+ tabList: 'link-picker-tabs',
79
+ tabItem: 'link-picker-tab'
80
+ };
81
+ exports.testIds = testIds;
82
+ var initState = {
83
+ url: '',
84
+ displayText: '',
85
+ activeIndex: -1,
86
+ selectedIndex: -1,
87
+ invalidUrl: false,
88
+ activeTab: 0
89
+ };
90
+
91
+ function reducer(state, payload) {
92
+ if (payload.url && state.url !== payload.url) {
93
+ return _objectSpread(_objectSpread({}, state), {}, {
94
+ invalidUrl: false,
95
+ selectedIndex: (0, _url2.isSafeUrl)(payload.url) && payload.url.length ? -1 : state.selectedIndex
96
+ }, payload);
97
+ }
76
98
 
77
- var LinkPicker = /*#__PURE__*/function (_PureComponent) {
78
- (0, _inherits2.default)(LinkPicker, _PureComponent);
79
-
80
- var _super = _createSuper(LinkPicker);
81
-
82
- function LinkPicker(props) {
83
- var _this;
84
-
85
- (0, _classCallCheck2.default)(this, LinkPicker);
86
- _this = _super.call(this, props);
87
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "queryVersion", 0);
88
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateInput", /*#__PURE__*/function () {
89
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(input) {
90
- return _regenerator.default.wrap(function _callee$(_context) {
91
- while (1) {
92
- switch (_context.prev = _context.next) {
93
- case 0:
94
- if (!(input.length && (0, _url.isSafeUrl)(input))) {
95
- _context.next = 2;
96
- break;
97
- }
98
-
99
- return _context.abrupt("return", _this.setState({
100
- url: input,
101
- selectedIndex: -1,
102
- items: [],
103
- isLoading: false,
104
- invalidUrl: null
105
- }));
106
-
107
- case 2:
108
- return _context.abrupt("return", _this.setState({
109
- url: input,
110
- // Unset selection on any input change
111
- selectedIndex: -1,
112
- invalidUrl: null
113
- }, function () {
114
- _this.updateResults();
115
- }));
116
-
117
- case 3:
118
- case "end":
119
- return _context.stop();
120
- }
121
- }
122
- }, _callee);
123
- }));
124
-
125
- return function (_x) {
126
- return _ref.apply(this, arguments);
127
- };
128
- }());
129
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "createClearHandler", function (field) {
130
- return function () {
131
- switch (field) {
132
- case 'url':
133
- {
134
- _this.updateInput('');
135
-
136
- break;
137
- }
138
-
139
- case 'displayText':
140
- {
141
- _this.setState((0, _defineProperty2.default)({}, field, ''));
142
- }
143
- }
144
- };
145
- });
146
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getScreenReaderText", function () {
147
- var intl = _this.props.intl;
148
- var _this$state = _this.state,
149
- items = _this$state.items,
150
- selectedIndex = _this$state.selectedIndex;
151
-
152
- if (items.length && selectedIndex > -1) {
153
- var _items$selectedIndex = items[selectedIndex],
154
- name = _items$selectedIndex.name,
155
- container = _items$selectedIndex.container,
156
- lastUpdatedDate = _items$selectedIndex.lastUpdatedDate,
157
- lastViewedDate = _items$selectedIndex.lastViewedDate;
158
- var date = (0, _transformTimeStamp.transformTimeStamp)(intl, lastViewedDate, lastUpdatedDate);
159
- 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(' ');
160
- return [name, container, formattedDate].filter(Boolean).join(', ');
161
- }
162
- });
163
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isUrlPopulatedWithSelectedItem", function () {
164
- /**
165
- * When we use ArrowKey to navigate through result items,
166
- * the URL field will be populated with the content of
167
- * selected item.
168
- * This function will check if the URL field is populated
169
- * with selected item.
170
- * It can be useful to detect whether we want to insert a
171
- * smartlink or a hyperlink with customized title
172
- */
173
- var _this$state2 = _this.state,
174
- items = _this$state2.items,
175
- selectedIndex = _this$state2.selectedIndex,
176
- url = _this$state2.url;
177
- var selectedItem = items[selectedIndex];
178
-
179
- if (selectedItem && selectedItem.url === url) {
180
- return true;
181
- }
182
-
183
- return false;
184
- });
185
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleSelected", function (objectId) {
186
- var items = _this.state.items;
187
- var selectedItem = items.find(function (item) {
188
- return item.objectId === objectId;
189
- });
190
-
191
- if (selectedItem) {
192
- var url = selectedItem.url,
193
- name = selectedItem.name;
99
+ return _objectSpread(_objectSpread({}, state), payload);
100
+ }
194
101
 
195
- _this.handleInsert(url, name, 'typeAhead');
196
- }
102
+ function LinkPicker(_ref) {
103
+ var onSubmit = _ref.onSubmit,
104
+ onCancel = _ref.onCancel,
105
+ plugins = _ref.plugins,
106
+ initUrl = _ref.url,
107
+ initDisplayText = _ref.displayText;
108
+
109
+ var _useReducer = (0, _react.useReducer)(reducer, _objectSpread(_objectSpread({}, initState), {}, {
110
+ url: (0, _url2.normalizeUrl)(initUrl) || '',
111
+ displayText: initDisplayText || ''
112
+ })),
113
+ _useReducer2 = (0, _slicedToArray2.default)(_useReducer, 2),
114
+ state = _useReducer2[0],
115
+ dispatch = _useReducer2[1];
116
+
117
+ var activeIndex = state.activeIndex,
118
+ selectedIndex = state.selectedIndex,
119
+ url = state.url,
120
+ displayText = state.displayText,
121
+ invalidUrl = state.invalidUrl;
122
+ var isEditing = !!initUrl;
123
+ var intl = (0, _reactIntlNext.useIntl)();
124
+
125
+ var _usePlugins = (0, _usePlugins2.usePlugins)(state, plugins),
126
+ items = _usePlugins.items,
127
+ isLoading = _usePlugins.isLoading,
128
+ isSelectedItem = _usePlugins.isSelectedItem,
129
+ isActivePlugin = _usePlugins.isActivePlugin,
130
+ tabs = _usePlugins.tabs;
131
+
132
+ var handleChangeUrl = (0, _react.useCallback)(function (url) {
133
+ dispatch({
134
+ url: url
197
135
  });
198
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleInsert", function (url, title, inputType) {
199
- var onSubmit = _this.props.onSubmit;
200
- var _this$state3 = _this.state,
201
- rawUrl = _this$state3.url,
202
- displayText = _this$state3.displayText;
203
-
204
- if (onSubmit) {
205
- onSubmit(_objectSpread({
206
- url: url,
207
- displayText: displayText || null,
208
- title: title || null,
209
- meta: {
210
- inputMethod: inputType
211
- }
212
- }, inputType === 'manual' ? {
213
- rawUrl: rawUrl
214
- } : {}));
215
- }
136
+ }, []);
137
+ var handleChangeText = (0, _react.useCallback)(function (displayText) {
138
+ dispatch({
139
+ displayText: displayText
216
140
  });
217
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleMouseEnterResultItem", function (objectId) {
218
- var items = _this.state.items;
219
- var index = findIndex(items, function (item) {
220
- return item.objectId === objectId;
221
- });
141
+ }, []);
142
+ var handleKeyDown = (0, _react.useCallback)(function (event) {
143
+ var keyCode = event.keyCode;
144
+ var KEY_CODE_ARROW_DOWN = 40;
145
+ var KEY_CODE_ARROW_UP = 38;
146
+
147
+ if (!items || !items.length) {
148
+ return;
149
+ }
222
150
 
223
- _this.setState({
224
- activeIndex: index
225
- });
226
- });
227
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleMouseLeaveResultItem", function (objectId) {
228
- var _this$state4 = _this.state,
229
- items = _this$state4.items,
230
- activeIndex = _this$state4.activeIndex;
231
- var index = findIndex(items, function (item) {
232
- return item.objectId === objectId;
233
- }); // This is to avoid updating index that was set by other mouseenter event
234
-
235
- if (activeIndex === index) {
236
- _this.setState({
237
- activeIndex: -1
238
- });
239
- }
240
- });
241
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleSubmit", function () {
242
- var _this$state5 = _this.state,
243
- url = _this$state5.url,
244
- selectedIndex = _this$state5.selectedIndex,
245
- items = _this$state5.items;
246
- var intl = _this.props.intl;
247
- var selectedItem = items[selectedIndex];
248
-
249
- if (_this.isUrlPopulatedWithSelectedItem()) {
250
- return _this.handleInsert(selectedItem.url, selectedItem.name, 'typeAhead');
251
- }
151
+ var updatedIndex = activeIndex;
252
152
 
253
- var normalized = (0, _url.normalizeUrl)(url);
153
+ switch (keyCode) {
154
+ case KEY_CODE_ARROW_DOWN:
155
+ // down
156
+ event.preventDefault();
157
+ updatedIndex = (activeIndex + 1) % items.length;
158
+ break;
254
159
 
255
- if (normalized) {
256
- return _this.handleInsert(normalized, null, 'manual');
257
- }
160
+ case KEY_CODE_ARROW_UP:
161
+ // up
162
+ event.preventDefault();
163
+ updatedIndex = activeIndex > 0 ? activeIndex - 1 : items.length - 1;
164
+ break;
165
+ }
258
166
 
259
- return _this.setState({
260
- invalidUrl: intl.formatMessage(_messages.messages.linkInvalid)
167
+ if ([KEY_CODE_ARROW_DOWN, KEY_CODE_ARROW_UP].includes(keyCode) && items[updatedIndex]) {
168
+ dispatch({
169
+ activeIndex: updatedIndex,
170
+ selectedIndex: updatedIndex,
171
+ url: items[updatedIndex].url,
172
+ invalidUrl: false
261
173
  });
174
+ }
175
+ }, [activeIndex, items]);
176
+ var handleClear = (0, _react.useCallback)(function (field) {
177
+ dispatch((0, _defineProperty2.default)({}, field, ''));
178
+ }, []);
179
+ var handleMouseEnterResultItem = (0, _react.useCallback)(function (objectId) {
180
+ var index = findIndex(items, function (item) {
181
+ return item.objectId === objectId;
262
182
  });
263
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleKeyDown", function (event) {
264
- var _this$state6 = _this.state,
265
- items = _this$state6.items,
266
- activeIndex = _this$state6.activeIndex;
267
- var keyCode = event.keyCode;
268
- var KEY_CODE_ARROW_DOWN = 40;
269
- var KEY_CODE_ARROW_UP = 38;
270
-
271
- if (!items || !items.length) {
272
- return;
273
- }
274
-
275
- var updatedIndex = activeIndex;
276
-
277
- switch (keyCode) {
278
- case KEY_CODE_ARROW_DOWN:
279
- // down
280
- event.preventDefault();
281
- updatedIndex = (activeIndex + 1) % items.length;
282
- break;
283
-
284
- case KEY_CODE_ARROW_UP:
285
- // up
286
- event.preventDefault();
287
- updatedIndex = activeIndex > 0 ? activeIndex - 1 : items.length - 1;
288
- break;
289
- }
290
-
291
- if ([KEY_CODE_ARROW_DOWN, KEY_CODE_ARROW_UP].includes(keyCode) && items[updatedIndex]) {
292
- _this.setState({
293
- activeIndex: updatedIndex,
294
- selectedIndex: updatedIndex,
295
- url: items[updatedIndex].url,
296
- invalidUrl: null
297
- });
298
- }
299
- });
300
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleCancel", function () {
301
- var onCancel = _this.props.onCancel;
302
-
303
- if (onCancel) {
304
- onCancel();
305
- }
183
+ dispatch({
184
+ activeIndex: index
306
185
  });
307
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateTextInput", function (displayText) {
308
- _this.setState({
309
- displayText: displayText
186
+ }, [items]);
187
+ var handleMouseLeaveResultItem = (0, _react.useCallback)(function (objectId) {
188
+ var index = findIndex(items, function (item) {
189
+ return item.objectId === objectId;
190
+ }); // This is to avoid updating index that was set by other mouseenter event
191
+
192
+ if (activeIndex === index) {
193
+ dispatch({
194
+ activeIndex: -1
310
195
  });
196
+ }
197
+ }, [activeIndex, items]);
198
+ var handleInsert = (0, _react.useCallback)(function (url, title, inputType) {
199
+ onSubmit(_objectSpread({
200
+ url: url,
201
+ displayText: displayText || null,
202
+ title: title || null,
203
+ meta: {
204
+ inputMethod: inputType
205
+ }
206
+ }, inputType === 'manual' ? {
207
+ rawUrl: state.url
208
+ } : {}));
209
+ }, [displayText, onSubmit, state.url]);
210
+ var handleSelected = (0, _react.useCallback)(function (objectId) {
211
+ var selectedItem = items.find(function (item) {
212
+ return item.objectId === objectId;
311
213
  });
312
- _this.state = {
313
- selectedIndex: -1,
314
- activeIndex: -1,
315
- isLoading: false,
316
- isEditing: !!props.url,
317
- url: (0, _url.normalizeUrl)(props.url) || '',
318
- displayText: props.displayText || '',
319
- items: [],
320
- invalidUrl: null
321
- };
322
- /* Cache functions */
323
-
324
- _this.handleClearUrl = _this.createClearHandler('url');
325
- _this.handleClearDisplayText = _this.createClearHandler('displayText');
326
- return _this;
327
- }
328
214
 
329
- (0, _createClass2.default)(LinkPicker, [{
330
- key: "componentDidMount",
331
- value: function componentDidMount() {
332
- this.loadInitialLinkSearchResult();
215
+ if (selectedItem) {
216
+ var _url = selectedItem.url,
217
+ name = selectedItem.name;
218
+ handleInsert(_url, name, 'typeAhead');
333
219
  }
334
- }, {
335
- key: "loadInitialLinkSearchResult",
336
- value: function loadInitialLinkSearchResult() {
337
- var url = this.state.url;
220
+ }, [handleInsert, items]);
221
+ var handleSubmit = (0, _react.useCallback)(function () {
222
+ var selectedItem = items[selectedIndex];
338
223
 
339
- if (!url) {
340
- this.updateResults();
341
- }
224
+ if (isSelectedItem) {
225
+ return handleInsert(selectedItem.url, selectedItem.name, 'typeAhead');
342
226
  }
343
- }, {
344
- key: "getActivePlugin",
345
- value: function getActivePlugin() {
346
- if (!this.props.plugins || this.props.plugins.length === 0) {
347
- return null;
348
- }
349
227
 
350
- return this.props.plugins[0];
228
+ var normalized = (0, _url2.normalizeUrl)(url);
229
+
230
+ if (normalized) {
231
+ return handleInsert(normalized, null, 'manual');
351
232
  }
352
- /**
353
- * Interface between link picker and plugins to update results
354
- */
355
-
356
- }, {
357
- key: "updateResults",
358
- value: function () {
359
- var _updateResults = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
360
- var queryVersion, activePlugin, updates, done, value, _result$done, result;
361
-
362
- return _regenerator.default.wrap(function _callee2$(_context2) {
363
- while (1) {
364
- switch (_context2.prev = _context2.next) {
365
- case 0:
366
- queryVersion = ++this.queryVersion;
367
- activePlugin = this.getActivePlugin();
368
-
369
- if (activePlugin) {
370
- _context2.next = 4;
371
- break;
372
- }
373
-
374
- return _context2.abrupt("return");
375
-
376
- case 4:
377
- updates = activePlugin.resolve({
378
- query: this.state.url
379
- });
380
- this.setState({
381
- isLoading: true,
382
- items: []
383
- });
384
- _context2.prev = 6;
385
-
386
- case 7:
387
- if (!(queryVersion === this.queryVersion)) {
388
- _context2.next = 29;
389
- break;
390
- }
391
-
392
- done = false;
393
- value = void 0;
394
-
395
- if (!(updates instanceof Promise)) {
396
- _context2.next = 17;
397
- break;
398
- }
399
-
400
- done = true;
401
- _context2.next = 14;
402
- return updates;
403
-
404
- case 14:
405
- value = _context2.sent;
406
- _context2.next = 22;
407
- break;
408
-
409
- case 17:
410
- _context2.next = 19;
411
- return updates.next();
412
-
413
- case 19:
414
- result = _context2.sent;
415
- done = (_result$done = result.done) !== null && _result$done !== void 0 ? _result$done : false;
416
- value = result.value;
417
-
418
- case 22:
419
- if (!(queryVersion !== this.queryVersion)) {
420
- _context2.next = 24;
421
- break;
422
- }
423
-
424
- return _context2.abrupt("return");
425
-
426
- case 24:
427
- this.setState({
428
- items: limit(value.data),
429
- isLoading: !done
430
- });
431
-
432
- if (!done) {
433
- _context2.next = 27;
434
- break;
435
- }
436
-
437
- return _context2.abrupt("return");
438
-
439
- case 27:
440
- _context2.next = 7;
441
- break;
442
-
443
- case 29:
444
- _context2.next = 34;
445
- break;
446
-
447
- case 31:
448
- _context2.prev = 31;
449
- _context2.t0 = _context2["catch"](6);
450
- this.setState({
451
- isLoading: false
452
- });
453
-
454
- case 34:
455
- case "end":
456
- return _context2.stop();
457
- }
458
- }
459
- }, _callee2, this, [[6, 31]]);
460
- }));
461
-
462
- function updateResults() {
463
- return _updateResults.apply(this, arguments);
464
- }
465
233
 
466
- return updateResults;
467
- }()
468
- }, {
469
- key: "render",
470
- value: function render() {
471
- var _this$state7 = this.state,
472
- items = _this$state7.items,
473
- isLoading = _this$state7.isLoading,
474
- isEditing = _this$state7.isEditing,
475
- activeIndex = _this$state7.activeIndex,
476
- selectedIndex = _this$state7.selectedIndex,
477
- url = _this$state7.url,
478
- displayText = _this$state7.displayText;
479
- var formatMessage = this.props.intl.formatMessage;
480
- var activePlugin = this.getActivePlugin();
481
- var linkPlaceHolder = formatMessage(activePlugin ? _messages.messages.placeholder : _messages.messages.linkPlaceholder);
482
- var linkLabel = formatMessage(_messages.messages.linkLabel);
483
- var linkTextLabel = formatMessage(_messages.messages.linkTextLabel);
484
- var linkTextPlaceHolder = formatMessage(_messages.messages.linkTextPlaceholder);
485
- var screenReaderDescriptionId = 'search-recent-links-field-description';
486
- var linkSearchListId = 'link-picker-search-list';
487
- var ariaActiveDescendant = selectedIndex > -1 ? "link-search-list-item-".concat(selectedIndex) : ''; // Added workaround with a screen reader Announcer specifically for VoiceOver + Safari
488
- // as the Aria design pattern for combobox does not work in this case
489
- // for details: https://a11y-internal.atlassian.net/browse/AK-740
490
-
491
- var screenReaderText = _browser.browser.safari && this.getScreenReaderText();
492
- var searchIcon = activePlugin && (0, _react2.jsx)("span", {
493
- css: _styled.searchIconStyles,
494
- "data-testid": "link-picker-search-icon"
495
- }, (0, _react2.jsx)(_search.default, {
496
- size: "medium",
497
- label: ''
498
- }));
499
- var noResults = activePlugin && !isLoading && !items.length && !(0, _url.isSafeUrl)(url);
500
- return (0, _react2.jsx)("div", {
501
- "data-testid": "link-picker",
502
- css: _styled.rootContainerStyles
503
- }, screenReaderText && (0, _react2.jsx)(_announcer.default, {
504
- ariaLive: "assertive",
505
- text: screenReaderText,
506
- ariaRelevant: "additions",
507
- delay: 250
508
- }), (0, _react2.jsx)(_visuallyHidden.default, null, (0, _react2.jsx)("span", {
509
- "aria-hidden": "true",
510
- id: screenReaderDescriptionId
511
- }, formatMessage(_messages.messages.searchLinkAriaDescription))), (0, _react2.jsx)(_textInput.default, {
512
- name: "link",
513
- testId: "link-url",
514
- role: "combobox",
515
- label: linkLabel,
516
- placeholder: linkPlaceHolder,
517
- value: url,
518
- autoFocus: true,
519
- autoComplete: "off",
520
- elemBeforeInput: searchIcon,
521
- onSubmit: this.handleSubmit,
522
- onChange: this.updateInput,
523
- onKeyDown: this.handleKeyDown,
524
- onClear: this.handleClearUrl,
525
- error: this.state.invalidUrl,
526
- clearLabel: formatMessage(_messages.messages.clearLink),
527
- "aria-controls": linkSearchListId,
528
- "aria-autocomplete": "list",
529
- "aria-activedescendant": ariaActiveDescendant,
530
- "aria-describedby": screenReaderDescriptionId,
531
- "aria-expanded": true
532
- }), (0, _react2.jsx)(_textInput.default, {
533
- name: "link-text",
534
- testId: "link-text",
535
- autoComplete: "off",
536
- label: linkTextLabel,
537
- placeholder: linkTextPlaceHolder,
538
- "aria-label": formatMessage(_messages.messages.linkAriaLabel),
539
- value: displayText,
540
- onSubmit: this.handleSubmit,
541
- onKeyDown: this.handleKeyDown,
542
- onChange: this.updateTextInput,
543
- onClear: this.handleClearDisplayText,
544
- clearLabel: formatMessage(_messages.messages.clearText)
545
- }), !!items.length && (0, _react2.jsx)("div", {
546
- css: _styled.listTitleStyles,
547
- id: "link-picker-list-title",
548
- "data-testid": "link-picker-list-title"
549
- }, formatMessage(this.state.url ? _messages.messages.titleResults : _messages.messages.titleRecentlyViewed)), (0, _react2.jsx)(_visuallyHidden.default, null, (0, _react2.jsx)("span", {
550
- "aria-live": "polite",
551
- "aria-atomic": "true",
552
- id: "fabric.smartcard.linkpicker.suggested.results"
553
- }, url && formatMessage(_messages.messages.searchLinkResults, {
554
- count: items.length
555
- }))), (0, _react2.jsx)(_linkSearchList.default, {
556
- ariaLabelledBy: "link-picker-list-title",
557
- ariaControls: "fabric.smartcard.linkpicker.suggested.results",
558
- id: linkSearchListId,
559
- role: "listbox",
560
- items: items,
561
- isLoading: isLoading,
562
- selectedIndex: selectedIndex,
563
- activeIndex: activeIndex,
564
- onSelect: this.handleSelected,
565
- onMouseEnter: this.handleMouseEnterResultItem,
566
- onMouseLeave: this.handleMouseLeaveResultItem
567
- }), noResults && (0, _react2.jsx)(_linkSearchNoResults.default, {
568
- testId: "link-search-no-results",
569
- header: formatMessage(_messages.messages.noResults),
570
- description: formatMessage(_messages.messages.noResultsDescription)
571
- }), (0, _react2.jsx)(_form.FormFooter, {
572
- align: "end"
573
- }, (0, _react2.jsx)(_button.ButtonGroup, null, (0, _react2.jsx)(_button.default, {
574
- appearance: "default",
575
- onClick: this.handleCancel,
576
- testId: "link-picker-cancel-button"
577
- }, formatMessage(_messages.messages.cancelButton)), (0, _react2.jsx)(_button.default, {
578
- type: "submit",
579
- appearance: "primary",
580
- onClick: this.handleSubmit,
581
- testId: "link-picker-insert-button"
582
- }, formatMessage(isEditing ? _messages.messages.saveButton : _messages.messages.insertButton)))));
234
+ return dispatch({
235
+ invalidUrl: true
236
+ });
237
+ }, [handleInsert, isSelectedItem, items, selectedIndex, url]);
238
+ var linkPlaceHolder = isActivePlugin ? _messages.messages.placeholder : _messages.messages.linkPlaceholder;
239
+ var linkListTitle = url ? _messages.messages.titleResults : _messages.messages.titleRecentlyViewed;
240
+ var insertButtonMsg = isEditing ? _messages.messages.saveButton : _messages.messages.insertButton;
241
+ var noResults = isActivePlugin && !isLoading && !items.length && !(0, _url2.isSafeUrl)(url);
242
+ var screenReaderDescriptionId = 'search-recent-links-field-description';
243
+ var linkSearchListId = 'link-picker-search-list';
244
+ var ariaActiveDescendant = selectedIndex > -1 ? "link-search-list-item-".concat(selectedIndex) : ''; // Added workaround with a screen reader Announcer specifically for VoiceOver + Safari
245
+ // as the Aria design pattern for combobox does not work in this case
246
+ // for details: https://a11y-internal.atlassian.net/browse/AK-740
247
+
248
+ var screenReaderText = _browser.browser.safari && getScreenReaderText(items, selectedIndex, intl);
249
+ var searchIcon = isActivePlugin && (0, _react2.jsx)("span", {
250
+ css: _styled.searchIconStyles,
251
+ "data-testid": testIds.searchIcon
252
+ }, (0, _react2.jsx)(_search.default, {
253
+ size: "medium",
254
+ label: ''
255
+ }));
256
+ return (0, _react2.jsx)("div", {
257
+ "data-testid": testIds.linkPicker,
258
+ css: _styled.rootContainerStyles
259
+ }, screenReaderText && (0, _react2.jsx)(_announcer.default, {
260
+ ariaLive: "assertive",
261
+ text: screenReaderText,
262
+ ariaRelevant: "additions",
263
+ delay: 250
264
+ }), (0, _react2.jsx)(_visuallyHidden.default, {
265
+ id: screenReaderDescriptionId
266
+ }, (0, _react2.jsx)(_reactIntlNext.FormattedMessage, _messages.messages.searchLinkAriaDescription)), (0, _react2.jsx)(_textInput.default, {
267
+ role: "combobox",
268
+ autoComplete: "off",
269
+ name: "url",
270
+ testId: testIds.urlInputField,
271
+ label: intl.formatMessage(_messages.messages.linkLabel),
272
+ placeholder: intl.formatMessage(linkPlaceHolder),
273
+ value: url,
274
+ autoFocus: true,
275
+ elemBeforeInput: searchIcon,
276
+ clearLabel: intl.formatMessage(_messages.messages.clearLink),
277
+ "aria-expanded": true,
278
+ "aria-autocomplete": "list",
279
+ "aria-controls": linkSearchListId,
280
+ "aria-activedescendant": ariaActiveDescendant,
281
+ "aria-describedby": screenReaderDescriptionId,
282
+ error: invalidUrl ? intl.formatMessage(_messages.messages.linkInvalid) : null,
283
+ onClear: handleClear,
284
+ onSubmit: handleSubmit,
285
+ onKeyDown: handleKeyDown,
286
+ onChange: handleChangeUrl
287
+ }), (0, _react2.jsx)(_textInput.default, {
288
+ autoComplete: "off",
289
+ name: "displayText",
290
+ testId: testIds.textInputField,
291
+ value: displayText,
292
+ label: intl.formatMessage(_messages.messages.linkTextLabel),
293
+ placeholder: intl.formatMessage(_messages.messages.linkTextPlaceholder),
294
+ clearLabel: intl.formatMessage(_messages.messages.clearText),
295
+ "aria-label": intl.formatMessage(_messages.messages.linkAriaLabel),
296
+ onClear: handleClear,
297
+ onSubmit: handleSubmit,
298
+ onKeyDown: handleKeyDown,
299
+ onChange: handleChangeText
300
+ }), tabs.length > 0 && (0, _react2.jsx)(_tabs.default, {
301
+ id: testIds.tabList,
302
+ testId: testIds.tabList,
303
+ onChange: function onChange(activeTab) {
304
+ return dispatch({
305
+ selectedIndex: -1,
306
+ activeIndex: -1,
307
+ invalidUrl: false,
308
+ activeTab: activeTab
309
+ });
583
310
  }
584
- }]);
585
- return LinkPicker;
586
- }(_react.PureComponent);
311
+ }, (0, _react2.jsx)(_tabs.TabList, null, tabs.map(function (tab) {
312
+ return (0, _react2.jsx)(_tabs.Tab, {
313
+ key: tab.tabTitle,
314
+ testId: testIds.tabItem
315
+ }, tab.tabTitle);
316
+ }))), !!items.length && (0, _react2.jsx)("div", {
317
+ css: _styled.listTitleStyles,
318
+ id: testIds.resultListTitle,
319
+ "data-testid": testIds.resultListTitle
320
+ }, (0, _react2.jsx)(_reactIntlNext.FormattedMessage, linkListTitle)), (0, _react2.jsx)(_visuallyHidden.default, {
321
+ id: "fabric.smartcard.linkpicker.suggested.results"
322
+ }, url && (0, _react2.jsx)(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, _messages.messages.searchLinkResults, {
323
+ values: {
324
+ count: items.length
325
+ },
326
+ "aria-live": "polite",
327
+ "aria-atomic": "true"
328
+ }))), (0, _react2.jsx)(_linkSearchList.default, {
329
+ ariaLabelledBy: testIds.resultListTitle,
330
+ ariaControls: "fabric.smartcard.linkpicker.suggested.results",
331
+ id: linkSearchListId,
332
+ role: "listbox",
333
+ items: items,
334
+ isLoading: isLoading,
335
+ selectedIndex: selectedIndex,
336
+ activeIndex: activeIndex,
337
+ onSelect: handleSelected,
338
+ onMouseEnter: handleMouseEnterResultItem,
339
+ onMouseLeave: handleMouseLeaveResultItem
340
+ }), noResults && (0, _react2.jsx)(_linkSearchNoResults.default, {
341
+ testId: testIds.emptyResultPage,
342
+ header: intl.formatMessage(_messages.messages.noResults),
343
+ description: intl.formatMessage(_messages.messages.noResultsDescription)
344
+ }), (0, _react2.jsx)(_form.FormFooter, {
345
+ align: "end"
346
+ }, (0, _react2.jsx)(_button.ButtonGroup, null, (0, _react2.jsx)(_button.default, {
347
+ appearance: "default",
348
+ onClick: onCancel,
349
+ testId: testIds.cancelButton
350
+ }, intl.formatMessage(_messages.messages.cancelButton)), (0, _react2.jsx)(_button.default, {
351
+ type: "submit",
352
+ appearance: "primary",
353
+ onClick: handleSubmit,
354
+ testId: testIds.insertButton
355
+ }, intl.formatMessage(insertButtonMsg)))));
356
+ }
357
+
358
+ var _default = LinkPicker;
359
+ exports.default = _default;
360
+
361
+ function getScreenReaderText(items, selectedIndex, intl) {
362
+ if (items.length && selectedIndex > -1) {
363
+ var _items$selectedIndex = items[selectedIndex],
364
+ name = _items$selectedIndex.name,
365
+ container = _items$selectedIndex.container,
366
+ lastUpdatedDate = _items$selectedIndex.lastUpdatedDate,
367
+ lastViewedDate = _items$selectedIndex.lastViewedDate;
368
+ var date = (0, _transformTimeStamp.transformTimeStamp)(intl, lastViewedDate, lastUpdatedDate);
369
+ 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(' ');
370
+ return [name, container, formattedDate].filter(Boolean).join(', ');
371
+ }
372
+ }
587
373
 
588
374
  function findIndex(array, predicate) {
589
375
  var index = -1;
@@ -596,12 +382,4 @@ function findIndex(array, predicate) {
596
382
  return false;
597
383
  });
598
384
  return index;
599
- }
600
-
601
- function limit(items) {
602
- return items.slice(0, RECENT_SEARCH_LIST_SIZE);
603
- }
604
-
605
- var _default = (0, _reactIntlNext.injectIntl)(LinkPicker);
606
-
607
- exports.default = _default;
385
+ }