@atlaskit/editor-common 87.1.0 → 87.2.1

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 (36) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/keymaps/index.js +3 -3
  3. package/dist/cjs/link/ConfigureLinkOverlay/Dropdown.js +5 -2
  4. package/dist/cjs/link/ConfigureLinkOverlay/handleNavigation.js +43 -0
  5. package/dist/cjs/link/ConfigureLinkOverlay/index.js +7 -5
  6. package/dist/cjs/link/ConfigureLinkOverlay/useLinkOverlayAnalyticsEvents.js +12 -0
  7. package/dist/cjs/link/index.js +7 -0
  8. package/dist/cjs/monitoring/error.js +1 -1
  9. package/dist/cjs/ui/DropList/index.js +1 -1
  10. package/dist/es2019/keymaps/index.js +3 -3
  11. package/dist/es2019/link/ConfigureLinkOverlay/Dropdown.js +5 -2
  12. package/dist/es2019/link/ConfigureLinkOverlay/handleNavigation.js +38 -0
  13. package/dist/es2019/link/ConfigureLinkOverlay/index.js +7 -5
  14. package/dist/es2019/link/ConfigureLinkOverlay/useLinkOverlayAnalyticsEvents.js +12 -0
  15. package/dist/es2019/link/index.js +2 -1
  16. package/dist/es2019/monitoring/error.js +1 -1
  17. package/dist/es2019/ui/DropList/index.js +1 -1
  18. package/dist/esm/keymaps/index.js +3 -3
  19. package/dist/esm/link/ConfigureLinkOverlay/Dropdown.js +5 -2
  20. package/dist/esm/link/ConfigureLinkOverlay/handleNavigation.js +37 -0
  21. package/dist/esm/link/ConfigureLinkOverlay/index.js +7 -5
  22. package/dist/esm/link/ConfigureLinkOverlay/useLinkOverlayAnalyticsEvents.js +12 -0
  23. package/dist/esm/link/index.js +2 -1
  24. package/dist/esm/monitoring/error.js +1 -1
  25. package/dist/esm/ui/DropList/index.js +1 -1
  26. package/dist/types/link/ConfigureLinkOverlay/Dropdown.d.ts +7 -1
  27. package/dist/types/link/ConfigureLinkOverlay/handleNavigation.d.ts +12 -0
  28. package/dist/types/link/ConfigureLinkOverlay/index.d.ts +9 -1
  29. package/dist/types/link/ConfigureLinkOverlay/useLinkOverlayAnalyticsEvents.d.ts +13 -1
  30. package/dist/types/link/index.d.ts +1 -0
  31. package/dist/types-ts4.5/link/ConfigureLinkOverlay/Dropdown.d.ts +7 -1
  32. package/dist/types-ts4.5/link/ConfigureLinkOverlay/handleNavigation.d.ts +12 -0
  33. package/dist/types-ts4.5/link/ConfigureLinkOverlay/index.d.ts +9 -1
  34. package/dist/types-ts4.5/link/ConfigureLinkOverlay/useLinkOverlayAnalyticsEvents.d.ts +13 -1
  35. package/dist/types-ts4.5/link/index.d.ts +1 -0
  36. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 87.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#125984](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/125984)
8
+ [`167a210dfd672`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/167a210dfd672) -
9
+ [ux] Update shortcuts for element dnd
10
+ - Updated dependencies
11
+
12
+ ## 87.2.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [`aef5432662b58`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/aef5432662b58) -
17
+ [ux] EDM-10363 Implement opening links via configure overlay dropdown open link button
18
+
3
19
  ## 87.1.0
4
20
 
5
21
  ### Minor Changes
@@ -211,9 +211,9 @@ var decreaseMediaSize = exports.decreaseMediaSize = makeKeyMapWithCommon('increa
211
211
  var activateVideoControls = exports.activateVideoControls = makeKeyMapWithCommon('Activate controls panel on video', 'Shift-F10');
212
212
  var toggleHighlightPalette = exports.toggleHighlightPalette = makeKeyMapWithCommon('Toggle Highlight Palette', 'Mod-Alt-b');
213
213
  var focusToContextMenuTrigger = exports.focusToContextMenuTrigger = makeKeyMapWithCommon('Focus table context menu trigger', 'Shift-F10');
214
- var dragToMoveUp = exports.dragToMoveUp = makeKeyMapWithCommon('Move node up in the document', 'Ctrl-Alt-Shift-ArrowUp');
215
- var dragToMoveDown = exports.dragToMoveDown = makeKeyMapWithCommon('Move node down in the document', 'Ctrl-Alt-Shift-ArrowDown');
216
- var showElementDragHandle = exports.showElementDragHandle = makeKeyMapWithCommon('Show drag handle for editor element', 'Ctrl-Alt-Shift-a');
214
+ var dragToMoveUp = exports.dragToMoveUp = makeKeyMapWithCommon('Move node up in the document', 'Ctrl-Shift-ArrowUp');
215
+ var dragToMoveDown = exports.dragToMoveDown = makeKeyMapWithCommon('Move node down in the document', 'Ctrl-Shift-ArrowDown');
216
+ var showElementDragHandle = exports.showElementDragHandle = makeKeyMapWithCommon('Show drag handle for editor element', 'Ctrl-Shift-h');
217
217
  var arrowKeysMap = {
218
218
  // for reference: https://wincent.com/wiki/Unicode_representations_of_modifier_keys
219
219
  ARROWLEFT: "\u2190",
@@ -30,6 +30,7 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
30
30
  var SMALL_LINK_TOOLBAR_ANALYTICS_SOURCE = 'smallLinkToolbar';
31
31
  var Dropdown = function Dropdown(_ref) {
32
32
  var onConfigureClickCallback = _ref.onConfigureClick,
33
+ onOpenLinkClickCallback = _ref.onOpenLinkClick,
33
34
  onDropdownChange = _ref.onDropdownChange,
34
35
  editorView = _ref.editorView,
35
36
  testId = _ref.testId;
@@ -60,10 +61,11 @@ var Dropdown = function Dropdown(_ref) {
60
61
  focusEditor();
61
62
  }
62
63
  }, [fireToolbarViewEvent, focusEditor, onDropdownChange]);
63
- var onGoToLinkClick = (0, _react.useCallback)(function () {
64
+ var onGoToLinkClick = (0, _react.useCallback)(function (event) {
64
65
  fireActionClickEvent('goToLink');
66
+ onOpenLinkClickCallback === null || onOpenLinkClickCallback === void 0 || onOpenLinkClickCallback(event);
65
67
  focusEditor();
66
- }, [fireActionClickEvent, focusEditor]);
68
+ }, [fireActionClickEvent, focusEditor, onOpenLinkClickCallback]);
67
69
  var onConfigureClick = (0, _react.useCallback)(function () {
68
70
  fireActionClickEvent('configureLink');
69
71
  onConfigureClickCallback === null || onConfigureClickCallback === void 0 || onConfigureClickCallback();
@@ -94,6 +96,7 @@ var Dropdown = function Dropdown(_ref) {
94
96
  label: goToLinkLabel,
95
97
  size: 'medium'
96
98
  }),
99
+ testId: "".concat(testId, "-dropdown-item-open-link"),
97
100
  onClick: onGoToLinkClick
98
101
  }, goToLinkLabel), (0, _react2.jsx)(_dropdownMenu.DropdownItem, {
99
102
  elemBefore: (0, _react2.jsx)(_preferences.default, {
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.handleNavigation = handleNavigation;
7
+ var _analytics = require("../../analytics");
8
+ /**
9
+ * Function that opens a new page and fires the relevant analytics events
10
+ */
11
+ function handleNavigation(_ref) {
12
+ var url = _ref.url,
13
+ event = _ref.event,
14
+ onClickCallback = _ref.onClickCallback,
15
+ fireAnalyticsEvent = _ref.fireAnalyticsEvent;
16
+ if (fireAnalyticsEvent) {
17
+ fireAnalyticsEvent({
18
+ action: _analytics.ACTION.VISITED,
19
+ actionSubject: _analytics.ACTION_SUBJECT.LINK,
20
+ eventType: _analytics.EVENT_TYPE.TRACK,
21
+ attributes: {
22
+ platform: _analytics.PLATFORMS.WEB,
23
+ mode: _analytics.MODE.EDITOR
24
+ }
25
+ });
26
+ }
27
+ if (url) {
28
+ try {
29
+ onClickCallback === null || onClickCallback === void 0 || onClickCallback({
30
+ event: event,
31
+ url: url
32
+ });
33
+ } catch (_unused) {}
34
+ /**
35
+ * Links should navigate by default in live pages if:
36
+ * - the link is the direct target of the click event
37
+ * - default handling wasn't prevented with `event.preventDefault()`
38
+ */
39
+ if (!event.defaultPrevented) {
40
+ window.location.href = url;
41
+ }
42
+ }
43
+ }
@@ -43,7 +43,8 @@ var OverlayButton = exports.OverlayButton = (0, _analyticsNext.withAnalyticsCont
43
43
  testId = _ref$testId === void 0 ? 'link-configure-overlay-button' : _ref$testId,
44
44
  _ref$targetElementPos = _ref.targetElementPos,
45
45
  targetElementPos = _ref$targetElementPos === void 0 ? 0 : _ref$targetElementPos,
46
- onDropdownChange = _ref.onDropdownChange;
46
+ onDropdownChange = _ref.onDropdownChange,
47
+ onOpenLinkClick = _ref.onOpenLinkClick;
47
48
  var _useIntl = (0, _reactIntlNext.useIntl)(),
48
49
  formatMessage = _useIntl.formatMessage;
49
50
  var configureLinkLabel = formatMessage(_messages.cardMessages.inlineConfigureLink);
@@ -52,8 +53,8 @@ var OverlayButton = exports.OverlayButton = (0, _analyticsNext.withAnalyticsCont
52
53
  showDropdown = _useState2[0],
53
54
  setShowDropdown = _useState2[1];
54
55
  var _useLinkOverlayAnalyt = (0, _useLinkOverlayAnalyticsEvents.useLinkOverlayAnalyticsEvents)(),
55
- fireLinkClickEvent = _useLinkOverlayAnalyt.fireLinkClickEvent,
56
- fireActionClickEvent = _useLinkOverlayAnalyt.fireActionClickEvent;
56
+ fireActionClickEvent = _useLinkOverlayAnalyt.fireActionClickEvent,
57
+ fireLinkClickEvent = _useLinkOverlayAnalyt.fireLinkClickEvent;
57
58
  (0, _react.useLayoutEffect)(function () {
58
59
  var _domNode;
59
60
  var domNode = editorView.nodeDOM(targetElementPos);
@@ -81,10 +82,10 @@ var OverlayButton = exports.OverlayButton = (0, _analyticsNext.withAnalyticsCont
81
82
  editorView.dispatch(tr);
82
83
  }, [editorView, isText, targetElementPos, nodeEnd]);
83
84
  var handleConfigureClickWithAnalytics = (0, _react.useCallback)(function () {
84
- fireLinkClickEvent();
85
85
  fireActionClickEvent('configureLink');
86
+ fireLinkClickEvent();
86
87
  handleConfigureClick();
87
- }, [fireActionClickEvent, fireLinkClickEvent, handleConfigureClick]);
88
+ }, [fireLinkClickEvent, handleConfigureClick, fireActionClickEvent]);
88
89
  var _editorView$state$sel = editorView.state.selection,
89
90
  from = _editorView$state$sel.from,
90
91
  to = _editorView$state$sel.to;
@@ -98,6 +99,7 @@ var OverlayButton = exports.OverlayButton = (0, _analyticsNext.withAnalyticsCont
98
99
  }, showDropdown ? (0, _react2.jsx)(_Dropdown.default, {
99
100
  testId: testId,
100
101
  onConfigureClick: handleConfigureClick,
102
+ onOpenLinkClick: onOpenLinkClick,
101
103
  onDropdownChange: onDropdownChange,
102
104
  editorView: editorView
103
105
  }) : (0, _react2.jsx)(_tooltip.default, {
@@ -13,6 +13,15 @@ var useLinkOverlayAnalyticsEvents = exports.useLinkOverlayAnalyticsEvents = func
13
13
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
14
14
  return (0, _react.useMemo)(function () {
15
15
  return {
16
+ /**
17
+ * When a user clicks go to link or configure link buttons.
18
+ *
19
+ * When a link is "wide" the overlay button is the configure button.
20
+ * When a link is "narrow" the configure button is inside the dropdown.
21
+ *
22
+ * @param linkAction 'goToLink' when somebody clicks on the Go to link button
23
+ * in the chevron menu; 'configureLink' when somebody clicks on the Configure button (whether it's the overlay or in the dropdown)
24
+ */
16
25
  fireActionClickEvent: function fireActionClickEvent(linkAction) {
17
26
  createAnalyticsEvent({
18
27
  action: _analytics.ACTION.CLICKED,
@@ -23,6 +32,9 @@ var useLinkOverlayAnalyticsEvents = exports.useLinkOverlayAnalyticsEvents = func
23
32
  }
24
33
  }).fire(_analyticsListeners.FabricChannel.media);
25
34
  },
35
+ /**
36
+ * When a user clicks on the dropdown for a short link, or when a user clicks on the configure button for a wide link.
37
+ */
26
38
  fireLinkClickEvent: function fireLinkClickEvent() {
27
39
  createAnalyticsEvent({
28
40
  action: _analytics.ACTION.CLICKED,
@@ -89,6 +89,12 @@ Object.defineProperty(exports, "getLinkPreferencesURLFromENV", {
89
89
  return _utils2.getLinkPreferencesURLFromENV;
90
90
  }
91
91
  });
92
+ Object.defineProperty(exports, "handleNavigation", {
93
+ enumerable: true,
94
+ get: function get() {
95
+ return _handleNavigation.handleNavigation;
96
+ }
97
+ });
92
98
  Object.defineProperty(exports, "inputWrapper", {
93
99
  enumerable: true,
94
100
  get: function get() {
@@ -131,5 +137,6 @@ var _HyperlinkAddToolbar2 = _interopRequireWildcard(require("./LinkPicker/Hyperl
131
137
  var _utils = require("./LinkPicker/HyperlinkAddToolbar/utils");
132
138
  var _utils2 = require("./utils");
133
139
  var _ConfigureLinkOverlay = require("./ConfigureLinkOverlay");
140
+ var _handleNavigation = require("./ConfigureLinkOverlay/handleNavigation");
134
141
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
135
142
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -17,7 +17,7 @@ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return
17
17
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
18
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
19
19
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
20
- var packageVersion = "87.1.0";
20
+ var packageVersion = "87.2.1";
21
21
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
22
22
  // Remove URL as it has UGC
23
23
  // TODO: Sanitise the URL instead of just removing it
@@ -23,7 +23,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
23
23
  * @jsx jsx
24
24
  */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
25
25
  var packageName = "@atlaskit/editor-common";
26
- var packageVersion = "87.1.0";
26
+ var packageVersion = "87.2.1";
27
27
  var halfFocusRing = 1;
28
28
  var dropOffset = '0, 8';
29
29
  var DropList = /*#__PURE__*/function (_Component) {
@@ -99,9 +99,9 @@ export const decreaseMediaSize = makeKeyMapWithCommon('increase image size', 'Mo
99
99
  export const activateVideoControls = makeKeyMapWithCommon('Activate controls panel on video', 'Shift-F10');
100
100
  export const toggleHighlightPalette = makeKeyMapWithCommon('Toggle Highlight Palette', 'Mod-Alt-b');
101
101
  export const focusToContextMenuTrigger = makeKeyMapWithCommon('Focus table context menu trigger', 'Shift-F10');
102
- export const dragToMoveUp = makeKeyMapWithCommon('Move node up in the document', 'Ctrl-Alt-Shift-ArrowUp');
103
- export const dragToMoveDown = makeKeyMapWithCommon('Move node down in the document', 'Ctrl-Alt-Shift-ArrowDown');
104
- export const showElementDragHandle = makeKeyMapWithCommon('Show drag handle for editor element', 'Ctrl-Alt-Shift-a');
102
+ export const dragToMoveUp = makeKeyMapWithCommon('Move node up in the document', 'Ctrl-Shift-ArrowUp');
103
+ export const dragToMoveDown = makeKeyMapWithCommon('Move node down in the document', 'Ctrl-Shift-ArrowDown');
104
+ export const showElementDragHandle = makeKeyMapWithCommon('Show drag handle for editor element', 'Ctrl-Shift-h');
105
105
  const arrowKeysMap = {
106
106
  // for reference: https://wincent.com/wiki/Unicode_representations_of_modifier_keys
107
107
  ARROWLEFT: '\u2190',
@@ -19,6 +19,7 @@ import { useLinkOverlayAnalyticsEvents } from './useLinkOverlayAnalyticsEvents';
19
19
  const SMALL_LINK_TOOLBAR_ANALYTICS_SOURCE = 'smallLinkToolbar';
20
20
  const Dropdown = ({
21
21
  onConfigureClick: onConfigureClickCallback,
22
+ onOpenLinkClick: onOpenLinkClickCallback,
22
23
  onDropdownChange,
23
24
  editorView,
24
25
  testId
@@ -51,10 +52,11 @@ const Dropdown = ({
51
52
  focusEditor();
52
53
  }
53
54
  }, [fireToolbarViewEvent, focusEditor, onDropdownChange]);
54
- const onGoToLinkClick = useCallback(() => {
55
+ const onGoToLinkClick = useCallback(event => {
55
56
  fireActionClickEvent('goToLink');
57
+ onOpenLinkClickCallback === null || onOpenLinkClickCallback === void 0 ? void 0 : onOpenLinkClickCallback(event);
56
58
  focusEditor();
57
- }, [fireActionClickEvent, focusEditor]);
59
+ }, [fireActionClickEvent, focusEditor, onOpenLinkClickCallback]);
58
60
  const onConfigureClick = useCallback(() => {
59
61
  fireActionClickEvent('configureLink');
60
62
  onConfigureClickCallback === null || onConfigureClickCallback === void 0 ? void 0 : onConfigureClickCallback();
@@ -84,6 +86,7 @@ const Dropdown = ({
84
86
  label: goToLinkLabel,
85
87
  size: 'medium'
86
88
  }),
89
+ testId: `${testId}-dropdown-item-open-link`,
87
90
  onClick: onGoToLinkClick
88
91
  }, goToLinkLabel), jsx(DropdownItem, {
89
92
  elemBefore: jsx(PreferencesIcon, {
@@ -0,0 +1,38 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, MODE, PLATFORMS } from '../../analytics';
2
+ /**
3
+ * Function that opens a new page and fires the relevant analytics events
4
+ */
5
+ export function handleNavigation({
6
+ url,
7
+ event,
8
+ onClickCallback,
9
+ fireAnalyticsEvent
10
+ }) {
11
+ if (fireAnalyticsEvent) {
12
+ fireAnalyticsEvent({
13
+ action: ACTION.VISITED,
14
+ actionSubject: ACTION_SUBJECT.LINK,
15
+ eventType: EVENT_TYPE.TRACK,
16
+ attributes: {
17
+ platform: PLATFORMS.WEB,
18
+ mode: MODE.EDITOR
19
+ }
20
+ });
21
+ }
22
+ if (url) {
23
+ try {
24
+ onClickCallback === null || onClickCallback === void 0 ? void 0 : onClickCallback({
25
+ event,
26
+ url
27
+ });
28
+ } catch {}
29
+ /**
30
+ * Links should navigate by default in live pages if:
31
+ * - the link is the direct target of the click event
32
+ * - default handling wasn't prevented with `event.preventDefault()`
33
+ */
34
+ if (!event.defaultPrevented) {
35
+ window.location.href = url;
36
+ }
37
+ }
38
+ }
@@ -31,7 +31,8 @@ export const OverlayButton = withAnalyticsContext()(({
31
31
  editorView,
32
32
  testId = 'link-configure-overlay-button',
33
33
  targetElementPos = 0,
34
- onDropdownChange
34
+ onDropdownChange,
35
+ onOpenLinkClick
35
36
  }) => {
36
37
  var _docNode$nodeSize;
37
38
  const {
@@ -40,8 +41,8 @@ export const OverlayButton = withAnalyticsContext()(({
40
41
  const configureLinkLabel = formatMessage(cardMessages.inlineConfigureLink);
41
42
  const [showDropdown, setShowDropdown] = useState(false);
42
43
  const {
43
- fireLinkClickEvent,
44
- fireActionClickEvent
44
+ fireActionClickEvent,
45
+ fireLinkClickEvent
45
46
  } = useLinkOverlayAnalyticsEvents();
46
47
  useLayoutEffect(() => {
47
48
  var _domNode;
@@ -71,10 +72,10 @@ export const OverlayButton = withAnalyticsContext()(({
71
72
  editorView.dispatch(tr);
72
73
  }, [editorView, isText, targetElementPos, nodeEnd]);
73
74
  const handleConfigureClickWithAnalytics = useCallback(() => {
74
- fireLinkClickEvent();
75
75
  fireActionClickEvent('configureLink');
76
+ fireLinkClickEvent();
76
77
  handleConfigureClick();
77
- }, [fireActionClickEvent, fireLinkClickEvent, handleConfigureClick]);
78
+ }, [fireLinkClickEvent, handleConfigureClick, fireActionClickEvent]);
78
79
  const {
79
80
  from,
80
81
  to
@@ -89,6 +90,7 @@ export const OverlayButton = withAnalyticsContext()(({
89
90
  }, showDropdown ? jsx(Dropdown, {
90
91
  testId: testId,
91
92
  onConfigureClick: handleConfigureClick,
93
+ onOpenLinkClick: onOpenLinkClick,
92
94
  onDropdownChange: onDropdownChange,
93
95
  editorView: editorView
94
96
  }) : jsx(Tooltip, {
@@ -7,6 +7,15 @@ export const useLinkOverlayAnalyticsEvents = () => {
7
7
  createAnalyticsEvent
8
8
  } = useAnalyticsEvents();
9
9
  return useMemo(() => ({
10
+ /**
11
+ * When a user clicks go to link or configure link buttons.
12
+ *
13
+ * When a link is "wide" the overlay button is the configure button.
14
+ * When a link is "narrow" the configure button is inside the dropdown.
15
+ *
16
+ * @param linkAction 'goToLink' when somebody clicks on the Go to link button
17
+ * in the chevron menu; 'configureLink' when somebody clicks on the Configure button (whether it's the overlay or in the dropdown)
18
+ */
10
19
  fireActionClickEvent: linkAction => {
11
20
  createAnalyticsEvent({
12
21
  action: ACTION.CLICKED,
@@ -17,6 +26,9 @@ export const useLinkOverlayAnalyticsEvents = () => {
17
26
  }
18
27
  }).fire(FabricChannel.media);
19
28
  },
29
+ /**
30
+ * When a user clicks on the dropdown for a short link, or when a user clicks on the configure button for a wide link.
31
+ */
20
32
  fireLinkClickEvent: () => {
21
33
  createAnalyticsEvent({
22
34
  action: ACTION.CLICKED,
@@ -9,4 +9,5 @@ export { HyperlinkAddToolbar } from './LinkPicker/HyperlinkAddToolbar';
9
9
  export { default as HyperlinkLinkAddToolbar, HyperlinkLinkAddToolbarWithIntl, RECENT_SEARCH_LIST_SIZE } from './LinkPicker/HyperlinkAddToolbar/HyperlinkAddToolbar';
10
10
  export { sha1 } from './LinkPicker/HyperlinkAddToolbar/utils';
11
11
  export { isLinkAtPos, isTextAtPos, getLinkPreferencesURLFromENV } from './utils';
12
- export { OverlayButton } from './ConfigureLinkOverlay';
12
+ export { OverlayButton } from './ConfigureLinkOverlay';
13
+ export { handleNavigation } from './ConfigureLinkOverlay/handleNavigation';
@@ -1,7 +1,7 @@
1
1
  import { isFedRamp } from './environment';
2
2
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
3
3
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
4
- const packageVersion = "87.1.0";
4
+ const packageVersion = "87.2.1";
5
5
  const sanitiseSentryEvents = (data, _hint) => {
6
6
  // Remove URL as it has UGC
7
7
  // TODO: Sanitise the URL instead of just removing it
@@ -12,7 +12,7 @@ import { createAndFireEvent, withAnalyticsContext, withAnalyticsEvents } from '@
12
12
  import { N0, N50A, N60A, N900 } from '@atlaskit/theme/colors';
13
13
  import Layer from '../Layer';
14
14
  const packageName = "@atlaskit/editor-common";
15
- const packageVersion = "87.1.0";
15
+ const packageVersion = "87.2.1";
16
16
  const halfFocusRing = 1;
17
17
  const dropOffset = '0, 8';
18
18
  class DropList extends Component {
@@ -100,9 +100,9 @@ export var decreaseMediaSize = makeKeyMapWithCommon('increase image size', 'Mod-
100
100
  export var activateVideoControls = makeKeyMapWithCommon('Activate controls panel on video', 'Shift-F10');
101
101
  export var toggleHighlightPalette = makeKeyMapWithCommon('Toggle Highlight Palette', 'Mod-Alt-b');
102
102
  export var focusToContextMenuTrigger = makeKeyMapWithCommon('Focus table context menu trigger', 'Shift-F10');
103
- export var dragToMoveUp = makeKeyMapWithCommon('Move node up in the document', 'Ctrl-Alt-Shift-ArrowUp');
104
- export var dragToMoveDown = makeKeyMapWithCommon('Move node down in the document', 'Ctrl-Alt-Shift-ArrowDown');
105
- export var showElementDragHandle = makeKeyMapWithCommon('Show drag handle for editor element', 'Ctrl-Alt-Shift-a');
103
+ export var dragToMoveUp = makeKeyMapWithCommon('Move node up in the document', 'Ctrl-Shift-ArrowUp');
104
+ export var dragToMoveDown = makeKeyMapWithCommon('Move node down in the document', 'Ctrl-Shift-ArrowDown');
105
+ export var showElementDragHandle = makeKeyMapWithCommon('Show drag handle for editor element', 'Ctrl-Shift-h');
106
106
  var arrowKeysMap = {
107
107
  // for reference: https://wincent.com/wiki/Unicode_representations_of_modifier_keys
108
108
  ARROWLEFT: "\u2190",
@@ -21,6 +21,7 @@ import { useLinkOverlayAnalyticsEvents } from './useLinkOverlayAnalyticsEvents';
21
21
  var SMALL_LINK_TOOLBAR_ANALYTICS_SOURCE = 'smallLinkToolbar';
22
22
  var Dropdown = function Dropdown(_ref) {
23
23
  var onConfigureClickCallback = _ref.onConfigureClick,
24
+ onOpenLinkClickCallback = _ref.onOpenLinkClick,
24
25
  onDropdownChange = _ref.onDropdownChange,
25
26
  editorView = _ref.editorView,
26
27
  testId = _ref.testId;
@@ -51,10 +52,11 @@ var Dropdown = function Dropdown(_ref) {
51
52
  focusEditor();
52
53
  }
53
54
  }, [fireToolbarViewEvent, focusEditor, onDropdownChange]);
54
- var onGoToLinkClick = useCallback(function () {
55
+ var onGoToLinkClick = useCallback(function (event) {
55
56
  fireActionClickEvent('goToLink');
57
+ onOpenLinkClickCallback === null || onOpenLinkClickCallback === void 0 || onOpenLinkClickCallback(event);
56
58
  focusEditor();
57
- }, [fireActionClickEvent, focusEditor]);
59
+ }, [fireActionClickEvent, focusEditor, onOpenLinkClickCallback]);
58
60
  var onConfigureClick = useCallback(function () {
59
61
  fireActionClickEvent('configureLink');
60
62
  onConfigureClickCallback === null || onConfigureClickCallback === void 0 || onConfigureClickCallback();
@@ -85,6 +87,7 @@ var Dropdown = function Dropdown(_ref) {
85
87
  label: goToLinkLabel,
86
88
  size: 'medium'
87
89
  }),
90
+ testId: "".concat(testId, "-dropdown-item-open-link"),
88
91
  onClick: onGoToLinkClick
89
92
  }, goToLinkLabel), jsx(DropdownItem, {
90
93
  elemBefore: jsx(PreferencesIcon, {
@@ -0,0 +1,37 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, MODE, PLATFORMS } from '../../analytics';
2
+ /**
3
+ * Function that opens a new page and fires the relevant analytics events
4
+ */
5
+ export function handleNavigation(_ref) {
6
+ var url = _ref.url,
7
+ event = _ref.event,
8
+ onClickCallback = _ref.onClickCallback,
9
+ fireAnalyticsEvent = _ref.fireAnalyticsEvent;
10
+ if (fireAnalyticsEvent) {
11
+ fireAnalyticsEvent({
12
+ action: ACTION.VISITED,
13
+ actionSubject: ACTION_SUBJECT.LINK,
14
+ eventType: EVENT_TYPE.TRACK,
15
+ attributes: {
16
+ platform: PLATFORMS.WEB,
17
+ mode: MODE.EDITOR
18
+ }
19
+ });
20
+ }
21
+ if (url) {
22
+ try {
23
+ onClickCallback === null || onClickCallback === void 0 || onClickCallback({
24
+ event: event,
25
+ url: url
26
+ });
27
+ } catch (_unused) {}
28
+ /**
29
+ * Links should navigate by default in live pages if:
30
+ * - the link is the direct target of the click event
31
+ * - default handling wasn't prevented with `event.preventDefault()`
32
+ */
33
+ if (!event.defaultPrevented) {
34
+ window.location.href = url;
35
+ }
36
+ }
37
+ }
@@ -35,7 +35,8 @@ export var OverlayButton = withAnalyticsContext()(function (_ref) {
35
35
  testId = _ref$testId === void 0 ? 'link-configure-overlay-button' : _ref$testId,
36
36
  _ref$targetElementPos = _ref.targetElementPos,
37
37
  targetElementPos = _ref$targetElementPos === void 0 ? 0 : _ref$targetElementPos,
38
- onDropdownChange = _ref.onDropdownChange;
38
+ onDropdownChange = _ref.onDropdownChange,
39
+ onOpenLinkClick = _ref.onOpenLinkClick;
39
40
  var _useIntl = useIntl(),
40
41
  formatMessage = _useIntl.formatMessage;
41
42
  var configureLinkLabel = formatMessage(cardMessages.inlineConfigureLink);
@@ -44,8 +45,8 @@ export var OverlayButton = withAnalyticsContext()(function (_ref) {
44
45
  showDropdown = _useState2[0],
45
46
  setShowDropdown = _useState2[1];
46
47
  var _useLinkOverlayAnalyt = useLinkOverlayAnalyticsEvents(),
47
- fireLinkClickEvent = _useLinkOverlayAnalyt.fireLinkClickEvent,
48
- fireActionClickEvent = _useLinkOverlayAnalyt.fireActionClickEvent;
48
+ fireActionClickEvent = _useLinkOverlayAnalyt.fireActionClickEvent,
49
+ fireLinkClickEvent = _useLinkOverlayAnalyt.fireLinkClickEvent;
49
50
  useLayoutEffect(function () {
50
51
  var _domNode;
51
52
  var domNode = editorView.nodeDOM(targetElementPos);
@@ -73,10 +74,10 @@ export var OverlayButton = withAnalyticsContext()(function (_ref) {
73
74
  editorView.dispatch(tr);
74
75
  }, [editorView, isText, targetElementPos, nodeEnd]);
75
76
  var handleConfigureClickWithAnalytics = useCallback(function () {
76
- fireLinkClickEvent();
77
77
  fireActionClickEvent('configureLink');
78
+ fireLinkClickEvent();
78
79
  handleConfigureClick();
79
- }, [fireActionClickEvent, fireLinkClickEvent, handleConfigureClick]);
80
+ }, [fireLinkClickEvent, handleConfigureClick, fireActionClickEvent]);
80
81
  var _editorView$state$sel = editorView.state.selection,
81
82
  from = _editorView$state$sel.from,
82
83
  to = _editorView$state$sel.to;
@@ -90,6 +91,7 @@ export var OverlayButton = withAnalyticsContext()(function (_ref) {
90
91
  }, showDropdown ? jsx(Dropdown, {
91
92
  testId: testId,
92
93
  onConfigureClick: handleConfigureClick,
94
+ onOpenLinkClick: onOpenLinkClick,
93
95
  onDropdownChange: onDropdownChange,
94
96
  editorView: editorView
95
97
  }) : jsx(Tooltip, {
@@ -7,6 +7,15 @@ export var useLinkOverlayAnalyticsEvents = function useLinkOverlayAnalyticsEvent
7
7
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
8
8
  return useMemo(function () {
9
9
  return {
10
+ /**
11
+ * When a user clicks go to link or configure link buttons.
12
+ *
13
+ * When a link is "wide" the overlay button is the configure button.
14
+ * When a link is "narrow" the configure button is inside the dropdown.
15
+ *
16
+ * @param linkAction 'goToLink' when somebody clicks on the Go to link button
17
+ * in the chevron menu; 'configureLink' when somebody clicks on the Configure button (whether it's the overlay or in the dropdown)
18
+ */
10
19
  fireActionClickEvent: function fireActionClickEvent(linkAction) {
11
20
  createAnalyticsEvent({
12
21
  action: ACTION.CLICKED,
@@ -17,6 +26,9 @@ export var useLinkOverlayAnalyticsEvents = function useLinkOverlayAnalyticsEvent
17
26
  }
18
27
  }).fire(FabricChannel.media);
19
28
  },
29
+ /**
30
+ * When a user clicks on the dropdown for a short link, or when a user clicks on the configure button for a wide link.
31
+ */
20
32
  fireLinkClickEvent: function fireLinkClickEvent() {
21
33
  createAnalyticsEvent({
22
34
  action: ACTION.CLICKED,
@@ -9,4 +9,5 @@ export { HyperlinkAddToolbar } from './LinkPicker/HyperlinkAddToolbar';
9
9
  export { default as HyperlinkLinkAddToolbar, HyperlinkLinkAddToolbarWithIntl, RECENT_SEARCH_LIST_SIZE } from './LinkPicker/HyperlinkAddToolbar/HyperlinkAddToolbar';
10
10
  export { sha1 } from './LinkPicker/HyperlinkAddToolbar/utils';
11
11
  export { isLinkAtPos, isTextAtPos, getLinkPreferencesURLFromENV } from './utils';
12
- export { OverlayButton } from './ConfigureLinkOverlay';
12
+ export { OverlayButton } from './ConfigureLinkOverlay';
13
+ export { handleNavigation } from './ConfigureLinkOverlay/handleNavigation';
@@ -7,7 +7,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
7
7
  import { isFedRamp } from './environment';
8
8
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
9
9
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
10
- var packageVersion = "87.1.0";
10
+ var packageVersion = "87.2.1";
11
11
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
12
12
  // Remove URL as it has UGC
13
13
  // TODO: Sanitise the URL instead of just removing it
@@ -20,7 +20,7 @@ import { createAndFireEvent, withAnalyticsContext, withAnalyticsEvents } from '@
20
20
  import { N0, N50A, N60A, N900 } from '@atlaskit/theme/colors';
21
21
  import Layer from '../Layer';
22
22
  var packageName = "@atlaskit/editor-common";
23
- var packageVersion = "87.1.0";
23
+ var packageVersion = "87.2.1";
24
24
  var halfFocusRing = 1;
25
25
  var dropOffset = '0, 8';
26
26
  var DropList = /*#__PURE__*/function (_Component) {
@@ -1,9 +1,15 @@
1
- /// <reference types="react" />
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ import { type MouseEvent } from 'react';
2
6
  import { type EditorView } from '@atlaskit/editor-prosemirror/view';
3
7
  export type OnDropdownChange = (isOpen: boolean) => void;
4
8
  export type DropdownProps = {
5
9
  /** Callback fired when the Configure dropdown item is clicked */
6
10
  onConfigureClick: () => void;
11
+ /** Callback fired when the Open Link dropdown item is clicked */
12
+ onOpenLinkClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
7
13
  /** Callback fired when the dropdown is open or close */
8
14
  onDropdownChange?: OnDropdownChange;
9
15
  editorView: EditorView;
@@ -0,0 +1,12 @@
1
+ import { type MouseEvent } from 'react';
2
+ import { type AnalyticsEventPayload } from '../../analytics';
3
+ import { type OnClickCallback } from '../../card';
4
+ /**
5
+ * Function that opens a new page and fires the relevant analytics events
6
+ */
7
+ export declare function handleNavigation({ url, event, onClickCallback, fireAnalyticsEvent, }: {
8
+ fireAnalyticsEvent: ((payload: AnalyticsEventPayload) => void | undefined) | undefined;
9
+ onClickCallback?: OnClickCallback;
10
+ url: string;
11
+ event: MouseEvent<HTMLAnchorElement>;
12
+ }): void;
@@ -1,4 +1,8 @@
1
- /// <reference types="react" />
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ import { type MouseEvent } from 'react';
2
6
  import { type EditorView } from '@atlaskit/editor-prosemirror/view';
3
7
  import { type OnDropdownChange } from './Dropdown';
4
8
  export interface OverlayButtonProps {
@@ -9,5 +13,9 @@ export interface OverlayButtonProps {
9
13
  * Called when the dropdown is open/closed with isOpen state as true and false respectively.
10
14
  */
11
15
  onDropdownChange?: OnDropdownChange;
16
+ /**
17
+ * Called when the open link button in the dropdown is clicked.
18
+ */
19
+ onOpenLinkClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
12
20
  }
13
21
  export declare const OverlayButton: import("react").ForwardRefExoticComponent<OverlayButtonProps & import("@atlaskit/analytics-next").WithContextProps & import("react").RefAttributes<any>>;
@@ -1,5 +1,17 @@
1
1
  export declare const useLinkOverlayAnalyticsEvents: () => {
2
- fireActionClickEvent: (linkAction: string) => void;
2
+ /**
3
+ * When a user clicks go to link or configure link buttons.
4
+ *
5
+ * When a link is "wide" the overlay button is the configure button.
6
+ * When a link is "narrow" the configure button is inside the dropdown.
7
+ *
8
+ * @param linkAction 'goToLink' when somebody clicks on the Go to link button
9
+ * in the chevron menu; 'configureLink' when somebody clicks on the Configure button (whether it's the overlay or in the dropdown)
10
+ */
11
+ fireActionClickEvent: (linkAction: 'goToLink' | 'configureLink') => void;
12
+ /**
13
+ * When a user clicks on the dropdown for a short link, or when a user clicks on the configure button for a wide link.
14
+ */
3
15
  fireLinkClickEvent: () => void;
4
16
  fireToolbarViewEvent: () => void;
5
17
  };
@@ -16,3 +16,4 @@ export { sha1 } from './LinkPicker/HyperlinkAddToolbar/utils';
16
16
  export { isLinkAtPos, isTextAtPos, getLinkPreferencesURLFromENV } from './utils';
17
17
  export { OverlayButton } from './ConfigureLinkOverlay';
18
18
  export type { OverlayButtonProps } from './ConfigureLinkOverlay';
19
+ export { handleNavigation } from './ConfigureLinkOverlay/handleNavigation';
@@ -1,9 +1,15 @@
1
- /// <reference types="react" />
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ import { type MouseEvent } from 'react';
2
6
  import { type EditorView } from '@atlaskit/editor-prosemirror/view';
3
7
  export type OnDropdownChange = (isOpen: boolean) => void;
4
8
  export type DropdownProps = {
5
9
  /** Callback fired when the Configure dropdown item is clicked */
6
10
  onConfigureClick: () => void;
11
+ /** Callback fired when the Open Link dropdown item is clicked */
12
+ onOpenLinkClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
7
13
  /** Callback fired when the dropdown is open or close */
8
14
  onDropdownChange?: OnDropdownChange;
9
15
  editorView: EditorView;
@@ -0,0 +1,12 @@
1
+ import { type MouseEvent } from 'react';
2
+ import { type AnalyticsEventPayload } from '../../analytics';
3
+ import { type OnClickCallback } from '../../card';
4
+ /**
5
+ * Function that opens a new page and fires the relevant analytics events
6
+ */
7
+ export declare function handleNavigation({ url, event, onClickCallback, fireAnalyticsEvent, }: {
8
+ fireAnalyticsEvent: ((payload: AnalyticsEventPayload) => void | undefined) | undefined;
9
+ onClickCallback?: OnClickCallback;
10
+ url: string;
11
+ event: MouseEvent<HTMLAnchorElement>;
12
+ }): void;
@@ -1,4 +1,8 @@
1
- /// <reference types="react" />
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ import { type MouseEvent } from 'react';
2
6
  import { type EditorView } from '@atlaskit/editor-prosemirror/view';
3
7
  import { type OnDropdownChange } from './Dropdown';
4
8
  export interface OverlayButtonProps {
@@ -9,5 +13,9 @@ export interface OverlayButtonProps {
9
13
  * Called when the dropdown is open/closed with isOpen state as true and false respectively.
10
14
  */
11
15
  onDropdownChange?: OnDropdownChange;
16
+ /**
17
+ * Called when the open link button in the dropdown is clicked.
18
+ */
19
+ onOpenLinkClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
12
20
  }
13
21
  export declare const OverlayButton: import("react").ForwardRefExoticComponent<OverlayButtonProps & import("@atlaskit/analytics-next").WithContextProps & import("react").RefAttributes<any>>;
@@ -1,5 +1,17 @@
1
1
  export declare const useLinkOverlayAnalyticsEvents: () => {
2
- fireActionClickEvent: (linkAction: string) => void;
2
+ /**
3
+ * When a user clicks go to link or configure link buttons.
4
+ *
5
+ * When a link is "wide" the overlay button is the configure button.
6
+ * When a link is "narrow" the configure button is inside the dropdown.
7
+ *
8
+ * @param linkAction 'goToLink' when somebody clicks on the Go to link button
9
+ * in the chevron menu; 'configureLink' when somebody clicks on the Configure button (whether it's the overlay or in the dropdown)
10
+ */
11
+ fireActionClickEvent: (linkAction: 'goToLink' | 'configureLink') => void;
12
+ /**
13
+ * When a user clicks on the dropdown for a short link, or when a user clicks on the configure button for a wide link.
14
+ */
3
15
  fireLinkClickEvent: () => void;
4
16
  fireToolbarViewEvent: () => void;
5
17
  };
@@ -16,3 +16,4 @@ export { sha1 } from './LinkPicker/HyperlinkAddToolbar/utils';
16
16
  export { isLinkAtPos, isTextAtPos, getLinkPreferencesURLFromENV } from './utils';
17
17
  export { OverlayButton } from './ConfigureLinkOverlay';
18
18
  export type { OverlayButtonProps } from './ConfigureLinkOverlay';
19
+ export { handleNavigation } from './ConfigureLinkOverlay/handleNavigation';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "87.1.0",
3
+ "version": "87.2.1",
4
4
  "description": "A package that contains common classes and components for editor and renderer",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -109,13 +109,13 @@
109
109
  "@atlaskit/code": "^15.4.0",
110
110
  "@atlaskit/codemod-utils": "^4.2.0",
111
111
  "@atlaskit/custom-steps": "^0.6.0",
112
- "@atlaskit/dropdown-menu": "^12.13.0",
112
+ "@atlaskit/dropdown-menu": "^12.15.0",
113
113
  "@atlaskit/editor-json-transformer": "^8.17.0",
114
114
  "@atlaskit/editor-palette": "1.6.0",
115
115
  "@atlaskit/editor-prosemirror": "5.0.1",
116
116
  "@atlaskit/editor-shared-styles": "^2.13.0",
117
117
  "@atlaskit/editor-tables": "^2.8.0",
118
- "@atlaskit/emoji": "^67.6.0",
118
+ "@atlaskit/emoji": "^67.7.0",
119
119
  "@atlaskit/icon": "^22.8.0",
120
120
  "@atlaskit/icon-object": "^6.4.0",
121
121
  "@atlaskit/link-datasource": "^2.9.0",
@@ -129,7 +129,7 @@
129
129
  "@atlaskit/media-ui": "^25.10.0",
130
130
  "@atlaskit/media-viewer": "48.6.13",
131
131
  "@atlaskit/mention": "^23.2.0",
132
- "@atlaskit/menu": "^2.8.0",
132
+ "@atlaskit/menu": "^2.9.0",
133
133
  "@atlaskit/platform-feature-flags": "^0.3.0",
134
134
  "@atlaskit/primitives": "^11.1.0",
135
135
  "@atlaskit/profilecard": "^19.17.0",