@atlaskit/link-picker 1.30.14 → 1.32.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 (33) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/ui/index.js +1 -1
  3. package/dist/cjs/ui/link-picker/form-footer/index.js +35 -10
  4. package/dist/cjs/ui/link-picker/form-footer/utils.js +4 -1
  5. package/dist/cjs/ui/link-picker/index.js +40 -11
  6. package/dist/cjs/ui/link-picker/search-results/index.js +2 -0
  7. package/dist/cjs/ui/link-picker/search-results/link-search-list/index.js +3 -1
  8. package/dist/cjs/ui/messages-provider/lazy-messages-provider/utils/fetch-messages-for-locale.js +5 -15
  9. package/dist/es2019/ui/index.js +1 -1
  10. package/dist/es2019/ui/link-picker/form-footer/index.js +31 -9
  11. package/dist/es2019/ui/link-picker/form-footer/utils.js +4 -1
  12. package/dist/es2019/ui/link-picker/index.js +39 -11
  13. package/dist/es2019/ui/link-picker/search-results/index.js +2 -0
  14. package/dist/es2019/ui/link-picker/search-results/link-search-list/index.js +2 -0
  15. package/dist/es2019/ui/messages-provider/lazy-messages-provider/utils/fetch-messages-for-locale.js +0 -10
  16. package/dist/esm/ui/index.js +1 -1
  17. package/dist/esm/ui/link-picker/form-footer/index.js +35 -10
  18. package/dist/esm/ui/link-picker/form-footer/utils.js +4 -1
  19. package/dist/esm/ui/link-picker/index.js +40 -11
  20. package/dist/esm/ui/link-picker/search-results/index.js +2 -0
  21. package/dist/esm/ui/link-picker/search-results/link-search-list/index.js +3 -1
  22. package/dist/esm/ui/messages-provider/lazy-messages-provider/utils/fetch-messages-for-locale.js +5 -15
  23. package/dist/types/ui/link-picker/form-footer/index.d.ts +28 -1
  24. package/dist/types/ui/link-picker/form-footer/utils.d.ts +1 -1
  25. package/dist/types/ui/link-picker/index.d.ts +20 -0
  26. package/dist/types/ui/link-picker/search-results/index.d.ts +2 -1
  27. package/dist/types/ui/link-picker/search-results/link-search-list/index.d.ts +1 -0
  28. package/dist/types-ts4.5/ui/link-picker/form-footer/index.d.ts +28 -1
  29. package/dist/types-ts4.5/ui/link-picker/form-footer/utils.d.ts +1 -1
  30. package/dist/types-ts4.5/ui/link-picker/index.d.ts +20 -0
  31. package/dist/types-ts4.5/ui/link-picker/search-results/index.d.ts +2 -1
  32. package/dist/types-ts4.5/ui/link-picker/search-results/link-search-list/index.d.ts +1 -0
  33. package/package.json +6 -9
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/link-picker
2
2
 
3
+ ## 1.32.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#61981](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/61981) [`0d7a20c43478`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/0d7a20c43478) - [ux] Added a UI experience for when a submission is in progress
8
+
9
+ ### Patch Changes
10
+
11
+ - [#64291](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/64291) [`c44535acbea9`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/c44535acbea9) - remove platform.linking-platform.link-create.tmp-fix-translations to permanently return undefined in the loaderFn when dynamic import of locale messages fail.
12
+
13
+ ## 1.31.0
14
+
15
+ ### Minor Changes
16
+
17
+ - [#64242](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/64242) [`066547c92554`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/066547c92554) - Add customMessages prop to link picker
18
+
3
19
  ## 1.30.14
4
20
 
5
21
  ### Patch Changes
@@ -26,7 +26,7 @@ var testIds = exports.testIds = {
26
26
  };
27
27
  var PACKAGE_DATA = exports.PACKAGE_DATA = {
28
28
  packageName: "@atlaskit/link-picker" || '',
29
- packageVersion: "1.30.14" || '',
29
+ packageVersion: "1.32.0" || '',
30
30
  componentName: _constants.COMPONENT_NAME,
31
31
  source: _constants.COMPONENT_NAME
32
32
  };
@@ -5,23 +5,26 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.testIds = exports.FormFooter = void 0;
8
+ exports.testIds = exports.messages = exports.FormFooter = void 0;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
10
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
11
11
  var _react = require("react");
12
12
  var _react2 = require("@emotion/react");
13
13
  var _reactIntlNext = require("react-intl-next");
14
+ var _uuid = _interopRequireDefault(require("uuid"));
14
15
  var _button = _interopRequireWildcard(require("@atlaskit/button"));
16
+ var _loadingButton = _interopRequireDefault(require("@atlaskit/button/loading-button"));
15
17
  var _add = _interopRequireDefault(require("@atlaskit/icon/glyph/editor/add"));
18
+ var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden"));
16
19
  var _errors = require("../../../common/utils/errors");
17
20
  var _featureDiscovery = _interopRequireDefault(require("./feature-discovery"));
18
21
  var _styled = require("./styled");
19
22
  var _utils = require("./utils");
20
- var _excluded = ["isLoading", "error", "url", "queryState", "items", "isEditing", "onCancel", "action", "createFeatureDiscovery"];
23
+ var _excluded = ["isLoading", "isSubmitting", "error", "url", "queryState", "items", "isEditing", "onCancel", "action", "createFeatureDiscovery", "customSubmitButtonLabel"];
21
24
  /** @jsx jsx */
22
25
  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); }
23
26
  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; }
24
- var messages = (0, _reactIntlNext.defineMessages)({
27
+ var messages = exports.messages = (0, _reactIntlNext.defineMessages)({
25
28
  cancelButton: {
26
29
  id: 'fabric.linkPicker.button.cancel',
27
30
  defaultMessage: 'Cancel',
@@ -36,17 +39,25 @@ var messages = (0, _reactIntlNext.defineMessages)({
36
39
  id: 'fabric.linkPicker.button.insert',
37
40
  defaultMessage: 'Insert',
38
41
  description: 'Button to insert searched or selected link'
42
+ },
43
+ submittingStatusMessage: {
44
+ id: 'fabric.linkPicker.status.submitting',
45
+ defaultMessage: 'Submitting',
46
+ description: 'Accessibility text to indicate the form has been submitted, and submission is in-progress'
39
47
  }
40
48
  });
41
49
  var testIds = exports.testIds = {
42
50
  insertButton: 'link-picker-insert-button',
43
51
  cancelButton: 'link-picker-cancel-button',
44
52
  actionButton: 'link-picker-action-button',
53
+ submitStatusA11yIndicator: 'link-picker-submit-status-a11y-indicator',
45
54
  /** Feature discovery for action button (css pulse) */
46
55
  actionButtonDiscovery: 'link-picker-action-button-discovery'
47
56
  };
48
57
  var FormFooter = exports.FormFooter = /*#__PURE__*/(0, _react.memo)(function (_ref) {
49
58
  var isLoading = _ref.isLoading,
59
+ _ref$isSubmitting = _ref.isSubmitting,
60
+ isSubmitting = _ref$isSubmitting === void 0 ? false : _ref$isSubmitting,
50
61
  error = _ref.error,
51
62
  url = _ref.url,
52
63
  queryState = _ref.queryState,
@@ -56,12 +67,16 @@ var FormFooter = exports.FormFooter = /*#__PURE__*/(0, _react.memo)(function (_r
56
67
  action = _ref.action,
57
68
  _ref$createFeatureDis = _ref.createFeatureDiscovery,
58
69
  createFeatureDiscovery = _ref$createFeatureDis === void 0 ? false : _ref$createFeatureDis,
70
+ customSubmitButtonLabel = _ref.customSubmitButtonLabel,
59
71
  restProps = (0, _objectWithoutProperties2.default)(_ref, _excluded);
60
72
  var intl = (0, _reactIntlNext.useIntl)();
73
+ var submitMessageId = (0, _react.useMemo)(function () {
74
+ return (0, _uuid.default)();
75
+ }, []);
61
76
  if (error && error instanceof _errors.UnauthenticatedError) {
62
77
  return null;
63
78
  }
64
- var isSubmitDisabled = (0, _utils.checkSubmitDisabled)(isLoading, error, url, queryState, items);
79
+ var isSubmitDisabled = (0, _utils.checkSubmitDisabled)(isLoading, isSubmitting, error, url, queryState, items);
65
80
  var insertButtonMsg = isEditing ? messages.saveButton : messages.insertButton;
66
81
  var createButton = function createButton(pluginAction) {
67
82
  return (0, _react2.jsx)(_button.default, {
@@ -71,23 +86,33 @@ var FormFooter = exports.FormFooter = /*#__PURE__*/(0, _react.memo)(function (_r
71
86
  iconBefore: (0, _react2.jsx)(_add.default, {
72
87
  label: "",
73
88
  size: "medium"
74
- })
89
+ }),
90
+ isDisabled: isSubmitting,
91
+ "aria-labelledby": isSubmitting ? submitMessageId : undefined
75
92
  }, typeof pluginAction.label === 'string' ? pluginAction.label : intl.formatMessage(pluginAction.label));
76
93
  };
77
94
  return (0, _react2.jsx)("footer", (0, _extends2.default)({
78
95
  css: _styled.formFooterStyles
79
- }, restProps), action && (0, _react2.jsx)("div", {
96
+ }, restProps), isSubmitting && (0, _react2.jsx)(_visuallyHidden.default, {
97
+ role: "status",
98
+ id: submitMessageId,
99
+ testId: testIds.submitStatusA11yIndicator
100
+ }, intl.formatMessage(messages.submittingStatusMessage)), action && (0, _react2.jsx)("div", {
80
101
  css: _styled.formFooterActionStyles
81
102
  }, createFeatureDiscovery ? (0, _react2.jsx)(_featureDiscovery.default, {
82
103
  testId: testIds.actionButtonDiscovery
83
104
  }, createButton(action)) : createButton(action)), (0, _react2.jsx)(_button.ButtonGroup, null, (0, _react2.jsx)(_button.default, {
84
105
  appearance: "subtle",
85
106
  onClick: onCancel,
86
- testId: testIds.cancelButton
87
- }, intl.formatMessage(messages.cancelButton)), (0, _react2.jsx)(_button.default, {
107
+ testId: testIds.cancelButton,
108
+ isDisabled: isSubmitting,
109
+ "aria-labelledby": isSubmitting ? submitMessageId : undefined
110
+ }, intl.formatMessage(messages.cancelButton)), (0, _react2.jsx)(_loadingButton.default, {
88
111
  type: "submit",
89
112
  appearance: "primary",
90
113
  testId: testIds.insertButton,
91
- isDisabled: isSubmitDisabled
92
- }, intl.formatMessage(insertButtonMsg))));
114
+ isDisabled: isSubmitDisabled,
115
+ "aria-labelledby": isSubmitting ? submitMessageId : undefined,
116
+ isLoading: isSubmitting
117
+ }, customSubmitButtonLabel ? intl.formatMessage(customSubmitButtonLabel) : intl.formatMessage(insertButtonMsg))));
93
118
  });
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.checkSubmitDisabled = void 0;
7
7
  var _url = require("@atlaskit/linking-common/url");
8
- var checkSubmitDisabled = exports.checkSubmitDisabled = function checkSubmitDisabled(isLoading, error, url, queryState, items) {
8
+ var checkSubmitDisabled = exports.checkSubmitDisabled = function checkSubmitDisabled(isLoading, isSubmitting, 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
@@ -13,6 +13,9 @@ var checkSubmitDisabled = exports.checkSubmitDisabled = function checkSubmitDisa
13
13
  * This should effectively be the validation function for the form, ie if the form
14
14
  * could be submitted, then it should not be disabled
15
15
  */
16
+ if (isSubmitting) {
17
+ return true;
18
+ }
16
19
  if (url && (0, _url.normalizeUrl)(url)) {
17
20
  return false;
18
21
  }
@@ -85,7 +85,10 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
85
85
  initUrl = _ref.url,
86
86
  initDisplayText = _ref.displayText,
87
87
  hideDisplayText = _ref.hideDisplayText,
88
- featureFlags = _ref.featureFlags;
88
+ featureFlags = _ref.featureFlags,
89
+ customMessages = _ref.customMessages,
90
+ _ref$isSubmitting = _ref.isSubmitting,
91
+ isSubmitting = _ref$isSubmitting === void 0 ? false : _ref$isSubmitting;
89
92
  var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
90
93
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
91
94
  var _useReducer = (0, _react.useReducer)(reducer, _objectSpread(_objectSpread({}, initState), {}, {
@@ -125,6 +128,11 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
125
128
  }
126
129
  }, [onContentResize, items, isLoadingResults, isActivePlugin, tabs]);
127
130
  var handleChangeUrl = (0, _react.useCallback)(function (e) {
131
+ if (isSubmitting) {
132
+ // Prevent changing url while submitting
133
+ return;
134
+ }
135
+
128
136
  /** Any on change event is triggered by manual input or paste, so source is null */
129
137
  trackAttribute('linkFieldContentInputSource', null);
130
138
  dispatch({
@@ -132,7 +140,7 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
132
140
  // If the last action was changing tabs, make sure we're now allowing recents to be hidden
133
141
  preventHidingRecents: false
134
142
  });
135
- }, [dispatch, trackAttribute]);
143
+ }, [dispatch, trackAttribute, isSubmitting]);
136
144
  var handleChangeText = (0, _react.useCallback)(function (e) {
137
145
  dispatch({
138
146
  displayText: e.currentTarget.value
@@ -145,9 +153,13 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
145
153
  }, field, ''));
146
154
  }, [dispatch]);
147
155
  var handleUrlClear = (0, _react.useCallback)(function () {
156
+ if (isSubmitting) {
157
+ // Prevent clearing url while submitting
158
+ return;
159
+ }
148
160
  trackAttribute('linkFieldContentInputSource', null);
149
161
  handleClear('url');
150
- }, [trackAttribute, handleClear]);
162
+ }, [trackAttribute, handleClear, isSubmitting]);
151
163
  var handleInsert = (0, _react.useCallback)(function (url, title, inputType) {
152
164
  var event = createAnalyticsEvent((0, _analytics2.default)('ui.form.submitted.linkPicker', {}));
153
165
 
@@ -173,6 +185,10 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
173
185
  } : {}), consumerEvent);
174
186
  }, [displayText, onSubmit, state.url, createAnalyticsEvent, getAttributes]);
175
187
  var handleSelected = (0, _react.useCallback)(function (objectId) {
188
+ if (isSubmitting) {
189
+ // Prevent changing selection while submitting
190
+ return;
191
+ }
176
192
  var selectedItem = items === null || items === void 0 ? void 0 : items.find(function (item) {
177
193
  return item.objectId === objectId;
178
194
  });
@@ -188,9 +204,13 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
188
204
  trackAttribute('linkFieldContentInputSource', (0, _utils.getDataSource)(selectedItem, activePlugin));
189
205
  handleInsert(_url, name, 'typeAhead');
190
206
  }
191
- }, [handleInsert, trackAttribute, items, activePlugin]);
207
+ }, [handleInsert, trackAttribute, items, activePlugin, isSubmitting]);
192
208
  var handleSubmit = (0, _react.useCallback)(function (event) {
193
209
  event === null || event === void 0 || event.preventDefault();
210
+ if (isSubmitting) {
211
+ // Prevent submit while submitting
212
+ return;
213
+ }
194
214
  if (isSelectedItem && selectedItem) {
195
215
  return handleInsert(selectedItem.url, selectedItem.name, 'typeAhead');
196
216
  }
@@ -201,7 +221,7 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
201
221
  return dispatch({
202
222
  invalidUrl: true
203
223
  });
204
- }, [dispatch, handleInsert, isSelectedItem, selectedItem, url]);
224
+ }, [dispatch, handleInsert, isSelectedItem, selectedItem, url, isSubmitting]);
205
225
  var handleTabChange = (0, _react.useCallback)(function (activeTab) {
206
226
  var _plugins$activeTab$ta, _plugins$activeTab;
207
227
  dispatch({
@@ -217,6 +237,10 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
217
237
  trackAttribute('tab', (_plugins$activeTab$ta = plugins === null || plugins === void 0 || (_plugins$activeTab = plugins[activeTab]) === null || _plugins$activeTab === void 0 ? void 0 : _plugins$activeTab.tabKey) !== null && _plugins$activeTab$ta !== void 0 ? _plugins$activeTab$ta : null);
218
238
  }, [dispatch, plugins, trackAttribute]);
219
239
  var handleSearchListOnChange = function handleSearchListOnChange(id) {
240
+ if (isSubmitting) {
241
+ // Prevent changing item while submitting
242
+ return;
243
+ }
220
244
  var index = items === null || items === void 0 ? void 0 : items.findIndex(function (item) {
221
245
  return item.objectId === id;
222
246
  });
@@ -290,13 +314,13 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
290
314
  delay: 250
291
315
  }), (0, _react2.jsx)(_visuallyHidden.default, {
292
316
  id: screenReaderDescriptionId
293
- }, (0, _react2.jsx)(_reactIntlNext.FormattedMessage, messages.linkAriaLabel)), (0, _react2.jsx)(LinkInputField, {
317
+ }, customMessages !== null && customMessages !== void 0 && customMessages.linkAriaLabel ? (0, _react2.jsx)(_reactIntlNext.FormattedMessage, customMessages.linkAriaLabel) : (0, _react2.jsx)(_reactIntlNext.FormattedMessage, messages.linkAriaLabel)), (0, _react2.jsx)(LinkInputField, {
294
318
  role: "combobox",
295
319
  autoComplete: "off",
296
320
  name: "url",
297
321
  testId: testIds.urlInputField,
298
- label: intl.formatMessage(messages.linkLabel),
299
- placeholder: intl.formatMessage(messages.linkPlaceholder),
322
+ label: customMessages !== null && customMessages !== void 0 && customMessages.linkLabel ? intl.formatMessage(customMessages.linkLabel) : intl.formatMessage(messages.linkLabel),
323
+ placeholder: customMessages !== null && customMessages !== void 0 && customMessages.linkPlaceholder ? intl.formatMessage(customMessages === null || customMessages === void 0 ? void 0 : customMessages.linkPlaceholder) : intl.formatMessage(messages.linkPlaceholder),
300
324
  value: url,
301
325
  autoFocus: true,
302
326
  clearLabel: intl.formatMessage(_messages.formMessages.clearLink),
@@ -305,6 +329,7 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
305
329
  "aria-controls": linkSearchListId,
306
330
  "aria-activedescendant": ariaActiveDescendant,
307
331
  "aria-describedby": screenReaderDescriptionId,
332
+ "aria-readonly": isSubmitting,
308
333
  error: invalidUrl ? intl.formatMessage(_messages.formMessages.linkInvalid) : null,
309
334
  spotlightTargetName: "link-picker-search-field-spotlight-target",
310
335
  onClear: handleUrlClear,
@@ -315,9 +340,10 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
315
340
  name: "displayText",
316
341
  testId: testIds.textInputField,
317
342
  value: displayText,
318
- label: intl.formatMessage(_messages.linkTextMessages.linkTextLabel),
319
- placeholder: intl.formatMessage(_messages.linkTextMessages.linkTextPlaceholder),
343
+ label: customMessages !== null && customMessages !== void 0 && customMessages.linkTextLabel ? intl.formatMessage(customMessages.linkTextLabel) : intl.formatMessage(_messages.linkTextMessages.linkTextLabel),
344
+ placeholder: customMessages !== null && customMessages !== void 0 && customMessages.linkTextPlaceholder ? intl.formatMessage(customMessages === null || customMessages === void 0 ? void 0 : customMessages.linkTextPlaceholder) : intl.formatMessage(_messages.linkTextMessages.linkTextPlaceholder),
320
345
  clearLabel: intl.formatMessage(_messages.linkTextMessages.clearLinkText),
346
+ readOnly: isSubmitting,
321
347
  onClear: handleClear,
322
348
  onChange: handleChangeText
323
349
  }), !!queryState && (isLoadingPlugins || isActivePlugin) && (0, _react2.jsx)(_searchResults.SearchResults, {
@@ -326,6 +352,7 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
326
352
  activePlugin: activePlugin,
327
353
  isLoadingResults: isLoadingResults,
328
354
  isLoadingPlugins: isLoadingPlugins,
355
+ isSubmitting: isSubmitting,
329
356
  linkSearchListId: linkSearchListId,
330
357
  error: error,
331
358
  featureFlags: featureFlags,
@@ -343,6 +370,7 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
343
370
  items: items
344
371
  /** If the results section appears to be loading, impact whether the submit button is disabled */,
345
372
  isLoading: isLoadingResults || !!isLoadingPlugins,
373
+ isSubmitting: isSubmitting,
346
374
  queryState: queryState,
347
375
  url: url,
348
376
  isEditing: isEditing,
@@ -351,6 +379,7 @@ var LinkPicker = exports.LinkPicker = (0, _analytics.withLinkPickerAnalyticsCont
351
379
  css: !queryState || !(plugins !== null && plugins !== void 0 && plugins.length) ? _styled.formFooterMargin : undefined
352
380
  /* Show the feature discovery pulse when we're on the Jira tab, we haven't started typing a url and
353
381
  the feature flag is enabled */,
354
- createFeatureDiscovery: (activePlugin === null || activePlugin === void 0 ? void 0 : activePlugin.tabKey) === 'jira' && allowCreateFeatureDiscovery && (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.link-picker.enable-jira-create')
382
+ createFeatureDiscovery: (activePlugin === null || activePlugin === void 0 ? void 0 : activePlugin.tabKey) === 'jira' && allowCreateFeatureDiscovery && (0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.link-picker.enable-jira-create'),
383
+ customSubmitButtonLabel: customMessages !== null && customMessages !== void 0 && customMessages.submitButtonLabel ? customMessages.submitButtonLabel : undefined
355
384
  }));
356
385
  }));
@@ -35,6 +35,7 @@ var SearchResults = exports.SearchResults = function SearchResults(_ref) {
35
35
  activePlugin = _ref.activePlugin,
36
36
  isLoadingPlugins = _ref.isLoadingPlugins,
37
37
  isLoadingResults = _ref.isLoadingResults,
38
+ isSubmitting = _ref.isSubmitting,
38
39
  handleTabChange = _ref.handleTabChange,
39
40
  handleSearchListOnChange = _ref.handleSearchListOnChange,
40
41
  featureFlags = _ref.featureFlags,
@@ -76,6 +77,7 @@ var SearchResults = exports.SearchResults = function SearchResults(_ref) {
76
77
  })), !error && (0, _react2.jsx)(_linkSearchList.LinkSearchList, {
77
78
  id: linkSearchListId,
78
79
  role: "listbox",
80
+ ariaReadOnly: isSubmitting,
79
81
  items: items,
80
82
  isLoading: isLoadingResults,
81
83
  selectedIndex: selectedIndex,
@@ -21,7 +21,7 @@ var _styled = require("./link-search-no-results/styled");
21
21
  var _listItem = require("./list-item");
22
22
  var _styled2 = require("./styled");
23
23
  var _useTrackResultsShown = require("./use-track-results-shown");
24
- var _excluded = ["onChange", "onSelect", "onKeyDown", "items", "activeIndex", "selectedIndex", "isLoading", "ariaControls", "ariaLabelledBy", "role", "id", "hasSearchTerm", "activePlugin"];
24
+ var _excluded = ["onChange", "onSelect", "onKeyDown", "items", "activeIndex", "selectedIndex", "isLoading", "ariaControls", "ariaLabelledBy", "ariaReadOnly", "role", "id", "hasSearchTerm", "activePlugin"];
25
25
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
26
26
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /** @jsx jsx */
27
27
  var messages = exports.messages = (0, _reactIntlNext.defineMessages)({
@@ -57,6 +57,7 @@ var LinkSearchList = exports.LinkSearchList = /*#__PURE__*/(0, _react.forwardRef
57
57
  isLoading = _ref.isLoading,
58
58
  ariaControls = _ref.ariaControls,
59
59
  ariaLabelledBy = _ref.ariaLabelledBy,
60
+ ariaReadOnly = _ref.ariaReadOnly,
60
61
  role = _ref.role,
61
62
  id = _ref.id,
62
63
  hasSearchTerm = _ref.hasSearchTerm,
@@ -132,6 +133,7 @@ var LinkSearchList = exports.LinkSearchList = /*#__PURE__*/(0, _react.forwardRef
132
133
  css: _styled2.listStyles,
133
134
  "aria-controls": "fabric.smartcard.linkpicker.suggested.results",
134
135
  "aria-labelledby": testIds.resultListTitle,
136
+ "aria-readonly": ariaReadOnly,
135
137
  "data-testid": testIds.searchResultList
136
138
  }, items.map(function (item, index) {
137
139
  return (0, _react2.jsx)(_listItem.LinkSearchListItem, {
@@ -8,13 +8,11 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.fetchMessagesForLocale = void 0;
9
9
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
10
10
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
- var _en = _interopRequireDefault(require("../../../../i18n/en"));
13
11
  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); }
14
12
  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; }
15
13
  var fetchMessagesForLocale = exports.fetchMessagesForLocale = /*#__PURE__*/function () {
16
14
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(locale) {
17
- var _messages, parentLocale, _messages2;
15
+ var messages, parentLocale, _messages;
18
16
  return _regenerator.default.wrap(function _callee$(_context) {
19
17
  while (1) switch (_context.prev = _context.next) {
20
18
  case 0:
@@ -28,8 +26,8 @@ var fetchMessagesForLocale = exports.fetchMessagesForLocale = /*#__PURE__*/funct
28
26
  });
29
27
  }( /* webpackChunkName: "@atlaskit-internal_link-picker-i18n-[request]" */"../../../../i18n/".concat(locale.replace('-', '_')));
30
28
  case 3:
31
- _messages = _context.sent;
32
- return _context.abrupt("return", _messages.default);
29
+ messages = _context.sent;
30
+ return _context.abrupt("return", messages.default);
33
31
  case 7:
34
32
  _context.prev = 7;
35
33
  _context.t0 = _context["catch"](0);
@@ -45,20 +43,12 @@ var fetchMessagesForLocale = exports.fetchMessagesForLocale = /*#__PURE__*/funct
45
43
  });
46
44
  }( /* webpackChunkName: "@atlaskit-internal_link-picker-i18n-[request]" */"../../../../i18n/".concat(parentLocale));
47
45
  case 13:
48
- _messages2 = _context.sent;
49
- return _context.abrupt("return", _messages2.default);
46
+ _messages = _context.sent;
47
+ return _context.abrupt("return", _messages.default);
50
48
  case 17:
51
49
  _context.prev = 17;
52
50
  _context.t1 = _context["catch"](9);
53
51
  case 19:
54
- if (!(0, _platformFeatureFlags.getBooleanFF)('platform.linking-platform.link-create.tmp-fix-translations')) {
55
- _context.next = 21;
56
- break;
57
- }
58
- return _context.abrupt("return");
59
- case 21:
60
- return _context.abrupt("return", _en.default);
61
- case 22:
62
52
  case "end":
63
53
  return _context.stop();
64
54
  }
@@ -16,7 +16,7 @@ export const testIds = {
16
16
  };
17
17
  export const PACKAGE_DATA = {
18
18
  packageName: "@atlaskit/link-picker" || '',
19
- packageVersion: "1.30.14" || '',
19
+ packageVersion: "1.32.0" || '',
20
20
  componentName: COMPONENT_NAME,
21
21
  source: COMPONENT_NAME
22
22
  };
@@ -1,15 +1,18 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  /** @jsx jsx */
3
- import { memo } from 'react';
3
+ import { memo, useMemo } from 'react';
4
4
  import { jsx } from '@emotion/react';
5
5
  import { defineMessages, useIntl } from 'react-intl-next';
6
+ import uuid from 'uuid';
6
7
  import Button, { ButtonGroup } from '@atlaskit/button';
8
+ import LoadingButton from '@atlaskit/button/loading-button';
7
9
  import EditorAddIcon from '@atlaskit/icon/glyph/editor/add';
10
+ import VisuallyHidden from '@atlaskit/visually-hidden';
8
11
  import { UnauthenticatedError } from '../../../common/utils/errors';
9
12
  import FeatureDiscovery from './feature-discovery';
10
13
  import { formFooterActionStyles, formFooterStyles } from './styled';
11
14
  import { checkSubmitDisabled } from './utils';
12
- const messages = defineMessages({
15
+ export const messages = defineMessages({
13
16
  cancelButton: {
14
17
  id: 'fabric.linkPicker.button.cancel',
15
18
  defaultMessage: 'Cancel',
@@ -24,17 +27,24 @@ const messages = defineMessages({
24
27
  id: 'fabric.linkPicker.button.insert',
25
28
  defaultMessage: 'Insert',
26
29
  description: 'Button to insert searched or selected link'
30
+ },
31
+ submittingStatusMessage: {
32
+ id: 'fabric.linkPicker.status.submitting',
33
+ defaultMessage: 'Submitting',
34
+ description: 'Accessibility text to indicate the form has been submitted, and submission is in-progress'
27
35
  }
28
36
  });
29
37
  export const testIds = {
30
38
  insertButton: 'link-picker-insert-button',
31
39
  cancelButton: 'link-picker-cancel-button',
32
40
  actionButton: 'link-picker-action-button',
41
+ submitStatusA11yIndicator: 'link-picker-submit-status-a11y-indicator',
33
42
  /** Feature discovery for action button (css pulse) */
34
43
  actionButtonDiscovery: 'link-picker-action-button-discovery'
35
44
  };
36
45
  export const FormFooter = /*#__PURE__*/memo(({
37
46
  isLoading,
47
+ isSubmitting = false,
38
48
  error,
39
49
  url,
40
50
  queryState,
@@ -43,13 +53,15 @@ export const FormFooter = /*#__PURE__*/memo(({
43
53
  onCancel,
44
54
  action,
45
55
  createFeatureDiscovery = false,
56
+ customSubmitButtonLabel,
46
57
  ...restProps
47
58
  }) => {
48
59
  const intl = useIntl();
60
+ const submitMessageId = useMemo(() => uuid(), []);
49
61
  if (error && error instanceof UnauthenticatedError) {
50
62
  return null;
51
63
  }
52
- const isSubmitDisabled = checkSubmitDisabled(isLoading, error, url, queryState, items);
64
+ const isSubmitDisabled = checkSubmitDisabled(isLoading, isSubmitting, error, url, queryState, items);
53
65
  const insertButtonMsg = isEditing ? messages.saveButton : messages.insertButton;
54
66
  const createButton = pluginAction => jsx(Button, {
55
67
  testId: testIds.actionButton,
@@ -58,22 +70,32 @@ export const FormFooter = /*#__PURE__*/memo(({
58
70
  iconBefore: jsx(EditorAddIcon, {
59
71
  label: "",
60
72
  size: "medium"
61
- })
73
+ }),
74
+ isDisabled: isSubmitting,
75
+ "aria-labelledby": isSubmitting ? submitMessageId : undefined
62
76
  }, typeof pluginAction.label === 'string' ? pluginAction.label : intl.formatMessage(pluginAction.label));
63
77
  return jsx("footer", _extends({
64
78
  css: formFooterStyles
65
- }, restProps), action && jsx("div", {
79
+ }, restProps), isSubmitting && jsx(VisuallyHidden, {
80
+ role: "status",
81
+ id: submitMessageId,
82
+ testId: testIds.submitStatusA11yIndicator
83
+ }, intl.formatMessage(messages.submittingStatusMessage)), action && jsx("div", {
66
84
  css: formFooterActionStyles
67
85
  }, createFeatureDiscovery ? jsx(FeatureDiscovery, {
68
86
  testId: testIds.actionButtonDiscovery
69
87
  }, createButton(action)) : createButton(action)), jsx(ButtonGroup, null, jsx(Button, {
70
88
  appearance: "subtle",
71
89
  onClick: onCancel,
72
- testId: testIds.cancelButton
73
- }, intl.formatMessage(messages.cancelButton)), jsx(Button, {
90
+ testId: testIds.cancelButton,
91
+ isDisabled: isSubmitting,
92
+ "aria-labelledby": isSubmitting ? submitMessageId : undefined
93
+ }, intl.formatMessage(messages.cancelButton)), jsx(LoadingButton, {
74
94
  type: "submit",
75
95
  appearance: "primary",
76
96
  testId: testIds.insertButton,
77
- isDisabled: isSubmitDisabled
78
- }, intl.formatMessage(insertButtonMsg))));
97
+ isDisabled: isSubmitDisabled,
98
+ "aria-labelledby": isSubmitting ? submitMessageId : undefined,
99
+ isLoading: isSubmitting
100
+ }, customSubmitButtonLabel ? intl.formatMessage(customSubmitButtonLabel) : intl.formatMessage(insertButtonMsg))));
79
101
  });
@@ -1,5 +1,5 @@
1
1
  import { normalizeUrl } from '@atlaskit/linking-common/url';
2
- export const checkSubmitDisabled = (isLoading, error, url, queryState, items) => {
2
+ export const checkSubmitDisabled = (isLoading, isSubmitting, 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
@@ -7,6 +7,9 @@ export const checkSubmitDisabled = (isLoading, error, url, queryState, items) =>
7
7
  * This should effectively be the validation function for the form, ie if the form
8
8
  * could be submitted, then it should not be disabled
9
9
  */
10
+ if (isSubmitting) {
11
+ return true;
12
+ }
10
13
  if (url && normalizeUrl(url)) {
11
14
  return false;
12
15
  }