@atlaskit/smart-card 21.0.1 → 21.0.4

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 (52) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/version.json +1 -1
  3. package/dist/cjs/view/FlexibleCard/components/actions/action/action-button/index.js +87 -0
  4. package/dist/cjs/view/FlexibleCard/components/actions/action/action-button/types.js +5 -0
  5. package/dist/cjs/view/FlexibleCard/components/actions/action/action-dropdown-item/index.js +31 -0
  6. package/dist/cjs/view/FlexibleCard/components/actions/action/action-dropdown-item/types.js +5 -0
  7. package/dist/cjs/view/FlexibleCard/components/actions/action/action-icon/index.js +52 -0
  8. package/dist/cjs/view/FlexibleCard/components/actions/action/action-icon/types.js +5 -0
  9. package/dist/cjs/view/FlexibleCard/components/actions/action/index.js +42 -104
  10. package/dist/cjs/view/FlexibleCard/components/blocks/action-group/index.js +44 -15
  11. package/dist/cjs/view/FlexibleCard/components/blocks/block/index.js +1 -1
  12. package/dist/cjs/view/FlexibleCard/components/blocks/utils.js +16 -3
  13. package/dist/cjs/view/FlexibleCard/components/utils.js +7 -2
  14. package/dist/cjs/view/HoverCard/components/HoverCardComponent.js +20 -20
  15. package/dist/es2019/version.json +1 -1
  16. package/dist/es2019/view/FlexibleCard/components/actions/action/action-button/index.js +88 -0
  17. package/dist/es2019/view/FlexibleCard/components/actions/action/action-button/types.js +1 -0
  18. package/dist/es2019/view/FlexibleCard/components/actions/action/action-dropdown-item/index.js +18 -0
  19. package/dist/es2019/view/FlexibleCard/components/actions/action/action-dropdown-item/types.js +1 -0
  20. package/dist/es2019/view/FlexibleCard/components/actions/action/action-icon/index.js +35 -0
  21. package/dist/es2019/view/FlexibleCard/components/actions/action/action-icon/types.js +1 -0
  22. package/dist/es2019/view/FlexibleCard/components/actions/action/index.js +26 -110
  23. package/dist/es2019/view/FlexibleCard/components/blocks/action-group/index.js +31 -12
  24. package/dist/es2019/view/FlexibleCard/components/blocks/block/index.js +2 -1
  25. package/dist/es2019/view/FlexibleCard/components/blocks/utils.js +23 -2
  26. package/dist/es2019/view/FlexibleCard/components/utils.js +6 -0
  27. package/dist/es2019/view/HoverCard/components/HoverCardComponent.js +20 -20
  28. package/dist/esm/version.json +1 -1
  29. package/dist/esm/view/FlexibleCard/components/actions/action/action-button/index.js +67 -0
  30. package/dist/esm/view/FlexibleCard/components/actions/action/action-button/types.js +1 -0
  31. package/dist/esm/view/FlexibleCard/components/actions/action/action-dropdown-item/index.js +19 -0
  32. package/dist/esm/view/FlexibleCard/components/actions/action/action-dropdown-item/types.js +1 -0
  33. package/dist/esm/view/FlexibleCard/components/actions/action/action-icon/index.js +39 -0
  34. package/dist/esm/view/FlexibleCard/components/actions/action/action-icon/types.js +1 -0
  35. package/dist/esm/view/FlexibleCard/components/actions/action/index.js +41 -99
  36. package/dist/esm/view/FlexibleCard/components/blocks/action-group/index.js +44 -16
  37. package/dist/esm/view/FlexibleCard/components/blocks/block/index.js +2 -2
  38. package/dist/esm/view/FlexibleCard/components/blocks/utils.js +14 -2
  39. package/dist/esm/view/FlexibleCard/components/utils.js +3 -1
  40. package/dist/esm/view/HoverCard/components/HoverCardComponent.js +20 -20
  41. package/dist/types/view/FlexibleCard/components/actions/action/action-button/index.d.ts +5 -0
  42. package/dist/types/view/FlexibleCard/components/actions/action/action-button/types.d.ts +8 -0
  43. package/dist/types/view/FlexibleCard/components/actions/action/action-dropdown-item/index.d.ts +4 -0
  44. package/dist/types/view/FlexibleCard/components/actions/action/action-dropdown-item/types.d.ts +8 -0
  45. package/dist/types/view/FlexibleCard/components/actions/action/action-icon/index.d.ts +5 -0
  46. package/dist/types/view/FlexibleCard/components/actions/action/action-icon/types.d.ts +7 -0
  47. package/dist/types/view/FlexibleCard/components/actions/action/index.d.ts +0 -3
  48. package/dist/types/view/FlexibleCard/components/actions/action/types.d.ts +0 -16
  49. package/dist/types/view/FlexibleCard/components/blocks/utils.d.ts +2 -1
  50. package/dist/types/view/FlexibleCard/components/utils.d.ts +2 -0
  51. package/package.json +8 -5
  52. package/report.api.md +32 -2
@@ -54,16 +54,23 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
54
54
  var fadeOutTimeoutId = (0, _react.useRef)();
55
55
  var fadeInTimeoutId = (0, _react.useRef)();
56
56
  var cardOpenTime = (0, _react.useRef)();
57
- var mousePos = (0, _react.useRef)({
58
- x: 0,
59
- y: 0
60
- });
57
+ var mousePos = (0, _react.useRef)();
61
58
  var popupOffset = (0, _react.useRef)();
62
59
  var parentSpan = (0, _react.useRef)(null);
63
60
  var renderers = (0, _renderers.useSmartLinkRenderers)();
64
61
  var linkState = (0, _store.useSmartCardState)(url);
65
62
  var hoverDisplay = 'card';
66
63
  var invokeMethod = 'mouse_hover';
64
+ var setMousePosition = (0, _react.useCallback)(function (event) {
65
+ if (isOpen) {
66
+ return;
67
+ }
68
+
69
+ mousePos.current = {
70
+ x: event.clientX,
71
+ y: event.clientY
72
+ };
73
+ }, [isOpen]);
67
74
  var hideCard = (0, _react.useCallback)(function () {
68
75
  //Check its previously open to avoid firing events when moving between the child and hover card components
69
76
  if (isOpen === true && cardOpenTime.current) {
@@ -82,19 +89,22 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
82
89
  return hideCard();
83
90
  }, delay);
84
91
  }, [hideCard]);
85
- var initShowCard = (0, _react.useCallback)(function () {
92
+ var initShowCard = (0, _react.useCallback)(function (event) {
86
93
  if (fadeOutTimeoutId.current) {
87
94
  clearTimeout(fadeOutTimeoutId.current);
88
- }
95
+ } //Set mouse position in the case it's not already set by onMouseMove, as in the case of scrolling
96
+
89
97
 
98
+ setMousePosition(event);
90
99
  fadeInTimeoutId.current = setTimeout(function () {
91
100
  //Check if its previously closed to avoid firing events when moving between the child and hover card components
92
101
  if (isOpen === false) {
93
102
  cardOpenTime.current = Date.now();
94
103
  analytics.ui.hoverCardViewedEvent(hoverDisplay, invokeMethod);
95
- }
104
+ } //If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
105
+
96
106
 
97
- if (parentSpan.current) {
107
+ if (parentSpan.current && mousePos.current) {
98
108
  var _parentSpan$current$g = parentSpan.current.getBoundingClientRect(),
99
109
  bottom = _parentSpan$current$g.bottom,
100
110
  left = _parentSpan$current$g.left;
@@ -104,7 +114,7 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
104
114
 
105
115
  setIsOpen(true);
106
116
  }, delay);
107
- }, [delay, isOpen, analytics.ui]);
117
+ }, [isOpen, setMousePosition, analytics.ui]);
108
118
  var linkActions = (0, _useSmartLinkActions.useSmartLinkActions)({
109
119
  url: url,
110
120
  appearance: _utils.SMART_CARD_ANALYTICS_DISPLAY,
@@ -114,17 +124,7 @@ var HoverCardComponent = function HoverCardComponent(_ref) {
114
124
  if (actionId === 'preview-content') {
115
125
  hideCard();
116
126
  }
117
- }, [hideCard]);
118
- var setMousePosition = (0, _react.useCallback)(function (event) {
119
- if (isOpen) {
120
- return;
121
- }
122
-
123
- mousePos.current = {
124
- x: event.clientX,
125
- y: event.clientY
126
- };
127
- }, [isOpen]); // Stop hover preview content to propagate event to parent.
127
+ }, [hideCard]); // Stop hover preview content to propagate event to parent.
128
128
 
129
129
  var onClick = (0, _react.useCallback)(function (e) {
130
130
  return e.stopPropagation();
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "21.0.1",
3
+ "version": "21.0.4",
4
4
  "sideEffects": false
5
5
  }
@@ -0,0 +1,88 @@
1
+ /** @jsx jsx */
2
+ import React, { useCallback } from 'react';
3
+ import { css, jsx } from '@emotion/core';
4
+ import Button from '@atlaskit/button/custom-theme-button';
5
+ import Tooltip from '@atlaskit/tooltip';
6
+ import { SmartLinkSize } from '../../../../../../constants';
7
+ import { sizeToButtonSpacing } from '../../../utils';
8
+
9
+ const getButtonStyle = (size, iconOnly) => {
10
+ switch (size) {
11
+ case SmartLinkSize.Large:
12
+ return iconOnly ? css`
13
+ button,
14
+ button:hover,
15
+ button:focus,
16
+ button:active {
17
+ padding: 0;
18
+ > span {
19
+ margin: 0;
20
+ }
21
+ }
22
+ ` : '';
23
+
24
+ case SmartLinkSize.Small:
25
+ return css`
26
+ font-size: 0.75rem;
27
+ font-weight: 500;
28
+ line-height: 1rem;
29
+ button,
30
+ button:hover,
31
+ button:focus,
32
+ button:active {
33
+ line-height: 1rem;
34
+ ${iconOnly ? `
35
+ padding: 0.125rem;
36
+ ` : `
37
+ padding-left: 0.25rem;
38
+ padding-right: 0.25rem;
39
+ `}
40
+ }
41
+ `;
42
+
43
+ case SmartLinkSize.XLarge:
44
+ case SmartLinkSize.Medium:
45
+ default:
46
+ return '';
47
+ }
48
+ };
49
+
50
+ const ActionButton = ({
51
+ appearance,
52
+ content,
53
+ iconAfter,
54
+ iconBefore,
55
+ onClick,
56
+ overrideCss,
57
+ size,
58
+ testId,
59
+ tooltipMessage
60
+ }) => {
61
+ const iconOnly = !content;
62
+ const onButtonClick = useCallback(handler => e => {
63
+ e.preventDefault();
64
+ handler();
65
+ }, []);
66
+ const onContainerClick = useCallback(e => {
67
+ // Stop button on click event from propagate into parent container.
68
+ e.stopPropagation();
69
+ }, []);
70
+ return jsx("div", {
71
+ css: [getButtonStyle(size, iconOnly), overrideCss],
72
+ "data-testid": `${testId}-button-wrapper`,
73
+ onClick: onContainerClick
74
+ }, jsx(Tooltip, {
75
+ content: tooltipMessage,
76
+ hideTooltipOnClick: true,
77
+ testId: `${testId}-tooltip`
78
+ }, jsx(Button, {
79
+ appearance: appearance,
80
+ iconAfter: iconAfter,
81
+ iconBefore: iconBefore,
82
+ onClick: onButtonClick(onClick),
83
+ spacing: sizeToButtonSpacing[size],
84
+ testId: testId
85
+ }, content)));
86
+ };
87
+
88
+ export default ActionButton;
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { DropdownItem } from '@atlaskit/dropdown-menu';
3
+ import { handleOnClick } from '../../../../../../utils';
4
+
5
+ const ActionDropdownItem = ({
6
+ content,
7
+ iconAfter,
8
+ iconBefore,
9
+ onClick,
10
+ testId
11
+ }) => /*#__PURE__*/React.createElement(DropdownItem, {
12
+ elemAfter: iconAfter,
13
+ elemBefore: iconBefore,
14
+ onClick: handleOnClick(onClick),
15
+ testId: testId
16
+ }, content);
17
+
18
+ export default ActionDropdownItem;
@@ -0,0 +1,35 @@
1
+ /** @jsx jsx */
2
+ import React from 'react';
3
+ import { css, jsx } from '@emotion/core';
4
+ import { SmartLinkSize } from '../../../../../../constants';
5
+ import { tokens } from '../../../../../../utils/token';
6
+ import { getIconSizeStyles } from '../../../utils';
7
+
8
+ const getIconWidth = size => {
9
+ switch (size) {
10
+ case SmartLinkSize.XLarge:
11
+ case SmartLinkSize.Large:
12
+ return '1.5rem';
13
+
14
+ case SmartLinkSize.Medium:
15
+ case SmartLinkSize.Small:
16
+ default:
17
+ return '1rem';
18
+ }
19
+ };
20
+
21
+ const getIconStyles = size => css`
22
+ color: ${tokens.actionIcon};
23
+ ${getIconSizeStyles(getIconWidth(size))};
24
+ `;
25
+
26
+ const ActionIcon = ({
27
+ size,
28
+ testId,
29
+ icon
30
+ }) => jsx("span", {
31
+ css: getIconStyles(size),
32
+ "data-testid": `${testId}-icon`
33
+ }, icon);
34
+
35
+ export default ActionIcon;
@@ -1,88 +1,10 @@
1
1
  /** @jsx jsx */
2
2
  import React from 'react';
3
- import { css, jsx } from '@emotion/core';
4
- import Button from '@atlaskit/button/custom-theme-button';
3
+ import { jsx } from '@emotion/core';
5
4
  import { SmartLinkSize } from '../../../../../constants';
6
- import Tooltip from '@atlaskit/tooltip';
7
- import { DropdownItem } from '@atlaskit/dropdown-menu';
8
- import { getIconSizeStyles } from '../../utils';
9
- import { tokens } from '../../../../../utils/token';
10
- import { handleOnClick } from '../../../../../utils';
11
-
12
- const getIconWidth = size => {
13
- switch (size) {
14
- case SmartLinkSize.XLarge:
15
- case SmartLinkSize.Large:
16
- return '1.5rem';
17
-
18
- case SmartLinkSize.Medium:
19
- case SmartLinkSize.Small:
20
- default:
21
- return '1rem';
22
- }
23
- };
24
-
25
- const getIconStyles = size => css`
26
- color: ${tokens.actionIcon};
27
- ${getIconSizeStyles(getIconWidth(size))};
28
- `;
29
-
30
- const getButtonStyle = (size, iconOnly) => {
31
- switch (size) {
32
- case SmartLinkSize.Large:
33
- return iconOnly ? css`
34
- button,
35
- button:hover,
36
- button:focus,
37
- button:active {
38
- padding: 0;
39
- > span {
40
- margin: 0;
41
- }
42
- }
43
- ` : '';
44
-
45
- case SmartLinkSize.Small:
46
- return css`
47
- font-size: 0.75rem;
48
- font-weight: 500;
49
- line-height: 1rem;
50
- button,
51
- button:hover,
52
- button:focus,
53
- button:active {
54
- line-height: 1rem;
55
- ${iconOnly ? `
56
- padding: 0.125rem;
57
- ` : `
58
- padding-left: 0.25rem;
59
- padding-right: 0.25rem;
60
- `}
61
- }
62
- `;
63
-
64
- case SmartLinkSize.XLarge:
65
- case SmartLinkSize.Medium:
66
- default:
67
- return '';
68
- }
69
- };
70
-
71
- const ActionIcon = ({
72
- size,
73
- testId,
74
- icon
75
- }) => jsx("span", {
76
- css: getIconStyles(size),
77
- "data-testid": `${testId}-icon`
78
- }, icon);
79
-
80
- export const sizeToSpacing = {
81
- [SmartLinkSize.Small]: 'none',
82
- [SmartLinkSize.Medium]: 'compact',
83
- [SmartLinkSize.Large]: 'compact',
84
- [SmartLinkSize.XLarge]: 'default'
85
- };
5
+ import ActionButton from './action-button';
6
+ import ActionDropdownItem from './action-dropdown-item';
7
+ import ActionIcon from './action-icon';
86
8
  /**
87
9
  * A base action that can be triggered with an on click.
88
10
  * @internal
@@ -108,40 +30,34 @@ const Action = ({
108
30
  return null;
109
31
  }
110
32
 
111
- const iconBefore = icon && iconPosition === 'before' ? jsx(ActionIcon, {
112
- size: size,
113
- testId: testId,
114
- icon: icon
115
- }) : undefined;
116
- const iconAfter = icon && iconPosition === 'after' ? jsx(ActionIcon, {
33
+ const actionIcon = icon && jsx(ActionIcon, {
34
+ icon: icon,
117
35
  size: size,
118
- testId: testId,
119
- icon: icon
120
- }) : undefined;
121
- const iconOnly = !content;
36
+ testId: testId
37
+ });
38
+ const iconBefore = icon && iconPosition === 'before' ? actionIcon : undefined;
39
+ const iconAfter = icon && iconPosition === 'after' ? actionIcon : undefined;
122
40
 
123
41
  if (asDropDownItem) {
124
- return jsx(DropdownItem, {
125
- elemBefore: iconBefore,
126
- elemAfter: iconAfter,
127
- testId: testId,
128
- onClick: handleOnClick(onClick)
129
- }, content);
42
+ return jsx(ActionDropdownItem, {
43
+ content: content,
44
+ iconAfter: iconAfter,
45
+ iconBefore: iconBefore,
46
+ onClick: onClick,
47
+ testId: testId
48
+ });
130
49
  } else {
131
- return jsx(Tooltip, {
132
- content: tooltipMessage,
133
- testId: `${testId}-tooltip`
134
- }, jsx("div", {
135
- css: [getButtonStyle(size, iconOnly), overrideCss],
136
- "data-testid": `${testId}-button-wrapper`
137
- }, jsx(Button, {
138
- spacing: sizeToSpacing[size],
50
+ return jsx(ActionButton, {
139
51
  appearance: appearance,
140
- testId: testId,
141
- onClick: handleOnClick(onClick),
52
+ content: content,
53
+ iconAfter: iconAfter,
142
54
  iconBefore: iconBefore,
143
- iconAfter: iconAfter
144
- }, content)));
55
+ onClick: onClick,
56
+ overrideCss: overrideCss,
57
+ size: size,
58
+ testId: testId,
59
+ tooltipMessage: tooltipMessage
60
+ });
145
61
  }
146
62
  };
147
63
 
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
 
3
3
  /** @jsx jsx */
4
- import { useCallback } from 'react';
4
+ import { useCallback, useMemo, useState } from 'react';
5
5
  import { FormattedMessage } from 'react-intl-next';
6
6
  import { css, jsx } from '@emotion/core';
7
7
  import ButtonGroup from '@atlaskit/button/button-group';
@@ -11,7 +11,7 @@ import DropdownMenu from '@atlaskit/dropdown-menu';
11
11
  import { SmartLinkSize } from '../../../../../constants';
12
12
  import Button from '@atlaskit/button/standard-button';
13
13
  import MoreIcon from '@atlaskit/icon/glyph/more';
14
- import { sizeToSpacing } from '../../actions/action';
14
+ import { sizeToButtonSpacing } from '../../utils';
15
15
  import { tokens } from '../../../../../utils/token';
16
16
  import { messages } from '../../../../../messages';
17
17
  const styles = css`
@@ -46,35 +46,54 @@ const ActionGroup = ({
46
46
  onDropdownOpenChange,
47
47
  testId
48
48
  }) => {
49
- const isMoreThenTwoItems = items.length > visibleButtonsNum;
50
- const firstActions = isMoreThenTwoItems ? items.slice(0, visibleButtonsNum - 1) : items;
51
- const restActions = isMoreThenTwoItems ? items.slice(visibleButtonsNum - 1) : []; // Stop AK dropdown menu to propagate event on click.
49
+ const [isOpen, setIsOpen] = useState(false);
50
+ const [buttonActions, dropdownItemActions] = useMemo(() => {
51
+ const isMoreThenTwoItems = items.length > visibleButtonsNum;
52
+ const buttons = isMoreThenTwoItems ? items.slice(0, visibleButtonsNum - 1) : items;
53
+ const dropdownItems = isMoreThenTwoItems ? items.slice(visibleButtonsNum - 1) : [];
54
+ return [buttons, dropdownItems];
55
+ }, [items, visibleButtonsNum]); // Stop AK dropdown menu to propagate event on click.
52
56
 
53
57
  const onClick = useCallback(e => e.stopPropagation(), []);
58
+ const onOpenChange = useCallback(attrs => {
59
+ setIsOpen(attrs.isOpen);
60
+
61
+ if (onDropdownOpenChange) {
62
+ onDropdownOpenChange(attrs.isOpen);
63
+ }
64
+ }, [onDropdownOpenChange]);
65
+ const onActionClick = useCallback(() => {
66
+ if (isOpen) {
67
+ onOpenChange({
68
+ isOpen: false
69
+ });
70
+ }
71
+ }, [isOpen, onOpenChange]);
54
72
  return jsx("div", {
55
73
  css: styles,
56
74
  className: "actions-button-group",
57
75
  onClick: onClick
58
- }, jsx(ButtonGroup, null, renderActionItems(firstActions, size, appearance), restActions.length > 0 ? jsx(DropdownMenu, {
59
- onOpenChange: ({
60
- isOpen
61
- }) => onDropdownOpenChange && onDropdownOpenChange(isOpen),
76
+ }, jsx(ButtonGroup, null, renderActionItems(buttonActions, size, appearance, false, onActionClick), dropdownItemActions.length > 0 ? jsx(DropdownMenu, {
77
+ isOpen: isOpen,
78
+ onOpenChange: onOpenChange,
62
79
  trigger: ({
63
80
  triggerRef,
64
81
  ...props
65
82
  }) => jsx(Tooltip, {
66
83
  content: jsx(FormattedMessage, messages.more_actions),
84
+ hideTooltipOnClick: true,
67
85
  testId: "action-group-more-button-tooltip",
68
86
  tag: "span"
69
87
  }, jsx(Button, _extends({}, props, {
70
- spacing: sizeToSpacing[size],
88
+ spacing: sizeToButtonSpacing[size],
71
89
  testId: "action-group-more-button",
72
90
  iconBefore: jsx(MoreIcon, {
73
91
  label: "more"
74
92
  }),
75
93
  ref: triggerRef
76
- })))
77
- }, renderActionItems(restActions, size, appearance, true)) : null));
94
+ }))),
95
+ testId: "action-group-dropdown"
96
+ }, renderActionItems(dropdownItemActions, size, appearance, true, onActionClick)) : null));
78
97
  };
79
98
 
80
99
  export default ActionGroup;
@@ -2,10 +2,11 @@
2
2
  import React from 'react';
3
3
  import { css, jsx } from '@emotion/core';
4
4
  import { ElementName, SmartLinkDirection, SmartLinkSize } from '../../../../../constants';
5
- import { getBaseStyles, getGapSize, renderChildren } from '../utils';
5
+ import { getBaseStyles, getGapSize, highlightRemoveStyles, renderChildren } from '../utils';
6
6
 
7
7
  const getBlockStyles = (direction, size) => css`
8
8
  ${getBaseStyles(direction, size)}
9
+ ${highlightRemoveStyles}
9
10
  justify-content: flex-start;
10
11
  [data-separator] + [data-separator]:before {
11
12
  content: '•';
@@ -84,6 +84,17 @@ export const getBaseStyles = (direction, size) => css`
84
84
  min-width: fit-content;
85
85
  }
86
86
  `;
87
+ export const highlightRemoveStyles = css`
88
+ outline: none !important;
89
+ outline-color: inherit;
90
+ color: inherit;
91
+ -webkit-tap-highlight-color: transparent;
92
+ -webkit-touch-callout: none;
93
+ -webkit-user-select: none;
94
+ -moz-user-select: none;
95
+ -ms-user-select: none;
96
+ user-select: none;
97
+ `;
87
98
 
88
99
  const isActionGroup = node => /*#__PURE__*/React.isValidElement(node) && node.type === ActionGroup;
89
100
 
@@ -138,7 +149,7 @@ export const renderElementItems = (items = [], display = 'inline') => {
138
149
  return elements;
139
150
  }
140
151
  };
141
- export const renderActionItems = (items = [], size = SmartLinkSize.Medium, appearance, asDropDownItems) => {
152
+ export const renderActionItems = (items = [], size = SmartLinkSize.Medium, appearance, asDropDownItems, onActionItemClick) => {
142
153
  const actions = items.reduce((acc, curr, idx) => {
143
154
  const {
144
155
  name,
@@ -160,12 +171,22 @@ export const renderActionItems = (items = [], size = SmartLinkSize.Medium, appea
160
171
  }
161
172
 
162
173
  if (Action) {
174
+ const handleOnClick = () => {
175
+ if (onActionItemClick) {
176
+ onActionItemClick();
177
+ }
178
+
179
+ if (onClick) {
180
+ onClick();
181
+ }
182
+ };
183
+
163
184
  return [...acc, /*#__PURE__*/React.createElement(Action, _extends({
164
185
  asDropDownItem: asDropDownItems,
165
186
  size: size,
166
187
  key: idx,
167
188
  appearance: appearance,
168
- onClick: onClick
189
+ onClick: handleOnClick
169
190
  }, actionProps))];
170
191
  }
171
192
 
@@ -3,6 +3,12 @@ import React from 'react';
3
3
  import { css } from '@emotion/core';
4
4
  import { FormattedMessage } from 'react-intl-next';
5
5
  import { SmartLinkSize } from '../../../constants';
6
+ export const sizeToButtonSpacing = {
7
+ [SmartLinkSize.Small]: 'none',
8
+ [SmartLinkSize.Medium]: 'compact',
9
+ [SmartLinkSize.Large]: 'compact',
10
+ [SmartLinkSize.XLarge]: 'default'
11
+ };
6
12
  export const getFormattedMessage = message => {
7
13
  if (message) {
8
14
  const {
@@ -22,16 +22,23 @@ export const HoverCardComponent = ({
22
22
  const fadeOutTimeoutId = useRef();
23
23
  const fadeInTimeoutId = useRef();
24
24
  const cardOpenTime = useRef();
25
- const mousePos = useRef({
26
- x: 0,
27
- y: 0
28
- });
25
+ const mousePos = useRef();
29
26
  const popupOffset = useRef();
30
27
  const parentSpan = useRef(null);
31
28
  const renderers = useSmartLinkRenderers();
32
29
  const linkState = useLinkState(url);
33
30
  const hoverDisplay = 'card';
34
31
  const invokeMethod = 'mouse_hover';
32
+ const setMousePosition = useCallback(event => {
33
+ if (isOpen) {
34
+ return;
35
+ }
36
+
37
+ mousePos.current = {
38
+ x: event.clientX,
39
+ y: event.clientY
40
+ };
41
+ }, [isOpen]);
35
42
  const hideCard = useCallback(() => {
36
43
  //Check its previously open to avoid firing events when moving between the child and hover card components
37
44
  if (isOpen === true && cardOpenTime.current) {
@@ -48,19 +55,22 @@ export const HoverCardComponent = ({
48
55
 
49
56
  fadeOutTimeoutId.current = setTimeout(() => hideCard(), delay);
50
57
  }, [hideCard]);
51
- const initShowCard = useCallback(() => {
58
+ const initShowCard = useCallback(event => {
52
59
  if (fadeOutTimeoutId.current) {
53
60
  clearTimeout(fadeOutTimeoutId.current);
54
- }
61
+ } //Set mouse position in the case it's not already set by onMouseMove, as in the case of scrolling
62
+
55
63
 
64
+ setMousePosition(event);
56
65
  fadeInTimeoutId.current = setTimeout(() => {
57
66
  //Check if its previously closed to avoid firing events when moving between the child and hover card components
58
67
  if (isOpen === false) {
59
68
  cardOpenTime.current = Date.now();
60
69
  analytics.ui.hoverCardViewedEvent(hoverDisplay, invokeMethod);
61
- }
70
+ } //If these are undefined then popupOffset is undefined and we fallback to default bottom-start placement
71
+
62
72
 
63
- if (parentSpan.current) {
73
+ if (parentSpan.current && mousePos.current) {
64
74
  const {
65
75
  bottom,
66
76
  left
@@ -70,7 +80,7 @@ export const HoverCardComponent = ({
70
80
 
71
81
  setIsOpen(true);
72
82
  }, delay);
73
- }, [delay, isOpen, analytics.ui]);
83
+ }, [isOpen, setMousePosition, analytics.ui]);
74
84
  const linkActions = useSmartLinkActions({
75
85
  url,
76
86
  appearance: SMART_CARD_ANALYTICS_DISPLAY,
@@ -80,17 +90,7 @@ export const HoverCardComponent = ({
80
90
  if (actionId === 'preview-content') {
81
91
  hideCard();
82
92
  }
83
- }, [hideCard]);
84
- const setMousePosition = useCallback(event => {
85
- if (isOpen) {
86
- return;
87
- }
88
-
89
- mousePos.current = {
90
- x: event.clientX,
91
- y: event.clientY
92
- };
93
- }, [isOpen]); // Stop hover preview content to propagate event to parent.
93
+ }, [hideCard]); // Stop hover preview content to propagate event to parent.
94
94
 
95
95
  const onClick = useCallback(e => e.stopPropagation(), []);
96
96
  return jsx(Popup, {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "21.0.1",
3
+ "version": "21.0.4",
4
4
  "sideEffects": false
5
5
  }