@atlaskit/feedback-collector 15.5.0 → 16.0.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 (57) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/FeedbackButton/package.json +1 -8
  3. package/FeedbackFlag/package.json +1 -8
  4. package/FeedbackForm/package.json +1 -8
  5. package/dist/cjs/components/FeedbackCollector.js +1 -1
  6. package/dist/cjs/components/FeedbackForm.js +65 -96
  7. package/dist/es2019/components/FeedbackCollector.js +1 -1
  8. package/dist/es2019/components/FeedbackForm.js +73 -88
  9. package/dist/esm/components/FeedbackCollector.js +1 -1
  10. package/dist/esm/components/FeedbackForm.js +65 -96
  11. package/messages/package.json +1 -8
  12. package/package.json +15 -22
  13. package/types/package.json +1 -8
  14. package/dist/types-ts4.5/components/FeedbackButton.d.ts +0 -9
  15. package/dist/types-ts4.5/components/FeedbackCollector.d.ts +0 -198
  16. package/dist/types-ts4.5/components/FeedbackFlag.d.ts +0 -11
  17. package/dist/types-ts4.5/components/FeedbackForm.d.ts +0 -68
  18. package/dist/types-ts4.5/components/IntlProviderWithResolvedMessages.d.ts +0 -4
  19. package/dist/types-ts4.5/entry-points/FeedbackButton.d.ts +0 -1
  20. package/dist/types-ts4.5/entry-points/FeedbackFlag.d.ts +0 -1
  21. package/dist/types-ts4.5/entry-points/FeedbackForm.d.ts +0 -1
  22. package/dist/types-ts4.5/i18n/cs.d.ts +0 -8
  23. package/dist/types-ts4.5/i18n/da.d.ts +0 -8
  24. package/dist/types-ts4.5/i18n/de.d.ts +0 -8
  25. package/dist/types-ts4.5/i18n/en.d.ts +0 -8
  26. package/dist/types-ts4.5/i18n/en_GB.d.ts +0 -8
  27. package/dist/types-ts4.5/i18n/en_ZZ.d.ts +0 -8
  28. package/dist/types-ts4.5/i18n/es.d.ts +0 -8
  29. package/dist/types-ts4.5/i18n/fi.d.ts +0 -8
  30. package/dist/types-ts4.5/i18n/fr.d.ts +0 -8
  31. package/dist/types-ts4.5/i18n/hr.d.ts +0 -8
  32. package/dist/types-ts4.5/i18n/hu.d.ts +0 -8
  33. package/dist/types-ts4.5/i18n/index.d.ts +0 -1
  34. package/dist/types-ts4.5/i18n/it.d.ts +0 -8
  35. package/dist/types-ts4.5/i18n/ja.d.ts +0 -8
  36. package/dist/types-ts4.5/i18n/ko.d.ts +0 -8
  37. package/dist/types-ts4.5/i18n/nb.d.ts +0 -8
  38. package/dist/types-ts4.5/i18n/nl.d.ts +0 -8
  39. package/dist/types-ts4.5/i18n/pl.d.ts +0 -8
  40. package/dist/types-ts4.5/i18n/pt_BR.d.ts +0 -8
  41. package/dist/types-ts4.5/i18n/ru.d.ts +0 -8
  42. package/dist/types-ts4.5/i18n/sl.d.ts +0 -8
  43. package/dist/types-ts4.5/i18n/sr_RS.d.ts +0 -8
  44. package/dist/types-ts4.5/i18n/sr_YR.d.ts +0 -8
  45. package/dist/types-ts4.5/i18n/sv.d.ts +0 -8
  46. package/dist/types-ts4.5/i18n/th.d.ts +0 -8
  47. package/dist/types-ts4.5/i18n/tr.d.ts +0 -8
  48. package/dist/types-ts4.5/i18n/uk.d.ts +0 -8
  49. package/dist/types-ts4.5/i18n/vi.d.ts +0 -8
  50. package/dist/types-ts4.5/i18n/zh.d.ts +0 -8
  51. package/dist/types-ts4.5/i18n/zh_TW.d.ts +0 -8
  52. package/dist/types-ts4.5/index.d.ts +0 -7
  53. package/dist/types-ts4.5/messages.d.ts +0 -192
  54. package/dist/types-ts4.5/types.d.ts +0 -16
  55. package/dist/types-ts4.5/utils/Truncate.d.ts +0 -1
  56. package/dist/types-ts4.5/utils/i18n-get-messages-for-locale.d.ts +0 -11
  57. package/dist/types-ts4.5/utils/is-api-gateway-url.d.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @atlaskit/feedback-collector
2
2
 
3
+ ## 16.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [`f2dc9097319f0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f2dc9097319f0) - ###
8
+ Dropped support for _legacy_ Typescript 4 types. **Typescript 5 is now the new minimum**.
9
+
10
+ Removes the `typesVersions` property and `dist/types-ts4.5` directory from the dist.
11
+
12
+ Types are now exclusively via the `"types": "dist/types/index.d.ts"` property.
13
+
14
+ ```diff
15
+ - "typesVersions": {
16
+ - ">=4.5 <4.9": {
17
+ - "*": [
18
+ - "dist/types-ts4.5/*",
19
+ - "dist/types-ts4.5/index.d.ts"
20
+ - ]
21
+ - }
22
+ - },
23
+ ```
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies
28
+
29
+ ## 15.6.0
30
+
31
+ ### Minor Changes
32
+
33
+ - [`fcbbf3c80f95a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fcbbf3c80f95a) -
34
+ [ux] AX-2068 — Announce feedback collector validation errors to screen readers and move focus to
35
+ the first invalid field on failed submit by delegating validation to @atlaskit/form's built-in
36
+ Field validate API.
37
+
38
+ ### Patch Changes
39
+
40
+ - Updated dependencies
41
+
3
42
  ## 15.5.0
4
43
 
5
44
  ### Minor Changes
@@ -4,12 +4,5 @@
4
4
  "module": "../dist/esm/entry-points/FeedbackButton.js",
5
5
  "module:es2019": "../dist/es2019/entry-points/FeedbackButton.js",
6
6
  "sideEffects": false,
7
- "types": "../dist/types/entry-points/FeedbackButton.d.ts",
8
- "typesVersions": {
9
- ">=4.5 <5.9": {
10
- "*": [
11
- "../dist/types-ts4.5/entry-points/FeedbackButton.d.ts"
12
- ]
13
- }
14
- }
7
+ "types": "../dist/types/entry-points/FeedbackButton.d.ts"
15
8
  }
@@ -4,12 +4,5 @@
4
4
  "module": "../dist/esm/entry-points/FeedbackFlag.js",
5
5
  "module:es2019": "../dist/es2019/entry-points/FeedbackFlag.js",
6
6
  "sideEffects": false,
7
- "types": "../dist/types/entry-points/FeedbackFlag.d.ts",
8
- "typesVersions": {
9
- ">=4.5 <5.9": {
10
- "*": [
11
- "../dist/types-ts4.5/entry-points/FeedbackFlag.d.ts"
12
- ]
13
- }
14
- }
7
+ "types": "../dist/types/entry-points/FeedbackFlag.d.ts"
15
8
  }
@@ -4,12 +4,5 @@
4
4
  "module": "../dist/esm/entry-points/FeedbackForm.js",
5
5
  "module:es2019": "../dist/es2019/entry-points/FeedbackForm.js",
6
6
  "sideEffects": false,
7
- "types": "../dist/types/entry-points/FeedbackForm.d.ts",
8
- "typesVersions": {
9
- ">=4.5 <5.9": {
10
- "*": [
11
- "../dist/types-ts4.5/entry-points/FeedbackForm.d.ts"
12
- ]
13
- }
14
- }
7
+ "types": "../dist/types/entry-points/FeedbackForm.d.ts"
15
8
  }
@@ -164,7 +164,7 @@ var FeedbackCollector = exports.default = /*#__PURE__*/function (_Component) {
164
164
  }, {
165
165
  key: "getPackageVersion",
166
166
  value: function getPackageVersion() {
167
- return "15.4.0" || 'Unknown, at least 11.0.0';
167
+ return "15.6.0" || 'Unknown, at least 11.0.0';
168
168
  }
169
169
  }, {
170
170
  key: "getEntitlementInformation",
@@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.default = void 0;
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
10
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
12
11
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
13
12
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
@@ -29,8 +28,6 @@ var _excluded = ["id"],
29
28
  _excluded2 = ["id"],
30
29
  _excluded3 = ["locale"];
31
30
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
32
- 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; }
33
- 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; }
34
31
  var LinkWrapper = function LinkWrapper(_ref) {
35
32
  var children = _ref.children;
36
33
  return /*#__PURE__*/_react.default.createElement("span", {
@@ -91,15 +88,20 @@ var FeedbackForm = function FeedbackForm(_ref2) {
91
88
  _useState0 = (0, _slicedToArray2.default)(_useState9, 2),
92
89
  isSubmitting = _useState0[0],
93
90
  setIsSubmitting = _useState0[1];
94
- var _useState1 = (0, _react.useState)({}),
95
- _useState10 = (0, _slicedToArray2.default)(_useState1, 2),
96
- validationErrors = _useState10[0],
97
- setValidationErrors = _useState10[1];
98
91
  var _useIntl = (0, _reactIntl.useIntl)(),
99
92
  formatMessage = _useIntl.formatMessage;
100
93
  var isTypeSelected = function isTypeSelected() {
101
94
  return type !== 'empty';
102
95
  };
96
+ var validateType = function validateType(value) {
97
+ return showTypeField && (!value || value === 'empty') ? formatMessage(_messages.messages.validationErrorTypeRequired) : undefined;
98
+ };
99
+ var validateDescription = function validateDescription(value) {
100
+ if (!showDefaultTextFields || hasDescriptionDefaultValue) {
101
+ return undefined;
102
+ }
103
+ return !value || !value.trim() ? formatMessage(_messages.messages.validationErrorDescriptionRequired) : undefined;
104
+ };
103
105
 
104
106
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
107
  var handleCancel = function handleCancel() {
@@ -112,22 +114,7 @@ var FeedbackForm = function FeedbackForm(_ref2) {
112
114
  onClose.apply(void 0, args);
113
115
  };
114
116
  var canShowTextField = isTypeSelected() || !showTypeField;
115
- var hasDescription = description || hasDescriptionDefaultValue;
116
117
  var isDisabled = isSubmitting || disableSubmitButton;
117
- var getValidationErrors = function getValidationErrors() {
118
- var errors = {};
119
-
120
- // Validate type selection if showTypeField is true
121
- if (showTypeField && !isTypeSelected()) {
122
- errors.type = formatMessage(_messages.messages.validationErrorTypeRequired);
123
- }
124
-
125
- // Validate description if showDefaultTextFields is true
126
- if (showDefaultTextFields && !hasDescription) {
127
- errors.description = formatMessage(_messages.messages.validationErrorDescriptionRequired);
128
- }
129
- return errors;
130
- };
131
118
  var getFieldLabels = function getFieldLabels(record) {
132
119
  var _record$bug, _record$comment, _record$suggestion, _record$question, _record$empty, _record$not_relevant, _record$not_accurate, _record$too_slow, _record$unhelpful_lin, _record$other;
133
120
  return {
@@ -200,60 +187,53 @@ var FeedbackForm = function FeedbackForm(_ref2) {
200
187
  shouldScrollInViewport: true
201
188
  }, (0, _platformFeatureFlags.fg)('platform-design_system_team-form_conversion') ? /*#__PURE__*/_react.default.createElement(_form.default, {
202
189
  onSubmit: /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
203
- var errors;
204
190
  return _regenerator.default.wrap(function (_context) {
205
191
  while (1) switch (_context.prev = _context.next) {
206
192
  case 0:
207
- errors = getValidationErrors();
208
- if (!(Object.keys(errors).length > 0)) {
209
- _context.next = 1;
210
- break;
211
- }
212
- setValidationErrors(errors);
213
- return _context.abrupt("return");
214
- case 1:
215
193
  setIsSubmitting(true);
216
- _context.prev = 2;
217
- _context.next = 3;
194
+ _context.prev = 1;
195
+ _context.next = 2;
218
196
  return onSubmit({
219
197
  canBeContacted: canBeContacted,
220
198
  description: description,
221
199
  enrollInResearchGroup: enrollInResearchGroup,
222
200
  type: type
223
201
  });
224
- case 3:
225
- _context.prev = 3;
202
+ case 2:
203
+ _context.prev = 2;
226
204
  setIsSubmitting(false);
227
- return _context.finish(3);
228
- case 4:
205
+ return _context.finish(2);
206
+ case 3:
229
207
  case "end":
230
208
  return _context.stop();
231
209
  }
232
- }, _callee, null, [[2,, 3, 4]]);
210
+ }, _callee, null, [[1,, 2, 3]]);
233
211
  }))
234
212
  }, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalHeader, {
235
213
  hasCloseButton: true
236
214
  }, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTitle, null, feedbackTitle || /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, _messages.messages.feedbackTitle))), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalBody, null, (0, _platformFeatureFlags.fg)('ak_feedback_collector_hide_required_summary') ? showRequiredFieldsSummary && requiredFieldsSummary : requiredFieldsSummary, feedbackTitleDetails, customContent, showTypeField ? /*#__PURE__*/_react.default.createElement(_form.Field, {
237
215
  name: "topic",
216
+ id: "topic",
238
217
  label: selectLabel || formatMessage(_messages.messages.selectionOptionDefaultLabel),
239
- isRequired: true
218
+ isRequired: true,
219
+ validate: validateType
240
220
  }, function (_ref4) {
221
+ var _selectOptions$find;
241
222
  var _ref4$fieldProps = _ref4.fieldProps,
242
223
  id = _ref4$fieldProps.id,
243
- restProps = (0, _objectWithoutProperties2.default)(_ref4$fieldProps, _excluded);
224
+ restProps = (0, _objectWithoutProperties2.default)(_ref4$fieldProps, _excluded),
225
+ error = _ref4.error;
244
226
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_select.default, (0, _extends2.default)({}, restProps, {
227
+ value: (_selectOptions$find = selectOptions.find(function (opt) {
228
+ return opt.value === type;
229
+ })) !== null && _selectOptions$find !== void 0 ? _selectOptions$find : null,
245
230
  onChange: function onChange(option) {
231
+ var _restProps$onChange;
246
232
  if (!option || option instanceof Array) {
247
233
  return;
248
234
  }
249
235
  setType(option.value);
250
- if (validationErrors.type) {
251
- setValidationErrors(function (prev) {
252
- return _objectSpread(_objectSpread({}, prev), {}, {
253
- type: undefined
254
- });
255
- });
256
- }
236
+ (_restProps$onChange = restProps.onChange) === null || _restProps$onChange === void 0 || _restProps$onChange.call(restProps, option.value);
257
237
  },
258
238
  menuPosition: "fixed",
259
239
  options: selectOptions
@@ -261,30 +241,28 @@ var FeedbackForm = function FeedbackForm(_ref2) {
261
241
  ,
262
242
  ref: focusRef,
263
243
  placeholder: getDefaultPlaceholder(feedbackGroupLabels),
264
- inputId: id
265
- })), validationErrors.type && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, validationErrors.type));
244
+ inputId: id,
245
+ isInvalid: !!error
246
+ })), error && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, error));
266
247
  }) : null, showDefaultTextFields && canShowTextField && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_form.Field, {
267
248
  label: showTypeField ? getFieldLabels(feedbackGroupLabels)[type] : customTextAreaLabel || formatMessage(_messages.messages.defaultCustomTextAreaLabel),
268
249
  isRequired: true,
269
- name: "description"
250
+ name: "description",
251
+ id: "description",
252
+ validate: validateDescription
270
253
  }, function (_ref5) {
271
- var fieldProps = _ref5.fieldProps;
254
+ var fieldProps = _ref5.fieldProps,
255
+ error = _ref5.error;
272
256
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_textarea.default, (0, _extends2.default)({}, fieldProps, {
273
257
  name: "foo",
274
258
  minimumRows: 6,
275
259
  placeholder: summaryPlaceholder || undefined,
276
260
  onChange: function onChange(e) {
277
261
  setDescription(e.target.value);
278
- if (validationErrors.description) {
279
- setValidationErrors(function (prev) {
280
- return _objectSpread(_objectSpread({}, prev), {}, {
281
- description: undefined
282
- });
283
- });
284
- }
262
+ fieldProps.onChange(e.target.value);
285
263
  },
286
264
  value: description
287
- })), validationErrors.description && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, validationErrors.description));
265
+ })), error && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, error));
288
266
  }), !anonymousFeedback && /*#__PURE__*/_react.default.createElement(_form.Fieldset, null, /*#__PURE__*/_react.default.createElement("legend", null, /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, _messages.messages.optInOptionsLegend)), /*#__PURE__*/_react.default.createElement(_form.Field, {
289
267
  name: "can-be-contacted"
290
268
  }, function (_ref6) {
@@ -338,36 +316,27 @@ var FeedbackForm = function FeedbackForm(_ref2) {
338
316
  testId: "feedbackCollectorSubmitBtn"
339
317
  }, submitButtonLabel || /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, _messages.messages.submitButtonLabel)))) : /*#__PURE__*/_react.default.createElement(_form.default, {
340
318
  onSubmit: /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
341
- var errors;
342
319
  return _regenerator.default.wrap(function (_context2) {
343
320
  while (1) switch (_context2.prev = _context2.next) {
344
321
  case 0:
345
- errors = getValidationErrors();
346
- if (!(Object.keys(errors).length > 0)) {
347
- _context2.next = 1;
348
- break;
349
- }
350
- setValidationErrors(errors);
351
- return _context2.abrupt("return");
352
- case 1:
353
322
  setIsSubmitting(true);
354
- _context2.prev = 2;
355
- _context2.next = 3;
323
+ _context2.prev = 1;
324
+ _context2.next = 2;
356
325
  return onSubmit({
357
326
  canBeContacted: canBeContacted,
358
327
  description: description,
359
328
  enrollInResearchGroup: enrollInResearchGroup,
360
329
  type: type
361
330
  });
362
- case 3:
363
- _context2.prev = 3;
331
+ case 2:
332
+ _context2.prev = 2;
364
333
  setIsSubmitting(false);
365
- return _context2.finish(3);
366
- case 4:
334
+ return _context2.finish(2);
335
+ case 3:
367
336
  case "end":
368
337
  return _context2.stop();
369
338
  }
370
- }, _callee2, null, [[2,, 3, 4]]);
339
+ }, _callee2, null, [[1,, 2, 3]]);
371
340
  }))
372
341
  }, function (_ref9) {
373
342
  var formProps = _ref9.formProps;
@@ -375,25 +344,27 @@ var FeedbackForm = function FeedbackForm(_ref2) {
375
344
  hasCloseButton: true
376
345
  }, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTitle, null, feedbackTitle || /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, _messages.messages.feedbackTitle))), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalBody, null, (0, _platformFeatureFlags.fg)('ak_feedback_collector_hide_required_summary') ? showRequiredFieldsSummary && requiredFieldsSummary : requiredFieldsSummary, feedbackTitleDetails, customContent, showTypeField ? /*#__PURE__*/_react.default.createElement(_form.Field, {
377
346
  name: "topic",
347
+ id: "topic",
378
348
  label: selectLabel || formatMessage(_messages.messages.selectionOptionDefaultLabel),
379
- isRequired: true
349
+ isRequired: true,
350
+ validate: validateType
380
351
  }, function (_ref0) {
352
+ var _selectOptions$find2;
381
353
  var _ref0$fieldProps = _ref0.fieldProps,
382
354
  id = _ref0$fieldProps.id,
383
- restProps = (0, _objectWithoutProperties2.default)(_ref0$fieldProps, _excluded2);
355
+ restProps = (0, _objectWithoutProperties2.default)(_ref0$fieldProps, _excluded2),
356
+ error = _ref0.error;
384
357
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_select.default, (0, _extends2.default)({}, restProps, {
358
+ value: (_selectOptions$find2 = selectOptions.find(function (opt) {
359
+ return opt.value === type;
360
+ })) !== null && _selectOptions$find2 !== void 0 ? _selectOptions$find2 : null,
385
361
  onChange: function onChange(option) {
362
+ var _restProps$onChange2;
386
363
  if (!option || option instanceof Array) {
387
364
  return;
388
365
  }
389
366
  setType(option.value);
390
- if (validationErrors.type) {
391
- setValidationErrors(function (prev) {
392
- return _objectSpread(_objectSpread({}, prev), {}, {
393
- type: undefined
394
- });
395
- });
396
- }
367
+ (_restProps$onChange2 = restProps.onChange) === null || _restProps$onChange2 === void 0 || _restProps$onChange2.call(restProps, option.value);
397
368
  },
398
369
  menuPosition: "fixed",
399
370
  options: selectOptions
@@ -401,30 +372,28 @@ var FeedbackForm = function FeedbackForm(_ref2) {
401
372
  ,
402
373
  ref: focusRef,
403
374
  placeholder: getDefaultPlaceholder(feedbackGroupLabels),
404
- inputId: id
405
- })), validationErrors.type && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, validationErrors.type));
375
+ inputId: id,
376
+ isInvalid: !!error
377
+ })), error && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, error));
406
378
  }) : null, showDefaultTextFields && canShowTextField && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_form.Field, {
407
379
  label: showTypeField ? getFieldLabels(feedbackGroupLabels)[type] : customTextAreaLabel || formatMessage(_messages.messages.defaultCustomTextAreaLabel),
408
380
  isRequired: true,
409
- name: "description"
381
+ name: "description",
382
+ id: "description",
383
+ validate: validateDescription
410
384
  }, function (_ref1) {
411
- var fieldProps = _ref1.fieldProps;
385
+ var fieldProps = _ref1.fieldProps,
386
+ error = _ref1.error;
412
387
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_textarea.default, (0, _extends2.default)({}, fieldProps, {
413
388
  name: "foo",
414
389
  minimumRows: 6,
415
390
  placeholder: summaryPlaceholder || undefined,
416
391
  onChange: function onChange(e) {
417
392
  setDescription(e.target.value);
418
- if (validationErrors.description) {
419
- setValidationErrors(function (prev) {
420
- return _objectSpread(_objectSpread({}, prev), {}, {
421
- description: undefined
422
- });
423
- });
424
- }
393
+ fieldProps.onChange(e.target.value);
425
394
  },
426
395
  value: description
427
- })), validationErrors.description && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, validationErrors.description));
396
+ })), error && /*#__PURE__*/_react.default.createElement(_form.ErrorMessage, null, error));
428
397
  }), !anonymousFeedback && /*#__PURE__*/_react.default.createElement(_form.Fieldset, null, /*#__PURE__*/_react.default.createElement("legend", null, /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, _messages.messages.optInOptionsLegend)), /*#__PURE__*/_react.default.createElement(_form.Field, {
429
398
  name: "can-be-contacted"
430
399
  }, function (_ref10) {
@@ -92,7 +92,7 @@ export default class FeedbackCollector extends Component {
92
92
  return FeedbackCollector.defaultProps.url;
93
93
  }
94
94
  getPackageVersion() {
95
- return "15.4.0" || 'Unknown, at least 11.0.0';
95
+ return "15.6.0" || 'Unknown, at least 11.0.0';
96
96
  }
97
97
  async getEntitlementInformation() {
98
98
  var _entitlementDetails, _entitlementDetails2, _productName, _entitlement, _productEntitlement;
@@ -55,11 +55,17 @@ const FeedbackForm = ({
55
55
  const [enrollInResearchGroup, setEnrollInResearchGroup] = useState(false);
56
56
  const [type, setType] = useState('empty');
57
57
  const [isSubmitting, setIsSubmitting] = useState(false);
58
- const [validationErrors, setValidationErrors] = useState({});
59
58
  const {
60
59
  formatMessage
61
60
  } = useIntl();
62
61
  const isTypeSelected = () => type !== 'empty';
62
+ const validateType = value => showTypeField && (!value || value === 'empty') ? formatMessage(messages.validationErrorTypeRequired) : undefined;
63
+ const validateDescription = value => {
64
+ if (!showDefaultTextFields || hasDescriptionDefaultValue) {
65
+ return undefined;
66
+ }
67
+ return !value || !value.trim() ? formatMessage(messages.validationErrorDescriptionRequired) : undefined;
68
+ };
63
69
 
64
70
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
71
  const handleCancel = (...args) => {
@@ -69,22 +75,7 @@ const FeedbackForm = ({
69
75
  onClose(...args);
70
76
  };
71
77
  const canShowTextField = isTypeSelected() || !showTypeField;
72
- const hasDescription = description || hasDescriptionDefaultValue;
73
78
  const isDisabled = isSubmitting || disableSubmitButton;
74
- const getValidationErrors = () => {
75
- const errors = {};
76
-
77
- // Validate type selection if showTypeField is true
78
- if (showTypeField && !isTypeSelected()) {
79
- errors.type = formatMessage(messages.validationErrorTypeRequired);
80
- }
81
-
82
- // Validate description if showDefaultTextFields is true
83
- if (showDefaultTextFields && !hasDescription) {
84
- errors.description = formatMessage(messages.validationErrorDescriptionRequired);
85
- }
86
- return errors;
87
- };
88
79
  const getFieldLabels = record => {
89
80
  var _record$bug, _record$comment, _record$suggestion, _record$question, _record$empty, _record$not_relevant, _record$not_accurate, _record$too_slow, _record$unhelpful_lin, _record$other;
90
81
  return {
@@ -157,11 +148,6 @@ const FeedbackForm = ({
157
148
  shouldScrollInViewport: true
158
149
  }, fg('platform-design_system_team-form_conversion') ? /*#__PURE__*/React.createElement(Form, {
159
150
  onSubmit: async () => {
160
- const errors = getValidationErrors();
161
- if (Object.keys(errors).length > 0) {
162
- setValidationErrors(errors);
163
- return;
164
- }
165
151
  setIsSubmitting(true);
166
152
  try {
167
153
  await onSubmit({
@@ -178,54 +164,56 @@ const FeedbackForm = ({
178
164
  hasCloseButton: true
179
165
  }, /*#__PURE__*/React.createElement(ModalTitle, null, feedbackTitle || /*#__PURE__*/React.createElement(FormattedMessage, messages.feedbackTitle))), /*#__PURE__*/React.createElement(ModalBody, null, fg('ak_feedback_collector_hide_required_summary') ? showRequiredFieldsSummary && requiredFieldsSummary : requiredFieldsSummary, feedbackTitleDetails, customContent, showTypeField ? /*#__PURE__*/React.createElement(Field, {
180
166
  name: "topic",
167
+ id: "topic",
181
168
  label: selectLabel || formatMessage(messages.selectionOptionDefaultLabel),
182
- isRequired: true
169
+ isRequired: true,
170
+ validate: validateType
183
171
  }, ({
184
172
  fieldProps: {
185
173
  id,
186
174
  ...restProps
187
- }
188
- }) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Select, _extends({}, restProps, {
189
- onChange: option => {
190
- if (!option || option instanceof Array) {
191
- return;
192
- }
193
- setType(option.value);
194
- if (validationErrors.type) {
195
- setValidationErrors(prev => ({
196
- ...prev,
197
- type: undefined
198
- }));
199
- }
200
175
  },
201
- menuPosition: "fixed",
202
- options: selectOptions
203
- // @ts-ignore
204
- ,
205
- ref: focusRef,
206
- placeholder: getDefaultPlaceholder(feedbackGroupLabels),
207
- inputId: id
208
- })), validationErrors.type && /*#__PURE__*/React.createElement(ErrorMessage, null, validationErrors.type))) : null, showDefaultTextFields && canShowTextField && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Field, {
176
+ error
177
+ }) => {
178
+ var _selectOptions$find;
179
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Select, _extends({}, restProps, {
180
+ value: (_selectOptions$find = selectOptions.find(opt => opt.value === type)) !== null && _selectOptions$find !== void 0 ? _selectOptions$find : null,
181
+ onChange: option => {
182
+ var _restProps$onChange;
183
+ if (!option || option instanceof Array) {
184
+ return;
185
+ }
186
+ setType(option.value);
187
+ (_restProps$onChange = restProps.onChange) === null || _restProps$onChange === void 0 ? void 0 : _restProps$onChange.call(restProps, option.value);
188
+ },
189
+ menuPosition: "fixed",
190
+ options: selectOptions
191
+ // @ts-ignore
192
+ ,
193
+ ref: focusRef,
194
+ placeholder: getDefaultPlaceholder(feedbackGroupLabels),
195
+ inputId: id,
196
+ isInvalid: !!error
197
+ })), error && /*#__PURE__*/React.createElement(ErrorMessage, null, error));
198
+ }) : null, showDefaultTextFields && canShowTextField && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Field, {
209
199
  label: showTypeField ? getFieldLabels(feedbackGroupLabels)[type] : customTextAreaLabel || formatMessage(messages.defaultCustomTextAreaLabel),
210
200
  isRequired: true,
211
- name: "description"
201
+ name: "description",
202
+ id: "description",
203
+ validate: validateDescription
212
204
  }, ({
213
- fieldProps
205
+ fieldProps,
206
+ error
214
207
  }) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TextArea, _extends({}, fieldProps, {
215
208
  name: "foo",
216
209
  minimumRows: 6,
217
210
  placeholder: summaryPlaceholder || undefined,
218
211
  onChange: e => {
219
212
  setDescription(e.target.value);
220
- if (validationErrors.description) {
221
- setValidationErrors(prev => ({
222
- ...prev,
223
- description: undefined
224
- }));
225
- }
213
+ fieldProps.onChange(e.target.value);
226
214
  },
227
215
  value: description
228
- })), validationErrors.description && /*#__PURE__*/React.createElement(ErrorMessage, null, validationErrors.description))), !anonymousFeedback && /*#__PURE__*/React.createElement(Fieldset, null, /*#__PURE__*/React.createElement("legend", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.optInOptionsLegend)), /*#__PURE__*/React.createElement(Field, {
216
+ })), error && /*#__PURE__*/React.createElement(ErrorMessage, null, error))), !anonymousFeedback && /*#__PURE__*/React.createElement(Fieldset, null, /*#__PURE__*/React.createElement("legend", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.optInOptionsLegend)), /*#__PURE__*/React.createElement(Field, {
229
217
  name: "can-be-contacted"
230
218
  }, ({
231
219
  fieldProps
@@ -268,11 +256,6 @@ const FeedbackForm = ({
268
256
  testId: "feedbackCollectorSubmitBtn"
269
257
  }, submitButtonLabel || /*#__PURE__*/React.createElement(FormattedMessage, messages.submitButtonLabel)))) : /*#__PURE__*/React.createElement(Form, {
270
258
  onSubmit: async () => {
271
- const errors = getValidationErrors();
272
- if (Object.keys(errors).length > 0) {
273
- setValidationErrors(errors);
274
- return;
275
- }
276
259
  setIsSubmitting(true);
277
260
  try {
278
261
  await onSubmit({
@@ -291,54 +274,56 @@ const FeedbackForm = ({
291
274
  hasCloseButton: true
292
275
  }, /*#__PURE__*/React.createElement(ModalTitle, null, feedbackTitle || /*#__PURE__*/React.createElement(FormattedMessage, messages.feedbackTitle))), /*#__PURE__*/React.createElement(ModalBody, null, fg('ak_feedback_collector_hide_required_summary') ? showRequiredFieldsSummary && requiredFieldsSummary : requiredFieldsSummary, feedbackTitleDetails, customContent, showTypeField ? /*#__PURE__*/React.createElement(Field, {
293
276
  name: "topic",
277
+ id: "topic",
294
278
  label: selectLabel || formatMessage(messages.selectionOptionDefaultLabel),
295
- isRequired: true
279
+ isRequired: true,
280
+ validate: validateType
296
281
  }, ({
297
282
  fieldProps: {
298
283
  id,
299
284
  ...restProps
300
- }
301
- }) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Select, _extends({}, restProps, {
302
- onChange: option => {
303
- if (!option || option instanceof Array) {
304
- return;
305
- }
306
- setType(option.value);
307
- if (validationErrors.type) {
308
- setValidationErrors(prev => ({
309
- ...prev,
310
- type: undefined
311
- }));
312
- }
313
285
  },
314
- menuPosition: "fixed",
315
- options: selectOptions
316
- // @ts-ignore
317
- ,
318
- ref: focusRef,
319
- placeholder: getDefaultPlaceholder(feedbackGroupLabels),
320
- inputId: id
321
- })), validationErrors.type && /*#__PURE__*/React.createElement(ErrorMessage, null, validationErrors.type))) : null, showDefaultTextFields && canShowTextField && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Field, {
286
+ error
287
+ }) => {
288
+ var _selectOptions$find2;
289
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Select, _extends({}, restProps, {
290
+ value: (_selectOptions$find2 = selectOptions.find(opt => opt.value === type)) !== null && _selectOptions$find2 !== void 0 ? _selectOptions$find2 : null,
291
+ onChange: option => {
292
+ var _restProps$onChange2;
293
+ if (!option || option instanceof Array) {
294
+ return;
295
+ }
296
+ setType(option.value);
297
+ (_restProps$onChange2 = restProps.onChange) === null || _restProps$onChange2 === void 0 ? void 0 : _restProps$onChange2.call(restProps, option.value);
298
+ },
299
+ menuPosition: "fixed",
300
+ options: selectOptions
301
+ // @ts-ignore
302
+ ,
303
+ ref: focusRef,
304
+ placeholder: getDefaultPlaceholder(feedbackGroupLabels),
305
+ inputId: id,
306
+ isInvalid: !!error
307
+ })), error && /*#__PURE__*/React.createElement(ErrorMessage, null, error));
308
+ }) : null, showDefaultTextFields && canShowTextField && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Field, {
322
309
  label: showTypeField ? getFieldLabels(feedbackGroupLabels)[type] : customTextAreaLabel || formatMessage(messages.defaultCustomTextAreaLabel),
323
310
  isRequired: true,
324
- name: "description"
311
+ name: "description",
312
+ id: "description",
313
+ validate: validateDescription
325
314
  }, ({
326
- fieldProps
315
+ fieldProps,
316
+ error
327
317
  }) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TextArea, _extends({}, fieldProps, {
328
318
  name: "foo",
329
319
  minimumRows: 6,
330
320
  placeholder: summaryPlaceholder || undefined,
331
321
  onChange: e => {
332
322
  setDescription(e.target.value);
333
- if (validationErrors.description) {
334
- setValidationErrors(prev => ({
335
- ...prev,
336
- description: undefined
337
- }));
338
- }
323
+ fieldProps.onChange(e.target.value);
339
324
  },
340
325
  value: description
341
- })), validationErrors.description && /*#__PURE__*/React.createElement(ErrorMessage, null, validationErrors.description))), !anonymousFeedback && /*#__PURE__*/React.createElement(Fieldset, null, /*#__PURE__*/React.createElement("legend", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.optInOptionsLegend)), /*#__PURE__*/React.createElement(Field, {
326
+ })), error && /*#__PURE__*/React.createElement(ErrorMessage, null, error))), !anonymousFeedback && /*#__PURE__*/React.createElement(Fieldset, null, /*#__PURE__*/React.createElement("legend", null, /*#__PURE__*/React.createElement(FormattedMessage, messages.optInOptionsLegend)), /*#__PURE__*/React.createElement(Field, {
342
327
  name: "can-be-contacted"
343
328
  }, ({
344
329
  fieldProps