@atlaskit/media-card 77.11.3 → 77.12.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 (93) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/card/card.js +5 -5
  3. package/dist/cjs/card/cardView.js +6 -10
  4. package/dist/cjs/card/inlinePlayerWrapperStyles.js +1 -1
  5. package/dist/cjs/card/media-card-analytics-error-boundary.js +1 -1
  6. package/dist/cjs/card/ui/styles.js +1 -12
  7. package/dist/cjs/card/ui/wrapper/imageContainer.js +52 -0
  8. package/dist/cjs/card/ui/wrapper/index.js +8 -1
  9. package/dist/cjs/card/ui/wrapper/styles.js +1 -1
  10. package/dist/cjs/card/v2/cardV2.js +1 -1
  11. package/dist/cjs/card/v2/cardViewV2.js +12 -17
  12. package/dist/cjs/card/v2/cardviews/cardViewWrapper.js +5 -9
  13. package/dist/cjs/card/v2/fileCard.js +66 -20
  14. package/dist/cjs/card/v2/svgView/helpers.js +16 -0
  15. package/dist/cjs/card/v2/svgView/index.js +12 -0
  16. package/dist/cjs/card/v2/svgView/svgView.js +134 -0
  17. package/dist/cjs/inline/loader.js +1 -1
  18. package/dist/cjs/inline/mediaInlineAnalyticsErrorBoundary.js +11 -11
  19. package/dist/cjs/utils/ufoExperiences.js +1 -1
  20. package/dist/es2019/card/card.js +5 -5
  21. package/dist/es2019/card/cardView.js +8 -12
  22. package/dist/es2019/card/inlinePlayerWrapperStyles.js +12 -12
  23. package/dist/es2019/card/media-card-analytics-error-boundary.js +1 -1
  24. package/dist/es2019/card/ui/styles.js +0 -11
  25. package/dist/es2019/card/ui/wrapper/imageContainer.js +44 -0
  26. package/dist/es2019/card/ui/wrapper/index.js +2 -1
  27. package/dist/es2019/card/ui/wrapper/styles.js +21 -21
  28. package/dist/es2019/card/v2/cardV2.js +1 -1
  29. package/dist/es2019/card/v2/cardViewV2.js +13 -18
  30. package/dist/es2019/card/v2/cardviews/cardViewWrapper.js +6 -10
  31. package/dist/es2019/card/v2/fileCard.js +51 -8
  32. package/dist/es2019/card/v2/svgView/helpers.js +12 -0
  33. package/dist/es2019/card/v2/svgView/index.js +1 -0
  34. package/dist/es2019/card/v2/svgView/svgView.js +113 -0
  35. package/dist/es2019/inline/loader.js +1 -1
  36. package/dist/es2019/inline/mediaInlineAnalyticsErrorBoundary.js +11 -11
  37. package/dist/es2019/utils/ufoExperiences.js +1 -1
  38. package/dist/esm/card/card.js +5 -5
  39. package/dist/esm/card/cardView.js +8 -12
  40. package/dist/esm/card/inlinePlayerWrapperStyles.js +1 -1
  41. package/dist/esm/card/media-card-analytics-error-boundary.js +1 -1
  42. package/dist/esm/card/ui/styles.js +0 -11
  43. package/dist/esm/card/ui/wrapper/imageContainer.js +45 -0
  44. package/dist/esm/card/ui/wrapper/index.js +2 -1
  45. package/dist/esm/card/ui/wrapper/styles.js +1 -1
  46. package/dist/esm/card/v2/cardV2.js +1 -1
  47. package/dist/esm/card/v2/cardViewV2.js +13 -18
  48. package/dist/esm/card/v2/cardviews/cardViewWrapper.js +6 -10
  49. package/dist/esm/card/v2/fileCard.js +66 -20
  50. package/dist/esm/card/v2/svgView/helpers.js +10 -0
  51. package/dist/esm/card/v2/svgView/index.js +1 -0
  52. package/dist/esm/card/v2/svgView/svgView.js +123 -0
  53. package/dist/esm/inline/loader.js +1 -1
  54. package/dist/esm/inline/mediaInlineAnalyticsErrorBoundary.js +11 -11
  55. package/dist/esm/utils/ufoExperiences.js +1 -1
  56. package/dist/types/card/ui/iconWrapper/styles.d.ts +1 -1
  57. package/dist/types/card/ui/styles.d.ts +0 -1
  58. package/dist/types/card/ui/titleBox/styles.d.ts +1 -1
  59. package/dist/types/card/ui/wrapper/imageContainer.d.ts +15 -0
  60. package/dist/types/card/ui/wrapper/index.d.ts +1 -0
  61. package/dist/types/card/v2/svgView/helpers.d.ts +3 -0
  62. package/dist/types/card/v2/svgView/index.d.ts +1 -0
  63. package/dist/types/card/v2/svgView/svgView.d.ts +31 -0
  64. package/dist/types/utils/preventClickThrough.d.ts +1 -1
  65. package/dist/types/utils/viewportDetector.d.ts +1 -1
  66. package/dist/types-ts4.5/card/ui/iconWrapper/styles.d.ts +1 -1
  67. package/dist/types-ts4.5/card/ui/styles.d.ts +0 -1
  68. package/dist/types-ts4.5/card/ui/titleBox/styles.d.ts +1 -1
  69. package/dist/types-ts4.5/card/ui/wrapper/imageContainer.d.ts +15 -0
  70. package/dist/types-ts4.5/card/ui/wrapper/index.d.ts +1 -0
  71. package/dist/types-ts4.5/card/v2/svgView/helpers.d.ts +3 -0
  72. package/dist/types-ts4.5/card/v2/svgView/index.d.ts +1 -0
  73. package/dist/types-ts4.5/card/v2/svgView/svgView.d.ts +31 -0
  74. package/dist/types-ts4.5/utils/preventClickThrough.d.ts +1 -1
  75. package/dist/types-ts4.5/utils/viewportDetector.d.ts +1 -1
  76. package/example-helpers/DelayedRender.tsx +19 -19
  77. package/example-helpers/cardViewWrapper.tsx +18 -22
  78. package/example-helpers/cards.tsx +268 -331
  79. package/example-helpers/developmentUseMessage.tsx +8 -9
  80. package/example-helpers/index.tsx +100 -124
  81. package/example-helpers/selectableCard.tsx +32 -35
  82. package/example-helpers/ssrHelpers.tsx +19 -29
  83. package/example-helpers/styles.ts +73 -73
  84. package/example-helpers/svg-helpers/cardContainer.tsx +24 -0
  85. package/example-helpers/svg-helpers/controls.tsx +21 -0
  86. package/example-helpers/svg-helpers/delayApiResponses.ts +31 -0
  87. package/example-helpers/svg-helpers/dimensionPicker.tsx +116 -0
  88. package/example-helpers/svg-helpers/index.ts +7 -0
  89. package/example-helpers/svg-helpers/svgContainer.tsx +32 -0
  90. package/example-helpers/svg-helpers/toggle.tsx +42 -0
  91. package/example-helpers/svg-helpers/uploader.ts +44 -0
  92. package/package.json +13 -5
  93. package/report.api.md +227 -232
@@ -33,17 +33,17 @@ var ErrorBoundaryComponent = function ErrorBoundaryComponent(_ref) {
33
33
  };
34
34
 
35
35
  /* Note:
36
- - styling is borrowed from packages/media/media-ui/src/MediaInlineCard/Frame/styled.ts
37
- - because we are not using styled components, we are not able to use themed(), here is the "themed" property of color and backgroundColor
38
- color: `${themed({
39
- light: token('color.text', N900),
40
- dark: token('color.text', DN600),
41
- })}`,
42
- backgroundColor: `${themed({
43
- light: token('color.background.neutral', N30A),
44
- dark: token('color.background.neutral', DN80),
45
- })}`,
46
- */
36
+ - styling is borrowed from packages/media/media-ui/src/MediaInlineCard/Frame/styled.ts
37
+ - because we are not using styled components, we are not able to use themed(), here is the "themed" property of color and backgroundColor
38
+ color: `${themed({
39
+ light: token('color.text', N900),
40
+ dark: token('color.text', DN600),
41
+ })}`,
42
+ backgroundColor: `${themed({
43
+ light: token('color.background.neutral', N30A),
44
+ dark: token('color.background.neutral', DN80),
45
+ })}`,
46
+ */
47
47
 
48
48
  var style = _objectSpread({
49
49
  lineHeight: '16px',
@@ -14,7 +14,7 @@ var _mediaClient = require("@atlaskit/media-client");
14
14
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
15
15
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
16
16
  var packageName = "@atlaskit/media-card";
17
- var packageVersion = "77.11.3";
17
+ var packageVersion = "77.12.1";
18
18
  var concurrentExperience;
19
19
  var getExperience = function getExperience(id) {
20
20
  if (!concurrentExperience) {
@@ -28,7 +28,7 @@ import { completeUfoExperience, startUfoExperience, abortUfoExperience } from '.
28
28
  import { generateUniqueId } from '../utils/generateUniqueId';
29
29
  import { DateOverrideContext } from '../dateOverrideContext';
30
30
  const packageName = "@atlaskit/media-card";
31
- const packageVersion = "77.11.3";
31
+ const packageVersion = "77.12.1";
32
32
  export class CardBase extends Component {
33
33
  constructor(props) {
34
34
  super(props);
@@ -220,8 +220,8 @@ export class CardBase extends Component {
220
220
  }
221
221
 
222
222
  /*
223
- If the cardPreview failed and it comes from server (global scope / ssrData), it means that we have reused it in client and the error counts for both: server & client.
224
- */
223
+ If the cardPreview failed and it comes from server (global scope / ssrData), it means that we have reused it in client and the error counts for both: server & client.
224
+ */
225
225
 
226
226
  if (isSSRDataPreview(cardPreview)) {
227
227
  this.ssrReliability.server = failedSSRObject;
@@ -272,8 +272,8 @@ export class CardBase extends Component {
272
272
  }
273
273
 
274
274
  /*
275
- If the image loads successfully and it comes from server (global scope / ssrData), it means that we have reused it in client and the success counts for both: server & client.
276
- */
275
+ If the image loads successfully and it comes from server (global scope / ssrData), it means that we have reused it in client and the success counts for both: server & client.
276
+ */
277
277
 
278
278
  if (isSSRDataPreview(cardPreview) && this.ssrReliability.server.status === 'unknown') {
279
279
  this.ssrReliability.server = {
@@ -12,7 +12,7 @@ import { isValidPercentageUnit } from '../utils/isValidPercentageUnit';
12
12
  import { getElementDimension } from '../utils/getElementDimension';
13
13
  import { createAndFireMediaCardEvent } from '../utils/analytics';
14
14
  import { attachDetailsToActions } from './actions';
15
- import { cardImageContainerStyles, calcBreakpointSize } from './ui/styles';
15
+ import { calcBreakpointSize } from './ui/styles';
16
16
  import { ImageRenderer } from './ui/imageRenderer/imageRenderer';
17
17
  import { TitleBox } from './ui/titleBox/titleBox';
18
18
  import { FailedTitleBox } from './ui/titleBox/failedTitleBox';
@@ -24,7 +24,7 @@ import { ActionsBar } from './ui/actionsBar/actionsBar';
24
24
  import { IconWrapper } from './ui/iconWrapper/iconWrapper';
25
25
  import { PreviewUnavailable, CreatingPreview, FailedToUpload, PreviewCurrentlyUnavailable, FailedToLoad } from './ui/iconMessage';
26
26
  import { isUploadError, isRateLimitedError, isPollingError } from '../errors';
27
- import { Wrapper } from './ui/wrapper';
27
+ import { ImageContainer, Wrapper } from './ui/wrapper';
28
28
  import { fileCardImageViewSelector } from './classnames';
29
29
  import OpenMediaViewerButton from './ui/openMediaViewerButton/openMediaViewerButton';
30
30
  /**
@@ -204,16 +204,12 @@ export class CardViewBase extends React.Component {
204
204
  name
205
205
  } = metadata || {};
206
206
  const hasTitleBox = !!renderTitleBox || !!renderFailedTitleBox;
207
- return jsx(React.Fragment, null, jsx("div", {
208
- css: cardImageContainerStyles
209
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
210
- ,
211
- className: fileCardImageViewSelector,
212
- "data-testid": fileCardImageViewSelector,
213
- "data-test-media-name": name,
214
- "data-test-status": status,
215
- "data-test-progress": progress,
216
- "data-test-selected": selected ? true : undefined
207
+ return jsx(React.Fragment, null, jsx(ImageContainer, {
208
+ testId: fileCardImageViewSelector,
209
+ mediaName: name,
210
+ status: status,
211
+ progress: progress,
212
+ selected: selected ? true : undefined
217
213
  }, renderTypeIcon && this.renderMediaTypeIcon(hasTitleBox, iconMessage), renderSpinner && this.renderSpinner(hasTitleBox), renderImageRenderer && this.renderImageRenderer(), renderPlayButton && this.renderPlayButton(hasTitleBox), renderBlanket && this.renderBlanket(!!isFixedBlanket), renderTitleBox && this.renderTitleBox(), renderFailedTitleBox && this.renderFailedTitleBox(customTitleMessage), renderProgressBar && this.renderProgressBar(!hasTitleBox), renderTickBox && this.renderTickBox()), this.renderActionsBar());
218
214
  });
219
215
  }
@@ -29,19 +29,19 @@ export const inlinePlayerWrapperStyles = ({
29
29
  dimensions,
30
30
  selected
31
31
  }) => css`
32
- width: ${getDimensionsWithDefault(dimensions).width || '100%'};
33
- height: ${getDimensionsWithDefault(dimensions).height || 'auto'};
34
- overflow: hidden;
35
- border-radius: ${borderRadius()}px;
36
- position: relative;
37
- max-width: 100%;
38
- max-height: 100%;
32
+ width: ${getDimensionsWithDefault(dimensions).width || '100%'};
33
+ height: ${getDimensionsWithDefault(dimensions).height || 'auto'};
34
+ overflow: hidden;
35
+ border-radius: ${borderRadius()}px;
36
+ position: relative;
37
+ max-width: 100%;
38
+ max-height: 100%;
39
39
 
40
- ${getSelectedBorderStyle(selected)}
40
+ ${getSelectedBorderStyle(selected)}
41
41
 
42
- video {
43
- width: 100%;
44
- height: 100%;
45
- }
42
+ video {
43
+ width: 100%;
44
+ height: 100%;
45
+ }
46
46
  `;
47
47
  inlinePlayerWrapperStyles.displayName = 'InlinePlayerWrapper';
@@ -66,7 +66,7 @@ class WrappedMediaCardAnalyticsErrorBoundary extends React.Component {
66
66
  }
67
67
  _defineProperty(WrappedMediaCardAnalyticsErrorBoundary, "displayName", 'MediaCardAnalyticsErrorBoundary');
68
68
  const packageName = "@atlaskit/media-card";
69
- const packageVersion = "77.11.3";
69
+ const packageVersion = "77.12.1";
70
70
  const MediaCardAnalyticsErrorBoundary = withMediaAnalyticsContext({
71
71
  packageVersion,
72
72
  packageName,
@@ -1,5 +1,3 @@
1
- import { css } from '@emotion/react';
2
- import { borderRadius } from '@atlaskit/media-ui';
3
1
  import { N60A } from '@atlaskit/theme/colors';
4
2
  import { akEditorSelectedBoxShadow } from '@atlaskit/editor-shared-styles/consts';
5
3
  import { getCSSUnitValue } from '../../utils/getCSSUnitValue';
@@ -65,15 +63,6 @@ export const getSelectableTickBoxStyles = isTickBoxSelectable => {
65
63
  }
66
64
  `;
67
65
  };
68
- export const cardImageContainerStyles = css({
69
- display: 'flex',
70
- position: 'relative',
71
- maxWidth: '100%',
72
- width: '100%',
73
- height: '100%',
74
- maxHeight: '100%',
75
- overflow: 'hidden'
76
- }, borderRadius);
77
66
  const defaultTransitionDuration = '.3s';
78
67
  export const transition = (propertyName = 'all') => `
79
68
  transition: ${propertyName} ${defaultTransitionDuration};
@@ -0,0 +1,44 @@
1
+ /** @jsx jsx */
2
+ import { jsx, css } from '@emotion/react';
3
+ import { fileCardImageViewSelector } from '../../classnames';
4
+ const imageContainerStyles = css({
5
+ display: 'flex',
6
+ position: 'relative',
7
+ maxWidth: '100%',
8
+ width: '100%',
9
+ height: '100%',
10
+ maxHeight: '100%',
11
+ overflow: 'hidden',
12
+ borderRadius: "var(--ds-border-radius, 3px)"
13
+ });
14
+ const imageContainerCenterStyles = css({
15
+ flexDirection: 'column',
16
+ justifyContent: 'center',
17
+ alignItems: 'center'
18
+ });
19
+ export const ImageContainer = ({
20
+ children,
21
+ testId,
22
+ mediaName,
23
+ status,
24
+ progress,
25
+ selected,
26
+ source,
27
+ centerElements
28
+ }) => jsx("div", {
29
+ css: [imageContainerStyles, centerElements && imageContainerCenterStyles],
30
+ "data-testid": fileCardImageViewSelector
31
+ /**
32
+ * This wrapper MUST add the classname in order to allow the editor to prevent bubbling up the click event.
33
+ * See the method isInteractiveElement in source platform/packages/editor/renderer/src/ui/Renderer/click-to-edit.ts
34
+ * Also, many other consumer tests rely on this selector.
35
+ */
36
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
37
+ ,
38
+ className: fileCardImageViewSelector,
39
+ "data-test-media-name": mediaName,
40
+ "data-test-status": status,
41
+ "data-test-progress": progress,
42
+ "data-test-selected": selected,
43
+ "data-test-source": source
44
+ }, children);
@@ -1 +1,2 @@
1
- export { Wrapper } from './wrapper';
1
+ export { Wrapper } from './wrapper';
2
+ export { ImageContainer } from './imageContainer';
@@ -19,36 +19,36 @@ export const wrapperStyles = ({
19
19
  shouldDisplayTooltip,
20
20
  mediaCardCursor
21
21
  }) => css`
22
- ${transition()}
23
- box-sizing: border-box;
24
- * {
25
- box-sizing: border-box;
26
- }
27
- position: relative;
28
- font-family: ${fontFamily()};
29
- ${getWrapperDimensions(dimensions, appearance)}
30
- ${displayBackground && `background: ${`var(--ds-background-neutral, ${N20})`};`}
22
+ ${transition()}
23
+ box-sizing: border-box;
24
+ * {
25
+ box-sizing: border-box;
26
+ }
27
+ position: relative;
28
+ font-family: ${fontFamily()};
29
+ ${getWrapperDimensions(dimensions, appearance)}
30
+ ${displayBackground && `background: ${`var(--ds-background-neutral, ${N20})`};`}
31
31
  ${borderRadius}
32
32
  ${getCursorStyle(mediaCardCursor)}
33
33
  ${getWrapperShadow(disableOverlay, selected)}
34
34
  ${generateResponsiveStyles(breakpoint)};
35
- ${hideNativeBrowserTextSelectionStyles}
35
+ ${hideNativeBrowserTextSelectionStyles}
36
36
 
37
- /* We use classnames from here exceptionally to be able to handle styles when the Card is on hover */
37
+ /* We use classnames from here exceptionally to be able to handle styles when the Card is on hover */
38
38
  ${getClickablePlayButtonStyles(isPlayButtonClickable)}
39
39
  ${getSelectableTickBoxStyles(isTickBoxSelectable)}
40
40
  &:hover .${blanketClassName} {
41
- ${fixedBlanketStyles}
42
- }
43
- &:hover .${actionsBarClassName}, &:focus-within .${actionsBarClassName} {
44
- ${fixedActionBarStyles}
45
- }
41
+ ${fixedBlanketStyles}
42
+ }
43
+ &:hover .${actionsBarClassName}, &:focus-within .${actionsBarClassName} {
44
+ ${fixedActionBarStyles}
45
+ }
46
46
 
47
- /* Tooltip does not support percentage dimensions. We enforce them here */
48
- ${shouldDisplayTooltip && `> div { width: 100%; height: 100%; }`}
47
+ /* Tooltip does not support percentage dimensions. We enforce them here */
48
+ ${shouldDisplayTooltip && `> div { width: 100%; height: 100%; }`}
49
49
 
50
- button:focus + & {
51
- outline: solid 2px ${`var(--ds-border-focused, ${B100})`};
52
- }
50
+ button:focus + & {
51
+ outline: solid 2px ${`var(--ds-border-focused, ${B100})`};
52
+ }
53
53
  `;
54
54
  wrapperStyles.displayName = 'NewFileExperienceWrapper';
@@ -7,7 +7,7 @@ import { IntlProvider, injectIntl } from 'react-intl-next';
7
7
  import { ExternalImageCard } from './externalImageCard';
8
8
  import { FileCard } from './fileCard';
9
9
  const packageName = "@atlaskit/media-card";
10
- const packageVersion = "77.11.3";
10
+ const packageVersion = "77.12.1";
11
11
  export const CardV2Base = ({
12
12
  identifier,
13
13
  ...otherProps
@@ -8,7 +8,6 @@ import Tooltip from '@atlaskit/tooltip';
8
8
  import { messages } from '@atlaskit/media-ui';
9
9
  import { createAndFireMediaCardEvent } from '../../utils/analytics';
10
10
  import { attachDetailsToActions } from '../actions';
11
- import { cardImageContainerStyles } from '../ui/styles';
12
11
  import { ImageRenderer } from '../ui/imageRenderer/imageRenderer';
13
12
  import { TitleBox } from '../ui/titleBox/titleBox';
14
13
  import { FailedTitleBox } from '../ui/titleBox/failedTitleBox';
@@ -20,7 +19,7 @@ import { ActionsBar } from '../ui/actionsBar/actionsBar';
20
19
  import { IconWrapper } from '../ui/iconWrapper/iconWrapper';
21
20
  import { PreviewUnavailable, CreatingPreview, FailedToUpload, PreviewCurrentlyUnavailable, FailedToLoad } from '../ui/iconMessage';
22
21
  import { isUploadError, isRateLimitedError, isPollingError } from '../../errors';
23
- import { Wrapper } from '../ui/wrapper';
22
+ import { Wrapper, ImageContainer } from '../ui/wrapper';
24
23
  import { fileCardImageViewSelector } from '../classnames';
25
24
  import { useBreakpoint } from '../useBreakpoint';
26
25
  import OpenMediaViewerButton from '../ui/openMediaViewerButton/openMediaViewerButton';
@@ -74,11 +73,11 @@ export const CardViewV2Base = ({
74
73
  return;
75
74
  }
76
75
  /*
77
- We render the icon & icon message always, even if there is cardPreview available.
78
- If the image fails to load/render, the icon will remain, i.e. the user won't see a change until the root card decides to chage status to error.
79
- If the image renders successfully, we switch this variable to hide the icon & icon message behind the thumbnail in case the image has transparency.
80
- It is less likely that root component replaces a suceeded cardPreview for a failed one than the opposite case. Therefore we prefer to hide the icon instead show when the image fails, for a smoother transition
81
- */
76
+ We render the icon & icon message always, even if there is cardPreview available.
77
+ If the image fails to load/render, the icon will remain, i.e. the user won't see a change until the root card decides to chage status to error.
78
+ If the image renders successfully, we switch this variable to hide the icon & icon message behind the thumbnail in case the image has transparency.
79
+ It is less likely that root component replaces a suceeded cardPreview for a failed one than the opposite case. Therefore we prefer to hide the icon instead show when the image fails, for a smoother transition
80
+ */
82
81
  setDidImageRender(true);
83
82
  onImageLoad === null || onImageLoad === void 0 ? void 0 : onImageLoad(cardPreview);
84
83
  };
@@ -205,17 +204,13 @@ export const CardViewV2Base = ({
205
204
  createdAt
206
205
  } = metadata || {};
207
206
  const actionsWithDetails = metadata && actions ? attachDetailsToActions(actions, metadata) : [];
208
- const contents = jsx(React.Fragment, null, jsx("div", {
209
- css: cardImageContainerStyles
210
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
211
- ,
212
- className: fileCardImageViewSelector,
213
- "data-testid": fileCardImageViewSelector,
214
- "data-test-media-name": name,
215
- "data-test-status": status,
216
- "data-test-progress": progress,
217
- "data-test-selected": selected,
218
- "data-test-source": cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source
207
+ const contents = jsx(React.Fragment, null, jsx(ImageContainer, {
208
+ testId: fileCardImageViewSelector,
209
+ mediaName: name,
210
+ status: status,
211
+ progress: progress,
212
+ selected: selected,
213
+ source: cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source
219
214
  }, renderTypeIcon && jsx(IconWrapper, {
220
215
  breakpoint: breakpoint,
221
216
  hasTitleBox: hasTitleBox
@@ -3,9 +3,8 @@ import _extends from "@babel/runtime/helpers/extends";
3
3
  import { jsx } from '@emotion/react';
4
4
  import React from 'react';
5
5
  import Tooltip from '@atlaskit/tooltip';
6
- import { Wrapper } from '../../ui/wrapper';
6
+ import { ImageContainer, Wrapper } from '../../ui/wrapper';
7
7
  import { attachDetailsToActions } from '../../actions';
8
- import { cardImageContainerStyles } from '../../ui/styles';
9
8
  import { TitleBox } from '../../ui/titleBox/titleBox';
10
9
  import { TickBox } from '../../ui/tickBox/tickBox';
11
10
  import { Blanket } from '../../ui/blanket/blanket';
@@ -52,14 +51,11 @@ export const CardViewWrapper = /*#__PURE__*/React.forwardRef(({
52
51
  titleBoxIcon: titleBoxIcon,
53
52
  titleBoxBgColor: titleBoxBgColor
54
53
  });
55
- const contents = jsx(React.Fragment, null, jsx("div", _extends({
56
- css: cardImageContainerStyles
57
- // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
58
- ,
59
- className: fileCardImageViewSelector,
60
- "data-testid": fileCardImageViewSelector,
61
- "data-test-media-name": name,
62
- "data-test-selected": selected ? true : undefined
54
+ const contents = jsx(React.Fragment, null, jsx(ImageContainer, _extends({
55
+ testId: fileCardImageViewSelector,
56
+ mediaName: name,
57
+ status: status,
58
+ selected: selected ? true : undefined
63
59
  }, props), children, customBlanket ? customBlanket() : defaultBlanket, customTitleBox ? customTitleBox() : defaultTitleBox, !disableOverlay && !!selectable && jsx(TickBox, {
64
60
  selected: selected
65
61
  }), progressBar && progressBar()), !disableOverlay && actions && actions.length !== 0 && jsx(ActionsBar, {
@@ -26,6 +26,7 @@ import { useFilePreview } from '@atlaskit/media-file-preview';
26
26
  import { performanceNow } from './performance';
27
27
  import { useContext } from 'react';
28
28
  import { DateOverrideContext } from '../../dateOverrideContext';
29
+ import { SvgView } from './svgView';
29
30
  const LoadedCardView = getBooleanFF('platform.media-experience.card-views-refactor_b91lr') ? CardViews : CardViewV2;
30
31
  export const FileCard = ({
31
32
  appearance = 'auto',
@@ -110,6 +111,7 @@ export const FileCard = ({
110
111
  }), []);
111
112
  const [status, setStatus] = useState('loading');
112
113
  const [isPlayingFile, setIsPlayingFile] = useState(false);
114
+ const [shouldRenderSVG, setShouldRenderSVG] = useState(false);
113
115
  const [shouldAutoplay, setShouldAutoplay] = useState(false);
114
116
  const [previewDidRender, setPreviewDidRender] = useState(false);
115
117
  const mediaBlobUrlAttrs = useMemo(() => {
@@ -393,6 +395,23 @@ export const FileCard = ({
393
395
  }
394
396
  }, [isCardVisible, disableOverlay, fileAttributes.fileMediatype, fileStateValue, identifier, isPlayingFile, finalStatus, useInlinePlayer]);
395
397
 
398
+ //----------------------------------------------------------------//
399
+ // Switch to SVG
400
+ //----------------------------------------------------------------//
401
+
402
+ useEffect(() => {
403
+ if (getBooleanFF('platform.media-card-svg-rendering_6tdbv') &&
404
+ /**
405
+ * We need to check that the card is visible before switching to SVG
406
+ * in order to avoid race conditions of the ViewportDector being unmounted before
407
+ * it is able to set isCardVisible to true.
408
+ */
409
+ isCardVisible && metadata.mimeType === 'image/svg+xml' && disableOverlay // SVG won't be supported when overlay is on
410
+ ) {
411
+ setShouldRenderSVG(true);
412
+ }
413
+ }, [isCardVisible, disableOverlay, metadata]);
414
+
396
415
  //----------------------------------------------------------------//
397
416
  //----------------- fireScreenEvent ------------------------------//
398
417
  //----------------------------------------------------------------//
@@ -460,6 +479,18 @@ export const FileCard = ({
460
479
  updateFileStateRef.current();
461
480
  }, [fileState, preview, previewStatus, updateFileStateRef]);
462
481
 
482
+ //----------------------------------------------------------------//
483
+ // Shared Card View & SVG View resources
484
+ //----------------------------------------------------------------//
485
+
486
+ const mediaCardCursor = getMediaCardCursor(!!useInlinePlayer, !!shouldOpenMediaViewer, finalStatus === 'error' || finalStatus === 'failed-processing', !!preview, metadata.mediaType);
487
+ const onImageMouseEnter = event => {
488
+ onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter({
489
+ event,
490
+ mediaItemDetails: metadata
491
+ });
492
+ };
493
+
463
494
  //----------------------------------------------------------------//
464
495
  //---------------------- Render Card Function --------------------//
465
496
  //----------------------------------------------------------------//
@@ -478,7 +509,6 @@ export const FileCard = ({
478
509
  const nativeLazyLoad = isLazyWithOverride && !isCardVisible && preview && isSSRPreview(preview);
479
510
  // Force Media Image to always display img for SSR
480
511
  const forceSyncDisplay = !!ssr;
481
- const mediaCardCursor = getMediaCardCursor(!!useInlinePlayer, !!shouldOpenMediaViewer, finalStatus === 'error' || finalStatus === 'failed-processing', !!preview, metadata.mediaType);
482
512
  const card = /*#__PURE__*/React.createElement(LoadedCardView, {
483
513
  status: cardStatusOverride || finalStatus,
484
514
  error: finalError,
@@ -494,12 +524,7 @@ export const FileCard = ({
494
524
  shouldOpenMediaViewer: shouldOpenMediaViewer,
495
525
  openMediaViewerButtonRef: mediaViewerButtonRef,
496
526
  onClick: withCallbacks ? onCardViewClick : undefined,
497
- onMouseEnter: withCallbacks ? event => {
498
- onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter({
499
- event,
500
- mediaItemDetails: metadata
501
- });
502
- } : undefined,
527
+ onMouseEnter: withCallbacks ? onImageMouseEnter : undefined,
503
528
  disableOverlay: disableOverlay,
504
529
  progress: uploadProgressRef.current,
505
530
  onDisplayImage: withCallbacks ? () => {
@@ -557,7 +582,25 @@ export const FileCard = ({
557
582
  testId: testId,
558
583
  cardPreview: preview,
559
584
  videoControlsWrapperRef: videoControlsWrapperRef
560
- })) : renderCard(), mediaViewerSelectedItem ? /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement(MediaViewer, {
585
+ })) : shouldRenderSVG ? /*#__PURE__*/React.createElement(SvgView, {
586
+ testId: testId,
587
+ identifier: identifier,
588
+ status: finalStatus,
589
+ fileName: metadata.name,
590
+ cardPreview: preview,
591
+ alt: alt,
592
+ resizeMode: resizeMode,
593
+ dimensions: cardDimensions,
594
+ selected: selected,
595
+ onClick: onCardViewClick,
596
+ onMouseEnter: onImageMouseEnter,
597
+ progress: uploadProgressRef.current,
598
+ onImageError: onImageError,
599
+ onImageLoad: onImageLoad,
600
+ mediaCardCursor: mediaCardCursor,
601
+ shouldOpenMediaViewer: shouldOpenMediaViewer,
602
+ openMediaViewerButtonRef: mediaViewerButtonRef
603
+ }) : renderCard(), mediaViewerSelectedItem ? /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement(MediaViewer, {
561
604
  collectionName: collectionName,
562
605
  items: mediaViewerItems || [],
563
606
  mediaClientConfig: mediaClient.config,
@@ -0,0 +1,12 @@
1
+ export const calculateSvgDimensions = (img, resizeMode) => {
2
+ const {
3
+ naturalWidth,
4
+ naturalHeight
5
+ } = img;
6
+ const isLadscape = naturalWidth / naturalHeight > 1;
7
+ return resizeMode === 'crop' ? isLadscape ? {
8
+ height: '100%'
9
+ } : {
10
+ width: '100%'
11
+ } : {};
12
+ };
@@ -0,0 +1 @@
1
+ export { SvgView } from './svgView';
@@ -0,0 +1,113 @@
1
+ /** @jsx jsx */
2
+ import { jsx } from '@emotion/react';
3
+ import React, { useState, useRef } from 'react';
4
+ import { withAnalyticsEvents } from '@atlaskit/analytics-next';
5
+ import { createAndFireMediaCardEvent } from '../../../utils/analytics';
6
+ import { ImageRenderer } from '../../ui/imageRenderer/imageRenderer';
7
+ import { ProgressBar } from '../../ui/progressBar/progressBar';
8
+ import { Blanket } from '../../ui/blanket/blanket';
9
+ import { Wrapper, ImageContainer } from '../../ui/wrapper';
10
+ import { fileCardImageViewSelector } from '../../classnames';
11
+ import { useBreakpoint } from '../../useBreakpoint';
12
+ import MediaSvg from '@atlaskit/media-svg';
13
+ import { calculateSvgDimensions } from './helpers';
14
+ import OpenMediaViewerButton from '../../ui/openMediaViewerButton/openMediaViewerButton';
15
+ export const convertResizeMode = resizeMode => {
16
+ switch (resizeMode) {
17
+ case 'crop':
18
+ return 'cover';
19
+ case 'fit':
20
+ case 'full-fit':
21
+ return 'scale-down';
22
+ case 'stretchy-fit':
23
+ return 'contain';
24
+ default:
25
+ return;
26
+ }
27
+ };
28
+ export const SvgViewBase = ({
29
+ identifier,
30
+ dimensions,
31
+ onClick,
32
+ onMouseEnter,
33
+ testId,
34
+ status,
35
+ selected,
36
+ fileName,
37
+ cardPreview,
38
+ mediaCardCursor,
39
+ progress,
40
+ alt,
41
+ resizeMode,
42
+ shouldOpenMediaViewer,
43
+ openMediaViewerButtonRef = null
44
+ }) => {
45
+ const [didSvgRender, setDidSvgRender] = useState(false);
46
+ const [didPreviewRender, setDidPreviewRender] = useState(false);
47
+ const [svgDimensions, setSvgDimensions] = useState();
48
+ const divRef = useRef(null);
49
+ const breakpoint = useBreakpoint(dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, divRef);
50
+ const onSvgLoad = evt => {
51
+ setSvgDimensions(calculateSvgDimensions(evt.currentTarget, resizeMode));
52
+ setDidSvgRender(true);
53
+ };
54
+ const onPreviewLoad = () => {
55
+ setDidPreviewRender(true);
56
+ };
57
+ return jsx(React.Fragment, null, shouldOpenMediaViewer && jsx(OpenMediaViewerButton, {
58
+ fileName: fileName !== null && fileName !== void 0 ? fileName : '',
59
+ innerRef: openMediaViewerButtonRef,
60
+ onClick: onClick
61
+ }), jsx(Wrapper, {
62
+ testId: testId || 'media-card-svg-wrapper',
63
+ dimensions: dimensions,
64
+ onClick: onClick,
65
+ onMouseEnter: onMouseEnter,
66
+ innerRef: divRef,
67
+ mediaCardCursor: mediaCardCursor,
68
+ selected: !!selected,
69
+ breakpoint: breakpoint,
70
+ disableOverlay: true,
71
+ displayBackground: !didSvgRender && !didPreviewRender,
72
+ isTickBoxSelectable: false,
73
+ shouldDisplayTooltip: false,
74
+ isPlayButtonClickable: false
75
+ }, jsx(ImageContainer, {
76
+ centerElements: true,
77
+ testId: fileCardImageViewSelector,
78
+ mediaName: fileName,
79
+ status: status,
80
+ progress: progress,
81
+ selected: selected,
82
+ source: cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source
83
+ }, jsx(MediaSvg, {
84
+ testId: "media-card-svg",
85
+ identifier: identifier,
86
+ dimensions: svgDimensions,
87
+ onLoad: onSvgLoad,
88
+ style: {
89
+ visibility: didSvgRender ? 'visible' : 'hidden',
90
+ objectFit: convertResizeMode(resizeMode)
91
+ }
92
+ }), !!cardPreview && !didSvgRender && jsx(ImageRenderer, {
93
+ cardPreview: cardPreview,
94
+ onImageLoad: onPreviewLoad,
95
+ mediaType: 'image',
96
+ alt: alt,
97
+ resizeMode: resizeMode
98
+ }), status === 'uploading' && jsx(Blanket, {
99
+ isFixed: true
100
+ }), status === 'uploading' && jsx(ProgressBar, {
101
+ progress: progress,
102
+ breakpoint: breakpoint,
103
+ positionBottom: true
104
+ }))));
105
+ };
106
+ export const SvgView = withAnalyticsEvents({
107
+ onClick: createAndFireMediaCardEvent({
108
+ eventType: 'ui',
109
+ action: 'clicked',
110
+ actionSubject: 'mediaCard',
111
+ attributes: {}
112
+ })
113
+ })(SvgViewBase);
@@ -37,7 +37,7 @@ export default class MediaInlineCardLoader extends React.PureComponent {
37
37
  } = this.state;
38
38
  const analyticsContext = {
39
39
  packageVersion: "@atlaskit/media-card",
40
- packageName: "77.11.3",
40
+ packageName: "77.12.1",
41
41
  componentName: 'mediaInlineCard',
42
42
  component: 'mediaInlineCard'
43
43
  };