@atlaskit/link-create 1.9.4 → 1.9.5

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 (63) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/analytics.spec.yaml +24 -2
  3. package/dist/cjs/common/ui/ModalDialog/index.js +49 -0
  4. package/dist/cjs/common/utils/analytics/analytics.codegen.js +1 -1
  5. package/dist/cjs/common/utils/form/index.js +14 -3
  6. package/dist/cjs/controllers/create-field/main.js +23 -26
  7. package/dist/cjs/controllers/form-context/main.js +0 -25
  8. package/dist/cjs/ui/create-form/form-footer/edit-button/index.js +5 -0
  9. package/dist/cjs/ui/create-form/form-footer/main.js +13 -6
  10. package/dist/cjs/ui/create-form/form-footer/submit-button/index.js +5 -0
  11. package/dist/cjs/ui/create-form/main.js +6 -25
  12. package/dist/cjs/ui/link-create/confirm-dismiss-dialog/main.js +5 -9
  13. package/dist/cjs/ui/link-create/edit-modal/index.js +6 -6
  14. package/dist/cjs/ui/link-create/main.js +6 -7
  15. package/dist/cjs/ui/main.js +1 -1
  16. package/dist/es2019/common/ui/ModalDialog/index.js +39 -0
  17. package/dist/es2019/common/utils/analytics/analytics.codegen.js +1 -1
  18. package/dist/es2019/common/utils/form/index.js +13 -2
  19. package/dist/es2019/controllers/create-field/main.js +21 -23
  20. package/dist/es2019/controllers/form-context/main.js +0 -18
  21. package/dist/es2019/ui/create-form/form-footer/edit-button/index.js +7 -1
  22. package/dist/es2019/ui/create-form/form-footer/main.js +13 -2
  23. package/dist/es2019/ui/create-form/form-footer/submit-button/index.js +7 -1
  24. package/dist/es2019/ui/create-form/main.js +3 -20
  25. package/dist/es2019/ui/link-create/confirm-dismiss-dialog/main.js +4 -5
  26. package/dist/es2019/ui/link-create/edit-modal/index.js +6 -3
  27. package/dist/es2019/ui/link-create/main.js +5 -3
  28. package/dist/es2019/ui/main.js +1 -1
  29. package/dist/esm/common/ui/ModalDialog/index.js +39 -0
  30. package/dist/esm/common/utils/analytics/analytics.codegen.js +1 -1
  31. package/dist/esm/common/utils/form/index.js +13 -2
  32. package/dist/esm/controllers/create-field/main.js +21 -24
  33. package/dist/esm/controllers/form-context/main.js +0 -25
  34. package/dist/esm/ui/create-form/form-footer/edit-button/index.js +6 -1
  35. package/dist/esm/ui/create-form/form-footer/main.js +12 -2
  36. package/dist/esm/ui/create-form/form-footer/submit-button/index.js +6 -1
  37. package/dist/esm/ui/create-form/main.js +7 -26
  38. package/dist/esm/ui/link-create/confirm-dismiss-dialog/main.js +4 -5
  39. package/dist/esm/ui/link-create/edit-modal/index.js +6 -3
  40. package/dist/esm/ui/link-create/main.js +5 -3
  41. package/dist/esm/ui/main.js +1 -1
  42. package/dist/types/common/ui/Button/index.d.ts +1 -1
  43. package/dist/types/common/ui/ModalDialog/index.d.ts +13 -0
  44. package/dist/types/common/utils/analytics/analytics.codegen.d.ts +7 -1
  45. package/dist/types/common/utils/analytics/components.d.ts +1 -2
  46. package/dist/types/common/utils/form/index.d.ts +1 -1
  47. package/dist/types/controllers/create-field/main.d.ts +1 -0
  48. package/dist/types/controllers/form-context/main.d.ts +1 -3
  49. package/dist/types/ui/link-create/edit-modal/index.d.ts +1 -1
  50. package/dist/types-ts4.5/common/ui/Button/index.d.ts +1 -1
  51. package/dist/types-ts4.5/common/ui/ModalDialog/index.d.ts +13 -0
  52. package/dist/types-ts4.5/common/utils/analytics/analytics.codegen.d.ts +7 -1
  53. package/dist/types-ts4.5/common/utils/analytics/components.d.ts +1 -2
  54. package/dist/types-ts4.5/common/utils/form/index.d.ts +1 -1
  55. package/dist/types-ts4.5/controllers/create-field/main.d.ts +1 -0
  56. package/dist/types-ts4.5/controllers/form-context/main.d.ts +1 -3
  57. package/dist/types-ts4.5/ui/link-create/edit-modal/index.d.ts +1 -1
  58. package/package.json +2 -2
  59. package/dist/cjs/ui/link-create/track-mount/index.js +0 -30
  60. package/dist/es2019/ui/link-create/track-mount/index.js +0 -24
  61. package/dist/esm/ui/link-create/track-mount/index.js +0 -23
  62. package/dist/types/ui/link-create/track-mount/index.d.ts +0 -5
  63. package/dist/types-ts4.5/ui/link-create/track-mount/index.d.ts +0 -5
@@ -0,0 +1,39 @@
1
+ import React, { useEffect } from 'react';
2
+ import { AnalyticsContext, useAnalyticsEvents } from '@atlaskit/analytics-next';
3
+ import ModalDialog from '@atlaskit/modal-dialog';
4
+ import { ANALYTICS_CHANNEL } from '../../constants';
5
+ import createEventPayload from '../../utils/analytics/analytics.codegen';
6
+ import { ScreenViewedEvent } from '../../utils/analytics/components';
7
+ const ModalOpenCloseEvents = () => {
8
+ const {
9
+ createAnalyticsEvent
10
+ } = useAnalyticsEvents();
11
+ useEffect(() => {
12
+ //will fire when modal is mounted
13
+ createAnalyticsEvent(createEventPayload(`ui.modalDialog.opened.linkCreate`, {})).fire(ANALYTICS_CHANNEL);
14
+
15
+ //will fire when modal is unmounted
16
+ return () => {
17
+ createAnalyticsEvent(createEventPayload(`ui.modalDialog.closed.linkCreate`, {})).fire(ANALYTICS_CHANNEL);
18
+ };
19
+ }, [createAnalyticsEvent]);
20
+ return null;
21
+ };
22
+
23
+ /**
24
+ * AkModal component with built-in analytics for screen event + open + close events + source context
25
+ */
26
+ export const Modal = ({
27
+ screen,
28
+ children,
29
+ ...props
30
+ }) => {
31
+ return /*#__PURE__*/React.createElement(ModalDialog, props, /*#__PURE__*/React.createElement(AnalyticsContext, {
32
+ data: {
33
+ source: screen,
34
+ component: 'modal'
35
+ }
36
+ }, /*#__PURE__*/React.createElement(ScreenViewedEvent, {
37
+ screen: screen
38
+ }), /*#__PURE__*/React.createElement(ModalOpenCloseEvents, null), children));
39
+ };
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Generates Typescript types for analytics events from analytics.spec.yaml
5
5
  *
6
- * @codegen <<SignedSource::af0139619517f37a8bca32ddb6b7d6e0>>
6
+ * @codegen <<SignedSource::be704bbbca0e49c927d1268b9a0f1d6a>>
7
7
  * @codegenCommand yarn workspace @atlaskit/link-create run codegen-analytics
8
8
  */
9
9
 
@@ -3,6 +3,17 @@
3
3
  * to let a Field know if it should hide the error message until
4
4
  * the next submit, or if it returns to the previous error state
5
5
  */
6
- export const validateSubmitErrors = meta => {
7
- return !!(meta.touched && (meta.error || meta.submitError && !meta.dirtySinceLastSubmit));
6
+ export const shouldShowValidationErrors = meta => {
7
+ if (!meta.touched) {
8
+ return false;
9
+ }
10
+ if (meta.submitFailed) {
11
+ if (meta.error) {
12
+ return !meta.dirtySinceLastSubmit;
13
+ }
14
+ if (meta.submitError) {
15
+ return !meta.dirtySinceLastSubmit;
16
+ }
17
+ }
18
+ return false;
8
19
  };
@@ -1,10 +1,8 @@
1
1
  /** @jsx jsx */
2
- import { Fragment, useEffect, useMemo } from 'react';
3
2
  import { css, jsx } from '@emotion/react';
4
3
  import { Field } from 'react-final-form';
5
4
  import { ErrorMessage, HelperMessage, Label, RequiredAsterisk } from '@atlaskit/form';
6
- import { validateSubmitErrors } from '../../common/utils/form';
7
- import { useFormContext } from '../form-context';
5
+ import { shouldShowValidationErrors } from '../../common/utils/form';
8
6
  const fieldWrapperStyles = css({
9
7
  marginTop: "var(--ds-space-100, 8px)"
10
8
  });
@@ -18,29 +16,29 @@ export function CreateField({
18
16
  testId,
19
17
  children
20
18
  }) {
21
- const {
22
- assignValidator
23
- } = useFormContext();
24
- useEffect(() => {
25
- if (validators) {
26
- assignValidator(name, validators);
19
+ const fieldId = id ? id : `link-create-field-${name}`;
20
+ return jsx(Field, {
21
+ name: name,
22
+ validate: value => {
23
+ var _find;
24
+ return (_find = (validators !== null && validators !== void 0 ? validators : []).find(validator => {
25
+ return !validator.isValid(value);
26
+ })) === null || _find === void 0 ? void 0 : _find.errorMessage;
27
27
  }
28
- }, [name, validators, assignValidator]);
29
- const fieldId = useMemo(() => id ? id : `link-create-field-${name}`, [id, name]);
30
- return jsx("div", {
31
- css: fieldWrapperStyles,
32
- "data-testid": testId
33
- }, jsx(Field, {
34
- name: name
35
28
  }, ({
36
29
  input,
37
30
  meta
38
31
  }) => {
39
- const isInvalid = validateSubmitErrors(meta);
32
+ const isInvalid = shouldShowValidationErrors(meta);
40
33
  const {
41
- submitError
34
+ submitError,
35
+ error
42
36
  } = meta;
43
- return jsx(Fragment, null, label && jsx(Label, {
37
+ const hasError = !!submitError || !!error;
38
+ return jsx("div", {
39
+ css: fieldWrapperStyles,
40
+ "data-testid": testId
41
+ }, label && jsx(Label, {
44
42
  htmlFor: fieldId,
45
43
  id: `${fieldId}-label`,
46
44
  testId: `${testId}-label`
@@ -48,10 +46,10 @@ export function CreateField({
48
46
  ...input,
49
47
  fieldId,
50
48
  isInvalid
51
- }), !submitError && validationHelpText && jsx(HelperMessage, {
49
+ }), !hasError && validationHelpText && jsx(HelperMessage, {
52
50
  testId: `${testId}-helper-message`
53
- }, validationHelpText), submitError && isInvalid && jsx(ErrorMessage, {
51
+ }, validationHelpText), hasError && isInvalid && jsx(ErrorMessage, {
54
52
  testId: `${testId}-error-message`
55
- }, submitError));
56
- }));
53
+ }, submitError || error));
54
+ });
57
55
  }
@@ -1,7 +1,5 @@
1
1
  import React, { createContext, useCallback, useContext, useState } from 'react';
2
2
  export const FormContext = /*#__PURE__*/createContext({
3
- assignValidator: () => {},
4
- getValidators: () => ({}),
5
3
  setFormErrorMessage: () => {},
6
4
  enableEditView: undefined
7
5
  });
@@ -10,20 +8,6 @@ const FormContextProvider = ({
10
8
  children
11
9
  }) => {
12
10
  const [error, setError] = useState();
13
- const [validators, setValidators] = useState({});
14
-
15
- // Add validators to the form
16
- const assignValidator = useCallback((name, fieldValidators) => {
17
- setValidators(prevValidators => ({
18
- ...prevValidators,
19
- [name]: fieldValidators
20
- }));
21
- }, []);
22
-
23
- // Returns a validator function array
24
- const getValidators = useCallback(() => {
25
- return validators;
26
- }, [validators]);
27
11
 
28
12
  // Sets the form footer error message
29
13
  const setFormErrorMessage = useCallback(errorMessage => {
@@ -31,8 +15,6 @@ const FormContextProvider = ({
31
15
  }, [setError]);
32
16
  return /*#__PURE__*/React.createElement(FormContext.Provider, {
33
17
  value: {
34
- assignValidator,
35
- getValidators,
36
18
  setFormErrorMessage,
37
19
  formErrorMessage: error,
38
20
  enableEditView
@@ -1,14 +1,19 @@
1
1
  import React from 'react';
2
2
  import { useForm, useFormState } from 'react-final-form';
3
3
  import { useIntl } from 'react-intl-next';
4
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
4
5
  import LoadingButton from '@atlaskit/button/loading-button';
5
- import { LINK_CREATE_FORM_POST_CREATE_FIELD } from '../../../../common/constants';
6
+ import { ANALYTICS_CHANNEL, LINK_CREATE_FORM_POST_CREATE_FIELD } from '../../../../common/constants';
7
+ import createEventPayload from '../../../../common/utils/analytics/analytics.codegen';
6
8
  import { useFormContext } from '../../../../controllers/form-context';
7
9
  // eslint-disable-next-line @atlassian/tangerine/import/no-parent-imports
8
10
  import { FormSpy } from '../../form-spy';
9
11
  import { messages } from './messages';
10
12
  export const EditButton = () => {
11
13
  const intl = useIntl();
14
+ const {
15
+ createAnalyticsEvent
16
+ } = useAnalyticsEvents();
12
17
  const {
13
18
  submitting
14
19
  } = useFormState();
@@ -35,6 +40,7 @@ export const EditButton = () => {
35
40
  submitting && values[LINK_CREATE_FORM_POST_CREATE_FIELD] === true,
36
41
  onClick: () => {
37
42
  var _mutators$setField;
43
+ createAnalyticsEvent(createEventPayload('ui.button.clicked.edit', {})).fire(ANALYTICS_CHANNEL);
38
44
  /**
39
45
  * Setting this field to true indicates that the edit button was clicked and that
40
46
  * we have the intention of triggering the edit/post create flow
@@ -2,10 +2,14 @@
2
2
  import { Fragment } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
4
  import { useIntl } from 'react-intl-next';
5
- import Button, { ButtonGroup } from '@atlaskit/button';
5
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
6
+ import { ButtonGroup } from '@atlaskit/button';
6
7
  import LoadingButton from '@atlaskit/button/loading-button';
7
8
  import ErrorIcon from '@atlaskit/icon/glyph/error';
8
9
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
10
+ import { ANALYTICS_CHANNEL } from '../../../common/constants';
11
+ import { Button } from '../../../common/ui/Button';
12
+ import createEventPayload from '../../../common/utils/analytics/analytics.codegen';
9
13
  import { EditButton } from './edit-button';
10
14
  import { messages } from './messages';
11
15
  import { SubmitButton } from './submit-button';
@@ -31,6 +35,9 @@ export function CreateFormFooter({
31
35
  testId
32
36
  }) {
33
37
  const intl = useIntl();
38
+ const {
39
+ createAnalyticsEvent
40
+ } = useAnalyticsEvents();
34
41
  return jsx("footer", {
35
42
  "data-testid": `${testId}-footer`,
36
43
  css: formFooterWrapperStyles
@@ -42,6 +49,7 @@ export function CreateFormFooter({
42
49
  primaryColor: "var(--ds-icon-danger, #E34935)"
43
50
  }), formErrorMessage), jsx(ButtonGroup, null, jsx(Button, {
44
51
  type: "button",
52
+ actionSubjectId: "cancel",
45
53
  appearance: "subtle",
46
54
  onClick: handleCancel,
47
55
  testId: `${testId}-button-cancel`
@@ -49,6 +57,9 @@ export function CreateFormFooter({
49
57
  type: "submit",
50
58
  appearance: "primary",
51
59
  isLoading: submitting,
52
- testId: `${testId}-button-submit`
60
+ testId: `${testId}-button-submit`,
61
+ onClick: () => {
62
+ createAnalyticsEvent(createEventPayload('ui.button.clicked.create', {})).fire(ANALYTICS_CHANNEL);
63
+ }
53
64
  }, intl.formatMessage(messages.create))));
54
65
  }
@@ -1,14 +1,19 @@
1
1
  import React from 'react';
2
2
  import { useForm, useFormState } from 'react-final-form';
3
3
  import { useIntl } from 'react-intl-next';
4
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
4
5
  import LoadingButton from '@atlaskit/button/loading-button';
5
- import { LINK_CREATE_FORM_POST_CREATE_FIELD } from '../../../../common/constants';
6
+ import { ANALYTICS_CHANNEL, LINK_CREATE_FORM_POST_CREATE_FIELD } from '../../../../common/constants';
7
+ import createEventPayload from '../../../../common/utils/analytics/analytics.codegen';
6
8
  // eslint-disable-next-line @atlassian/tangerine/import/no-parent-imports
7
9
  import { FormSpy } from '../../form-spy';
8
10
  // eslint-disable-next-line @atlassian/tangerine/import/no-parent-imports
9
11
  import { messages } from '../messages';
10
12
  export const SubmitButton = () => {
11
13
  const intl = useIntl();
14
+ const {
15
+ createAnalyticsEvent
16
+ } = useAnalyticsEvents();
12
17
  const {
13
18
  submitting
14
19
  } = useFormState();
@@ -29,6 +34,7 @@ export const SubmitButton = () => {
29
34
  testId: "link-create-form-button-submit",
30
35
  onClick: () => {
31
36
  var _mutators$setField;
37
+ createAnalyticsEvent(createEventPayload('ui.button.clicked.create', {})).fire(ANALYTICS_CHANNEL);
32
38
  (_mutators$setField = mutators.setField) === null || _mutators$setField === void 0 ? void 0 : _mutators$setField.call(mutators, LINK_CREATE_FORM_POST_CREATE_FIELD, false);
33
39
  }
34
40
  }, intl.formatMessage(messages.create)));
@@ -2,16 +2,13 @@
2
2
  import { useCallback } from 'react';
3
3
  import { css, jsx } from '@emotion/react';
4
4
  import { Form, FormSpy } from 'react-final-form';
5
- import { useAnalyticsEvents } from '@atlaskit/analytics-next';
6
5
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
6
  import { Box } from '@atlaskit/primitives';
8
- import { ANALYTICS_CHANNEL, CREATE_FORM_MAX_WIDTH_IN_PX, LINK_CREATE_FORM_POST_CREATE_FIELD } from '../../common/constants';
9
- import createEventPayload from '../../common/utils/analytics/analytics.codegen';
7
+ import { CREATE_FORM_MAX_WIDTH_IN_PX, LINK_CREATE_FORM_POST_CREATE_FIELD } from '../../common/constants';
10
8
  import { useExitWarningModal } from '../../controllers/exit-warning-modal-context';
11
9
  import { useFormContext } from '../../controllers/form-context';
12
10
  import { CreateFormFooter } from './form-footer';
13
11
  import { CreateFormLoader } from './form-loader';
14
- import { validateFormData } from './utils';
15
12
  const formStyles = css({
16
13
  maxWidth: `${CREATE_FORM_MAX_WIDTH_IN_PX}px`,
17
14
  padding: `0 0 ${"var(--ds-space-300, 24px)"} 0`,
@@ -29,10 +26,6 @@ export const CreateForm = ({
29
26
  initialValues
30
27
  }) => {
31
28
  const {
32
- createAnalyticsEvent
33
- } = useAnalyticsEvents();
34
- const {
35
- getValidators,
36
29
  formErrorMessage,
37
30
  enableEditView
38
31
  } = useFormContext();
@@ -40,15 +33,6 @@ export const CreateForm = ({
40
33
  setShouldShowWarning
41
34
  } = useExitWarningModal();
42
35
  const handleSubmit = useCallback(async data => {
43
- createAnalyticsEvent(createEventPayload('ui.button.clicked.create', {})).fire(ANALYTICS_CHANNEL);
44
- const validators = getValidators();
45
- const errors = validateFormData({
46
- data,
47
- validators
48
- });
49
- if (Object.keys(errors).length !== 0) {
50
- return errors;
51
- }
52
36
  if (getBooleanFF('platform.linking-platform.link-create.enable-edit')) {
53
37
  const {
54
38
  [LINK_CREATE_FORM_POST_CREATE_FIELD]: shouldEnableEditView,
@@ -64,11 +48,10 @@ export const CreateForm = ({
64
48
  return onSubmit(formData);
65
49
  }
66
50
  return onSubmit(data);
67
- }, [createAnalyticsEvent, getValidators, onSubmit, enableEditView]);
51
+ }, [onSubmit, enableEditView]);
68
52
  const handleCancel = useCallback(() => {
69
- createAnalyticsEvent(createEventPayload('ui.button.clicked.cancel', {})).fire(ANALYTICS_CHANNEL);
70
53
  onCancel && onCancel();
71
- }, [createAnalyticsEvent, onCancel]);
54
+ }, [onCancel]);
72
55
  if (isLoading) {
73
56
  return jsx(CreateFormLoader, null);
74
57
  }
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
2
  import { useIntl } from 'react-intl-next';
3
3
  import { AnalyticsContext } from '@atlaskit/analytics-next';
4
- import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
4
+ import { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
5
5
  import { Button } from '../../../common/ui/Button';
6
- import { ScreenViewedEvent } from '../../../common/utils/analytics/components';
6
+ import { Modal } from '../../../common/ui/ModalDialog';
7
7
  import { useLinkCreateCallback } from '../../../controllers/callback-context';
8
8
  import messages from './messages';
9
9
  const screen = 'linkCreateExitWarningScreen';
@@ -28,11 +28,10 @@ export const ConfirmDismissDialog = ({
28
28
  data: context
29
29
  }, /*#__PURE__*/React.createElement(Modal, {
30
30
  testId: "link-create-confirm-dismiss-dialog",
31
+ screen: screen,
31
32
  onClose: onCancelDismiss,
32
33
  width: "small"
33
- }, /*#__PURE__*/React.createElement(ScreenViewedEvent, {
34
- screen: screen
35
- }), /*#__PURE__*/React.createElement(ModalHeader, null, /*#__PURE__*/React.createElement(ModalTitle, null, intl.formatMessage(messages.title))), /*#__PURE__*/React.createElement(ModalBody, null, intl.formatMessage(messages.description)), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
34
+ }, /*#__PURE__*/React.createElement(ModalHeader, null, /*#__PURE__*/React.createElement(ModalTitle, null, intl.formatMessage(messages.title))), /*#__PURE__*/React.createElement(ModalBody, null, intl.formatMessage(messages.description)), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
36
35
  actionSubjectId: "cancel",
37
36
  appearance: "subtle",
38
37
  onClick: onCancelDismiss
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import Modal, { ModalTransition } from '@atlaskit/modal-dialog';
2
+ import { ModalTransition } from '@atlaskit/modal-dialog';
3
+ import { Modal } from '../../../common/ui/ModalDialog';
3
4
  import { useEditPostCreateModal } from '../../../controllers/edit-post-create-context';
4
5
  import { useLinkCreatePlugins } from '../../../controllers/plugin-context';
6
+ const SCREEN = 'linkCreateEditScreen';
5
7
  export const EditModal = ({
6
8
  onClose,
7
9
  onCloseComplete
@@ -13,8 +15,9 @@ export const EditModal = ({
13
15
  const {
14
16
  activePlugin
15
17
  } = useLinkCreatePlugins();
16
- return /*#__PURE__*/React.createElement(ModalTransition, null, !!editViewPayload && /*#__PURE__*/React.createElement(Modal, {
18
+ return /*#__PURE__*/React.createElement(ModalTransition, null, !!editViewPayload && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Modal, {
17
19
  testId: "link-create-edit-modal",
20
+ screen: SCREEN,
18
21
  onClose: onClose,
19
22
  shouldScrollInViewport: true,
20
23
  width: "calc(100vw - 120px)",
@@ -23,5 +26,5 @@ export const EditModal = ({
23
26
  }, activePlugin === null || activePlugin === void 0 ? void 0 : (_activePlugin$editVie = activePlugin.editView) === null || _activePlugin$editVie === void 0 ? void 0 : _activePlugin$editVie.call(activePlugin, {
24
27
  payload: editViewPayload,
25
28
  onClose
26
- })));
29
+ }))));
27
30
  };
@@ -3,10 +3,11 @@ import _extends from "@babel/runtime/helpers/extends";
3
3
  import { Fragment, useCallback, useLayoutEffect, useRef, useState } from 'react';
4
4
  import { jsx } from '@emotion/react';
5
5
  import { useIntl } from 'react-intl-next';
6
- import Modal, { ModalBody, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
6
+ import { ModalBody, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
7
7
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
8
8
  import { Box } from '@atlaskit/primitives';
9
9
  import { CREATE_FORM_MAX_WIDTH_IN_PX } from '../../common/constants';
10
+ import { Modal } from '../../common/ui/ModalDialog';
10
11
  import { LinkCreateCallbackProvider } from '../../controllers/callback-context';
11
12
  import { EditPostCreateModalProvider } from '../../controllers/edit-post-create-context';
12
13
  import { ExitWarningModalProvider, useExitWarningModal } from '../../controllers/exit-warning-modal-context';
@@ -16,8 +17,8 @@ import { ConfirmDismissDialog } from './confirm-dismiss-dialog';
16
17
  import { EditModal } from './edit-modal';
17
18
  import { ErrorBoundary } from './error-boundary';
18
19
  import { messages } from './messages';
19
- import TrackMount from './track-mount';
20
20
  export const TEST_ID = 'link-create';
21
+ const SCREEN_ID = 'linkCreateScreen';
21
22
  const LinkCreateContent = ({
22
23
  plugins,
23
24
  entityKey
@@ -77,6 +78,7 @@ const LinkCreateWithModal = ({
77
78
  onCancel: handleCancel
78
79
  }, jsx(ModalTransition, null, active && jsx(Modal, {
79
80
  testId: "link-create-modal",
81
+ screen: SCREEN_ID,
80
82
  onClose: handleCancel,
81
83
  shouldScrollInViewport: true,
82
84
  onOpenComplete: onOpenComplete,
@@ -84,7 +86,7 @@ const LinkCreateWithModal = ({
84
86
  width: `${CREATE_FORM_MAX_WIDTH_IN_PX}px`
85
87
  }, jsx(ModalHeader, null, jsx(ModalTitle, null, modalTitle || intl.formatMessage(messages.heading))), jsx(ModalBody, null, jsx(Box, {
86
88
  testId: testId
87
- }, jsx(ErrorBoundary, null, jsx(TrackMount, null), jsx(LinkCreateContent, {
89
+ }, jsx(ErrorBoundary, null, jsx(LinkCreateContent, {
88
90
  plugins: plugins,
89
91
  entityKey: entityKey
90
92
  })))))), getBooleanFF('platform.linking-platform.link-create.enable-edit') && onComplete && jsx(EditModal, {
@@ -22,7 +22,7 @@ const LinkCreateWithAnalyticsContext = withLinkCreateAnalyticsContext( /*#__PURE
22
22
  }));
23
23
  export const PACKAGE_DATA = {
24
24
  packageName: "@atlaskit/link-create" || '',
25
- packageVersion: "1.9.4" || '',
25
+ packageVersion: "1.9.5" || '',
26
26
  componentName: COMPONENT_NAME,
27
27
  source: COMPONENT_NAME
28
28
  };
@@ -0,0 +1,39 @@
1
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
2
+ var _excluded = ["screen", "children"];
3
+ import React, { useEffect } from 'react';
4
+ import { AnalyticsContext, useAnalyticsEvents } from '@atlaskit/analytics-next';
5
+ import ModalDialog from '@atlaskit/modal-dialog';
6
+ import { ANALYTICS_CHANNEL } from '../../constants';
7
+ import createEventPayload from '../../utils/analytics/analytics.codegen';
8
+ import { ScreenViewedEvent } from '../../utils/analytics/components';
9
+ var ModalOpenCloseEvents = function ModalOpenCloseEvents() {
10
+ var _useAnalyticsEvents = useAnalyticsEvents(),
11
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
12
+ useEffect(function () {
13
+ //will fire when modal is mounted
14
+ createAnalyticsEvent(createEventPayload("ui.modalDialog.opened.linkCreate", {})).fire(ANALYTICS_CHANNEL);
15
+
16
+ //will fire when modal is unmounted
17
+ return function () {
18
+ createAnalyticsEvent(createEventPayload("ui.modalDialog.closed.linkCreate", {})).fire(ANALYTICS_CHANNEL);
19
+ };
20
+ }, [createAnalyticsEvent]);
21
+ return null;
22
+ };
23
+
24
+ /**
25
+ * AkModal component with built-in analytics for screen event + open + close events + source context
26
+ */
27
+ export var Modal = function Modal(_ref) {
28
+ var screen = _ref.screen,
29
+ children = _ref.children,
30
+ props = _objectWithoutProperties(_ref, _excluded);
31
+ return /*#__PURE__*/React.createElement(ModalDialog, props, /*#__PURE__*/React.createElement(AnalyticsContext, {
32
+ data: {
33
+ source: screen,
34
+ component: 'modal'
35
+ }
36
+ }, /*#__PURE__*/React.createElement(ScreenViewedEvent, {
37
+ screen: screen
38
+ }), /*#__PURE__*/React.createElement(ModalOpenCloseEvents, null), children));
39
+ };
@@ -4,7 +4,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
4
  *
5
5
  * Generates Typescript types for analytics events from analytics.spec.yaml
6
6
  *
7
- * @codegen <<SignedSource::af0139619517f37a8bca32ddb6b7d6e0>>
7
+ * @codegen <<SignedSource::be704bbbca0e49c927d1268b9a0f1d6a>>
8
8
  * @codegenCommand yarn workspace @atlaskit/link-create run codegen-analytics
9
9
  */
10
10
 
@@ -3,6 +3,17 @@
3
3
  * to let a Field know if it should hide the error message until
4
4
  * the next submit, or if it returns to the previous error state
5
5
  */
6
- export var validateSubmitErrors = function validateSubmitErrors(meta) {
7
- return !!(meta.touched && (meta.error || meta.submitError && !meta.dirtySinceLastSubmit));
6
+ export var shouldShowValidationErrors = function shouldShowValidationErrors(meta) {
7
+ if (!meta.touched) {
8
+ return false;
9
+ }
10
+ if (meta.submitFailed) {
11
+ if (meta.error) {
12
+ return !meta.dirtySinceLastSubmit;
13
+ }
14
+ if (meta.submitError) {
15
+ return !meta.dirtySinceLastSubmit;
16
+ }
17
+ }
18
+ return false;
8
19
  };
@@ -2,12 +2,10 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  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; }
3
3
  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) { _defineProperty(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; }
4
4
  /** @jsx jsx */
5
- import { Fragment, useEffect, useMemo } from 'react';
6
5
  import { css, jsx } from '@emotion/react';
7
6
  import { Field } from 'react-final-form';
8
7
  import { ErrorMessage, HelperMessage, Label, RequiredAsterisk } from '@atlaskit/form';
9
- import { validateSubmitErrors } from '../../common/utils/form';
10
- import { useFormContext } from '../form-context';
8
+ import { shouldShowValidationErrors } from '../../common/utils/form';
11
9
  var fieldWrapperStyles = css({
12
10
  marginTop: "var(--ds-space-100, 8px)"
13
11
  });
@@ -20,37 +18,36 @@ export function CreateField(_ref) {
20
18
  validationHelpText = _ref.validationHelpText,
21
19
  testId = _ref.testId,
22
20
  children = _ref.children;
23
- var _useFormContext = useFormContext(),
24
- assignValidator = _useFormContext.assignValidator;
25
- useEffect(function () {
26
- if (validators) {
27
- assignValidator(name, validators);
21
+ var fieldId = id ? id : "link-create-field-".concat(name);
22
+ return jsx(Field, {
23
+ name: name,
24
+ validate: function validate(value) {
25
+ var _find;
26
+ return (_find = (validators !== null && validators !== void 0 ? validators : []).find(function (validator) {
27
+ return !validator.isValid(value);
28
+ })) === null || _find === void 0 ? void 0 : _find.errorMessage;
28
29
  }
29
- }, [name, validators, assignValidator]);
30
- var fieldId = useMemo(function () {
31
- return id ? id : "link-create-field-".concat(name);
32
- }, [id, name]);
33
- return jsx("div", {
34
- css: fieldWrapperStyles,
35
- "data-testid": testId
36
- }, jsx(Field, {
37
- name: name
38
30
  }, function (_ref2) {
39
31
  var input = _ref2.input,
40
32
  meta = _ref2.meta;
41
- var isInvalid = validateSubmitErrors(meta);
42
- var submitError = meta.submitError;
43
- return jsx(Fragment, null, label && jsx(Label, {
33
+ var isInvalid = shouldShowValidationErrors(meta);
34
+ var submitError = meta.submitError,
35
+ error = meta.error;
36
+ var hasError = !!submitError || !!error;
37
+ return jsx("div", {
38
+ css: fieldWrapperStyles,
39
+ "data-testid": testId
40
+ }, label && jsx(Label, {
44
41
  htmlFor: fieldId,
45
42
  id: "".concat(fieldId, "-label"),
46
43
  testId: "".concat(testId, "-label")
47
44
  }, label, isRequired && jsx(RequiredAsterisk, null)), children(_objectSpread(_objectSpread({}, input), {}, {
48
45
  fieldId: fieldId,
49
46
  isInvalid: isInvalid
50
- })), !submitError && validationHelpText && jsx(HelperMessage, {
47
+ })), !hasError && validationHelpText && jsx(HelperMessage, {
51
48
  testId: "".concat(testId, "-helper-message")
52
- }, validationHelpText), submitError && isInvalid && jsx(ErrorMessage, {
49
+ }, validationHelpText), hasError && isInvalid && jsx(ErrorMessage, {
53
50
  testId: "".concat(testId, "-error-message")
54
- }, submitError));
55
- }));
51
+ }, submitError || error));
52
+ });
56
53
  }
@@ -1,13 +1,6 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
- 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; }
4
- 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) { _defineProperty(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; }
5
2
  import React, { createContext, useCallback, useContext, useState } from 'react';
6
3
  export var FormContext = /*#__PURE__*/createContext({
7
- assignValidator: function assignValidator() {},
8
- getValidators: function getValidators() {
9
- return {};
10
- },
11
4
  setFormErrorMessage: function setFormErrorMessage() {},
12
5
  enableEditView: undefined
13
6
  });
@@ -18,22 +11,6 @@ var FormContextProvider = function FormContextProvider(_ref) {
18
11
  _useState2 = _slicedToArray(_useState, 2),
19
12
  error = _useState2[0],
20
13
  setError = _useState2[1];
21
- var _useState3 = useState({}),
22
- _useState4 = _slicedToArray(_useState3, 2),
23
- validators = _useState4[0],
24
- setValidators = _useState4[1];
25
-
26
- // Add validators to the form
27
- var assignValidator = useCallback(function (name, fieldValidators) {
28
- setValidators(function (prevValidators) {
29
- return _objectSpread(_objectSpread({}, prevValidators), {}, _defineProperty({}, name, fieldValidators));
30
- });
31
- }, []);
32
-
33
- // Returns a validator function array
34
- var getValidators = useCallback(function () {
35
- return validators;
36
- }, [validators]);
37
14
 
38
15
  // Sets the form footer error message
39
16
  var setFormErrorMessage = useCallback(function (errorMessage) {
@@ -41,8 +18,6 @@ var FormContextProvider = function FormContextProvider(_ref) {
41
18
  }, [setError]);
42
19
  return /*#__PURE__*/React.createElement(FormContext.Provider, {
43
20
  value: {
44
- assignValidator: assignValidator,
45
- getValidators: getValidators,
46
21
  setFormErrorMessage: setFormErrorMessage,
47
22
  formErrorMessage: error,
48
23
  enableEditView: enableEditView