@atlaskit/link-picker 1.8.3 → 1.9.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/controllers/use-fix-height/index.js +27 -0
  3. package/dist/cjs/services/use-plugins/index.js +48 -90
  4. package/dist/cjs/services/use-plugins/reducer.js +64 -0
  5. package/dist/cjs/services/use-plugins/utils.js +134 -0
  6. package/dist/cjs/ui/index.js +2 -1
  7. package/dist/cjs/ui/link-picker/form-footer/index.js +76 -0
  8. package/dist/cjs/ui/link-picker/form-footer/styled.js +17 -0
  9. package/dist/cjs/ui/link-picker/index.js +35 -76
  10. package/dist/cjs/ui/link-picker/link-search-error/index.js +47 -6
  11. package/dist/cjs/ui/link-picker/link-search-list/index.js +89 -20
  12. package/dist/cjs/ui/link-picker/link-search-list/link-search-no-results/index.js +54 -0
  13. package/dist/cjs/ui/link-picker/{link-search-no-results → link-search-list/link-search-no-results}/no-results-svg/index.js +0 -0
  14. package/dist/cjs/ui/link-picker/{link-search-no-results → link-search-list/link-search-no-results}/no-results-svg/styled.js +0 -0
  15. package/dist/cjs/ui/link-picker/link-search-list/link-search-no-results/styled.js +17 -0
  16. package/dist/cjs/ui/link-picker/link-search-list/styled.js +13 -6
  17. package/dist/cjs/ui/link-picker/messages.js +0 -50
  18. package/dist/cjs/ui/link-picker/styled.js +16 -11
  19. package/dist/cjs/ui/link-picker/text-input/styled.js +1 -1
  20. package/dist/cjs/version.json +1 -1
  21. package/dist/es2019/controllers/use-fix-height/index.js +19 -0
  22. package/dist/es2019/services/use-plugins/index.js +35 -57
  23. package/dist/es2019/services/use-plugins/reducer.js +37 -0
  24. package/dist/es2019/services/use-plugins/utils.js +59 -0
  25. package/dist/es2019/ui/index.js +1 -1
  26. package/dist/es2019/ui/link-picker/form-footer/index.js +51 -0
  27. package/dist/es2019/ui/link-picker/form-footer/styled.js +5 -0
  28. package/dist/es2019/ui/link-picker/index.js +30 -68
  29. package/dist/es2019/ui/link-picker/link-search-error/index.js +40 -4
  30. package/dist/es2019/ui/link-picker/link-search-list/index.js +60 -14
  31. package/dist/es2019/ui/link-picker/link-search-list/link-search-no-results/index.js +35 -0
  32. package/dist/es2019/ui/link-picker/{link-search-no-results → link-search-list/link-search-no-results}/no-results-svg/index.js +0 -0
  33. package/dist/es2019/ui/link-picker/{link-search-no-results → link-search-list/link-search-no-results}/no-results-svg/styled.js +0 -0
  34. package/dist/es2019/ui/link-picker/link-search-list/link-search-no-results/styled.js +6 -0
  35. package/dist/es2019/ui/link-picker/link-search-list/styled.js +23 -2
  36. package/dist/es2019/ui/link-picker/messages.js +0 -50
  37. package/dist/es2019/ui/link-picker/styled.js +20 -15
  38. package/dist/es2019/ui/link-picker/text-input/styled.js +3 -1
  39. package/dist/es2019/version.json +1 -1
  40. package/dist/esm/controllers/use-fix-height/index.js +19 -0
  41. package/dist/esm/services/use-plugins/index.js +49 -94
  42. package/dist/esm/services/use-plugins/reducer.js +43 -0
  43. package/dist/esm/services/use-plugins/utils.js +111 -0
  44. package/dist/esm/ui/index.js +1 -1
  45. package/dist/esm/ui/link-picker/form-footer/index.js +53 -0
  46. package/dist/esm/ui/link-picker/form-footer/styled.js +6 -0
  47. package/dist/esm/ui/link-picker/index.js +31 -73
  48. package/dist/esm/ui/link-picker/link-search-error/index.js +41 -5
  49. package/dist/esm/ui/link-picker/link-search-list/index.js +67 -13
  50. package/dist/esm/ui/link-picker/link-search-list/link-search-no-results/index.js +37 -0
  51. package/dist/esm/ui/link-picker/{link-search-no-results → link-search-list/link-search-no-results}/no-results-svg/index.js +0 -0
  52. package/dist/esm/ui/link-picker/{link-search-no-results → link-search-list/link-search-no-results}/no-results-svg/styled.js +0 -0
  53. package/dist/esm/ui/link-picker/link-search-list/link-search-no-results/styled.js +6 -0
  54. package/dist/esm/ui/link-picker/link-search-list/styled.js +11 -5
  55. package/dist/esm/ui/link-picker/messages.js +0 -50
  56. package/dist/esm/ui/link-picker/styled.js +14 -11
  57. package/dist/esm/ui/link-picker/text-input/styled.js +1 -1
  58. package/dist/esm/version.json +1 -1
  59. package/dist/types/controllers/use-fix-height/index.d.ts +8 -0
  60. package/dist/types/services/use-plugins/reducer.d.ts +30 -0
  61. package/dist/types/services/use-plugins/utils.d.ts +18 -0
  62. package/dist/types/ui/index.d.ts +5 -0
  63. package/dist/types/ui/link-picker/form-footer/index.d.ts +13 -0
  64. package/dist/types/ui/link-picker/form-footer/styled.d.ts +1 -0
  65. package/dist/types/ui/link-picker/index.d.ts +21 -18
  66. package/dist/types/ui/link-picker/link-search-error/index.d.ts +19 -3
  67. package/dist/types/ui/link-picker/link-search-list/index.d.ts +30 -5
  68. package/dist/types/ui/link-picker/link-search-list/link-search-no-results/index.d.ts +19 -0
  69. package/dist/types/ui/link-picker/{link-search-no-results → link-search-list/link-search-no-results}/no-results-svg/index.d.ts +0 -0
  70. package/dist/types/ui/link-picker/{link-search-no-results → link-search-list/link-search-no-results}/no-results-svg/styled.d.ts +0 -0
  71. package/dist/types/ui/link-picker/link-search-list/link-search-no-results/styled.d.ts +1 -0
  72. package/dist/types/ui/link-picker/link-search-list/styled.d.ts +1 -0
  73. package/dist/types/ui/link-picker/messages.d.ts +0 -50
  74. package/dist/types/ui/link-picker/styled.d.ts +5 -1
  75. package/package.json +15 -14
  76. package/report.api.md +8 -2
  77. package/dist/cjs/ui/link-picker/link-search-no-results/index.js +0 -27
  78. package/dist/es2019/ui/link-picker/link-search-no-results/index.js +0 -10
  79. package/dist/esm/ui/link-picker/link-search-no-results/index.js +0 -14
  80. package/dist/types/ui/link-picker/link-search-no-results/index.d.ts +0 -4
@@ -11,8 +11,6 @@ import { Fragment, useCallback, useEffect, useLayoutEffect, useReducer, memo } f
11
11
  import { jsx } from '@emotion/react';
12
12
  import { useIntl, FormattedMessage } from 'react-intl-next';
13
13
  import { useAnalyticsEvents } from '@atlaskit/analytics-next';
14
- import Button, { ButtonGroup } from '@atlaskit/button';
15
- import { FormFooter } from '@atlaskit/form';
16
14
  import EditorSearchIcon from '@atlaskit/icon/glyph/editor/search';
17
15
  import Tabs, { Tab, TabList } from '@atlaskit/tabs';
18
16
  import VisuallyHidden from '@atlaskit/visually-hidden';
@@ -23,34 +21,28 @@ import { useSearchQuery } from '../../services/use-search-query';
23
21
  import { withLinkPickerAnalyticsContext } from '../../services/with-link-picker-analytics';
24
22
  import { messages } from './messages';
25
23
  import PanelTextInput from './text-input';
26
- import LinkSearchList from './link-search-list';
27
24
  import { normalizeUrl, isSafeUrl } from '../../common/utils/url';
28
- import { rootContainerStyles, searchIconStyles, listTitleStyles, tabsWrapperStyles } from './styled';
25
+ import useFixHeight from '../../controllers/use-fix-height';
26
+ import { rootContainerStyles, searchIconStyles, tabsWrapperStyles, flexColumnStyles, formFooterMargin } from './styled';
29
27
  import { browser } from './browser';
30
28
  import Announcer from './announcer';
31
- import LinkSearchNoResults from './link-search-no-results';
32
29
  import { transformTimeStamp } from './transformTimeStamp';
33
- import LinkSearchError from './link-search-error';
30
+ import LinkSearchList, { testIds as listTestIds } from './link-search-list';
31
+ import LinkSearchError, { testIds as searchErrorTestIds } from './link-search-error';
32
+ import FormFooter, { testIds as formFooterTestIds } from './form-footer';
34
33
  export var RECENT_SEARCH_LIST_SIZE = 5;
35
34
  export var CONTACT_SUPPORT_LINK = 'https://support.atlassian.com/contact/';
36
- export var testIds = {
35
+ export var testIds = _objectSpread(_objectSpread(_objectSpread(_objectSpread({
37
36
  linkPicker: 'link-picker',
38
37
  urlInputField: 'link-url',
39
38
  textInputField: 'link-text',
40
- searchIcon: 'link-picker-search-icon',
41
- insertButton: 'link-picker-insert-button',
42
- cancelButton: 'link-picker-cancel-button',
39
+ searchIcon: 'link-picker-search-icon'
40
+ }, formFooterTestIds), searchErrorTestIds), listTestIds), {}, {
43
41
  clearUrlButton: 'clear-text',
44
- resultListTitle: 'link-picker-list-title',
45
- emptyResultPage: 'link-search-no-results',
46
- searchResultList: 'link-search-list',
47
- searchResultItem: 'link-search-list-item',
48
- searchResultLoadingIndicator: 'link-picker.results-loading-indicator',
49
42
  urlError: 'link-error',
50
43
  tabList: 'link-picker-tabs',
51
- tabItem: 'link-picker-tab',
52
- searchError: 'link-search-error'
53
- };
44
+ tabItem: 'link-picker-tab'
45
+ });
54
46
  var initState = {
55
47
  url: '',
56
48
  displayText: '',
@@ -72,7 +64,7 @@ function reducer(state, payload) {
72
64
  }
73
65
 
74
66
  function LinkPicker(_ref) {
75
- var _queryState$query, _items$length, _errorFallback;
67
+ var _errorFallback;
76
68
 
77
69
  var onSubmit = _ref.onSubmit,
78
70
  onCancel = _ref.onCancel,
@@ -110,6 +102,7 @@ function LinkPicker(_ref) {
110
102
  retry = _usePlugins.retry,
111
103
  errorFallback = _usePlugins.errorFallback;
112
104
 
105
+ var fixListHeightProps = useFixHeight(isLoading);
113
106
  var isEditing = !!initUrl;
114
107
  var selectedItem = items === null || items === void 0 ? void 0 : items[selectedIndex];
115
108
  var isSelectedItem = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.url) === url;
@@ -195,7 +188,11 @@ function LinkPicker(_ref) {
195
188
  }
196
189
  }, [activeIndex, items]);
197
190
  var handleInsert = useCallback(function (url, title, inputType) {
198
- var event = createAnalyticsEvent(createEventPayload('ui.form.submitted.linkPicker', {}));
191
+ var event = createAnalyticsEvent(createEventPayload('ui.form.submitted.linkPicker', {})); // Clone the event so that it can be emitted for consumer usage
192
+ // This must happen BEFORE the original event is fired!
193
+
194
+ var consumerEvent = event.clone(); // Dispatch the original event to our channel
195
+
199
196
  event.fire(ANALYTICS_CHANNEL);
200
197
  onSubmit(_objectSpread({
201
198
  url: url,
@@ -206,7 +203,7 @@ function LinkPicker(_ref) {
206
203
  }
207
204
  }, inputType === 'manual' ? {
208
205
  rawUrl: state.url
209
- } : {}));
206
+ } : {}), consumerEvent);
210
207
  }, [displayText, onSubmit, state.url, createAnalyticsEvent]);
211
208
  var handleSelected = useCallback(function (objectId) {
212
209
  var selectedItem = items === null || items === void 0 ? void 0 : items.find(function (item) {
@@ -238,9 +235,6 @@ function LinkPicker(_ref) {
238
235
  });
239
236
  }, [handleInsert, isSelectedItem, selectedItem, url]);
240
237
  var linkPlaceHolder = isActivePlugin ? messages.placeholder : messages.linkPlaceholder;
241
- var linkListTitle = (queryState === null || queryState === void 0 ? void 0 : (_queryState$query = queryState.query) === null || _queryState$query === void 0 ? void 0 : _queryState$query.length) !== 0 ? messages.titleResults : messages.titleRecentlyViewed;
242
- var insertButtonMsg = isEditing ? messages.saveButton : messages.insertButton;
243
- var noResults = (items === null || items === void 0 ? void 0 : items.length) === 0 && !error;
244
238
  var screenReaderDescriptionId = 'search-recent-links-field-description';
245
239
  var linkSearchListId = 'link-picker-search-list';
246
240
  var ariaActiveDescendant = selectedIndex > -1 ? "link-search-list-item-".concat(selectedIndex) : ''; // Added workaround with a screen reader Announcer specifically for VoiceOver + Safari
@@ -298,7 +292,7 @@ function LinkPicker(_ref) {
298
292
  onClear: handleClear,
299
293
  onKeyDown: handleKeyDown,
300
294
  onChange: handleChangeText
301
- }), queryState && jsx(Fragment, null, tabs.length > 0 && jsx("div", {
295
+ }), isActivePlugin && !!queryState && jsx(Fragment, null, tabs.length > 0 && jsx("div", {
302
296
  css: tabsWrapperStyles
303
297
  }, jsx(Tabs, {
304
298
  id: testIds.tabList,
@@ -316,61 +310,25 @@ function LinkPicker(_ref) {
316
310
  key: tab.tabTitle,
317
311
  testId: testIds.tabItem
318
312
  }, tab.tabTitle);
319
- })))), !!(items !== null && items !== void 0 && items.length) && jsx("div", {
320
- css: listTitleStyles,
321
- id: testIds.resultListTitle,
322
- "data-testid": testIds.resultListTitle
323
- }, jsx(FormattedMessage, linkListTitle)), jsx(VisuallyHidden, {
324
- id: "fabric.smartcard.linkpicker.suggested.results"
325
- }, url && jsx(FormattedMessage, _extends({}, messages.searchLinkResults, {
326
- values: {
327
- count: (_items$length = items === null || items === void 0 ? void 0 : items.length) !== null && _items$length !== void 0 ? _items$length : 0
328
- },
329
- "aria-live": "polite",
330
- "aria-atomic": "true"
331
- }))), jsx(LinkSearchList, {
332
- ariaLabelledBy: testIds.resultListTitle,
333
- ariaControls: "fabric.smartcard.linkpicker.suggested.results",
313
+ })))), jsx("div", _extends({
314
+ css: flexColumnStyles
315
+ }, fixListHeightProps), !error && jsx(LinkSearchList, {
334
316
  id: linkSearchListId,
335
317
  role: "listbox",
336
- items: items !== null && items !== void 0 ? items : [],
318
+ items: items,
337
319
  isLoading: isLoading,
338
320
  selectedIndex: selectedIndex,
339
321
  activeIndex: activeIndex,
340
322
  onSelect: handleSelected,
341
323
  onMouseEnter: handleMouseEnterResultItem,
342
- onMouseLeave: handleMouseLeaveResultItem
343
- }), error && ((_errorFallback = errorFallback === null || errorFallback === void 0 ? void 0 : errorFallback(error, retry)) !== null && _errorFallback !== void 0 ? _errorFallback : jsx(LinkSearchError, {
344
- testId: testIds.searchError,
345
- header: intl.formatMessage(messages.searchErrorHeader),
346
- description: jsx(FormattedMessage, _extends({}, messages.searchErrorDescription, {
347
- values: {
348
- a: function a(label) {
349
- return jsx(Button, {
350
- appearance: "link",
351
- spacing: "none",
352
- href: CONTACT_SUPPORT_LINK,
353
- target: "_blank",
354
- rel: "noopener noreferrer"
355
- }, label);
356
- }
357
- }
358
- }))
359
- })), noResults && jsx(LinkSearchNoResults, {
360
- testId: testIds.emptyResultPage,
361
- header: intl.formatMessage(messages.noResults),
362
- description: intl.formatMessage(messages.noResultsDescription)
363
- })), jsx(FormFooter, {
364
- align: "end"
365
- }, jsx(ButtonGroup, null, jsx(Button, {
366
- appearance: "default",
367
- onClick: onCancel,
368
- testId: testIds.cancelButton
369
- }, intl.formatMessage(messages.cancelButton)), jsx(Button, {
370
- type: "submit",
371
- appearance: "primary",
372
- testId: testIds.insertButton
373
- }, intl.formatMessage(insertButtonMsg)))));
324
+ onMouseLeave: handleMouseLeaveResultItem,
325
+ error: error,
326
+ hasSearchTerm: !!(queryState !== null && queryState !== void 0 && queryState.query.length)
327
+ }), error && ((_errorFallback = errorFallback === null || errorFallback === void 0 ? void 0 : errorFallback(error, retry)) !== null && _errorFallback !== void 0 ? _errorFallback : jsx(LinkSearchError, null)))), jsx(FormFooter, {
328
+ css: !queryState || !(plugins !== null && plugins !== void 0 && plugins.length) ? formFooterMargin : undefined,
329
+ isEditing: isEditing,
330
+ onCancel: onCancel
331
+ }));
374
332
  }
375
333
 
376
334
  export default withLinkPickerAnalyticsContext( /*#__PURE__*/memo(LinkPicker));
@@ -1,14 +1,50 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import React from 'react';
2
+
3
+ /** @jsx jsx */
4
+ import { jsx } from '@emotion/react';
5
+ import { useIntl, FormattedMessage, defineMessages } from 'react-intl-next';
6
+ import Button from '@atlaskit/button';
7
+ export var CONTACT_SUPPORT_LINK = 'https://support.atlassian.com/contact/';
8
+ export var messages = defineMessages({
9
+ searchErrorHeader: {
10
+ id: 'fabric.linkPicker.search.error.heading',
11
+ defaultMessage: 'We’re having trouble loading data.',
12
+ description: 'Heading message shown when a search throws an error'
13
+ },
14
+ searchErrorDescription: {
15
+ id: 'fabric.linkPicker.search.error.description',
16
+ defaultMessage: 'Refresh the page, or contact <a>Atlassian Support</a> if this keeps happening.',
17
+ description: 'Describes possible actions when search throws an error'
18
+ }
19
+ });
3
20
  import EmptyState from '@atlaskit/empty-state';
4
21
  import GenericErrorSVG from '../../../common/generic-error-svg';
22
+ export var testIds = {
23
+ searchError: 'link-search-error'
24
+ };
5
25
 
6
- var LinkSearchError = function LinkSearchError(props) {
7
- return /*#__PURE__*/React.createElement(EmptyState, _extends({}, props, {
26
+ var LinkSearchError = function LinkSearchError() {
27
+ var intl = useIntl();
28
+ return jsx(EmptyState, {
29
+ testId: testIds.searchError,
30
+ header: intl.formatMessage(messages.searchErrorHeader),
31
+ description: jsx(FormattedMessage, _extends({}, messages.searchErrorDescription, {
32
+ values: {
33
+ a: function a(label) {
34
+ return jsx(Button, {
35
+ appearance: "link",
36
+ spacing: "none",
37
+ href: CONTACT_SUPPORT_LINK,
38
+ target: "_blank",
39
+ rel: "noopener noreferrer"
40
+ }, label);
41
+ }
42
+ }
43
+ })),
8
44
  renderImage: function renderImage() {
9
- return /*#__PURE__*/React.createElement(GenericErrorSVG, null);
45
+ return jsx(GenericErrorSVG, null);
10
46
  }
11
- }));
47
+ });
12
48
  };
13
49
 
14
50
  export default LinkSearchError;
@@ -1,11 +1,45 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ var _excluded = ["onSelect", "onMouseEnter", "onMouseLeave", "items", "activeIndex", "selectedIndex", "isLoading", "ariaControls", "ariaLabelledBy", "role", "id", "hasSearchTerm"];
5
+
6
+ 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; }
7
+
8
+ 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; }
9
+
1
10
  /** @jsx jsx */
11
+ import { forwardRef, Fragment } from 'react';
2
12
  import { jsx } from '@emotion/react';
13
+ import { defineMessages, FormattedMessage } from 'react-intl-next';
3
14
  import Spinner from '@atlaskit/spinner';
15
+ import VisuallyHidden from '@atlaskit/visually-hidden';
4
16
  import LinkSearchListItem from '../list-item';
5
- import { listContainerStyles, spinnerContainerStyles, listStyles } from './styled';
6
- import { testIds } from '../';
7
-
8
- var LinkSearchList = function LinkSearchList(_ref) {
17
+ import { listContainerStyles, spinnerContainerStyles, listStyles, listTitleStyles } from './styled';
18
+ import LinkSearchNoResults, { testIds as noResultsTestIds } from './link-search-no-results';
19
+ export var messages = defineMessages({
20
+ titleRecentlyViewed: {
21
+ id: 'fabric.linkPicker.listTitle.recentlyViewed',
22
+ defaultMessage: 'Recently Viewed',
23
+ description: 'Describes type of items shown in the list for screen-reader users'
24
+ },
25
+ titleResults: {
26
+ id: 'fabric.linkPicker.listTitle.results',
27
+ defaultMessage: 'Results',
28
+ description: 'Describes type of items shown in the list for screen-reader users'
29
+ },
30
+ searchLinkResults: {
31
+ id: 'fabric.linkPicker.hyperlink.searchLinkResults',
32
+ defaultMessage: '{count, plural, =0 {no results} one {# result} other {# results}} found',
33
+ description: 'Announce search results for screen-reader users.'
34
+ }
35
+ });
36
+ export var testIds = _objectSpread(_objectSpread({}, noResultsTestIds), {}, {
37
+ resultListTitle: 'link-picker-list-title',
38
+ searchResultItem: 'link-search-list-item',
39
+ searchResultList: 'link-search-list',
40
+ searchResultLoadingIndicator: 'link-picker.results-loading-indicator'
41
+ });
42
+ var LinkSearchList = /*#__PURE__*/forwardRef(function (_ref, ref) {
9
43
  var onSelect = _ref.onSelect,
10
44
  onMouseEnter = _ref.onMouseEnter,
11
45
  onMouseLeave = _ref.onMouseLeave,
@@ -16,17 +50,37 @@ var LinkSearchList = function LinkSearchList(_ref) {
16
50
  ariaControls = _ref.ariaControls,
17
51
  ariaLabelledBy = _ref.ariaLabelledBy,
18
52
  role = _ref.role,
19
- id = _ref.id;
53
+ id = _ref.id,
54
+ hasSearchTerm = _ref.hasSearchTerm,
55
+ restProps = _objectWithoutProperties(_ref, _excluded);
56
+
20
57
  var itemsContent;
21
58
  var loadingContent;
59
+ var linkListTitle = hasSearchTerm ? messages.titleResults : messages.titleRecentlyViewed;
60
+
61
+ if ((items === null || items === void 0 ? void 0 : items.length) === 0) {
62
+ return jsx(LinkSearchNoResults, null);
63
+ }
22
64
 
23
65
  if (items && items.length > 0) {
24
- itemsContent = jsx("ul", {
66
+ itemsContent = jsx(Fragment, null, jsx("div", {
67
+ css: listTitleStyles,
68
+ id: testIds.resultListTitle,
69
+ "data-testid": testIds.resultListTitle
70
+ }, jsx(FormattedMessage, linkListTitle)), jsx(VisuallyHidden, {
71
+ id: "fabric.smartcard.linkpicker.suggested.results"
72
+ }, hasSearchTerm && jsx(FormattedMessage, _extends({}, messages.searchLinkResults, {
73
+ values: {
74
+ count: items.length
75
+ },
76
+ "aria-live": "polite",
77
+ "aria-atomic": "true"
78
+ }))), jsx("ul", {
25
79
  id: id,
26
80
  role: role,
27
81
  css: listStyles,
28
- "aria-controls": ariaControls,
29
- "aria-labelledby": ariaLabelledBy,
82
+ "aria-controls": "fabric.smartcard.linkpicker.suggested.results",
83
+ "aria-labelledby": testIds.resultListTitle,
30
84
  "data-testid": testIds.searchResultList
31
85
  }, items.map(function (item, index) {
32
86
  return jsx(LinkSearchListItem, {
@@ -40,7 +94,7 @@ var LinkSearchList = function LinkSearchList(_ref) {
40
94
  onSelect: onSelect,
41
95
  key: item.objectId
42
96
  });
43
- }));
97
+ })));
44
98
  }
45
99
 
46
100
  if (isLoading) {
@@ -52,9 +106,9 @@ var LinkSearchList = function LinkSearchList(_ref) {
52
106
  }));
53
107
  }
54
108
 
55
- return jsx("div", {
109
+ return jsx("div", _extends({
110
+ ref: ref,
56
111
  css: listContainerStyles
57
- }, itemsContent, loadingContent);
58
- };
59
-
112
+ }, restProps), itemsContent, loadingContent);
113
+ });
60
114
  export default LinkSearchList;
@@ -0,0 +1,37 @@
1
+ /** @jsx jsx */
2
+ import { jsx } from '@emotion/react';
3
+ import EmptyState from '@atlaskit/empty-state';
4
+ import { useIntl, defineMessages } from 'react-intl-next';
5
+ import NoResultsSVG from './no-results-svg';
6
+ import { emptyStateWrapperStyles } from './styled';
7
+ export var messages = defineMessages({
8
+ noResults: {
9
+ id: 'fabric.linkPicker.search.noResults.heading',
10
+ defaultMessage: 'We couldn’t find anything matching your search.',
11
+ description: 'Heading message shown when a search has no results'
12
+ },
13
+ noResultsDescription: {
14
+ id: 'fabric.linkPicker.search.noResults.description',
15
+ defaultMessage: 'Try again with a different term.',
16
+ description: 'Describes possible action when a search returns no results'
17
+ }
18
+ });
19
+ export var testIds = {
20
+ emptyResultPage: 'link-search-no-results'
21
+ };
22
+
23
+ var NoResults = function NoResults() {
24
+ var intl = useIntl();
25
+ return jsx("div", {
26
+ css: emptyStateWrapperStyles
27
+ }, jsx(EmptyState, {
28
+ testId: testIds.emptyResultPage,
29
+ header: intl.formatMessage(messages.noResults),
30
+ description: intl.formatMessage(messages.noResultsDescription),
31
+ renderImage: function renderImage() {
32
+ return jsx(NoResultsSVG, null);
33
+ }
34
+ }));
35
+ };
36
+
37
+ export default NoResults;
@@ -0,0 +1,6 @@
1
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
+
3
+ var _templateObject;
4
+
5
+ import { css } from '@emotion/react';
6
+ export var emptyStateWrapperStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n & p {\n margin: 0;\n }\n"])));
@@ -1,8 +1,14 @@
1
1
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
2
 
3
- var _templateObject, _templateObject2, _templateObject3;
3
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4;
4
4
 
5
- import { css } from '@emotion/react';
6
- export var listContainerStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding-top: 0;\n"])));
7
- export var spinnerContainerStyles = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n text-align: center;\n min-height: 80px;\n margin-top: 30px;\n"])));
8
- export var listStyles = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n padding: 0;\n list-style: none;\n"])));
5
+ import { css } from '@emotion/react'; // AFP-2532 TODO: Fix automatic suppressions below
6
+ // eslint-disable-next-line @atlassian/tangerine/import/entry-points
7
+
8
+ import { typography } from '@atlaskit/theme';
9
+ import { gridSize as getGridSize } from '@atlaskit/theme/constants';
10
+ var gridSize = getGridSize();
11
+ export var listContainerStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding-top: 0;\n min-height: 80px;\n margin-top: ", "px;\n margin-bottom: ", "px;\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n"])), gridSize * 2, gridSize * 2);
12
+ export var spinnerContainerStyles = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n text-align: center;\n min-height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-grow: 1;\n"])));
13
+ export var listStyles = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n padding: 0;\n margin: 0;\n list-style: none;\n"])));
14
+ export var listTitleStyles = css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n ", "\n text-transform: uppercase;\n margin-top: 0;\n margin-bottom: ", "px;\n"])), typography.h100(), gridSize / 2);
@@ -45,11 +45,6 @@ export var messages = defineMessages({
45
45
  defaultMessage: 'Suggestions will appear below as you type into the field',
46
46
  description: 'Describes what the search field does for screen reader users.'
47
47
  },
48
- searchLinkResults: {
49
- id: 'fabric.linkPicker.hyperlink.searchLinkResults',
50
- defaultMessage: '{count, plural, =0 {no results} one {# result} other {# results}} found',
51
- description: 'Announce search results for screen-reader users.'
52
- },
53
48
  linkAriaLabel: {
54
49
  id: 'fabric.linkPicker.hyperlink.linkAriaLabel',
55
50
  defaultMessage: 'Link label',
@@ -69,50 +64,5 @@ export var messages = defineMessages({
69
64
  id: 'fabric.linkPicker.time.ago',
70
65
  defaultMessage: 'ago',
71
66
  description: 'Some time ago'
72
- },
73
- titleRecentlyViewed: {
74
- id: 'fabric.linkPicker.listTitle.recentlyViewed',
75
- defaultMessage: 'Recently Viewed',
76
- description: 'Describes type of items shown in the list for screen-reader users'
77
- },
78
- titleResults: {
79
- id: 'fabric.linkPicker.listTitle.results',
80
- defaultMessage: 'Results',
81
- description: 'Describes type of items shown in the list for screen-reader users'
82
- },
83
- cancelButton: {
84
- id: 'fabric.linkPicker.button.cancel',
85
- defaultMessage: 'Cancel',
86
- description: 'Button to cancel and dismiss the link picker'
87
- },
88
- insertButton: {
89
- id: 'fabric.linkPicker.button.insert',
90
- defaultMessage: 'Insert',
91
- description: 'Button to insert searched or selected link'
92
- },
93
- noResults: {
94
- id: 'fabric.linkPicker.search.noResults.heading',
95
- defaultMessage: 'We couldn’t find anything matching your search.',
96
- description: 'Heading message shown when a search has no results'
97
- },
98
- noResultsDescription: {
99
- id: 'fabric.linkPicker.search.noResults.description',
100
- defaultMessage: 'Try again with a different term.',
101
- description: 'Describes possible action when a search returns no results'
102
- },
103
- saveButton: {
104
- id: 'fabric.linkPicker.button.save',
105
- defaultMessage: 'Save',
106
- description: 'Button to save edited link'
107
- },
108
- searchErrorHeader: {
109
- id: 'fabric.linkPicker.search.error.heading',
110
- defaultMessage: 'We’re having trouble loading data.',
111
- description: 'Heading message shown when a search throws an error'
112
- },
113
- searchErrorDescription: {
114
- id: 'fabric.linkPicker.search.error.description',
115
- defaultMessage: 'Refresh the page, or contact <a>Atlassian Support</a> if this keeps happening.',
116
- description: 'Describes possible actions when search throws an error'
117
67
  }
118
68
  });
@@ -1,18 +1,21 @@
1
1
  import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
2
 
3
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
3
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6;
4
4
 
5
5
  import { token } from '@atlaskit/tokens';
6
6
  import { css } from '@emotion/react';
7
- import { N500 } from '@atlaskit/theme/colors'; // AFP-2532 TODO: Fix automatic suppressions below
8
- // eslint-disable-next-line @atlassian/tangerine/import/entry-points
9
-
10
- import { typography } from '@atlaskit/theme';
11
- import { gridSize } from '@atlaskit/theme/constants';
7
+ import { N500 } from '@atlaskit/theme/colors';
8
+ import { gridSize as getGridSize } from '@atlaskit/theme/constants';
12
9
  var LINK_PICKER_WIDTH_IN_PX = 342;
13
- var LINK_PICKER_MIN_HEIGHT_IN_PX = 234;
14
- export var rootContainerStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n width: ", "px;\n padding: ", "px;\n box-sizing: border-box;\n line-height: initial;\n min-height: ", "px;\n"])), LINK_PICKER_WIDTH_IN_PX, gridSize() * 2, LINK_PICKER_MIN_HEIGHT_IN_PX);
10
+ var LINK_PICKER_MIN_HEIGHT_IN_PX = 220;
11
+ var gridSize = getGridSize();
12
+ /**
13
+ * Half padding on the top as the form field has a `gridSize()` margin top that cannot be overridden
14
+ */
15
+
16
+ export var rootContainerStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n width: ", "px;\n padding: ", "px ", "px ", "px;\n box-sizing: border-box;\n line-height: initial;\n min-height: ", "px;\n"])), LINK_PICKER_WIDTH_IN_PX, gridSize, gridSize * 2, gridSize * 2, LINK_PICKER_MIN_HEIGHT_IN_PX);
15
17
  export var rootContainerStylesForLoader = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n ", "\n display: flex;\n align-items: center;\n justify-content: center;\n"])), rootContainerStyles);
16
- export var searchIconStyles = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n margin-left: ", "px;\n color: ", ";\n cursor: default;\n"])), gridSize() / 2, token('color.icon', N500));
17
- export var listTitleStyles = css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n ", "\n text-transform: uppercase;\n margin-bottom: ", "px;\n"])), typography.h100(), gridSize() / 2);
18
- export var tabsWrapperStyles = css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n margin-left: -", "px;\n margin-right: -", "px;\n"])), gridSize(), gridSize());
18
+ export var searchIconStyles = css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n margin-left: ", "px;\n color: ", ";\n cursor: default;\n"])), gridSize / 2, token('color.icon', N500));
19
+ export var tabsWrapperStyles = css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n margin-top: ", "px;\n margin-left: -", "px;\n margin-right: -", "px;\n"])), gridSize * 1.5, gridSize, gridSize);
20
+ export var flexColumnStyles = css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n"])));
21
+ export var formFooterMargin = css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n margin-top: ", "px;\n"])), gridSize * 2);
@@ -7,4 +7,4 @@ import { css } from '@emotion/react';
7
7
  import { N500 } from '@atlaskit/theme/colors';
8
8
  import { gridSize } from '@atlaskit/theme/constants';
9
9
  export var clearTextButtonStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding: 0;\n margin-right: ", "px;\n color: ", ";\n background: transparent;\n border: none;\n cursor: pointer;\n"])), gridSize() / 2, token('color.icon.subtle', N500));
10
- export var fieldStyles = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n margin-bottom: ", "px;\n"])), gridSize() * 2);
10
+ export var fieldStyles = css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n & + & {\n margin-top: ", "px;\n }\n"])), gridSize() * 2);
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-picker",
3
- "version": "1.8.3",
3
+ "version": "1.9.0",
4
4
  "sideEffects": false
5
5
  }
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ declare const useFixHeight: (shouldFixHeight: boolean) => {
3
+ ref: import("react").RefObject<HTMLDivElement>;
4
+ style: {
5
+ minHeight: string | number;
6
+ } | undefined;
7
+ };
8
+ export default useFixHeight;
@@ -0,0 +1,30 @@
1
+ /// <reference types="react" />
2
+ import { LinkSearchListItemData } from '../../ui/types';
3
+ export interface PluginState {
4
+ items: LinkSearchListItemData[] | null;
5
+ error: unknown | null;
6
+ isLoading: boolean;
7
+ }
8
+ export declare const ACTION_CLEAR = "CLEAR";
9
+ export declare const ACTION_LOADING = "LOADING";
10
+ export declare const ACTION_SUCCESS = "SUCCESS";
11
+ export declare const ACTION_ERRORED = "ERROR";
12
+ interface ClearAction {
13
+ type: typeof ACTION_CLEAR;
14
+ }
15
+ interface ResolveLoadingAction {
16
+ type: typeof ACTION_LOADING;
17
+ }
18
+ interface ResolveSuccessAction {
19
+ type: typeof ACTION_SUCCESS;
20
+ payload: Pick<PluginState, 'items' | 'isLoading'>;
21
+ }
22
+ interface ResolveErrorAction {
23
+ type: typeof ACTION_ERRORED;
24
+ payload: PluginState['error'];
25
+ }
26
+ export declare type ReducerAction = ClearAction | ResolveLoadingAction | ResolveSuccessAction | ResolveErrorAction;
27
+ export declare const INITIAL_STATE: PluginState;
28
+ export declare function reducer(state: PluginState, action: ReducerAction): PluginState;
29
+ export declare const usePluginReducer: () => [PluginState, import("react").Dispatch<ReducerAction>];
30
+ export {};
@@ -0,0 +1,18 @@
1
+ import { LinkPickerPlugin, LinkPickerState, ResolveResult } from '../../ui/types';
2
+ export declare class CancellationError extends Error {
3
+ }
4
+ export declare const cancellable: <T extends unknown>(promise: Promise<T>) => {
5
+ promise: Promise<T>;
6
+ cancel: () => void;
7
+ };
8
+ /**
9
+ * Wraps the resolve with a cancellation wrapper and makes promise + generator plugin resolves more compatible
10
+ * Calling cancel for generator plugin prevents it from yielding any further updates
11
+ */
12
+ export declare const resolvePluginUpdates: (plugin: LinkPickerPlugin, state: LinkPickerState) => {
13
+ cancel: () => void;
14
+ next: () => Promise<{
15
+ done?: boolean;
16
+ value: ResolveResult;
17
+ }>;
18
+ };
@@ -1,3 +1,8 @@
1
1
  import React from 'react';
2
2
  import { LinkPickerProps } from './link-picker';
3
+ export declare const PACKAGE_DATA: {
4
+ packageName: any;
5
+ packageVersion: any;
6
+ componentName: string;
7
+ };
3
8
  export declare const ComposedLinkPicker: React.MemoExoticComponent<(props: LinkPickerProps) => JSX.Element>;
@@ -0,0 +1,13 @@
1
+ /// <reference types="react" />
2
+ /** @jsx jsx */
3
+ import { jsx } from '@emotion/react';
4
+ export declare const testIds: {
5
+ readonly insertButton: "link-picker-insert-button";
6
+ readonly cancelButton: "link-picker-cancel-button";
7
+ };
8
+ interface FormFooterProps extends React.HTMLAttributes<HTMLElement> {
9
+ isEditing?: boolean;
10
+ onCancel?: () => void;
11
+ }
12
+ declare const _default: import("react").MemoExoticComponent<({ isEditing, onCancel, ...restProps }: FormFooterProps) => jsx.JSX.Element>;
13
+ export default _default;
@@ -0,0 +1 @@
1
+ export declare const formFooterStyles: import("@emotion/react").SerializedStyles;