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