@atlaskit/link-picker 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +4 -1
  3. package/dist/cjs/browser.js +0 -39
  4. package/dist/cjs/index.js +0 -13
  5. package/dist/cjs/messages.js +0 -112
  6. package/dist/cjs/transformTimeStamp.js +0 -55
  7. package/dist/cjs/types.js +0 -5
  8. package/dist/cjs/ui/announcer.js +0 -64
  9. package/dist/cjs/ui/link-picker.js +0 -611
  10. package/dist/cjs/ui/link-search-list/index.js +0 -102
  11. package/dist/cjs/ui/link-search-list/styled.js +0 -21
  12. package/dist/cjs/ui/link-search-no-results/index.js +0 -27
  13. package/dist/cjs/ui/list-item/index.js +0 -103
  14. package/dist/cjs/ui/list-item/styled.js +0 -59
  15. package/dist/cjs/ui/styled.js +0 -32
  16. package/dist/cjs/ui/text-input/index.js +0 -116
  17. package/dist/cjs/ui/text-input/styled.js +0 -25
  18. package/dist/cjs/url.js +0 -104
  19. package/dist/cjs/utils.js +0 -27
  20. package/dist/cjs/version.json +0 -5
  21. package/dist/es2019/browser.js +0 -34
  22. package/dist/es2019/index.js +0 -1
  23. package/dist/es2019/messages.js +0 -103
  24. package/dist/es2019/transformTimeStamp.js +0 -41
  25. package/dist/es2019/types.js +0 -1
  26. package/dist/es2019/ui/announcer.js +0 -38
  27. package/dist/es2019/ui/link-picker.js +0 -499
  28. package/dist/es2019/ui/link-search-list/index.js +0 -60
  29. package/dist/es2019/ui/link-search-list/styled.js +0 -13
  30. package/dist/es2019/ui/link-search-no-results/index.js +0 -12
  31. package/dist/es2019/ui/list-item/index.js +0 -88
  32. package/dist/es2019/ui/list-item/styled.js +0 -65
  33. package/dist/es2019/ui/styled.js +0 -28
  34. package/dist/es2019/ui/text-input/index.js +0 -99
  35. package/dist/es2019/ui/text-input/styled.js +0 -15
  36. package/dist/es2019/url.js +0 -88
  37. package/dist/es2019/utils.js +0 -13
  38. package/dist/es2019/version.json +0 -5
  39. package/dist/esm/browser.js +0 -34
  40. package/dist/esm/index.js +0 -1
  41. package/dist/esm/messages.js +0 -103
  42. package/dist/esm/transformTimeStamp.js +0 -41
  43. package/dist/esm/types.js +0 -1
  44. package/dist/esm/ui/announcer.js +0 -51
  45. package/dist/esm/ui/link-picker.js +0 -589
  46. package/dist/esm/ui/link-search-list/index.js +0 -88
  47. package/dist/esm/ui/link-search-list/styled.js +0 -8
  48. package/dist/esm/ui/link-search-no-results/index.js +0 -14
  49. package/dist/esm/ui/list-item/index.js +0 -90
  50. package/dist/esm/ui/list-item/styled.js +0 -37
  51. package/dist/esm/ui/styled.js +0 -16
  52. package/dist/esm/ui/text-input/index.js +0 -99
  53. package/dist/esm/ui/text-input/styled.js +0 -10
  54. package/dist/esm/url.js +0 -90
  55. package/dist/esm/utils.js +0 -13
  56. package/dist/esm/version.json +0 -5
  57. package/dist/types/browser.d.ts +0 -15
  58. package/dist/types/index.d.ts +0 -3
  59. package/dist/types/messages.d.ts +0 -102
  60. package/dist/types/transformTimeStamp.d.ts +0 -3
  61. package/dist/types/types.d.ts +0 -40
  62. package/dist/types/ui/announcer.d.ts +0 -22
  63. package/dist/types/ui/link-picker.d.ts +0 -51
  64. package/dist/types/ui/link-search-list/index.d.ts +0 -20
  65. package/dist/types/ui/link-search-list/styled.d.ts +0 -3
  66. package/dist/types/ui/link-search-no-results/index.d.ts +0 -4
  67. package/dist/types/ui/list-item/index.d.ts +0 -17
  68. package/dist/types/ui/list-item/styled.d.ts +0 -7
  69. package/dist/types/ui/styled.d.ts +0 -4
  70. package/dist/types/ui/text-input/index.d.ts +0 -17
  71. package/dist/types/ui/text-input/styled.d.ts +0 -2
  72. package/dist/types/url.d.ts +0 -5
  73. package/dist/types/utils.d.ts +0 -3
@@ -1,51 +0,0 @@
1
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import React, { forwardRef, memo, useState, useEffect } from 'react'; // How to use:
3
- // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions#Preferring_specialized_live_region_roles
4
- // Demo: https://dequeuniversity.com/library/aria/liveregion-playground
5
- // Important: Strongly recommend test your solution in all supported screen readers
6
- // if you use non default value of properties: ariaAtomic, ariaLive, ariaRelevant, role
7
- // Note: Text won't be announced if the text message doesn't change after the render.
8
- // For using a forced announcement in this case, set the 'key' attribute - key={Date.now()}
9
-
10
- // Note: Flag 'contentRendered' resolves bug with duplicates messages (NVDA + Firefox)
11
- // https://github.com/nvaccess/nvda/labels/bug%2Fdouble-speaking
12
- var timer;
13
- var Announcer = /*#__PURE__*/forwardRef(function (_ref, ref) {
14
- var _ref$ariaAtomic = _ref.ariaAtomic,
15
- ariaAtomic = _ref$ariaAtomic === void 0 ? 'true' : _ref$ariaAtomic,
16
- _ref$ariaLive = _ref.ariaLive,
17
- ariaLive = _ref$ariaLive === void 0 ? 'polite' : _ref$ariaLive,
18
- _ref$ariaRelevant = _ref.ariaRelevant,
19
- ariaRelevant = _ref$ariaRelevant === void 0 ? 'all' : _ref$ariaRelevant,
20
- _ref$role = _ref.role,
21
- role = _ref$role === void 0 ? 'status' : _ref$role,
22
- _ref$text = _ref.text,
23
- text = _ref$text === void 0 ? '' : _ref$text,
24
- _ref$delay = _ref.delay,
25
- delay = _ref$delay === void 0 ? 0 : _ref$delay;
26
-
27
- var _useState = useState(false),
28
- _useState2 = _slicedToArray(_useState, 2),
29
- contentRendered = _useState2[0],
30
- setContentRendered = _useState2[1];
31
-
32
- useEffect(function () {
33
- clearTimeout(timer);
34
- setContentRendered(false);
35
- timer = setTimeout(function () {
36
- setContentRendered(true);
37
- }, delay);
38
- return function () {
39
- return clearTimeout(timer);
40
- };
41
- }, [text, delay]);
42
- return /*#__PURE__*/React.createElement("div", {
43
- className: "assistive",
44
- ref: ref,
45
- role: role,
46
- "aria-atomic": ariaAtomic,
47
- "aria-relevant": ariaRelevant,
48
- "aria-live": ariaLive
49
- }, contentRendered && /*#__PURE__*/React.createElement("span", null, text));
50
- });
51
- export default /*#__PURE__*/memo(Announcer);
@@ -1,589 +0,0 @@
1
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
- import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
- import _createClass from "@babel/runtime/helpers/createClass";
4
- import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
5
- import _inherits from "@babel/runtime/helpers/inherits";
6
- import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
7
- import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
8
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
9
-
10
- 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; }
11
-
12
- 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) { _defineProperty(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; }
13
-
14
- import _regeneratorRuntime from "@babel/runtime/regenerator";
15
-
16
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
17
-
18
- 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; } }
19
-
20
- /** @jsx jsx */
21
- import React, { PureComponent } from 'react';
22
- import { jsx } from '@emotion/react';
23
- import { injectIntl } from 'react-intl-next';
24
- import { messages } from '../messages';
25
- import PanelTextInput from './text-input';
26
- import LinkSearchList from './link-search-list';
27
- import { normalizeUrl, isSafeUrl } from '../url';
28
- import { recentListStyles, containerStyles, searchIconStyles, listTitleStyles } from './styled';
29
- import { browser } from '../browser';
30
- import { transformTimeStamp } from '../transformTimeStamp';
31
- import Announcer from './announcer';
32
- import Button, { ButtonGroup } from '@atlaskit/button';
33
- import { FormFooter } from '@atlaskit/form';
34
- import EditorSearchIcon from '@atlaskit/icon/glyph/editor/search';
35
- import VisuallyHidden from '@atlaskit/visually-hidden';
36
- import LinkSearchNoResults from './link-search-no-results';
37
- export var RECENT_SEARCH_LIST_SIZE = 5;
38
-
39
- var LinkPicker = /*#__PURE__*/function (_PureComponent) {
40
- _inherits(LinkPicker, _PureComponent);
41
-
42
- var _super = _createSuper(LinkPicker);
43
-
44
- function LinkPicker(props) {
45
- var _this;
46
-
47
- _classCallCheck(this, LinkPicker);
48
-
49
- _this = _super.call(this, props);
50
-
51
- _defineProperty(_assertThisInitialized(_this), "wrapperRef", /*#__PURE__*/React.createRef());
52
-
53
- _defineProperty(_assertThisInitialized(_this), "queryVersion", 0);
54
-
55
- _defineProperty(_assertThisInitialized(_this), "updateInput", /*#__PURE__*/function () {
56
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(input) {
57
- return _regeneratorRuntime.wrap(function _callee$(_context) {
58
- while (1) {
59
- switch (_context.prev = _context.next) {
60
- case 0:
61
- if (!(input.length && isSafeUrl(input))) {
62
- _context.next = 2;
63
- break;
64
- }
65
-
66
- return _context.abrupt("return", _this.setState({
67
- url: input,
68
- selectedIndex: -1,
69
- items: [],
70
- isLoading: false,
71
- invalidUrl: null
72
- }));
73
-
74
- case 2:
75
- return _context.abrupt("return", _this.setState({
76
- url: input,
77
- // Unset selection on any input change
78
- selectedIndex: -1,
79
- invalidUrl: null
80
- }, function () {
81
- _this.updateResults();
82
- }));
83
-
84
- case 3:
85
- case "end":
86
- return _context.stop();
87
- }
88
- }
89
- }, _callee);
90
- }));
91
-
92
- return function (_x) {
93
- return _ref.apply(this, arguments);
94
- };
95
- }());
96
-
97
- _defineProperty(_assertThisInitialized(_this), "createClearHandler", function (field) {
98
- return function () {
99
- switch (field) {
100
- case 'url':
101
- {
102
- _this.updateInput('');
103
-
104
- break;
105
- }
106
-
107
- case 'displayText':
108
- {
109
- _this.setState(_defineProperty({}, field, ''));
110
- }
111
- }
112
- };
113
- });
114
-
115
- _defineProperty(_assertThisInitialized(_this), "getScreenReaderText", function () {
116
- var intl = _this.props.intl;
117
- var _this$state = _this.state,
118
- items = _this$state.items,
119
- selectedIndex = _this$state.selectedIndex;
120
-
121
- if (items.length && selectedIndex > -1) {
122
- var _items$selectedIndex = items[selectedIndex],
123
- name = _items$selectedIndex.name,
124
- container = _items$selectedIndex.container,
125
- lastUpdatedDate = _items$selectedIndex.lastUpdatedDate,
126
- lastViewedDate = _items$selectedIndex.lastViewedDate;
127
- var date = transformTimeStamp(intl, lastViewedDate, lastUpdatedDate);
128
- 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(' ');
129
- return [name, container, formattedDate].filter(Boolean).join(', ');
130
- }
131
- });
132
-
133
- _defineProperty(_assertThisInitialized(_this), "isUrlPopulatedWithSelectedItem", function () {
134
- /**
135
- * When we use ArrowKey to navigate through result items,
136
- * the URL field will be populated with the content of
137
- * selected item.
138
- * This function will check if the URL field is populated
139
- * with selected item.
140
- * It can be useful to detect whether we want to insert a
141
- * smartlink or a hyperlink with customized title
142
- */
143
- var _this$state2 = _this.state,
144
- items = _this$state2.items,
145
- selectedIndex = _this$state2.selectedIndex,
146
- url = _this$state2.url;
147
- var selectedItem = items[selectedIndex];
148
-
149
- if (selectedItem && selectedItem.url === url) {
150
- return true;
151
- }
152
-
153
- return false;
154
- });
155
-
156
- _defineProperty(_assertThisInitialized(_this), "handleSelected", function (objectId) {
157
- var items = _this.state.items;
158
- var selectedItem = items.find(function (item) {
159
- return item.objectId === objectId;
160
- });
161
-
162
- if (selectedItem) {
163
- var url = selectedItem.url,
164
- name = selectedItem.name;
165
-
166
- _this.handleInsert(url, name, 'typeAhead');
167
- }
168
- });
169
-
170
- _defineProperty(_assertThisInitialized(_this), "handleInsert", function (url, title, inputType) {
171
- var onSubmit = _this.props.onSubmit;
172
- var _this$state3 = _this.state,
173
- rawUrl = _this$state3.url,
174
- displayText = _this$state3.displayText;
175
-
176
- if (onSubmit) {
177
- onSubmit(_objectSpread({
178
- url: url,
179
- displayText: displayText || null,
180
- title: title || null,
181
- meta: {
182
- inputMethod: inputType
183
- }
184
- }, inputType === 'manual' ? {
185
- rawUrl: rawUrl
186
- } : {}));
187
- }
188
- });
189
-
190
- _defineProperty(_assertThisInitialized(_this), "handleMouseEnterResultItem", function (objectId) {
191
- var items = _this.state.items;
192
- var index = findIndex(items, function (item) {
193
- return item.objectId === objectId;
194
- });
195
-
196
- _this.setState({
197
- activeIndex: index
198
- });
199
- });
200
-
201
- _defineProperty(_assertThisInitialized(_this), "handleMouseLeaveResultItem", function (objectId) {
202
- var _this$state4 = _this.state,
203
- items = _this$state4.items,
204
- activeIndex = _this$state4.activeIndex;
205
- var index = findIndex(items, function (item) {
206
- return item.objectId === objectId;
207
- }); // This is to avoid updating index that was set by other mouseenter event
208
-
209
- if (activeIndex === index) {
210
- _this.setState({
211
- activeIndex: -1
212
- });
213
- }
214
- });
215
-
216
- _defineProperty(_assertThisInitialized(_this), "handleSubmit", function () {
217
- var _this$state5 = _this.state,
218
- url = _this$state5.url,
219
- selectedIndex = _this$state5.selectedIndex,
220
- items = _this$state5.items;
221
- var selectedItem = items[selectedIndex];
222
-
223
- if (_this.isUrlPopulatedWithSelectedItem()) {
224
- _this.handleInsert(selectedItem.url, selectedItem.name, 'typeAhead');
225
- } else if (url.length > 0) {
226
- var normalized = normalizeUrl(url);
227
-
228
- if (normalized) {
229
- _this.handleInsert(normalized, null, 'manual');
230
- } else {
231
- var intl = _this.props.intl;
232
- var linkInvalid = intl.formatMessage(messages.linkInvalid);
233
-
234
- _this.setState({
235
- invalidUrl: linkInvalid
236
- });
237
- }
238
- }
239
- });
240
-
241
- _defineProperty(_assertThisInitialized(_this), "handleKeyDown", function (event) {
242
- var _this$state6 = _this.state,
243
- items = _this$state6.items,
244
- activeIndex = _this$state6.activeIndex;
245
- var keyCode = event.keyCode;
246
- var KEY_CODE_ARROW_DOWN = 40;
247
- var KEY_CODE_ARROW_UP = 38;
248
-
249
- if (!items || !items.length) {
250
- return;
251
- }
252
-
253
- var updatedIndex = activeIndex;
254
-
255
- switch (keyCode) {
256
- case KEY_CODE_ARROW_DOWN:
257
- // down
258
- event.preventDefault();
259
- updatedIndex = (activeIndex + 1) % items.length;
260
- break;
261
-
262
- case KEY_CODE_ARROW_UP:
263
- // up
264
- event.preventDefault();
265
- updatedIndex = activeIndex > 0 ? activeIndex - 1 : items.length - 1;
266
- break;
267
- }
268
-
269
- if ([KEY_CODE_ARROW_DOWN, KEY_CODE_ARROW_UP].includes(keyCode) && items[updatedIndex]) {
270
- _this.setState({
271
- activeIndex: updatedIndex,
272
- selectedIndex: updatedIndex,
273
- url: items[updatedIndex].url,
274
- invalidUrl: null
275
- });
276
- }
277
- });
278
-
279
- _defineProperty(_assertThisInitialized(_this), "handleCancel", function () {
280
- var onCancel = _this.props.onCancel;
281
-
282
- if (onCancel) {
283
- onCancel();
284
- }
285
- });
286
-
287
- _defineProperty(_assertThisInitialized(_this), "updateTextInput", function (displayText) {
288
- _this.setState({
289
- displayText: displayText
290
- });
291
- });
292
-
293
- _this.state = {
294
- selectedIndex: -1,
295
- activeIndex: -1,
296
- isLoading: false,
297
- url: normalizeUrl(props.url) || '',
298
- displayText: props.displayText || '',
299
- items: [],
300
- invalidUrl: null
301
- };
302
- /* Cache functions */
303
-
304
- _this.handleClearUrl = _this.createClearHandler('url');
305
- _this.handleClearDisplayText = _this.createClearHandler('displayText');
306
- return _this;
307
- }
308
-
309
- _createClass(LinkPicker, [{
310
- key: "componentDidMount",
311
- value: function componentDidMount() {
312
- this.loadInitialLinkSearchResult();
313
- }
314
- }, {
315
- key: "loadInitialLinkSearchResult",
316
- value: function loadInitialLinkSearchResult() {
317
- var url = this.state.url;
318
-
319
- if (!url) {
320
- this.updateResults();
321
- }
322
- }
323
- }, {
324
- key: "getActivePlugin",
325
- value: function getActivePlugin() {
326
- if (!this.props.plugins || this.props.plugins.length === 0) {
327
- return null;
328
- }
329
-
330
- return this.props.plugins[0];
331
- }
332
- /**
333
- * Interface between link picker and plugins to update results
334
- */
335
-
336
- }, {
337
- key: "updateResults",
338
- value: function () {
339
- var _updateResults = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
340
- var queryVersion, activePlugin, updates, done, value, _result$done, result;
341
-
342
- return _regeneratorRuntime.wrap(function _callee2$(_context2) {
343
- while (1) {
344
- switch (_context2.prev = _context2.next) {
345
- case 0:
346
- queryVersion = ++this.queryVersion;
347
- activePlugin = this.getActivePlugin();
348
-
349
- if (activePlugin) {
350
- _context2.next = 4;
351
- break;
352
- }
353
-
354
- return _context2.abrupt("return");
355
-
356
- case 4:
357
- updates = activePlugin.resolve({
358
- query: this.state.url
359
- });
360
- this.setState({
361
- isLoading: true,
362
- items: []
363
- });
364
- _context2.prev = 6;
365
-
366
- case 7:
367
- if (!(queryVersion === this.queryVersion)) {
368
- _context2.next = 29;
369
- break;
370
- }
371
-
372
- done = false;
373
- value = void 0;
374
-
375
- if (!(updates instanceof Promise)) {
376
- _context2.next = 17;
377
- break;
378
- }
379
-
380
- done = true;
381
- _context2.next = 14;
382
- return updates;
383
-
384
- case 14:
385
- value = _context2.sent;
386
- _context2.next = 22;
387
- break;
388
-
389
- case 17:
390
- _context2.next = 19;
391
- return updates.next();
392
-
393
- case 19:
394
- result = _context2.sent;
395
- done = (_result$done = result.done) !== null && _result$done !== void 0 ? _result$done : false;
396
- value = result.value;
397
-
398
- case 22:
399
- if (!(queryVersion !== this.queryVersion)) {
400
- _context2.next = 24;
401
- break;
402
- }
403
-
404
- return _context2.abrupt("return");
405
-
406
- case 24:
407
- this.setState({
408
- items: limit(value.data),
409
- isLoading: !done
410
- });
411
-
412
- if (!done) {
413
- _context2.next = 27;
414
- break;
415
- }
416
-
417
- return _context2.abrupt("return");
418
-
419
- case 27:
420
- _context2.next = 7;
421
- break;
422
-
423
- case 29:
424
- _context2.next = 34;
425
- break;
426
-
427
- case 31:
428
- _context2.prev = 31;
429
- _context2.t0 = _context2["catch"](6);
430
- this.setState({
431
- isLoading: false
432
- });
433
-
434
- case 34:
435
- case "end":
436
- return _context2.stop();
437
- }
438
- }
439
- }, _callee2, this, [[6, 31]]);
440
- }));
441
-
442
- function updateResults() {
443
- return _updateResults.apply(this, arguments);
444
- }
445
-
446
- return updateResults;
447
- }()
448
- }, {
449
- key: "render",
450
- value: function render() {
451
- var _this$state7 = this.state,
452
- items = _this$state7.items,
453
- isLoading = _this$state7.isLoading,
454
- activeIndex = _this$state7.activeIndex,
455
- selectedIndex = _this$state7.selectedIndex,
456
- url = _this$state7.url,
457
- displayText = _this$state7.displayText;
458
- var formatMessage = this.props.intl.formatMessage;
459
- var activePlugin = this.getActivePlugin();
460
- var linkPlaceHolder = formatMessage(activePlugin ? messages.placeholder : messages.linkPlaceholder);
461
- var linkLabel = formatMessage(messages.linkLabel);
462
- var linkTextLabel = formatMessage(messages.linkTextLabel);
463
- var linkTextPlaceHolder = formatMessage(messages.linkTextPlaceholder);
464
- var screenReaderDescriptionId = 'search-recent-links-field-description';
465
- var linkSearchListId = 'link-picker-search-list';
466
- var ariaActiveDescendant = selectedIndex > -1 ? "link-search-list-item-".concat(selectedIndex) : ''; // Added workaround with a screen reader Announcer specifically for VoiceOver + Safari
467
- // as the Aria design pattern for combobox does not work in this case
468
- // for details: https://a11y-internal.atlassian.net/browse/AK-740
469
-
470
- var screenReaderText = browser.safari && this.getScreenReaderText();
471
- var searchIcon = activePlugin && jsx("span", {
472
- css: searchIconStyles,
473
- "data-testid": "link-picker-search-icon"
474
- }, jsx(EditorSearchIcon, {
475
- size: "medium",
476
- label: ''
477
- }));
478
- var noResults = activePlugin && !isLoading && !items.length && !isSafeUrl(url);
479
- return jsx("div", {
480
- "data-testid": "link-picker",
481
- className: "recent-list",
482
- css: recentListStyles
483
- }, jsx("div", {
484
- css: containerStyles,
485
- ref: this.wrapperRef
486
- }, screenReaderText && jsx(Announcer, {
487
- ariaLive: "assertive",
488
- text: screenReaderText,
489
- ariaRelevant: "additions",
490
- delay: 250
491
- }), jsx(VisuallyHidden, null, jsx("span", {
492
- "aria-hidden": "true",
493
- id: screenReaderDescriptionId
494
- }, formatMessage(messages.searchLinkAriaDescription))), jsx(PanelTextInput, {
495
- name: "link",
496
- testId: "link-url",
497
- role: "combobox",
498
- label: linkLabel,
499
- placeholder: linkPlaceHolder,
500
- value: url,
501
- autoFocus: true,
502
- autoComplete: "off",
503
- elemBeforeInput: searchIcon,
504
- onSubmit: this.handleSubmit,
505
- onChange: this.updateInput,
506
- onKeyDown: this.handleKeyDown,
507
- onClear: this.handleClearUrl,
508
- error: this.state.invalidUrl,
509
- clearLabel: formatMessage(messages.clearLink),
510
- "aria-controls": linkSearchListId,
511
- "aria-autocomplete": "list",
512
- "aria-activedescendant": ariaActiveDescendant,
513
- "aria-describedby": screenReaderDescriptionId,
514
- "aria-expanded": true
515
- }), jsx(PanelTextInput, {
516
- name: "link-text",
517
- testId: "link-text",
518
- autoComplete: "off",
519
- label: linkTextLabel,
520
- placeholder: linkTextPlaceHolder,
521
- "aria-label": formatMessage(messages.linkAriaLabel),
522
- value: displayText,
523
- onSubmit: this.handleSubmit,
524
- onKeyDown: this.handleKeyDown,
525
- onChange: this.updateTextInput,
526
- onClear: this.handleClearDisplayText,
527
- clearLabel: formatMessage(messages.clearText)
528
- }), !!items.length && jsx("div", {
529
- css: listTitleStyles,
530
- id: "link-picker-list-title",
531
- "data-testid": "link-picker-list-title"
532
- }, formatMessage(this.state.url ? messages.titleResults : messages.titleRecentlyViewed)), jsx(VisuallyHidden, null, jsx("span", {
533
- "aria-live": "polite",
534
- "aria-atomic": "true",
535
- id: "fabric.smartcard.linkpicker.suggested.results"
536
- }, url && formatMessage(messages.searchLinkResults, {
537
- count: items.length
538
- }))), jsx(LinkSearchList, {
539
- ariaLabelledBy: "link-picker-list-title",
540
- ariaControls: "fabric.smartcard.linkpicker.suggested.results",
541
- id: linkSearchListId,
542
- role: "listbox",
543
- items: items,
544
- isLoading: isLoading,
545
- selectedIndex: selectedIndex,
546
- activeIndex: activeIndex,
547
- onSelect: this.handleSelected,
548
- onMouseEnter: this.handleMouseEnterResultItem,
549
- onMouseLeave: this.handleMouseLeaveResultItem
550
- }), noResults && jsx(LinkSearchNoResults, {
551
- testId: "link-search-no-results",
552
- header: formatMessage(messages.noResults),
553
- description: formatMessage(messages.noResultsDescription)
554
- }), jsx(FormFooter, {
555
- align: "end"
556
- }, jsx(ButtonGroup, null, jsx(Button, {
557
- appearance: "default",
558
- onClick: this.handleCancel,
559
- testId: "link-picker-cancel-button"
560
- }, formatMessage(messages.cancelButton)), jsx(Button, {
561
- type: "submit",
562
- appearance: "primary",
563
- onClick: this.handleSubmit,
564
- testId: "link-picker-insert-button"
565
- }, formatMessage(messages.insertButton))))));
566
- }
567
- }]);
568
-
569
- return LinkPicker;
570
- }(PureComponent);
571
-
572
- function findIndex(array, predicate) {
573
- var index = -1;
574
- array.some(function (item, i) {
575
- if (predicate(item)) {
576
- index = i;
577
- return true;
578
- }
579
-
580
- return false;
581
- });
582
- return index;
583
- }
584
-
585
- function limit(items) {
586
- return items.slice(0, RECENT_SEARCH_LIST_SIZE);
587
- }
588
-
589
- export var LinkPickerWithIntl = injectIntl(LinkPicker);