@atlaskit/link-picker 1.24.1 → 1.25.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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # @atlaskit/link-picker
2
2
 
3
+ ## 1.25.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`bf9689fce97`](https://bitbucket.org/atlassian/atlassian-frontend/commits/bf9689fce97) - [ux] Modified behaviour to load to all plugins before Link Picker UI is loaded, introduces a isLoading attribute to
8
+ indicate when a plugins have loaded
9
+
3
10
  ## 1.24.1
4
11
 
5
12
  ### Patch Changes
@@ -16,7 +16,7 @@ var _add = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/add"));
16
16
  var _styled = require("./styled");
17
17
  var _utils = require("./utils");
18
18
  var _errors = require("../../../common/utils/errors");
19
- var _excluded = ["isLoading", "error", "state", "items", "isEditing", "onCancel", "action"];
19
+ var _excluded = ["isLoading", "error", "url", "queryState", "items", "isEditing", "onCancel", "action"];
20
20
  /** @jsx jsx */
21
21
  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); }
22
22
  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; }
@@ -46,7 +46,8 @@ exports.testIds = testIds;
46
46
  var FormFooter = function FormFooter(_ref) {
47
47
  var isLoading = _ref.isLoading,
48
48
  error = _ref.error,
49
- state = _ref.state,
49
+ url = _ref.url,
50
+ queryState = _ref.queryState,
50
51
  items = _ref.items,
51
52
  isEditing = _ref.isEditing,
52
53
  onCancel = _ref.onCancel,
@@ -56,7 +57,7 @@ var FormFooter = function FormFooter(_ref) {
56
57
  if (error && error instanceof _errors.UnauthenticatedError) {
57
58
  return null;
58
59
  }
59
- var isSubmitDisabled = (0, _utils.checkSubmitDisabled)(isLoading, error, state, items);
60
+ var isSubmitDisabled = (0, _utils.checkSubmitDisabled)(isLoading, error, url, queryState, items);
60
61
  var insertButtonMsg = isEditing ? messages.saveButton : messages.insertButton;
61
62
  return (0, _react.jsx)("footer", (0, _extends2.default)({
62
63
  css: _styled.formFooterStyles
@@ -5,12 +5,15 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.checkSubmitDisabled = void 0;
7
7
  var _url = require("@atlaskit/linking-common/url");
8
- var checkSubmitDisabled = function checkSubmitDisabled(isLoading, error, state, items) {
8
+ var checkSubmitDisabled = function checkSubmitDisabled(isLoading, error, url, queryState, items) {
9
9
  /*
10
10
  * Enable insert when search term is a valid url and it can be normalized
11
11
  * Need to explicitly enable it here otherwise next condition could meet
12
+ *
13
+ * This should effectively be the validation function for the form, ie if the form
14
+ * could be submitted, then it should not be disabled
12
15
  */
13
- if (state && (0, _url.normalizeUrl)(state.query)) {
16
+ if (url && (0, _url.normalizeUrl)(url)) {
14
17
  return false;
15
18
  }
16
19
 
@@ -18,7 +21,7 @@ var checkSubmitDisabled = function checkSubmitDisabled(isLoading, error, state,
18
21
  * Disable insert button when plugin returns no results,
19
22
  * but not if it is a valid url
20
23
  */
21
- if (state && (items === null || items === void 0 ? void 0 : items.length) === 0) {
24
+ if (queryState && (items === null || items === void 0 ? void 0 : items.length) === 0) {
22
25
  return true;
23
26
  }
24
27
 
@@ -35,6 +35,8 @@ var _formFooter = _interopRequireWildcard(require("./form-footer"));
35
35
  var _utils = require("./utils");
36
36
  var _trackTabViewed = _interopRequireDefault(require("./track-tab-viewed"));
37
37
  var _trackMount = _interopRequireDefault(require("./track-mount"));
38
+ var _styled2 = require("./link-search-list/styled");
39
+ var _spinner = _interopRequireDefault(require("@atlaskit/spinner/spinner"));
38
40
  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); }
39
41
  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; }
40
42
  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; }
@@ -93,6 +95,7 @@ function LinkPicker(_ref) {
93
95
  onCancel = _ref.onCancel,
94
96
  onContentResize = _ref.onContentResize,
95
97
  plugins = _ref.plugins,
98
+ isLoadingPlugins = _ref.isLoadingPlugins,
96
99
  initUrl = _ref.url,
97
100
  initDisplayText = _ref.displayText,
98
101
  hideDisplayText = _ref.hideDisplayText,
@@ -116,14 +119,14 @@ function LinkPicker(_ref) {
116
119
  var queryState = (0, _useSearchQuery.useSearchQuery)(state);
117
120
  var _usePlugins = (0, _usePlugins2.usePlugins)(queryState, activeTab, plugins),
118
121
  items = _usePlugins.items,
119
- isLoading = _usePlugins.isLoading,
122
+ isLoadingResults = _usePlugins.isLoading,
120
123
  isActivePlugin = _usePlugins.isActivePlugin,
121
124
  activePlugin = _usePlugins.activePlugin,
122
125
  tabs = _usePlugins.tabs,
123
126
  error = _usePlugins.error,
124
127
  retry = _usePlugins.retry,
125
128
  pluginAction = _usePlugins.pluginAction;
126
- var fixListHeightProps = (0, _useFixHeight.default)(isLoading);
129
+ var fixListHeightProps = (0, _useFixHeight.default)(isLoadingResults);
127
130
  var isEditing = !!initUrl;
128
131
  var selectedItem = items === null || items === void 0 ? void 0 : items[selectedIndex];
129
132
  var isSelectedItem = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.url) === url;
@@ -134,7 +137,7 @@ function LinkPicker(_ref) {
134
137
  if (onContentResize) {
135
138
  onContentResize();
136
139
  }
137
- }, [onContentResize, items, isLoading, isActivePlugin, tabs]);
140
+ }, [onContentResize, items, isLoadingResults, isActivePlugin, tabs]);
138
141
  var handleChangeUrl = (0, _react.useCallback)(function (e) {
139
142
  /** Any on change event is triggered by manual input or paste, so source is null */
140
143
  trackAttribute('linkFieldContentInputSource', null);
@@ -346,7 +349,12 @@ function LinkPicker(_ref) {
346
349
  "aria-label": intl.formatMessage(_messages.linkTextMessages.linkTextAriaLabel),
347
350
  onClear: handleClear,
348
351
  onChange: handleChangeText
349
- }), isActivePlugin && !!queryState && (0, _react2.jsx)(_react.Fragment, null, tabs.length > 0 && (0, _react2.jsx)("div", {
352
+ }), isLoadingPlugins && !!queryState && (0, _react2.jsx)("div", {
353
+ css: _styled2.spinnerContainerStyles
354
+ }, (0, _react2.jsx)(_spinner.default, {
355
+ testId: testIds.tabsLoadingIndicator,
356
+ size: "medium"
357
+ })), !isLoadingPlugins && isActivePlugin && !!queryState && (0, _react2.jsx)(_react.Fragment, null, tabs.length > 0 && (0, _react2.jsx)("div", {
350
358
  css: _styled.tabsWrapperStyles
351
359
  }, (0, _react2.jsx)(_tabs.default, {
352
360
  id: testIds.tabList,
@@ -361,7 +369,7 @@ function LinkPicker(_ref) {
361
369
  id: linkSearchListId,
362
370
  role: "listbox",
363
371
  items: items,
364
- isLoading: isLoading,
372
+ isLoading: isLoadingResults,
365
373
  selectedIndex: selectedIndex,
366
374
  activeIndex: activeIndex,
367
375
  onSelect: handleSelected,
@@ -371,9 +379,11 @@ function LinkPicker(_ref) {
371
379
  activePlugin: activePlugin
372
380
  }), error && ((_activePlugin$errorFa = activePlugin === null || activePlugin === void 0 ? void 0 : (_activePlugin$errorFa2 = activePlugin.errorFallback) === null || _activePlugin$errorFa2 === void 0 ? void 0 : _activePlugin$errorFa2.call(activePlugin, error, retry)) !== null && _activePlugin$errorFa !== void 0 ? _activePlugin$errorFa : (0, _react2.jsx)(_linkSearchError.default, null)))), (0, _react2.jsx)(_formFooter.default, {
373
381
  error: error,
374
- items: items,
375
- state: queryState,
376
- isLoading: isLoading,
382
+ items: items
383
+ /** If the results section appears to be loading, impact whether the submit button is disabled */,
384
+ isLoading: isLoadingResults || !!isLoadingPlugins,
385
+ queryState: queryState,
386
+ url: url,
377
387
  isEditing: isEditing,
378
388
  onCancel: onCancel,
379
389
  action: pluginAction,
@@ -48,7 +48,8 @@ var testIds = _objectSpread(_objectSpread({}, _linkSearchNoResults.testIds), {},
48
48
  resultListTitle: 'link-picker-list-title',
49
49
  searchResultItem: 'link-search-list-item',
50
50
  searchResultList: 'link-search-list',
51
- searchResultLoadingIndicator: 'link-picker.results-loading-indicator'
51
+ searchResultLoadingIndicator: 'link-picker.results-loading-indicator',
52
+ tabsLoadingIndicator: 'link-picker.tabs-loading-indicator'
52
53
  });
53
54
  exports.testIds = testIds;
54
55
  var LinkSearchList = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-picker",
3
- "version": "1.24.1",
3
+ "version": "1.25.0",
4
4
  "sideEffects": false
5
5
  }
@@ -33,7 +33,8 @@ export const testIds = {
33
33
  const FormFooter = ({
34
34
  isLoading,
35
35
  error,
36
- state,
36
+ url,
37
+ queryState,
37
38
  items,
38
39
  isEditing,
39
40
  onCancel,
@@ -44,7 +45,7 @@ const FormFooter = ({
44
45
  if (error && error instanceof UnauthenticatedError) {
45
46
  return null;
46
47
  }
47
- const isSubmitDisabled = checkSubmitDisabled(isLoading, error, state, items);
48
+ const isSubmitDisabled = checkSubmitDisabled(isLoading, error, url, queryState, items);
48
49
  const insertButtonMsg = isEditing ? messages.saveButton : messages.insertButton;
49
50
  return jsx("footer", _extends({
50
51
  css: formFooterStyles
@@ -1,10 +1,13 @@
1
1
  import { normalizeUrl } from '@atlaskit/linking-common/url';
2
- export const checkSubmitDisabled = (isLoading, error, state, items) => {
2
+ export const checkSubmitDisabled = (isLoading, error, url, queryState, items) => {
3
3
  /*
4
4
  * Enable insert when search term is a valid url and it can be normalized
5
5
  * Need to explicitly enable it here otherwise next condition could meet
6
+ *
7
+ * This should effectively be the validation function for the form, ie if the form
8
+ * could be submitted, then it should not be disabled
6
9
  */
7
- if (state && normalizeUrl(state.query)) {
10
+ if (url && normalizeUrl(url)) {
8
11
  return false;
9
12
  }
10
13
 
@@ -12,7 +15,7 @@ export const checkSubmitDisabled = (isLoading, error, state, items) => {
12
15
  * Disable insert button when plugin returns no results,
13
16
  * but not if it is a valid url
14
17
  */
15
- if (state && (items === null || items === void 0 ? void 0 : items.length) === 0) {
18
+ if (queryState && (items === null || items === void 0 ? void 0 : items.length) === 0) {
16
19
  return true;
17
20
  }
18
21
 
@@ -26,6 +26,8 @@ import FormFooter, { testIds as formFooterTestIds } from './form-footer';
26
26
  import { getDataSource, getScreenReaderText, handleNavKeyDown } from './utils';
27
27
  import TrackTabViewed from './track-tab-viewed';
28
28
  import TrackMount from './track-mount';
29
+ import { spinnerContainerStyles } from './link-search-list/styled';
30
+ import Spinner from '@atlaskit/spinner/spinner';
29
31
  export const RECENT_SEARCH_LIST_SIZE = 5;
30
32
  export const testIds = {
31
33
  linkPickerRoot: 'link-picker-root',
@@ -84,6 +86,7 @@ function LinkPicker({
84
86
  onCancel,
85
87
  onContentResize,
86
88
  plugins,
89
+ isLoadingPlugins,
87
90
  url: initUrl,
88
91
  displayText: initDisplayText,
89
92
  hideDisplayText,
@@ -110,7 +113,7 @@ function LinkPicker({
110
113
  const queryState = useSearchQuery(state);
111
114
  const {
112
115
  items,
113
- isLoading,
116
+ isLoading: isLoadingResults,
114
117
  isActivePlugin,
115
118
  activePlugin,
116
119
  tabs,
@@ -118,7 +121,7 @@ function LinkPicker({
118
121
  retry,
119
122
  pluginAction
120
123
  } = usePlugins(queryState, activeTab, plugins);
121
- const fixListHeightProps = useFixHeight(isLoading);
124
+ const fixListHeightProps = useFixHeight(isLoadingResults);
122
125
  const isEditing = !!initUrl;
123
126
  const selectedItem = items === null || items === void 0 ? void 0 : items[selectedIndex];
124
127
  const isSelectedItem = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.url) === url;
@@ -130,7 +133,7 @@ function LinkPicker({
130
133
  if (onContentResize) {
131
134
  onContentResize();
132
135
  }
133
- }, [onContentResize, items, isLoading, isActivePlugin, tabs]);
136
+ }, [onContentResize, items, isLoadingResults, isActivePlugin, tabs]);
134
137
  const handleChangeUrl = useCallback(e => {
135
138
  /** Any on change event is triggered by manual input or paste, so source is null */
136
139
  trackAttribute('linkFieldContentInputSource', null);
@@ -340,7 +343,12 @@ function LinkPicker({
340
343
  "aria-label": intl.formatMessage(linkTextMessages.linkTextAriaLabel),
341
344
  onClear: handleClear,
342
345
  onChange: handleChangeText
343
- }), isActivePlugin && !!queryState && jsx(Fragment, null, tabs.length > 0 && jsx("div", {
346
+ }), isLoadingPlugins && !!queryState && jsx("div", {
347
+ css: spinnerContainerStyles
348
+ }, jsx(Spinner, {
349
+ testId: testIds.tabsLoadingIndicator,
350
+ size: "medium"
351
+ })), !isLoadingPlugins && isActivePlugin && !!queryState && jsx(Fragment, null, tabs.length > 0 && jsx("div", {
344
352
  css: tabsWrapperStyles
345
353
  }, jsx(Tabs, {
346
354
  id: testIds.tabList,
@@ -355,7 +363,7 @@ function LinkPicker({
355
363
  id: linkSearchListId,
356
364
  role: "listbox",
357
365
  items: items,
358
- isLoading: isLoading,
366
+ isLoading: isLoadingResults,
359
367
  selectedIndex: selectedIndex,
360
368
  activeIndex: activeIndex,
361
369
  onSelect: handleSelected,
@@ -365,9 +373,11 @@ function LinkPicker({
365
373
  activePlugin: activePlugin
366
374
  }), error && ((_activePlugin$errorFa = activePlugin === null || activePlugin === void 0 ? void 0 : (_activePlugin$errorFa2 = activePlugin.errorFallback) === null || _activePlugin$errorFa2 === void 0 ? void 0 : _activePlugin$errorFa2.call(activePlugin, error, retry)) !== null && _activePlugin$errorFa !== void 0 ? _activePlugin$errorFa : jsx(LinkSearchError, null)))), jsx(FormFooter, {
367
375
  error: error,
368
- items: items,
369
- state: queryState,
370
- isLoading: isLoading,
376
+ items: items
377
+ /** If the results section appears to be loading, impact whether the submit button is disabled */,
378
+ isLoading: isLoadingResults || !!isLoadingPlugins,
379
+ queryState: queryState,
380
+ url: url,
371
381
  isEditing: isEditing,
372
382
  onCancel: onCancel,
373
383
  action: pluginAction,
@@ -34,7 +34,8 @@ export const testIds = {
34
34
  resultListTitle: 'link-picker-list-title',
35
35
  searchResultItem: 'link-search-list-item',
36
36
  searchResultList: 'link-search-list',
37
- searchResultLoadingIndicator: 'link-picker.results-loading-indicator'
37
+ searchResultLoadingIndicator: 'link-picker.results-loading-indicator',
38
+ tabsLoadingIndicator: 'link-picker.tabs-loading-indicator'
38
39
  };
39
40
  const LinkSearchList = /*#__PURE__*/forwardRef(({
40
41
  onChange,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-picker",
3
- "version": "1.24.1",
3
+ "version": "1.25.0",
4
4
  "sideEffects": false
5
5
  }
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- var _excluded = ["isLoading", "error", "state", "items", "isEditing", "onCancel", "action"];
3
+ var _excluded = ["isLoading", "error", "url", "queryState", "items", "isEditing", "onCancel", "action"];
4
4
  /** @jsx jsx */
5
5
  import { jsx } from '@emotion/react';
6
6
  import { memo } from 'react';
@@ -35,7 +35,8 @@ export var testIds = {
35
35
  var FormFooter = function FormFooter(_ref) {
36
36
  var isLoading = _ref.isLoading,
37
37
  error = _ref.error,
38
- state = _ref.state,
38
+ url = _ref.url,
39
+ queryState = _ref.queryState,
39
40
  items = _ref.items,
40
41
  isEditing = _ref.isEditing,
41
42
  onCancel = _ref.onCancel,
@@ -45,7 +46,7 @@ var FormFooter = function FormFooter(_ref) {
45
46
  if (error && error instanceof UnauthenticatedError) {
46
47
  return null;
47
48
  }
48
- var isSubmitDisabled = checkSubmitDisabled(isLoading, error, state, items);
49
+ var isSubmitDisabled = checkSubmitDisabled(isLoading, error, url, queryState, items);
49
50
  var insertButtonMsg = isEditing ? messages.saveButton : messages.insertButton;
50
51
  return jsx("footer", _extends({
51
52
  css: formFooterStyles
@@ -1,10 +1,13 @@
1
1
  import { normalizeUrl } from '@atlaskit/linking-common/url';
2
- export var checkSubmitDisabled = function checkSubmitDisabled(isLoading, error, state, items) {
2
+ export var checkSubmitDisabled = function checkSubmitDisabled(isLoading, error, url, queryState, items) {
3
3
  /*
4
4
  * Enable insert when search term is a valid url and it can be normalized
5
5
  * Need to explicitly enable it here otherwise next condition could meet
6
+ *
7
+ * This should effectively be the validation function for the form, ie if the form
8
+ * could be submitted, then it should not be disabled
6
9
  */
7
- if (state && normalizeUrl(state.query)) {
10
+ if (url && normalizeUrl(url)) {
8
11
  return false;
9
12
  }
10
13
 
@@ -12,7 +15,7 @@ export var checkSubmitDisabled = function checkSubmitDisabled(isLoading, error,
12
15
  * Disable insert button when plugin returns no results,
13
16
  * but not if it is a valid url
14
17
  */
15
- if (state && (items === null || items === void 0 ? void 0 : items.length) === 0) {
18
+ if (queryState && (items === null || items === void 0 ? void 0 : items.length) === 0) {
16
19
  return true;
17
20
  }
18
21
 
@@ -30,6 +30,8 @@ import FormFooter, { testIds as formFooterTestIds } from './form-footer';
30
30
  import { getDataSource, getScreenReaderText, handleNavKeyDown } from './utils';
31
31
  import TrackTabViewed from './track-tab-viewed';
32
32
  import TrackMount from './track-mount';
33
+ import { spinnerContainerStyles } from './link-search-list/styled';
34
+ import Spinner from '@atlaskit/spinner/spinner';
33
35
  export var RECENT_SEARCH_LIST_SIZE = 5;
34
36
  export var testIds = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
35
37
  linkPickerRoot: 'link-picker-root',
@@ -82,6 +84,7 @@ function LinkPicker(_ref) {
82
84
  onCancel = _ref.onCancel,
83
85
  onContentResize = _ref.onContentResize,
84
86
  plugins = _ref.plugins,
87
+ isLoadingPlugins = _ref.isLoadingPlugins,
85
88
  initUrl = _ref.url,
86
89
  initDisplayText = _ref.displayText,
87
90
  hideDisplayText = _ref.hideDisplayText,
@@ -105,14 +108,14 @@ function LinkPicker(_ref) {
105
108
  var queryState = useSearchQuery(state);
106
109
  var _usePlugins = usePlugins(queryState, activeTab, plugins),
107
110
  items = _usePlugins.items,
108
- isLoading = _usePlugins.isLoading,
111
+ isLoadingResults = _usePlugins.isLoading,
109
112
  isActivePlugin = _usePlugins.isActivePlugin,
110
113
  activePlugin = _usePlugins.activePlugin,
111
114
  tabs = _usePlugins.tabs,
112
115
  error = _usePlugins.error,
113
116
  retry = _usePlugins.retry,
114
117
  pluginAction = _usePlugins.pluginAction;
115
- var fixListHeightProps = useFixHeight(isLoading);
118
+ var fixListHeightProps = useFixHeight(isLoadingResults);
116
119
  var isEditing = !!initUrl;
117
120
  var selectedItem = items === null || items === void 0 ? void 0 : items[selectedIndex];
118
121
  var isSelectedItem = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.url) === url;
@@ -123,7 +126,7 @@ function LinkPicker(_ref) {
123
126
  if (onContentResize) {
124
127
  onContentResize();
125
128
  }
126
- }, [onContentResize, items, isLoading, isActivePlugin, tabs]);
129
+ }, [onContentResize, items, isLoadingResults, isActivePlugin, tabs]);
127
130
  var handleChangeUrl = useCallback(function (e) {
128
131
  /** Any on change event is triggered by manual input or paste, so source is null */
129
132
  trackAttribute('linkFieldContentInputSource', null);
@@ -335,7 +338,12 @@ function LinkPicker(_ref) {
335
338
  "aria-label": intl.formatMessage(linkTextMessages.linkTextAriaLabel),
336
339
  onClear: handleClear,
337
340
  onChange: handleChangeText
338
- }), isActivePlugin && !!queryState && jsx(Fragment, null, tabs.length > 0 && jsx("div", {
341
+ }), isLoadingPlugins && !!queryState && jsx("div", {
342
+ css: spinnerContainerStyles
343
+ }, jsx(Spinner, {
344
+ testId: testIds.tabsLoadingIndicator,
345
+ size: "medium"
346
+ })), !isLoadingPlugins && isActivePlugin && !!queryState && jsx(Fragment, null, tabs.length > 0 && jsx("div", {
339
347
  css: tabsWrapperStyles
340
348
  }, jsx(Tabs, {
341
349
  id: testIds.tabList,
@@ -350,7 +358,7 @@ function LinkPicker(_ref) {
350
358
  id: linkSearchListId,
351
359
  role: "listbox",
352
360
  items: items,
353
- isLoading: isLoading,
361
+ isLoading: isLoadingResults,
354
362
  selectedIndex: selectedIndex,
355
363
  activeIndex: activeIndex,
356
364
  onSelect: handleSelected,
@@ -360,9 +368,11 @@ function LinkPicker(_ref) {
360
368
  activePlugin: activePlugin
361
369
  }), error && ((_activePlugin$errorFa = activePlugin === null || activePlugin === void 0 ? void 0 : (_activePlugin$errorFa2 = activePlugin.errorFallback) === null || _activePlugin$errorFa2 === void 0 ? void 0 : _activePlugin$errorFa2.call(activePlugin, error, retry)) !== null && _activePlugin$errorFa !== void 0 ? _activePlugin$errorFa : jsx(LinkSearchError, null)))), jsx(FormFooter, {
362
370
  error: error,
363
- items: items,
364
- state: queryState,
365
- isLoading: isLoading,
371
+ items: items
372
+ /** If the results section appears to be loading, impact whether the submit button is disabled */,
373
+ isLoading: isLoadingResults || !!isLoadingPlugins,
374
+ queryState: queryState,
375
+ url: url,
366
376
  isEditing: isEditing,
367
377
  onCancel: onCancel,
368
378
  action: pluginAction,
@@ -38,7 +38,8 @@ export var testIds = _objectSpread(_objectSpread({}, noResultsTestIds), {}, {
38
38
  resultListTitle: 'link-picker-list-title',
39
39
  searchResultItem: 'link-search-list-item',
40
40
  searchResultList: 'link-search-list',
41
- searchResultLoadingIndicator: 'link-picker.results-loading-indicator'
41
+ searchResultLoadingIndicator: 'link-picker.results-loading-indicator',
42
+ tabsLoadingIndicator: 'link-picker.tabs-loading-indicator'
42
43
  });
43
44
  var LinkSearchList = /*#__PURE__*/forwardRef(function (_ref, ref) {
44
45
  var onChange = _ref.onChange,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-picker",
3
- "version": "1.24.1",
3
+ "version": "1.25.0",
4
4
  "sideEffects": false
5
5
  }
@@ -8,13 +8,15 @@ export declare const testIds: {
8
8
  readonly actionButton: "link-picker-action-button";
9
9
  };
10
10
  interface FormFooterProps extends React.HTMLAttributes<HTMLElement> {
11
+ /** If the results section appears to be loading, impact whether the submit button is disabled */
11
12
  isLoading: boolean;
12
13
  error: unknown | null;
13
- state: LinkPickerState | null;
14
+ url: string;
15
+ queryState: LinkPickerState | null;
14
16
  items: LinkSearchListItemData[] | null;
15
17
  isEditing?: boolean;
16
18
  onCancel?: () => void;
17
19
  action?: LinkPickerPluginAction;
18
20
  }
19
- declare const _default: import("react").MemoExoticComponent<({ isLoading, error, state, items, isEditing, onCancel, action, ...restProps }: FormFooterProps) => jsx.JSX.Element | null>;
21
+ declare const _default: import("react").MemoExoticComponent<({ isLoading, error, url, queryState, items, isEditing, onCancel, action, ...restProps }: FormFooterProps) => jsx.JSX.Element | null>;
20
22
  export default _default;
@@ -1,2 +1,2 @@
1
1
  import { LinkPickerState, LinkSearchListItemData } from '../../types';
2
- export declare const checkSubmitDisabled: (isLoading: boolean, error: unknown | null, state: LinkPickerState | null, items: LinkSearchListItemData[] | null) => boolean;
2
+ export declare const checkSubmitDisabled: (isLoading: boolean, error: unknown | null, url: string, queryState: LinkPickerState | null, items: LinkSearchListItemData[] | null) => boolean;
@@ -11,6 +11,7 @@ export declare const testIds: {
11
11
  readonly searchResultItem: string;
12
12
  readonly searchResultList: string;
13
13
  readonly searchResultLoadingIndicator: string;
14
+ readonly tabsLoadingIndicator: string;
14
15
  readonly emptyResultPage: string;
15
16
  readonly searchError: string;
16
17
  readonly insertButton: "link-picker-insert-button";
@@ -58,6 +59,8 @@ export interface LinkPickerProps {
58
59
  displayText?: string | null;
59
60
  /** Plugins that provide link suggestions / search capabilities. */
60
61
  plugins?: LinkPickerPlugin[];
62
+ /** If set true, Link picker will show the loading spinner where the tabs and results will show. */
63
+ isLoadingPlugins?: boolean;
61
64
  /** Customise the link picker root component */
62
65
  component?: React.ComponentType<Partial<LinkPickerProps> & {
63
66
  children: React.ReactElement;
@@ -23,6 +23,7 @@ export declare const testIds: {
23
23
  searchResultItem: string;
24
24
  searchResultList: string;
25
25
  searchResultLoadingIndicator: string;
26
+ tabsLoadingIndicator: string;
26
27
  emptyResultPage: string;
27
28
  };
28
29
  type LinkSearchListElement = HTMLElement;
@@ -8,13 +8,15 @@ export declare const testIds: {
8
8
  readonly actionButton: "link-picker-action-button";
9
9
  };
10
10
  interface FormFooterProps extends React.HTMLAttributes<HTMLElement> {
11
+ /** If the results section appears to be loading, impact whether the submit button is disabled */
11
12
  isLoading: boolean;
12
13
  error: unknown | null;
13
- state: LinkPickerState | null;
14
+ url: string;
15
+ queryState: LinkPickerState | null;
14
16
  items: LinkSearchListItemData[] | null;
15
17
  isEditing?: boolean;
16
18
  onCancel?: () => void;
17
19
  action?: LinkPickerPluginAction;
18
20
  }
19
- declare const _default: import("react").MemoExoticComponent<({ isLoading, error, state, items, isEditing, onCancel, action, ...restProps }: FormFooterProps) => jsx.JSX.Element | null>;
21
+ declare const _default: import("react").MemoExoticComponent<({ isLoading, error, url, queryState, items, isEditing, onCancel, action, ...restProps }: FormFooterProps) => jsx.JSX.Element | null>;
20
22
  export default _default;
@@ -1,2 +1,2 @@
1
1
  import { LinkPickerState, LinkSearchListItemData } from '../../types';
2
- export declare const checkSubmitDisabled: (isLoading: boolean, error: unknown | null, state: LinkPickerState | null, items: LinkSearchListItemData[] | null) => boolean;
2
+ export declare const checkSubmitDisabled: (isLoading: boolean, error: unknown | null, url: string, queryState: LinkPickerState | null, items: LinkSearchListItemData[] | null) => boolean;
@@ -11,6 +11,7 @@ export declare const testIds: {
11
11
  readonly searchResultItem: string;
12
12
  readonly searchResultList: string;
13
13
  readonly searchResultLoadingIndicator: string;
14
+ readonly tabsLoadingIndicator: string;
14
15
  readonly emptyResultPage: string;
15
16
  readonly searchError: string;
16
17
  readonly insertButton: "link-picker-insert-button";
@@ -58,6 +59,8 @@ export interface LinkPickerProps {
58
59
  displayText?: string | null;
59
60
  /** Plugins that provide link suggestions / search capabilities. */
60
61
  plugins?: LinkPickerPlugin[];
62
+ /** If set true, Link picker will show the loading spinner where the tabs and results will show. */
63
+ isLoadingPlugins?: boolean;
61
64
  /** Customise the link picker root component */
62
65
  component?: React.ComponentType<Partial<LinkPickerProps> & {
63
66
  children: React.ReactElement;
@@ -23,6 +23,7 @@ export declare const testIds: {
23
23
  searchResultItem: string;
24
24
  searchResultList: string;
25
25
  searchResultLoadingIndicator: string;
26
+ tabsLoadingIndicator: string;
26
27
  emptyResultPage: string;
27
28
  };
28
29
  type LinkSearchListElement = HTMLElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/link-picker",
3
- "version": "1.24.1",
3
+ "version": "1.25.0",
4
4
  "description": "Standalone link picker",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "publishConfig": {
@@ -90,7 +90,7 @@
90
90
  "@atlassian/atlassian-frontend-prettier-config-1.0.0": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.0",
91
91
  "@atlassian/feature-flags-test-utils": "*",
92
92
  "@atlassian/link-picker-atlassian-plugin": "^33.3.0",
93
- "@atlassian/link-picker-plugins": "^22.3.0",
93
+ "@atlassian/link-picker-plugins": "^23.0.0",
94
94
  "@atlassian/recent-work-client": "^1.8.0",
95
95
  "@testing-library/dom": "^8.17.1",
96
96
  "@testing-library/jest-dom": "^5.16.5",
package/report.api.md CHANGED
@@ -75,6 +75,7 @@ export interface LinkPickerProps {
75
75
  // (undocumented)
76
76
  featureFlags?: Record<string, unknown>;
77
77
  hideDisplayText?: boolean;
78
+ isLoadingPlugins?: boolean;
78
79
  onCancel: () => void;
79
80
  onContentResize?: () => void;
80
81
  onSubmit: (
@@ -55,6 +55,7 @@ export interface LinkPickerProps {
55
55
  // (undocumented)
56
56
  featureFlags?: Record<string, unknown>;
57
57
  hideDisplayText?: boolean;
58
+ isLoadingPlugins?: boolean;
58
59
  onCancel: () => void;
59
60
  onContentResize?: () => void;
60
61
  onSubmit: (arg: OnSubmitParameter, analytic?: UIAnalyticsEvent | null) => void;