@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.
Files changed (82) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/constants.js +10 -2
  3. package/dist/cjs/index.js +6 -0
  4. package/dist/cjs/state/flexible-ui-context/utils.js +16 -0
  5. package/dist/cjs/utils/flexible.js +8 -2
  6. package/dist/cjs/version.json +1 -1
  7. package/dist/cjs/view/BlockCard/components/flexible/footer/index.js +2 -2
  8. package/dist/cjs/view/BlockCard/index.js +83 -12
  9. package/dist/cjs/view/BlockCard/views/flexible/FlexibleResolvedView.js +108 -0
  10. package/dist/cjs/view/BlockCard/views/flexible/FlexibleUnauthorisedView.js +1 -1
  11. package/dist/cjs/view/CardWithUrl/component.js +4 -2
  12. package/dist/cjs/view/FlexibleCard/components/blocks/preview-block/index.js +6 -9
  13. package/dist/cjs/view/FlexibleCard/components/blocks/preview-block/resolved/index.js +109 -0
  14. package/dist/cjs/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  15. package/dist/cjs/view/FlexibleCard/components/container/index.js +40 -4
  16. package/dist/cjs/view/FlexibleCard/components/elements/lozenge/index.js +12 -4
  17. package/dist/cjs/view/FlexibleCard/components/elements/media/index.js +2 -0
  18. package/dist/cjs/view/HoverCard/components/HoverCardContent.js +18 -6
  19. package/dist/cjs/view/HoverCard/utils.js +41 -2
  20. package/dist/es2019/constants.js +8 -1
  21. package/dist/es2019/index.js +1 -1
  22. package/dist/es2019/state/flexible-ui-context/utils.js +5 -0
  23. package/dist/es2019/utils/flexible.js +3 -2
  24. package/dist/es2019/version.json +1 -1
  25. package/dist/es2019/view/BlockCard/components/flexible/footer/index.js +2 -2
  26. package/dist/es2019/view/BlockCard/index.js +80 -13
  27. package/dist/es2019/view/BlockCard/views/flexible/FlexibleErroredView.js +2 -2
  28. package/dist/es2019/view/BlockCard/views/flexible/FlexibleForbiddenView.js +2 -2
  29. package/dist/es2019/view/BlockCard/views/flexible/FlexibleNotFoundView.js +2 -2
  30. package/dist/es2019/view/BlockCard/views/flexible/FlexibleResolvedView.js +81 -0
  31. package/dist/es2019/view/BlockCard/views/flexible/FlexibleUnauthorisedView.js +3 -3
  32. package/dist/es2019/view/CardWithUrl/component.js +4 -2
  33. package/dist/es2019/view/FlexibleCard/components/blocks/preview-block/index.js +6 -7
  34. package/dist/es2019/view/FlexibleCard/components/blocks/preview-block/resolved/index.js +103 -0
  35. package/dist/es2019/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  36. package/dist/es2019/view/FlexibleCard/components/container/index.js +73 -21
  37. package/dist/es2019/view/FlexibleCard/components/elements/lozenge/index.js +22 -3
  38. package/dist/es2019/view/FlexibleCard/components/elements/media/index.js +2 -0
  39. package/dist/es2019/view/HoverCard/components/HoverCardContent.js +14 -4
  40. package/dist/es2019/view/HoverCard/utils.js +20 -0
  41. package/dist/esm/constants.js +8 -1
  42. package/dist/esm/index.js +1 -1
  43. package/dist/esm/state/flexible-ui-context/utils.js +7 -0
  44. package/dist/esm/utils/flexible.js +4 -1
  45. package/dist/esm/version.json +1 -1
  46. package/dist/esm/view/BlockCard/components/flexible/footer/index.js +2 -2
  47. package/dist/esm/view/BlockCard/index.js +77 -12
  48. package/dist/esm/view/BlockCard/views/flexible/FlexibleErroredView.js +2 -2
  49. package/dist/esm/view/BlockCard/views/flexible/FlexibleForbiddenView.js +2 -2
  50. package/dist/esm/view/BlockCard/views/flexible/FlexibleNotFoundView.js +2 -2
  51. package/dist/esm/view/BlockCard/views/flexible/FlexibleResolvedView.js +87 -0
  52. package/dist/esm/view/BlockCard/views/flexible/FlexibleUnauthorisedView.js +3 -3
  53. package/dist/esm/view/CardWithUrl/component.js +4 -2
  54. package/dist/esm/view/FlexibleCard/components/blocks/preview-block/index.js +7 -8
  55. package/dist/esm/view/FlexibleCard/components/blocks/preview-block/resolved/index.js +86 -0
  56. package/dist/esm/view/FlexibleCard/components/common/image-icon/index.js +4 -2
  57. package/dist/esm/view/FlexibleCard/components/container/index.js +42 -6
  58. package/dist/esm/view/FlexibleCard/components/elements/lozenge/index.js +11 -4
  59. package/dist/esm/view/FlexibleCard/components/elements/media/index.js +2 -0
  60. package/dist/esm/view/HoverCard/components/HoverCardContent.js +17 -6
  61. package/dist/esm/view/HoverCard/utils.js +34 -0
  62. package/dist/types/constants.d.ts +4 -0
  63. package/dist/types/index.d.ts +1 -1
  64. package/dist/types/state/flexible-ui-context/utils.d.ts +6 -0
  65. package/dist/types/utils/flexible.d.ts +1 -0
  66. package/dist/types/view/BlockCard/components/flexible/footer/index.d.ts +2 -2
  67. package/dist/types/view/BlockCard/index.d.ts +1 -0
  68. package/dist/types/view/BlockCard/types.d.ts +1 -0
  69. package/dist/types/view/BlockCard/views/flexible/FlexibleResolvedView.d.ts +9 -0
  70. package/dist/types/view/BlockCard/views/flexible/FlexibleUnauthorisedView.d.ts +1 -1
  71. package/dist/types/view/FlexibleCard/components/blocks/preview-block/index.d.ts +1 -0
  72. package/dist/types/view/FlexibleCard/components/blocks/preview-block/resolved/index.d.ts +11 -0
  73. package/dist/types/view/FlexibleCard/components/blocks/preview-block/types.d.ts +15 -0
  74. package/dist/types/view/FlexibleCard/components/common/image-icon/types.d.ts +1 -0
  75. package/dist/types/view/FlexibleCard/components/container/index.d.ts +2 -2
  76. package/dist/types/view/FlexibleCard/components/container/types.d.ts +4 -0
  77. package/dist/types/view/FlexibleCard/components/elements/lozenge/types.d.ts +5 -0
  78. package/dist/types/view/FlexibleCard/components/elements/media/types.d.ts +1 -0
  79. package/dist/types/view/HoverCard/utils.d.ts +3 -0
  80. package/package.json +2 -2
  81. package/report.api.md +10 -0
  82. 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
- } // Setup UI handlers.
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 Block from '../block';
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 /*#__PURE__*/React.createElement(Block, _extends({}, blockProps, {
24
- testId: `${testId}-resolved-view`
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
- export const getContainerStyles = (size, hideBackground, hideElevation, hidePadding, clickableContainer) => css`
60
- display: flex;
61
- gap: ${getGap(size)} 0;
62
- flex-direction: column;
63
- min-width: 0;
64
- overflow-x: hidden;
65
- position: relative;
66
- ${hideBackground ? '' : `background-color: ${tokens.background};`}
67
- ${hidePadding ? '' : `padding: ${getPadding(size)};`}
68
- ${hideElevation ? '' : elevationStyles}
69
- ${clickableContainer ? clickableContainerStyles : ''}
70
- &:hover ~ .actions-button-group {
71
- opacity: 1;
72
- }
73
- a:focus,
74
- .has-action:focus {
75
- outline-offset: -2px;
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
- } = extractMetadata(getSimulatedMetadata(extensionKey, types));
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
  };
@@ -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';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Returns true if preview data is available in the FlexibleUiDataContext
3
+ * @param context is the FlexibleUiDataContext
4
+ */
5
+ export var isFlexUiPreviewPresent = function isFlexUiPreviewPresent(context) {
6
+ return Boolean(context && context.preview);
7
+ };
@@ -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
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "23.4.8",
3
+ "version": "23.5.1",
4
4
  "sideEffects": false
5
5
  }
@@ -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 Footer = function Footer(props) {
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 Footer;
52
+ export default BlockCardFooter;