@atlaskit/smart-card 23.4.8 → 23.5.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.
- package/CHANGELOG.md +17 -0
- package/dist/cjs/constants.js +10 -2
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/state/flexible-ui-context/utils.js +16 -0
- package/dist/cjs/utils/flexible.js +8 -2
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/BlockCard/components/flexible/footer/index.js +2 -2
- package/dist/cjs/view/BlockCard/index.js +83 -12
- package/dist/cjs/view/BlockCard/views/flexible/FlexibleResolvedView.js +108 -0
- package/dist/cjs/view/BlockCard/views/flexible/FlexibleUnauthorisedView.js +1 -1
- package/dist/cjs/view/CardWithUrl/component.js +4 -2
- package/dist/cjs/view/FlexibleCard/components/blocks/preview-block/index.js +6 -9
- package/dist/cjs/view/FlexibleCard/components/blocks/preview-block/resolved/index.js +109 -0
- package/dist/cjs/view/FlexibleCard/components/common/image-icon/index.js +4 -2
- package/dist/cjs/view/FlexibleCard/components/container/index.js +40 -4
- package/dist/cjs/view/FlexibleCard/components/elements/lozenge/index.js +12 -4
- package/dist/cjs/view/FlexibleCard/components/elements/media/index.js +2 -0
- package/dist/cjs/view/HoverCard/components/HoverCardContent.js +18 -6
- package/dist/cjs/view/HoverCard/utils.js +41 -2
- package/dist/es2019/constants.js +8 -1
- package/dist/es2019/index.js +1 -1
- package/dist/es2019/state/flexible-ui-context/utils.js +5 -0
- package/dist/es2019/utils/flexible.js +3 -2
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/BlockCard/components/flexible/footer/index.js +2 -2
- package/dist/es2019/view/BlockCard/index.js +80 -13
- package/dist/es2019/view/BlockCard/views/flexible/FlexibleErroredView.js +2 -2
- package/dist/es2019/view/BlockCard/views/flexible/FlexibleForbiddenView.js +2 -2
- package/dist/es2019/view/BlockCard/views/flexible/FlexibleNotFoundView.js +2 -2
- package/dist/es2019/view/BlockCard/views/flexible/FlexibleResolvedView.js +81 -0
- package/dist/es2019/view/BlockCard/views/flexible/FlexibleUnauthorisedView.js +3 -3
- package/dist/es2019/view/CardWithUrl/component.js +4 -2
- package/dist/es2019/view/FlexibleCard/components/blocks/preview-block/index.js +6 -7
- package/dist/es2019/view/FlexibleCard/components/blocks/preview-block/resolved/index.js +103 -0
- package/dist/es2019/view/FlexibleCard/components/common/image-icon/index.js +4 -2
- package/dist/es2019/view/FlexibleCard/components/container/index.js +73 -21
- package/dist/es2019/view/FlexibleCard/components/elements/lozenge/index.js +22 -3
- package/dist/es2019/view/FlexibleCard/components/elements/media/index.js +2 -0
- package/dist/es2019/view/HoverCard/components/HoverCardContent.js +14 -4
- package/dist/es2019/view/HoverCard/utils.js +20 -0
- package/dist/esm/constants.js +8 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/state/flexible-ui-context/utils.js +7 -0
- package/dist/esm/utils/flexible.js +4 -1
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/BlockCard/components/flexible/footer/index.js +2 -2
- package/dist/esm/view/BlockCard/index.js +77 -12
- package/dist/esm/view/BlockCard/views/flexible/FlexibleErroredView.js +2 -2
- package/dist/esm/view/BlockCard/views/flexible/FlexibleForbiddenView.js +2 -2
- package/dist/esm/view/BlockCard/views/flexible/FlexibleNotFoundView.js +2 -2
- package/dist/esm/view/BlockCard/views/flexible/FlexibleResolvedView.js +87 -0
- package/dist/esm/view/BlockCard/views/flexible/FlexibleUnauthorisedView.js +3 -3
- package/dist/esm/view/CardWithUrl/component.js +4 -2
- package/dist/esm/view/FlexibleCard/components/blocks/preview-block/index.js +7 -8
- package/dist/esm/view/FlexibleCard/components/blocks/preview-block/resolved/index.js +86 -0
- package/dist/esm/view/FlexibleCard/components/common/image-icon/index.js +4 -2
- package/dist/esm/view/FlexibleCard/components/container/index.js +42 -6
- package/dist/esm/view/FlexibleCard/components/elements/lozenge/index.js +11 -4
- package/dist/esm/view/FlexibleCard/components/elements/media/index.js +2 -0
- package/dist/esm/view/HoverCard/components/HoverCardContent.js +17 -6
- package/dist/esm/view/HoverCard/utils.js +34 -0
- package/dist/types/constants.d.ts +4 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/state/flexible-ui-context/utils.d.ts +6 -0
- package/dist/types/utils/flexible.d.ts +1 -0
- package/dist/types/view/BlockCard/components/flexible/footer/index.d.ts +2 -2
- package/dist/types/view/BlockCard/index.d.ts +1 -0
- package/dist/types/view/BlockCard/types.d.ts +1 -0
- package/dist/types/view/BlockCard/views/flexible/FlexibleResolvedView.d.ts +9 -0
- package/dist/types/view/BlockCard/views/flexible/FlexibleUnauthorisedView.d.ts +1 -1
- package/dist/types/view/FlexibleCard/components/blocks/preview-block/index.d.ts +1 -0
- package/dist/types/view/FlexibleCard/components/blocks/preview-block/resolved/index.d.ts +11 -0
- package/dist/types/view/FlexibleCard/components/blocks/preview-block/types.d.ts +15 -0
- package/dist/types/view/FlexibleCard/components/common/image-icon/types.d.ts +1 -0
- package/dist/types/view/FlexibleCard/components/container/index.d.ts +2 -2
- package/dist/types/view/FlexibleCard/components/container/types.d.ts +4 -0
- package/dist/types/view/FlexibleCard/components/elements/lozenge/types.d.ts +5 -0
- package/dist/types/view/FlexibleCard/components/elements/media/types.d.ts +1 -0
- package/dist/types/view/HoverCard/utils.d.ts +3 -0
- package/package.json +2 -2
- package/report.api.md +10 -0
- package/tmp/api-report-tmp.d.ts +10 -0
|
@@ -52,8 +52,9 @@ export function CardWithUrlContent({
|
|
|
52
52
|
|
|
53
53
|
if (showHoverPreview === undefined && showHoverPreviewFlag !== undefined) {
|
|
54
54
|
showHoverPreview = Boolean(showHoverPreviewFlag);
|
|
55
|
-
}
|
|
55
|
+
}
|
|
56
56
|
|
|
57
|
+
const enableFlexibleBlockCardFlag = Boolean(useFeatureFlag('enableFlexibleBlockCard')); // Setup UI handlers.
|
|
57
58
|
|
|
58
59
|
const handleClick = useCallback(event => {
|
|
59
60
|
const clickUrl = getClickUrl(url, state.details);
|
|
@@ -182,7 +183,8 @@ export function CardWithUrlContent({
|
|
|
182
183
|
onError: onError,
|
|
183
184
|
testId: testId,
|
|
184
185
|
showActions: showActions,
|
|
185
|
-
platform: platform
|
|
186
|
+
platform: platform,
|
|
187
|
+
enableFlexibleBlockCard: enableFlexibleBlockCardFlag
|
|
186
188
|
});
|
|
187
189
|
|
|
188
190
|
case 'embed':
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
|
|
3
|
+
/** @jsx jsx */
|
|
2
4
|
import React from 'react';
|
|
5
|
+
import { jsx } from '@emotion/react';
|
|
3
6
|
import { SmartLinkStatus } from '../../../../../constants';
|
|
4
|
-
import
|
|
5
|
-
import { Preview } from '../../elements';
|
|
7
|
+
import PreviewBlockResolvedView from './resolved';
|
|
6
8
|
/**
|
|
7
9
|
* Represents a PreviewBlock, which typically contains media or other large format content.
|
|
8
10
|
* @public
|
|
@@ -13,17 +15,14 @@ import { Preview } from '../../elements';
|
|
|
13
15
|
const PreviewBlock = ({
|
|
14
16
|
status = SmartLinkStatus.Fallback,
|
|
15
17
|
testId = 'smart-block-preview',
|
|
16
|
-
onError,
|
|
17
18
|
...blockProps
|
|
18
19
|
}) => {
|
|
19
20
|
if (status !== SmartLinkStatus.Resolved) {
|
|
20
21
|
return null;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
return
|
|
24
|
-
testId:
|
|
25
|
-
}), /*#__PURE__*/React.createElement(Preview, {
|
|
26
|
-
onError: onError
|
|
24
|
+
return jsx(PreviewBlockResolvedView, _extends({}, blockProps, {
|
|
25
|
+
testId: testId
|
|
27
26
|
}));
|
|
28
27
|
};
|
|
29
28
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
|
|
3
|
+
/** @jsx jsx */
|
|
4
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
5
|
+
import { css, jsx } from '@emotion/react';
|
|
6
|
+
import { MediaPlacement } from '../../../../../../constants';
|
|
7
|
+
import Block from '../../block';
|
|
8
|
+
import { Preview } from '../../../elements';
|
|
9
|
+
/**
|
|
10
|
+
* Due to its placement on the left/right and ignoreContainerPadding prop
|
|
11
|
+
* rely on its parent container styling, css variables are declared in
|
|
12
|
+
* <Container /> to preset the base values for the preview block styling.
|
|
13
|
+
*
|
|
14
|
+
* `--container-padding` is the padding of the Container. This value is based
|
|
15
|
+
* on size and hidePadding.
|
|
16
|
+
* `--container-gap-left` and `--container-gap-right` are the gap or padding of
|
|
17
|
+
* the Container depending on whether the container has other preview blocks
|
|
18
|
+
* with left/right positioning.
|
|
19
|
+
* `--preview-block-width` is the size of the preview image in relation to
|
|
20
|
+
* the Container width when the placement is left/right.
|
|
21
|
+
* @param placement
|
|
22
|
+
* @param ignoreContainerPadding
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const getPreviewBlockStyles = (placement, ignoreContainerPadding) => {
|
|
26
|
+
if (placement === MediaPlacement.Left || placement === MediaPlacement.Right) {
|
|
27
|
+
const containerPadding = ignoreContainerPadding ? '0rem' : 'var(--container-padding)';
|
|
28
|
+
return css`
|
|
29
|
+
position: absolute;
|
|
30
|
+
top: ${containerPadding};
|
|
31
|
+
bottom: ${containerPadding};
|
|
32
|
+
width: calc(var(--preview-block-width) - ${containerPadding});
|
|
33
|
+
|
|
34
|
+
${placement === MediaPlacement.Left ? `left: ${containerPadding};` : ''}
|
|
35
|
+
${placement === MediaPlacement.Right ? `right: ${containerPadding};` : ''}
|
|
36
|
+
|
|
37
|
+
[data-smart-element-media='image'] {
|
|
38
|
+
aspect-ratio: unset;
|
|
39
|
+
padding-top: unset;
|
|
40
|
+
width: 100%;
|
|
41
|
+
height: 100%;
|
|
42
|
+
object-fit: cover;
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (ignoreContainerPadding) {
|
|
48
|
+
return css`
|
|
49
|
+
margin-left: calc(var(--container-gap-left) * -1);
|
|
50
|
+
margin-right: calc(var(--container-gap-right) * -1);
|
|
51
|
+
&:first-of-type {
|
|
52
|
+
margin-top: calc(var(--container-padding) * -1);
|
|
53
|
+
}
|
|
54
|
+
&:last-of-type {
|
|
55
|
+
margin-bottom: calc(var(--container-padding) * -1);
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Represents a resolved PreviewBlock, which typically contains media or other large format content.
|
|
62
|
+
* @public
|
|
63
|
+
* @param {PreviewBlock} PreviewBlock
|
|
64
|
+
* @see Block
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
const PreviewBlockResolvedView = ({
|
|
69
|
+
ignoreContainerPadding = false,
|
|
70
|
+
onError,
|
|
71
|
+
overrideCss,
|
|
72
|
+
placement,
|
|
73
|
+
testId,
|
|
74
|
+
...blockProps
|
|
75
|
+
}) => {
|
|
76
|
+
const [styles, setStyles] = useState(overrideCss);
|
|
77
|
+
const updateStyles = useCallback(() => {
|
|
78
|
+
setStyles(css`
|
|
79
|
+
${getPreviewBlockStyles(placement, ignoreContainerPadding)}
|
|
80
|
+
${overrideCss}
|
|
81
|
+
`);
|
|
82
|
+
}, [ignoreContainerPadding, overrideCss, placement]);
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
updateStyles();
|
|
85
|
+
}, [ignoreContainerPadding, overrideCss, placement, updateStyles]);
|
|
86
|
+
const handleOnLoad = useCallback(() => {
|
|
87
|
+
updateStyles();
|
|
88
|
+
}, [updateStyles]);
|
|
89
|
+
const handleOnError = useCallback(() => {
|
|
90
|
+
if (onError) {
|
|
91
|
+
onError();
|
|
92
|
+
}
|
|
93
|
+
}, [onError]);
|
|
94
|
+
return jsx(Block, _extends({}, blockProps, {
|
|
95
|
+
overrideCss: styles,
|
|
96
|
+
testId: `${testId}-resolved-view`
|
|
97
|
+
}), jsx(Preview, {
|
|
98
|
+
onError: handleOnError,
|
|
99
|
+
onLoad: handleOnLoad
|
|
100
|
+
}));
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export default PreviewBlockResolvedView;
|
|
@@ -8,7 +8,8 @@ const ImageIcon = ({
|
|
|
8
8
|
defaultIcon,
|
|
9
9
|
testId,
|
|
10
10
|
url,
|
|
11
|
-
onError
|
|
11
|
+
onError,
|
|
12
|
+
onLoad
|
|
12
13
|
}) => jsx(ImageLoader, {
|
|
13
14
|
src: url,
|
|
14
15
|
loading: jsx(LoadingSkeleton, {
|
|
@@ -19,7 +20,8 @@ const ImageIcon = ({
|
|
|
19
20
|
"data-testid": `${testId}-image`
|
|
20
21
|
}),
|
|
21
22
|
errored: defaultIcon,
|
|
22
|
-
onError: onError
|
|
23
|
+
onError: onError,
|
|
24
|
+
onLoad: onLoad
|
|
23
25
|
});
|
|
24
26
|
|
|
25
27
|
export default ImageIcon;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/** @jsx jsx */
|
|
2
2
|
import React, { useContext } from 'react';
|
|
3
3
|
import { css, jsx } from '@emotion/react';
|
|
4
|
-
import { SmartLinkSize, SmartLinkTheme } from '../../../../constants';
|
|
5
|
-
import { isFlexibleUiBlock, isFlexibleUiTitleBlock } from '../../../../utils/flexible';
|
|
4
|
+
import { MediaPlacement, SmartLinkSize, SmartLinkTheme } from '../../../../constants';
|
|
5
|
+
import { isFlexibleUiBlock, isFlexibleUiPreviewBlock, isFlexibleUiTitleBlock } from '../../../../utils/flexible';
|
|
6
6
|
import { tokens } from '../../../../utils/token';
|
|
7
7
|
import { FlexibleUiContext } from '../../../../state/flexible-ui-context';
|
|
8
8
|
import LayeredLink from './layered-link';
|
|
9
|
+
import { isFlexUiPreviewPresent } from '../../../../state/flexible-ui-context/utils';
|
|
9
10
|
const elevationStyles = css`
|
|
10
11
|
border: 1px solid transparent;
|
|
11
12
|
border-radius: 1.5px;
|
|
@@ -56,25 +57,75 @@ const clickableContainerStyles = css`
|
|
|
56
57
|
z-index: 1;
|
|
57
58
|
}
|
|
58
59
|
`;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
60
|
+
|
|
61
|
+
const getContainerPaddingStyles = (size, hidePadding, childrenOptions) => {
|
|
62
|
+
const padding = hidePadding ? '0rem' : getPadding(size);
|
|
63
|
+
const gap = getGap(size);
|
|
64
|
+
const {
|
|
65
|
+
previewOnLeft,
|
|
66
|
+
previewOnRight
|
|
67
|
+
} = childrenOptions;
|
|
68
|
+
return css`
|
|
69
|
+
// Set variables for PreviewBlock to use.
|
|
70
|
+
--container-padding: ${padding};
|
|
71
|
+
--container-gap-left: ${previewOnLeft ? gap : padding};
|
|
72
|
+
--container-gap-right: ${previewOnRight ? gap : padding};
|
|
73
|
+
--preview-block-width: 30%;
|
|
74
|
+
|
|
75
|
+
padding: ${padding};
|
|
76
|
+
${previewOnLeft ? `padding-left: calc(var(--preview-block-width) + ${gap});` : ''}
|
|
77
|
+
${previewOnRight ? `padding-right: calc(var(--preview-block-width) + ${gap});` : ''}
|
|
78
|
+
`;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const getChildrenOptions = (children, context) => {
|
|
82
|
+
let options = {};
|
|
83
|
+
|
|
84
|
+
if (isFlexUiPreviewPresent(context)) {
|
|
85
|
+
React.Children.map(children, child => {
|
|
86
|
+
if ( /*#__PURE__*/React.isValidElement(child)) {
|
|
87
|
+
if (isFlexibleUiPreviewBlock(child)) {
|
|
88
|
+
const {
|
|
89
|
+
placement
|
|
90
|
+
} = child.props;
|
|
91
|
+
|
|
92
|
+
if (placement === MediaPlacement.Left) {
|
|
93
|
+
options.previewOnLeft = true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (placement === MediaPlacement.Right) {
|
|
97
|
+
options.previewOnRight = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
76
102
|
}
|
|
77
|
-
|
|
103
|
+
|
|
104
|
+
return options;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const getContainerStyles = (size, hideBackground, hideElevation, hidePadding, clickableContainer, childrenOptions) => {
|
|
108
|
+
const paddingCss = getContainerPaddingStyles(size, hidePadding, childrenOptions);
|
|
109
|
+
return css`
|
|
110
|
+
display: flex;
|
|
111
|
+
gap: ${getGap(size)} 0;
|
|
112
|
+
flex-direction: column;
|
|
113
|
+
min-width: 0;
|
|
114
|
+
overflow-x: hidden;
|
|
115
|
+
position: relative;
|
|
116
|
+
${hideBackground ? '' : `background-color: ${tokens.background};`}
|
|
117
|
+
${paddingCss}
|
|
118
|
+
${hideElevation ? '' : elevationStyles}
|
|
119
|
+
${clickableContainer ? clickableContainerStyles : ''}
|
|
120
|
+
&:hover ~ .actions-button-group {
|
|
121
|
+
opacity: 1;
|
|
122
|
+
}
|
|
123
|
+
a:focus,
|
|
124
|
+
.has-action:focus {
|
|
125
|
+
outline-offset: -2px;
|
|
126
|
+
}
|
|
127
|
+
`;
|
|
128
|
+
};
|
|
78
129
|
|
|
79
130
|
const renderChildren = (children, containerSize, containerTheme, status, retry, onClick) => React.Children.map(children, child => {
|
|
80
131
|
if ( /*#__PURE__*/React.isValidElement(child) && isFlexibleUiBlock(child)) {
|
|
@@ -149,8 +200,9 @@ const Container = ({
|
|
|
149
200
|
theme = SmartLinkTheme.Link
|
|
150
201
|
}) => {
|
|
151
202
|
const context = useContext(FlexibleUiContext);
|
|
203
|
+
const childrenOptions = getChildrenOptions(children, context);
|
|
152
204
|
return jsx("div", {
|
|
153
|
-
css: getContainerStyles(size, hideBackground, hideElevation, hidePadding, clickableContainer),
|
|
205
|
+
css: getContainerStyles(size, hideBackground, hideElevation, hidePadding, clickableContainer, childrenOptions),
|
|
154
206
|
"data-smart-link-container": true,
|
|
155
207
|
"data-testid": testId
|
|
156
208
|
}, clickableContainer ? getLayeredLink(testId, context, children, onClick) : null, renderChildren(children, size, theme, status, retry, onClick));
|
|
@@ -2,10 +2,24 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { css, jsx } from '@emotion/react';
|
|
4
4
|
import AtlaskitLozenge from '@atlaskit/lozenge';
|
|
5
|
+
import ChevronDownIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
5
6
|
const styles = css`
|
|
6
7
|
display: inline-flex;
|
|
7
8
|
line-height: inherit;
|
|
8
9
|
`;
|
|
10
|
+
const actionStyles = css`
|
|
11
|
+
> span > span {
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
margin-right: -2px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
svg {
|
|
18
|
+
width: unset;
|
|
19
|
+
height: unset;
|
|
20
|
+
margin: -4px 0;
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
9
23
|
/**
|
|
10
24
|
* A base element that displays a Lozenge.
|
|
11
25
|
* @internal
|
|
@@ -16,6 +30,7 @@ const styles = css`
|
|
|
16
30
|
const Lozenge = ({
|
|
17
31
|
appearance = 'default',
|
|
18
32
|
name,
|
|
33
|
+
onClick,
|
|
19
34
|
overrideCss,
|
|
20
35
|
text,
|
|
21
36
|
testId = 'smart-element-lozenge'
|
|
@@ -25,15 +40,19 @@ const Lozenge = ({
|
|
|
25
40
|
}
|
|
26
41
|
|
|
27
42
|
return jsx("span", {
|
|
28
|
-
css: [styles, overrideCss],
|
|
43
|
+
css: [styles, onClick ? actionStyles : undefined, overrideCss],
|
|
29
44
|
"data-fit-to-content": true,
|
|
30
45
|
"data-smart-element": name,
|
|
31
46
|
"data-smart-element-lozenge": true,
|
|
32
|
-
"data-testid": testId
|
|
47
|
+
"data-testid": testId,
|
|
48
|
+
onClick: onClick
|
|
33
49
|
}, jsx(AtlaskitLozenge, {
|
|
34
50
|
appearance: appearance,
|
|
35
51
|
testId: `${testId}-lozenge`
|
|
36
|
-
}, text
|
|
52
|
+
}, text, onClick && jsx(ChevronDownIcon, {
|
|
53
|
+
label: "action",
|
|
54
|
+
testId: `${testId}-action`
|
|
55
|
+
})));
|
|
37
56
|
};
|
|
38
57
|
|
|
39
58
|
export default Lozenge;
|
|
@@ -60,6 +60,7 @@ const Media = ({
|
|
|
60
60
|
testId = 'smart-element-media',
|
|
61
61
|
type,
|
|
62
62
|
url,
|
|
63
|
+
onLoad,
|
|
63
64
|
onError
|
|
64
65
|
}) => {
|
|
65
66
|
if (!type || !url) {
|
|
@@ -75,6 +76,7 @@ const Media = ({
|
|
|
75
76
|
testId: `${testId}-image`,
|
|
76
77
|
url: url,
|
|
77
78
|
onError: onError,
|
|
79
|
+
onLoad: onLoad,
|
|
78
80
|
defaultIcon: null
|
|
79
81
|
}));
|
|
80
82
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useFeatureFlag } from '@atlaskit/link-provider';
|
|
1
2
|
import ShortcutIcon from '@atlaskit/icon/glyph/shortcut';
|
|
2
3
|
import { extractType } from '@atlaskit/linking-common/extractors';
|
|
3
4
|
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
@@ -9,7 +10,7 @@ import { isSpecialEvent } from '../../../utils';
|
|
|
9
10
|
import FlexibleCard from '../../FlexibleCard';
|
|
10
11
|
import { FooterBlock, MetadataBlock, SnippetBlock, TitleBlock } from '../../FlexibleCard/components/blocks';
|
|
11
12
|
import { flexibleUiOptions, footerBlockCss, metadataBlockCss, titleBlockCss, hiddenSnippetStyles } from '../styled';
|
|
12
|
-
import { getSimulatedMetadata, SMART_CARD_ANALYTICS_DISPLAY } from '../utils';
|
|
13
|
+
import { toActionableMetadata, getSimulatedMetadata, SMART_CARD_ANALYTICS_DISPLAY } from '../utils';
|
|
13
14
|
import HoverCardLoadingView from './HoverCardLoadingView';
|
|
14
15
|
import SnippetOrPreview from './SnippetOrPreview';
|
|
15
16
|
export const getOpenAction = (url, analytics, onActionClick) => ({
|
|
@@ -56,6 +57,7 @@ const HoverCardContent = ({
|
|
|
56
57
|
}) => {
|
|
57
58
|
var _cardState$details;
|
|
58
59
|
|
|
60
|
+
const showActionableElement = useFeatureFlag('enableActionableElement');
|
|
59
61
|
const actions = useSmartCardActions(id, url, analytics);
|
|
60
62
|
useEffect(() => {
|
|
61
63
|
actions.loadMetadata();
|
|
@@ -82,13 +84,21 @@ const HoverCardContent = ({
|
|
|
82
84
|
const titleActions = useMemo(() => [getOpenAction(url, analytics, onActionClick)], [url, analytics, onActionClick]);
|
|
83
85
|
const footerActions = useMemo(() => toFooterActions(cardActions, onActionClick), [cardActions, onActionClick]);
|
|
84
86
|
const data = (_cardState$details = cardState.details) === null || _cardState$details === void 0 ? void 0 : _cardState$details.data;
|
|
85
|
-
const types = data ? extractType(data) : undefined; //TODO: EDM-3224 deleted simulated and use real JsonLd
|
|
86
|
-
|
|
87
87
|
const {
|
|
88
88
|
primary,
|
|
89
89
|
secondary,
|
|
90
90
|
subtitle
|
|
91
|
-
} =
|
|
91
|
+
} = useMemo(() => {
|
|
92
|
+
const types = data ? extractType(data) : undefined; //TODO: EDM-3224 deleted simulated and use real JsonLd
|
|
93
|
+
|
|
94
|
+
const metadata = extractMetadata(getSimulatedMetadata(extensionKey, types));
|
|
95
|
+
const primary = showActionableElement ? toActionableMetadata(onActionClick, extensionKey, types, cardActions, metadata.primary) : metadata.primary;
|
|
96
|
+
return {
|
|
97
|
+
primary,
|
|
98
|
+
secondary: metadata.secondary,
|
|
99
|
+
subtitle: metadata.subtitle
|
|
100
|
+
};
|
|
101
|
+
}, [cardActions, data, extensionKey, onActionClick, showActionableElement]);
|
|
92
102
|
const titleMaxLines = subtitle && subtitle.length > 0 ? 1 : 2;
|
|
93
103
|
const snippetHeight = React.useRef(0);
|
|
94
104
|
const snippetBlockRef = useRef(null);
|
|
@@ -77,4 +77,24 @@ export const getSimulatedMetadata = (extensionKey = '', types = []) => {
|
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
+
};
|
|
81
|
+
export const toActionableMetadata = (onActionClick, extensionKey, types = [], cardActions = [], elementItems = []) => {
|
|
82
|
+
// Actionable State for Jira issue
|
|
83
|
+
if (extensionKey === 'jira-object-provider' && types !== null && types !== void 0 && types.includes('atlassian:Task')) {
|
|
84
|
+
const previewAction = cardActions.find(action => action.id === 'preview-content');
|
|
85
|
+
|
|
86
|
+
if (previewAction) {
|
|
87
|
+
return elementItems.map(elementItem => elementItem.name === ElementName.State ? { ...elementItem,
|
|
88
|
+
onClick: () => {
|
|
89
|
+
if (onActionClick) {
|
|
90
|
+
onActionClick(previewAction.id);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return previewAction.invoke();
|
|
94
|
+
}
|
|
95
|
+
} : elementItem);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return elementItems;
|
|
80
100
|
};
|
package/dist/esm/constants.js
CHANGED
|
@@ -221,4 +221,11 @@ export var MediaType;
|
|
|
221
221
|
|
|
222
222
|
(function (MediaType) {
|
|
223
223
|
MediaType["Image"] = "image";
|
|
224
|
-
})(MediaType || (MediaType = {}));
|
|
224
|
+
})(MediaType || (MediaType = {}));
|
|
225
|
+
|
|
226
|
+
export var MediaPlacement;
|
|
227
|
+
|
|
228
|
+
(function (MediaPlacement) {
|
|
229
|
+
MediaPlacement["Left"] = "left";
|
|
230
|
+
MediaPlacement["Right"] = "right";
|
|
231
|
+
})(MediaPlacement || (MediaPlacement = {}));
|
package/dist/esm/index.js
CHANGED
|
@@ -12,5 +12,5 @@ export { useSmartLinkEvents } from './view/SmartLinkEvents/useSmartLinkEvents';
|
|
|
12
12
|
export { contentFooterClassName, metadataListClassName, blockCardResolvingViewClassName, blockCardResolvedViewClassName, blockCardForbiddenViewClassName, blockCardIconImageClassName, blockCardResolvedViewByClassName, blockCardForbiddenViewLinkClassName, blockCardContentClassName, blockCardContentHeaderClassName, blockCardContentHeaderNameClassName, blockCardNotFoundViewClassName, blockCardErroredViewClassName } from './classNames';
|
|
13
13
|
export { loadingPlaceholderClassName } from './view/CardWithUrl/component-lazy/LazyFallback'; // Flexible UI
|
|
14
14
|
|
|
15
|
-
export { ActionName, ElementName, SmartLinkDirection, SmartLinkPosition, SmartLinkSize, SmartLinkTheme } from './constants';
|
|
15
|
+
export { ActionName, ElementName, MediaPlacement, SmartLinkDirection, SmartLinkPosition, SmartLinkSize, SmartLinkTheme } from './constants';
|
|
16
16
|
export { MetadataBlock, PreviewBlock, SnippetBlock, TitleBlock, FooterBlock } from './view/FlexibleCard/components/blocks';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import * as Blocks from '../view/FlexibleCard/components/blocks';
|
|
3
|
-
import { TitleBlock } from '../view/FlexibleCard/components/blocks';
|
|
3
|
+
import { PreviewBlock, TitleBlock } from '../view/FlexibleCard/components/blocks';
|
|
4
4
|
import * as Elements from '../view/FlexibleCard/components/elements';
|
|
5
5
|
export var isFlexibleUiCard = function isFlexibleUiCard(children) {
|
|
6
6
|
if (children && React.Children.toArray(children).some(function (child) {
|
|
@@ -23,4 +23,7 @@ export var isFlexibleUiElement = function isFlexibleUiElement(node) {
|
|
|
23
23
|
};
|
|
24
24
|
export var isFlexibleUiTitleBlock = function isFlexibleUiTitleBlock(node) {
|
|
25
25
|
return /*#__PURE__*/React.isValidElement(node) && node.type === TitleBlock;
|
|
26
|
+
};
|
|
27
|
+
export var isFlexibleUiPreviewBlock = function isFlexibleUiPreviewBlock(node) {
|
|
28
|
+
return /*#__PURE__*/React.isValidElement(node) && node.type === PreviewBlock;
|
|
26
29
|
};
|
package/dist/esm/version.json
CHANGED
|
@@ -28,7 +28,7 @@ var providerStyles = css(_templateObject2 || (_templateObject2 = _taggedTemplate
|
|
|
28
28
|
* @param props are the data required for the block, such as actions to be displayed.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
var
|
|
31
|
+
var BlockCardFooter = function BlockCardFooter(props) {
|
|
32
32
|
var actions = props.actions,
|
|
33
33
|
_props$size = props.size,
|
|
34
34
|
size = _props$size === void 0 ? SmartLinkSize.Medium : _props$size,
|
|
@@ -49,4 +49,4 @@ var Footer = function Footer(props) {
|
|
|
49
49
|
})) : null);
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
export default
|
|
52
|
+
export default BlockCardFooter;
|