@atlaskit/smart-card 24.0.0 → 24.0.2
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.
- package/CHANGELOG.md +13 -0
- package/dist/cjs/state/analytics/useMouseDownEvent.js +24 -0
- package/dist/cjs/utils/analytics/click.js +121 -0
- package/dist/cjs/utils/index.js +10 -0
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/BlockCard/components/ContentHeader.js +4 -0
- package/dist/cjs/view/BlockCard/index.js +1 -0
- package/dist/cjs/view/BlockCard/views/flexible/FlexibleResolvedView.js +2 -0
- package/dist/cjs/view/CardWithUrl/component.js +24 -9
- package/dist/cjs/view/EmbedCard/components/ExpandedFrame.js +4 -1
- package/dist/cjs/view/EmbedModal/components/link-info/link-info-button/index.js +3 -0
- package/dist/cjs/view/FlexibleCard/components/blocks/title-block/index.js +3 -0
- package/dist/cjs/view/FlexibleCard/components/container/layered-link/index.js +3 -0
- package/dist/cjs/view/FlexibleCard/components/elements/link/index.js +3 -0
- package/dist/cjs/view/HoverCard/components/HoverCardContent.js +6 -1
- package/dist/cjs/view/InlineCard/Frame/index.js +4 -0
- package/dist/es2019/state/analytics/useMouseDownEvent.js +18 -0
- package/dist/es2019/utils/analytics/click.js +106 -0
- package/dist/es2019/utils/index.js +10 -0
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/BlockCard/components/ContentHeader.js +19 -14
- package/dist/es2019/view/BlockCard/index.js +1 -0
- package/dist/es2019/view/BlockCard/views/flexible/FlexibleResolvedView.js +2 -0
- package/dist/es2019/view/CardWithUrl/component.js +25 -9
- package/dist/es2019/view/EmbedCard/components/ExpandedFrame.js +4 -1
- package/dist/es2019/view/EmbedModal/components/link-info/link-info-button/index.js +3 -0
- package/dist/es2019/view/FlexibleCard/components/blocks/title-block/index.js +3 -0
- package/dist/es2019/view/FlexibleCard/components/container/layered-link/index.js +14 -9
- package/dist/es2019/view/FlexibleCard/components/elements/link/index.js +3 -0
- package/dist/es2019/view/HoverCard/components/HoverCardContent.js +7 -1
- package/dist/es2019/view/InlineCard/Frame/index.js +3 -0
- package/dist/esm/state/analytics/useMouseDownEvent.js +17 -0
- package/dist/esm/utils/analytics/click.js +109 -0
- package/dist/esm/utils/index.js +10 -0
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/BlockCard/components/ContentHeader.js +3 -0
- package/dist/esm/view/BlockCard/index.js +1 -0
- package/dist/esm/view/BlockCard/views/flexible/FlexibleResolvedView.js +2 -0
- package/dist/esm/view/CardWithUrl/component.js +24 -9
- package/dist/esm/view/EmbedCard/components/ExpandedFrame.js +4 -1
- package/dist/esm/view/EmbedModal/components/link-info/link-info-button/index.js +3 -0
- package/dist/esm/view/FlexibleCard/components/blocks/title-block/index.js +3 -0
- package/dist/esm/view/FlexibleCard/components/container/layered-link/index.js +3 -0
- package/dist/esm/view/FlexibleCard/components/elements/link/index.js +3 -0
- package/dist/esm/view/HoverCard/components/HoverCardContent.js +6 -1
- package/dist/esm/view/InlineCard/Frame/index.js +3 -0
- package/dist/types/state/analytics/useMouseDownEvent.d.ts +3 -0
- package/dist/types/utils/analytics/click.d.ts +21 -0
- package/dist/types/utils/analytics/types.d.ts +16 -0
- package/dist/types/utils/index.d.ts +9 -0
- package/dist/types/view/FlexibleCard/components/elements/link/types.d.ts +4 -0
- package/package.json +4 -2
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import { jsx } from '@emotion/react';
|
|
3
|
+
import useMouseDownEvent from '../../../state/analytics/useMouseDownEvent';
|
|
3
4
|
export const blockCardContentHeaderClassName = 'block-card-content-header';
|
|
4
5
|
export const ContentHeader = ({
|
|
5
6
|
onClick,
|
|
6
7
|
link,
|
|
7
8
|
children
|
|
8
|
-
}) =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
},
|
|
9
|
+
}) => {
|
|
10
|
+
const onMouseDown = useMouseDownEvent();
|
|
11
|
+
return jsx("a", {
|
|
12
|
+
onClick: onClick,
|
|
13
|
+
onMouseDown: onMouseDown,
|
|
14
|
+
href: link,
|
|
15
|
+
target: "_blank",
|
|
16
|
+
css: {
|
|
17
|
+
display: 'flex',
|
|
18
|
+
alignItems: 'flex-start',
|
|
19
|
+
// EDM-713: fixes copy-paste from renderer to editor for Firefox
|
|
20
|
+
// due to HTML its unwrapping behaviour on paste.
|
|
21
|
+
MozUserSelect: 'none'
|
|
22
|
+
},
|
|
23
|
+
"data-trello-do-not-use-override": "block-card-content-header",
|
|
24
|
+
className: blockCardContentHeaderClassName
|
|
25
|
+
}, children);
|
|
26
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useCallback, useMemo } from 'react';
|
|
2
|
+
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
2
3
|
import { useFeatureFlag } from '@atlaskit/link-provider';
|
|
3
4
|
import { isSpecialEvent } from '../../utils';
|
|
4
5
|
import * as measure from '../../utils/performance';
|
|
@@ -11,6 +12,7 @@ import { isFlexibleUiCard } from '../../utils/flexible';
|
|
|
11
12
|
import FlexibleCard from '../FlexibleCard';
|
|
12
13
|
import { APIError } from '../..';
|
|
13
14
|
import { CardDisplay } from '../../constants';
|
|
15
|
+
import { fireLinkClickedEvent } from '../../utils/analytics/click';
|
|
14
16
|
export function CardWithUrlContent({
|
|
15
17
|
id,
|
|
16
18
|
url,
|
|
@@ -33,6 +35,10 @@ export function CardWithUrlContent({
|
|
|
33
35
|
showAuthTooltip: showAuthTooltipProp,
|
|
34
36
|
analyticsEvents
|
|
35
37
|
}) {
|
|
38
|
+
const {
|
|
39
|
+
createAnalyticsEvent
|
|
40
|
+
} = useAnalyticsEvents();
|
|
41
|
+
|
|
36
42
|
// Get state, actions for this card.
|
|
37
43
|
const {
|
|
38
44
|
state,
|
|
@@ -55,10 +61,6 @@ export function CardWithUrlContent({
|
|
|
55
61
|
const enableFlexibleBlockCardFlag = Boolean(useFeatureFlag('enableFlexibleBlockCard'));
|
|
56
62
|
|
|
57
63
|
// Setup UI handlers.
|
|
58
|
-
const handleClick = useCallback(event => {
|
|
59
|
-
const clickUrl = getClickUrl(url, state.details);
|
|
60
|
-
isSpecialEvent(event) ? window.open(clickUrl, '_blank') : window.open(clickUrl, '_self');
|
|
61
|
-
}, [state.details, url]);
|
|
62
64
|
const handleClickWrapper = useCallback(event => {
|
|
63
65
|
const isModifierKeyPressed = isSpecialEvent(event);
|
|
64
66
|
analytics.ui.cardClickedEvent({
|
|
@@ -71,12 +73,26 @@ export function CardWithUrlContent({
|
|
|
71
73
|
destinationProduct: product,
|
|
72
74
|
destinationSubproduct: subproduct
|
|
73
75
|
});
|
|
74
|
-
if (onClick) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
if (!onClick && !isFlexibleUi) {
|
|
77
|
+
const clickUrl = getClickUrl(url, state.details);
|
|
78
|
+
// Ctrl+left click on mac typically doesn't trigger onClick
|
|
79
|
+
// The event could have potentially had `e.preventDefault()` called on it by now
|
|
80
|
+
// event by smart card internally
|
|
81
|
+
// If it has been called then only then can `isModifierKeyPressed` be true.
|
|
82
|
+
const target = isModifierKeyPressed ? '_blank' : '_self';
|
|
83
|
+
window.open(clickUrl, target);
|
|
84
|
+
fireLinkClickedEvent(createAnalyticsEvent)(event, {
|
|
85
|
+
attributes: {
|
|
86
|
+
clickOutcome: target === '_blank' ? 'clickThroughNewTabOrWindow' : 'clickThrough'
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
if (onClick) {
|
|
91
|
+
onClick(event);
|
|
92
|
+
}
|
|
93
|
+
fireLinkClickedEvent(createAnalyticsEvent)(event);
|
|
78
94
|
}
|
|
79
|
-
}, [id, state.status, analytics.ui, appearance, definitionId, extensionKey, onClick,
|
|
95
|
+
}, [id, url, state.details, state.status, analytics.ui, appearance, definitionId, extensionKey, onClick, isFlexibleUi, product, subproduct, createAnalyticsEvent]);
|
|
80
96
|
const handleAuthorize = useCallback(() => actions.authorize(appearance), [actions, appearance]);
|
|
81
97
|
const handleRetry = useCallback(() => {
|
|
82
98
|
actions.reload();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { className, LinkWrapper, Wrapper, Header, IconWrapper, TextWrapper, Content } from './styled';
|
|
3
3
|
import { handleClickCommon } from '../../BlockCard/utils/handlers';
|
|
4
|
+
import useMouseDownEvent from '../../../state/analytics/useMouseDownEvent';
|
|
4
5
|
export const ExpandedFrame = ({
|
|
5
6
|
isPlaceholder = false,
|
|
6
7
|
children,
|
|
@@ -19,6 +20,7 @@ export const ExpandedFrame = ({
|
|
|
19
20
|
}) => {
|
|
20
21
|
const isInteractive = () => !isPlaceholder && (Boolean(href) || Boolean(onClick));
|
|
21
22
|
const handleClick = event => handleClickCommon(event, onClick);
|
|
23
|
+
const handleMouseDown = useMouseDownEvent();
|
|
22
24
|
const renderHeader = () => /*#__PURE__*/React.createElement(Header, {
|
|
23
25
|
className: "embed-header"
|
|
24
26
|
}, /*#__PURE__*/React.createElement(IconWrapper, {
|
|
@@ -27,7 +29,8 @@ export const ExpandedFrame = ({
|
|
|
27
29
|
isPlaceholder: isPlaceholder
|
|
28
30
|
}, !isPlaceholder && /*#__PURE__*/React.createElement("a", {
|
|
29
31
|
href: href,
|
|
30
|
-
onClick: handleClick
|
|
32
|
+
onClick: handleClick,
|
|
33
|
+
onMouseDown: handleMouseDown
|
|
31
34
|
}, text)));
|
|
32
35
|
const renderContent = () => /*#__PURE__*/React.createElement(Content, {
|
|
33
36
|
"data-testid": "embed-content-wrapper",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import Tooltip from '@atlaskit/tooltip';
|
|
3
3
|
import Button from '@atlaskit/button/custom-theme-button';
|
|
4
|
+
import useMouseDownEvent from '../../../../../state/analytics/useMouseDownEvent';
|
|
4
5
|
const LinkInfoButton = ({
|
|
5
6
|
content,
|
|
6
7
|
href,
|
|
@@ -9,6 +10,7 @@ const LinkInfoButton = ({
|
|
|
9
10
|
target,
|
|
10
11
|
testId
|
|
11
12
|
}) => {
|
|
13
|
+
const onMouseDown = useMouseDownEvent();
|
|
12
14
|
return /*#__PURE__*/React.createElement(Tooltip, {
|
|
13
15
|
content: content,
|
|
14
16
|
hideTooltipOnClick: true,
|
|
@@ -20,6 +22,7 @@ const LinkInfoButton = ({
|
|
|
20
22
|
href: href,
|
|
21
23
|
iconBefore: icon,
|
|
22
24
|
onClick: onClick,
|
|
25
|
+
onMouseDown: onMouseDown,
|
|
23
26
|
spacing: "none",
|
|
24
27
|
target: target,
|
|
25
28
|
testId: `${testId}-button`
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
import React, { useCallback, useState } from 'react';
|
|
3
3
|
import { css } from '@emotion/react';
|
|
4
|
+
import useMouseDownEvent from '../../../../../state/analytics/useMouseDownEvent';
|
|
4
5
|
import { SmartLinkStatus } from '../../../../../constants';
|
|
5
6
|
import TitleBlockResolvedView from './resolved';
|
|
6
7
|
import TitleBlockErroredView from './errored';
|
|
@@ -90,10 +91,12 @@ const TitleBlock = ({
|
|
|
90
91
|
const overrideText = !!text ? {
|
|
91
92
|
text
|
|
92
93
|
} : {};
|
|
94
|
+
const onMouseDown = useMouseDownEvent();
|
|
93
95
|
const title = /*#__PURE__*/React.createElement(Title, _extends({
|
|
94
96
|
hideTooltip: hideTitleTooltip,
|
|
95
97
|
maxLines: maxLines,
|
|
96
98
|
onClick: onClick,
|
|
99
|
+
onMouseDown: onMouseDown,
|
|
97
100
|
target: anchorTarget,
|
|
98
101
|
theme: theme
|
|
99
102
|
}, overrideText));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { jsx, css } from '@emotion/react';
|
|
4
|
+
import useMouseDownEvent from '../../../../../state/analytics/useMouseDownEvent';
|
|
4
5
|
const styles = css`
|
|
5
6
|
// Stretch the invisible link over the whole of the post.
|
|
6
7
|
// Hide the link’s text.
|
|
@@ -47,13 +48,17 @@ const LayeredLink = ({
|
|
|
47
48
|
testId,
|
|
48
49
|
text,
|
|
49
50
|
url
|
|
50
|
-
}) =>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
}) => {
|
|
52
|
+
const onMouseDown = useMouseDownEvent();
|
|
53
|
+
return jsx("a", {
|
|
54
|
+
className: "layered-link",
|
|
55
|
+
css: styles,
|
|
56
|
+
"data-testid": `${testId}-layered-link`,
|
|
57
|
+
href: url,
|
|
58
|
+
onClick: onClick,
|
|
59
|
+
onMouseDown: onMouseDown,
|
|
60
|
+
target: target,
|
|
61
|
+
tabIndex: -1 // Hide tab index and let the title link be the link.
|
|
62
|
+
}, text);
|
|
63
|
+
};
|
|
59
64
|
export default LayeredLink;
|
|
@@ -5,6 +5,7 @@ import Tooltip from '@atlaskit/tooltip';
|
|
|
5
5
|
import { SmartLinkSize, SmartLinkTheme } from '../../../../../constants';
|
|
6
6
|
import { getLinkLineHeight, getLinkSizeStyles, getTruncateStyles, hasWhiteSpace } from '../../utils';
|
|
7
7
|
import { tokens } from '../../../../../utils/token';
|
|
8
|
+
import useMouseDownEvent from '../../../../../state/analytics/useMouseDownEvent';
|
|
8
9
|
const DEFAULT_MAX_LINES = 2;
|
|
9
10
|
const MAXIMUM_MAX_LINES = 2;
|
|
10
11
|
const MINIMUM_MAX_LINES = 1;
|
|
@@ -83,6 +84,7 @@ const Link = ({
|
|
|
83
84
|
onClick,
|
|
84
85
|
target
|
|
85
86
|
}) => {
|
|
87
|
+
const onMouseDown = useMouseDownEvent();
|
|
86
88
|
const hasSpace = useMemo(() => text ? hasWhiteSpace(text) : false, [text]);
|
|
87
89
|
const anchor = jsx("a", {
|
|
88
90
|
css: [getAnchorStyles(size, theme, getMaxLines(maxLines), hasSpace), overrideCss],
|
|
@@ -90,6 +92,7 @@ const Link = ({
|
|
|
90
92
|
"data-smart-element-link": true,
|
|
91
93
|
"data-testid": testId,
|
|
92
94
|
onClick: onClick,
|
|
95
|
+
onMouseDown: onMouseDown,
|
|
93
96
|
href: url,
|
|
94
97
|
target: target || '_blank'
|
|
95
98
|
}, text);
|
|
@@ -3,6 +3,7 @@ import { jsx } from '@emotion/react';
|
|
|
3
3
|
import ShortcutIcon from '@atlaskit/icon/glyph/shortcut';
|
|
4
4
|
import CopyIcon from '@atlaskit/icon/glyph/copy';
|
|
5
5
|
import { extractType } from '@atlaskit/linking-common/extractors';
|
|
6
|
+
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
6
7
|
import React, { useCallback, useEffect, useMemo } from 'react';
|
|
7
8
|
import { ActionName, CardDisplay, SmartLinkPosition, SmartLinkSize } from '../../../constants';
|
|
8
9
|
import { extractMetadata } from '../../../extractors/hover/extractMetadata';
|
|
@@ -16,6 +17,7 @@ import HoverCardResolvedView from './views/resolved';
|
|
|
16
17
|
import { FormattedMessage } from 'react-intl-next';
|
|
17
18
|
import { messages } from '../../../messages';
|
|
18
19
|
import { useSmartCardActions } from '../../../state/actions';
|
|
20
|
+
import { fireLinkClickedEvent } from '../../../utils/analytics/click';
|
|
19
21
|
export const hoverCardClassName = 'smart-links-hover-preview';
|
|
20
22
|
export const getOpenAction = (url, analytics, onActionClick) => ({
|
|
21
23
|
name: ActionName.CustomAction,
|
|
@@ -60,6 +62,9 @@ const HoverCardContent = ({
|
|
|
60
62
|
onMouseLeave
|
|
61
63
|
}) => {
|
|
62
64
|
var _cardState$details;
|
|
65
|
+
const {
|
|
66
|
+
createAnalyticsEvent
|
|
67
|
+
} = useAnalyticsEvents();
|
|
63
68
|
const extensionKey = useMemo(() => getExtensionKey(cardState.details), [cardState.details]);
|
|
64
69
|
const actions = useSmartCardActions(id, url, analytics);
|
|
65
70
|
useEffect(() => {
|
|
@@ -74,7 +79,8 @@ const HoverCardContent = ({
|
|
|
74
79
|
isModifierKeyPressed,
|
|
75
80
|
actionSubjectId: 'titleGoToLink'
|
|
76
81
|
});
|
|
77
|
-
|
|
82
|
+
fireLinkClickedEvent(createAnalyticsEvent)(event);
|
|
83
|
+
}, [createAnalyticsEvent, cardState.status, analytics.ui, id]);
|
|
78
84
|
const titleActions = useMemo(() => [getCopyAction(url), getOpenAction(url, analytics, onActionClick)], [url, analytics, onActionClick]);
|
|
79
85
|
const data = (_cardState$details = cardState.details) === null || _cardState$details === void 0 ? void 0 : _cardState$details.data;
|
|
80
86
|
const types = data ? extractType(data) : undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
2
|
import { useGlobalTheme } from '@atlaskit/theme/components';
|
|
3
3
|
import { WrapperAnchor, WrapperSpan } from './styled';
|
|
4
|
+
import useMouseDownEvent from '../../../state/analytics/useMouseDownEvent';
|
|
4
5
|
export const Frame = props => {
|
|
5
6
|
const {
|
|
6
7
|
isSelected,
|
|
@@ -28,6 +29,7 @@ export const Frame = props => {
|
|
|
28
29
|
onClick(event);
|
|
29
30
|
}
|
|
30
31
|
}, [onClick]);
|
|
32
|
+
const handleMouseDown = useMouseDownEvent();
|
|
31
33
|
const isInteractive = Boolean(onClick);
|
|
32
34
|
|
|
33
35
|
// Depending on whenever Frame was given onClick or link itself we display span or anchor elements
|
|
@@ -44,6 +46,7 @@ export const Frame = props => {
|
|
|
44
46
|
tabIndex: isInteractive ? 0 : undefined,
|
|
45
47
|
role: isInteractive ? 'button' : undefined,
|
|
46
48
|
onClick: handleClick,
|
|
49
|
+
onMouseDown: handleMouseDown,
|
|
47
50
|
onKeyPress: handleKeyPress,
|
|
48
51
|
"data-testid": testId,
|
|
49
52
|
className: className
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
3
|
+
import { fireLinkClickedEvent } from '../../utils/analytics/click';
|
|
4
|
+
var useMouseDownEvent = function useMouseDownEvent(onMouseDown) {
|
|
5
|
+
var _useAnalyticsEvents = useAnalyticsEvents(),
|
|
6
|
+
createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
|
|
7
|
+
return useCallback(function (event) {
|
|
8
|
+
onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(event);
|
|
9
|
+
|
|
10
|
+
// ignore left clicks
|
|
11
|
+
// these would be handled by `onClick` handler instead
|
|
12
|
+
if (event.button !== 0) {
|
|
13
|
+
fireLinkClickedEvent(createAnalyticsEvent)(event);
|
|
14
|
+
}
|
|
15
|
+
}, [onMouseDown, createAnalyticsEvent]);
|
|
16
|
+
};
|
|
17
|
+
export default useMouseDownEvent;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
3
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
4
|
+
import { browser } from '@atlaskit/linking-common/user-agent';
|
|
5
|
+
import { ANALYTICS_CHANNEL } from './analytics';
|
|
6
|
+
export var buttonMap = new Map([[undefined, 'none'], [0, 'left'], [1, 'middle'], [2, 'right']]);
|
|
7
|
+
export var getKeys = function getKeys(e) {
|
|
8
|
+
return ['alt', 'ctrl', 'meta', 'shift'].filter(function (key) {
|
|
9
|
+
return e["".concat(key, "Key")] === true;
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var isContentEditable = function isContentEditable(el) {
|
|
13
|
+
return el instanceof HTMLElement && el.isContentEditable;
|
|
14
|
+
};
|
|
15
|
+
export function getLinkClickOutcome(e, clickType) {
|
|
16
|
+
var _browser = browser(),
|
|
17
|
+
mac = _browser.mac,
|
|
18
|
+
safari = _browser.safari;
|
|
19
|
+
if (e.defaultPrevented) {
|
|
20
|
+
return 'prevented';
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* If the link/parent is content editable then left click won't have typical effect
|
|
24
|
+
*/
|
|
25
|
+
if (isContentEditable(e.currentTarget) && ['left', 'middle'].includes(clickType)) {
|
|
26
|
+
return 'contentEditable';
|
|
27
|
+
}
|
|
28
|
+
switch (clickType) {
|
|
29
|
+
case 'left':
|
|
30
|
+
{
|
|
31
|
+
// Meta key = Cmd for macOS, Windows key sometimes for Windows (otherwise false)
|
|
32
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/metaKey
|
|
33
|
+
if (e.metaKey) {
|
|
34
|
+
return mac ? 'clickThroughNewTabOrWindow' : 'clickThrough';
|
|
35
|
+
}
|
|
36
|
+
if (e.shiftKey) {
|
|
37
|
+
// Alt/option click in safari typically adds the link to bookmarks
|
|
38
|
+
if (safari) {
|
|
39
|
+
return 'alt';
|
|
40
|
+
}
|
|
41
|
+
return 'clickThroughNewTabOrWindow';
|
|
42
|
+
}
|
|
43
|
+
if (e.ctrlKey) {
|
|
44
|
+
// Ctrl+Left on macOS defaults to triggering a right click instead (so won't trigger onClick)
|
|
45
|
+
// but if this behaviour is disabled, likely outcome is clickThrough
|
|
46
|
+
if (mac) {
|
|
47
|
+
return 'clickThrough';
|
|
48
|
+
}
|
|
49
|
+
return 'clickThroughNewTabOrWindow';
|
|
50
|
+
}
|
|
51
|
+
if (e.altKey) {
|
|
52
|
+
return 'alt';
|
|
53
|
+
}
|
|
54
|
+
var target = e.currentTarget.getAttribute('target');
|
|
55
|
+
if (target === '_blank') {
|
|
56
|
+
return 'clickThroughNewTabOrWindow';
|
|
57
|
+
}
|
|
58
|
+
return 'clickThrough';
|
|
59
|
+
}
|
|
60
|
+
case 'middle':
|
|
61
|
+
{
|
|
62
|
+
return 'clickThroughNewTabOrWindow';
|
|
63
|
+
}
|
|
64
|
+
case 'right':
|
|
65
|
+
{
|
|
66
|
+
return 'contextMenu';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return '_unknown';
|
|
70
|
+
}
|
|
71
|
+
var linkClickedEvent = function linkClickedEvent(_ref) {
|
|
72
|
+
var clickType = _ref.clickType,
|
|
73
|
+
clickOutcome = _ref.clickOutcome,
|
|
74
|
+
keysHeld = _ref.keysHeld;
|
|
75
|
+
return {
|
|
76
|
+
action: 'clicked',
|
|
77
|
+
actionSubject: 'link',
|
|
78
|
+
eventType: 'ui',
|
|
79
|
+
attributes: {
|
|
80
|
+
clickType: clickType,
|
|
81
|
+
clickOutcome: clickOutcome,
|
|
82
|
+
keysHeld: keysHeld
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
export var createLinkClickedPayload = function createLinkClickedPayload(event) {
|
|
87
|
+
var clickType = buttonMap.get(event.button);
|
|
88
|
+
if (!clickType) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
var clickOutcome = getLinkClickOutcome(event, clickType);
|
|
92
|
+
var keysHeld = getKeys(event);
|
|
93
|
+
return linkClickedEvent({
|
|
94
|
+
clickType: clickType,
|
|
95
|
+
clickOutcome: clickOutcome,
|
|
96
|
+
keysHeld: keysHeld
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
export var fireLinkClickedEvent = function fireLinkClickedEvent(createAnalyticsEvent) {
|
|
100
|
+
return function (event) {
|
|
101
|
+
var overrides = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
102
|
+
var payload = createLinkClickedPayload(event);
|
|
103
|
+
if (payload) {
|
|
104
|
+
createAnalyticsEvent(_objectSpread(_objectSpread(_objectSpread({}, payload), overrides), {}, {
|
|
105
|
+
attributes: _objectSpread(_objectSpread({}, payload.attributes), overrides === null || overrides === void 0 ? void 0 : overrides.attributes)
|
|
106
|
+
})).fire(ANALYTICS_CHANNEL);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
};
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -12,6 +12,16 @@ export var isSpecialEvent = function isSpecialEvent(evt) {
|
|
|
12
12
|
export var isIframe = function isIframe() {
|
|
13
13
|
return window.parent !== parent;
|
|
14
14
|
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Meta key = cmd on mac, windows key on windows
|
|
18
|
+
* Ctrl key on mac by default triggers a right click instead of left click
|
|
19
|
+
* Ctrl key on Windows has the same behaviour of cmd key of mac (open in new tab)
|
|
20
|
+
*
|
|
21
|
+
* `isSpecialKey` on a mouse event on mac with default behaviour should be equivalent to opening in new tab
|
|
22
|
+
* On Windows it will be equivalent to opening a new tab, unless its the Window key that is held
|
|
23
|
+
* in which case typically only a standard clickthrough will occur, this is likely a small portion of events
|
|
24
|
+
*/
|
|
15
25
|
export var isSpecialKey = function isSpecialKey(event) {
|
|
16
26
|
return event.metaKey || event.ctrlKey;
|
|
17
27
|
};
|
package/dist/esm/version.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import { jsx } from '@emotion/react';
|
|
3
|
+
import useMouseDownEvent from '../../../state/analytics/useMouseDownEvent';
|
|
3
4
|
export var blockCardContentHeaderClassName = 'block-card-content-header';
|
|
4
5
|
export var ContentHeader = function ContentHeader(_ref) {
|
|
5
6
|
var onClick = _ref.onClick,
|
|
6
7
|
link = _ref.link,
|
|
7
8
|
children = _ref.children;
|
|
9
|
+
var onMouseDown = useMouseDownEvent();
|
|
8
10
|
return jsx("a", {
|
|
9
11
|
onClick: onClick,
|
|
12
|
+
onMouseDown: onMouseDown,
|
|
10
13
|
href: link,
|
|
11
14
|
target: "_blank",
|
|
12
15
|
css: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useCallback, useMemo } from 'react';
|
|
2
|
+
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
2
3
|
import { useFeatureFlag } from '@atlaskit/link-provider';
|
|
3
4
|
import { isSpecialEvent } from '../../utils';
|
|
4
5
|
import * as measure from '../../utils/performance';
|
|
@@ -11,6 +12,7 @@ import { isFlexibleUiCard } from '../../utils/flexible';
|
|
|
11
12
|
import FlexibleCard from '../FlexibleCard';
|
|
12
13
|
import { APIError } from '../..';
|
|
13
14
|
import { CardDisplay } from '../../constants';
|
|
15
|
+
import { fireLinkClickedEvent } from '../../utils/analytics/click';
|
|
14
16
|
export function CardWithUrlContent(_ref) {
|
|
15
17
|
var id = _ref.id,
|
|
16
18
|
url = _ref.url,
|
|
@@ -32,6 +34,9 @@ export function CardWithUrlContent(_ref) {
|
|
|
32
34
|
showHoverPreview = _ref.showHoverPreview,
|
|
33
35
|
showAuthTooltipProp = _ref.showAuthTooltip,
|
|
34
36
|
analyticsEvents = _ref.analyticsEvents;
|
|
37
|
+
var _useAnalyticsEvents = useAnalyticsEvents(),
|
|
38
|
+
createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
|
|
39
|
+
|
|
35
40
|
// Get state, actions for this card.
|
|
36
41
|
var _useSmartLink = useSmartLink(id, url, dispatchAnalytics),
|
|
37
42
|
state = _useSmartLink.state,
|
|
@@ -55,10 +60,6 @@ export function CardWithUrlContent(_ref) {
|
|
|
55
60
|
var enableFlexibleBlockCardFlag = Boolean(useFeatureFlag('enableFlexibleBlockCard'));
|
|
56
61
|
|
|
57
62
|
// Setup UI handlers.
|
|
58
|
-
var handleClick = useCallback(function (event) {
|
|
59
|
-
var clickUrl = getClickUrl(url, state.details);
|
|
60
|
-
isSpecialEvent(event) ? window.open(clickUrl, '_blank') : window.open(clickUrl, '_self');
|
|
61
|
-
}, [state.details, url]);
|
|
62
63
|
var handleClickWrapper = useCallback(function (event) {
|
|
63
64
|
var isModifierKeyPressed = isSpecialEvent(event);
|
|
64
65
|
analytics.ui.cardClickedEvent({
|
|
@@ -71,12 +72,26 @@ export function CardWithUrlContent(_ref) {
|
|
|
71
72
|
destinationProduct: product,
|
|
72
73
|
destinationSubproduct: subproduct
|
|
73
74
|
});
|
|
74
|
-
if (onClick) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
if (!onClick && !isFlexibleUi) {
|
|
76
|
+
var clickUrl = getClickUrl(url, state.details);
|
|
77
|
+
// Ctrl+left click on mac typically doesn't trigger onClick
|
|
78
|
+
// The event could have potentially had `e.preventDefault()` called on it by now
|
|
79
|
+
// event by smart card internally
|
|
80
|
+
// If it has been called then only then can `isModifierKeyPressed` be true.
|
|
81
|
+
var target = isModifierKeyPressed ? '_blank' : '_self';
|
|
82
|
+
window.open(clickUrl, target);
|
|
83
|
+
fireLinkClickedEvent(createAnalyticsEvent)(event, {
|
|
84
|
+
attributes: {
|
|
85
|
+
clickOutcome: target === '_blank' ? 'clickThroughNewTabOrWindow' : 'clickThrough'
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
} else {
|
|
89
|
+
if (onClick) {
|
|
90
|
+
onClick(event);
|
|
91
|
+
}
|
|
92
|
+
fireLinkClickedEvent(createAnalyticsEvent)(event);
|
|
78
93
|
}
|
|
79
|
-
}, [id, state.status, analytics.ui, appearance, definitionId, extensionKey, onClick,
|
|
94
|
+
}, [id, url, state.details, state.status, analytics.ui, appearance, definitionId, extensionKey, onClick, isFlexibleUi, product, subproduct, createAnalyticsEvent]);
|
|
80
95
|
var handleAuthorize = useCallback(function () {
|
|
81
96
|
return actions.authorize(appearance);
|
|
82
97
|
}, [actions, appearance]);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { className, LinkWrapper, Wrapper, Header, IconWrapper, TextWrapper, Content } from './styled';
|
|
3
3
|
import { handleClickCommon } from '../../BlockCard/utils/handlers';
|
|
4
|
+
import useMouseDownEvent from '../../../state/analytics/useMouseDownEvent';
|
|
4
5
|
export var ExpandedFrame = function ExpandedFrame(_ref) {
|
|
5
6
|
var _ref$isPlaceholder = _ref.isPlaceholder,
|
|
6
7
|
isPlaceholder = _ref$isPlaceholder === void 0 ? false : _ref$isPlaceholder,
|
|
@@ -25,6 +26,7 @@ export var ExpandedFrame = function ExpandedFrame(_ref) {
|
|
|
25
26
|
var handleClick = function handleClick(event) {
|
|
26
27
|
return handleClickCommon(event, onClick);
|
|
27
28
|
};
|
|
29
|
+
var handleMouseDown = useMouseDownEvent();
|
|
28
30
|
var renderHeader = function renderHeader() {
|
|
29
31
|
return /*#__PURE__*/React.createElement(Header, {
|
|
30
32
|
className: "embed-header"
|
|
@@ -34,7 +36,8 @@ export var ExpandedFrame = function ExpandedFrame(_ref) {
|
|
|
34
36
|
isPlaceholder: isPlaceholder
|
|
35
37
|
}, !isPlaceholder && /*#__PURE__*/React.createElement("a", {
|
|
36
38
|
href: href,
|
|
37
|
-
onClick: handleClick
|
|
39
|
+
onClick: handleClick,
|
|
40
|
+
onMouseDown: handleMouseDown
|
|
38
41
|
}, text)));
|
|
39
42
|
};
|
|
40
43
|
var renderContent = function renderContent() {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import Tooltip from '@atlaskit/tooltip';
|
|
3
3
|
import Button from '@atlaskit/button/custom-theme-button';
|
|
4
|
+
import useMouseDownEvent from '../../../../../state/analytics/useMouseDownEvent';
|
|
4
5
|
var LinkInfoButton = function LinkInfoButton(_ref) {
|
|
5
6
|
var content = _ref.content,
|
|
6
7
|
href = _ref.href,
|
|
@@ -8,6 +9,7 @@ var LinkInfoButton = function LinkInfoButton(_ref) {
|
|
|
8
9
|
onClick = _ref.onClick,
|
|
9
10
|
target = _ref.target,
|
|
10
11
|
testId = _ref.testId;
|
|
12
|
+
var onMouseDown = useMouseDownEvent();
|
|
11
13
|
return /*#__PURE__*/React.createElement(Tooltip, {
|
|
12
14
|
content: content,
|
|
13
15
|
hideTooltipOnClick: true,
|
|
@@ -19,6 +21,7 @@ var LinkInfoButton = function LinkInfoButton(_ref) {
|
|
|
19
21
|
href: href,
|
|
20
22
|
iconBefore: icon,
|
|
21
23
|
onClick: onClick,
|
|
24
|
+
onMouseDown: onMouseDown,
|
|
22
25
|
spacing: "none",
|
|
23
26
|
target: target,
|
|
24
27
|
testId: "".concat(testId, "-button")
|
|
@@ -6,6 +6,7 @@ var _excluded = ["actions", "anchorTarget", "hideTitleTooltip", "maxLines", "onA
|
|
|
6
6
|
var _templateObject, _templateObject2;
|
|
7
7
|
import React, { useCallback, useState } from 'react';
|
|
8
8
|
import { css } from '@emotion/react';
|
|
9
|
+
import useMouseDownEvent from '../../../../../state/analytics/useMouseDownEvent';
|
|
9
10
|
import { SmartLinkStatus } from '../../../../../constants';
|
|
10
11
|
import TitleBlockResolvedView from './resolved';
|
|
11
12
|
import TitleBlockErroredView from './errored';
|
|
@@ -89,10 +90,12 @@ var TitleBlock = function TitleBlock(_ref) {
|
|
|
89
90
|
var overrideText = !!text ? {
|
|
90
91
|
text: text
|
|
91
92
|
} : {};
|
|
93
|
+
var onMouseDown = useMouseDownEvent();
|
|
92
94
|
var title = /*#__PURE__*/React.createElement(Title, _extends({
|
|
93
95
|
hideTooltip: hideTitleTooltip,
|
|
94
96
|
maxLines: maxLines,
|
|
95
97
|
onClick: onClick,
|
|
98
|
+
onMouseDown: onMouseDown,
|
|
96
99
|
target: anchorTarget,
|
|
97
100
|
theme: theme
|
|
98
101
|
}, overrideText));
|