@atlaskit/media-card 81.10.19 → 81.12.0

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 (39) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/cjs/card/card.js +1 -1
  3. package/dist/cjs/card/cardView.js +47 -19
  4. package/dist/cjs/card/fileCard.js +3 -1
  5. package/dist/cjs/card/media-card-analytics-error-boundary.js +1 -1
  6. package/dist/cjs/card/ui/loadingHold/loadingHold.js +34 -0
  7. package/dist/cjs/card/ui/wrapper/imageContainer-compiled.compiled.css +8 -1
  8. package/dist/cjs/card/ui/wrapper/imageContainer-compiled.js +9 -2
  9. package/dist/cjs/inline/loader.js +1 -1
  10. package/dist/cjs/utils/lightCards/cardLoading.js +1 -5
  11. package/dist/cjs/utils/ufoExperiences.js +1 -1
  12. package/dist/es2019/card/card.js +1 -1
  13. package/dist/es2019/card/cardView.js +45 -19
  14. package/dist/es2019/card/fileCard.js +3 -1
  15. package/dist/es2019/card/media-card-analytics-error-boundary.js +1 -1
  16. package/dist/es2019/card/ui/loadingHold/loadingHold.js +29 -0
  17. package/dist/es2019/card/ui/wrapper/imageContainer-compiled.compiled.css +8 -1
  18. package/dist/es2019/card/ui/wrapper/imageContainer-compiled.js +9 -2
  19. package/dist/es2019/inline/loader.js +1 -1
  20. package/dist/es2019/utils/lightCards/cardLoading.js +1 -5
  21. package/dist/es2019/utils/ufoExperiences.js +1 -1
  22. package/dist/esm/card/card.js +1 -1
  23. package/dist/esm/card/cardView.js +47 -19
  24. package/dist/esm/card/fileCard.js +3 -1
  25. package/dist/esm/card/media-card-analytics-error-boundary.js +1 -1
  26. package/dist/esm/card/ui/loadingHold/loadingHold.js +28 -0
  27. package/dist/esm/card/ui/wrapper/imageContainer-compiled.compiled.css +8 -1
  28. package/dist/esm/card/ui/wrapper/imageContainer-compiled.js +9 -2
  29. package/dist/esm/inline/loader.js +1 -1
  30. package/dist/esm/utils/lightCards/cardLoading.js +1 -5
  31. package/dist/esm/utils/ufoExperiences.js +1 -1
  32. package/dist/types/card/cardView.d.ts +3 -2
  33. package/dist/types/card/fileCard.d.ts +6 -1
  34. package/dist/types/card/ui/loadingHold/loadingHold.d.ts +12 -0
  35. package/dist/types/card/ui/wrapper/imageContainer-compiled.d.ts +6 -1
  36. package/dist/types/card/ui/wrapper/imageContainer.d.ts +1 -0
  37. package/dist/types/types.d.ts +1 -0
  38. package/example-helpers/index.tsx +5 -2
  39. package/package.json +6 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @atlaskit/media-card
2
2
 
3
+ ## 81.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`2a1e8245a006e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2a1e8245a006e) -
8
+ Clean up experiment `cc-maui-ai-edit-loading-experiment`. The enabled behaviour is now permanent:
9
+ media cards and MAUI embeds always render the simple loading bar instead of the spinner/icon
10
+ carousel, and the AI-edit blanket overlay is always applied when a MAUI app is replaced from the
11
+ toolbar.
12
+
13
+ `@atlaskit/tmp-editor-statsig` removes the `cc-maui-ai-edit-loading-experiment` key from
14
+ `editorExperimentsConfig`, so reading it via `expValEquals`/`expValEqualsNoExposure` is now a type
15
+ error — remove those call sites.
16
+
17
+ `@atlaskit/media-card` drops its now-unused `@atlaskit/spinner` dependency, and
18
+ `@atlassian/native-embeds-maui-experience` drops its now-unused `@atlaskit/icon-lab` dependency.
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+
24
+ ## 81.11.0
25
+
26
+ ### Minor Changes
27
+
28
+ - [`2d026706450c6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2d026706450c6) -
29
+ Add the `allowAIGeneratedMediaMotion` media plugin option and the `hasLoadingMotion` card prop, so
30
+ media that arrives mid-flight opens the document out to make room for itself and then fades its
31
+ preview in, instead of drawing a loading indicator and snapping into place. Behind
32
+ `aifc_page_create_defer_generated_visuals`.
33
+
3
34
  ## 81.10.19
4
35
 
5
36
  ### Patch Changes
@@ -8,7 +8,7 @@ var _reactIntl = require("react-intl");
8
8
  var _mediaCommon = require("@atlaskit/media-common");
9
9
  var _CardWithPerformanceObserver = require("./CardWithPerformanceObserver");
10
10
  var packageName = "@atlaskit/media-card";
11
- var packageVersion = "81.10.18";
11
+ var packageVersion = "81.11.0";
12
12
  var Card = exports.Card = (0, _mediaCommon.withMediaAnalyticsContext)({
13
13
  packageVersion: packageVersion,
14
14
  packageName: packageName,
@@ -16,7 +16,6 @@ var _mediaClient = require("@atlaskit/media-client");
16
16
  var _messages = require("@atlaskit/media-ui/messages");
17
17
  var _mimeTypeIcon = require("@atlaskit/media-ui/mime-type-icon");
18
18
  var _fg = require("@atlaskit/platform-feature-flags/fg");
19
- var _spinner = _interopRequireDefault(require("@atlaskit/spinner/spinner"));
20
19
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
21
20
  var _Tooltip = _interopRequireDefault(require("@atlaskit/tooltip/Tooltip"));
22
21
  var _isUploadError = require("../isUploadError");
@@ -36,6 +35,7 @@ var _PreviewUnavailable = require("./ui/iconMessage/PreviewUnavailable");
36
35
  var _iconWrapper = require("./ui/iconWrapper/iconWrapper");
37
36
  var _imageRenderer = require("./ui/imageRenderer");
38
37
  var _loadingBar = require("./ui/loadingBar/loadingBar");
38
+ var _loadingHold = require("./ui/loadingHold/loadingHold");
39
39
  var _openMediaViewerButton = _interopRequireDefault(require("./ui/openMediaViewerButton/openMediaViewerButton"));
40
40
  var _playButton = require("./ui/playButton/playButton");
41
41
  var _progressBar = require("./ui/progressBar/progressBar");
@@ -99,6 +99,7 @@ var CardViewBase = exports.CardViewBase = function CardViewBase(_ref) {
99
99
  traceId = _ref.traceId,
100
100
  isAIGenerating = _ref.isAIGenerating,
101
101
  isCWR = _ref.isCWR,
102
+ hasLoadingMotion = _ref.hasLoadingMotion,
102
103
  backgroundColor = _ref.backgroundColor;
103
104
  var intl = (0, _reactIntl.useIntl)();
104
105
  var _useState = (0, _react.useState)(false),
@@ -112,6 +113,18 @@ var CardViewBase = exports.CardViewBase = function CardViewBase(_ref) {
112
113
  var divRef = (0, _react.useRef)(null);
113
114
  var prevCardPreviewRef = (0, _react.useRef)();
114
115
  var breakpoint = (0, _useBreakpoint.useBreakpoint)(dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, divRef);
116
+ var isErrorStatus = status === 'error' || status === 'failed-processing';
117
+ // While the motion owns the loading presentation the card draws nothing of its own — no
118
+ // indicator, progress bar, type icon or background — so the consumer can open space into
119
+ // emptiness and fade the preview in over it. Errors keep their normal treatment, or a
120
+ // failure would be indistinguishable from empty space.
121
+ //
122
+ // Every consumer below derives from this, so gating it here enforces the gate at the
123
+ // component boundary rather than trusting callers to do it. The prop is the left operand
124
+ // because every media card in every product renders this component — reading the gate
125
+ // unconditionally would put all of them in its exposure population. `isErrorStatus` is
126
+ // checked after it, so cards that opted in still count towards that population.
127
+ var suppressLoadingUI = !!hasLoadingMotion && (0, _fg.fg)('aifc_page_create_defer_generated_visuals') && !isErrorStatus;
115
128
  (0, _react.useEffect)(function () {
116
129
  // We should only switch didImageRender to false when cardPreview goes undefined, not when it is changed. as this method could be triggered after onImageLoad callback, falling on a race condition
117
130
  if (prevCardPreviewRef.current && !cardPreview) {
@@ -166,18 +179,20 @@ var CardViewBase = exports.CardViewBase = function CardViewBase(_ref) {
166
179
  var loadingConfig = _objectSpread(_objectSpread({}, defaultConfig), {}, {
167
180
  renderPlayButton: false,
168
181
  renderTypeIcon: false,
169
- renderSpinner: !didImageRender && !didSvgRender
182
+ renderLoading: !didImageRender && !didSvgRender
170
183
  });
171
184
  switch (status) {
172
185
  case 'uploading':
173
186
  return _objectSpread(_objectSpread({}, defaultConfig), {}, {
174
- renderBlanket: !disableOverlay || mediaType !== 'video',
187
+ renderBlanket: !suppressLoadingUI && (!disableOverlay || mediaType !== 'video'),
175
188
  isFixedBlanket: true,
176
- renderProgressBar: !isAIGenerating
189
+ renderProgressBar: !isAIGenerating && !suppressLoadingUI,
190
+ renderTypeIcon: !suppressLoadingUI && defaultConfig.renderTypeIcon
177
191
  });
178
192
  case 'processing':
179
193
  return _objectSpread(_objectSpread({}, defaultConfig), {}, {
180
- iconMessage: !didImageRender && !isZeroSize ? /*#__PURE__*/_react.default.createElement(_CreatingPreview.CreatingPreview, {
194
+ renderTypeIcon: !suppressLoadingUI && defaultConfig.renderTypeIcon,
195
+ iconMessage: !didImageRender && !isZeroSize && !suppressLoadingUI ? /*#__PURE__*/_react.default.createElement(_CreatingPreview.CreatingPreview, {
181
196
  disableAnimation: disableAnimation
182
197
  }) : undefined
183
198
  });
@@ -236,7 +251,7 @@ var CardViewBase = exports.CardViewBase = function CardViewBase(_ref) {
236
251
  iconMessage = _getRenderConfigBySta.iconMessage,
237
252
  renderImageRenderer = _getRenderConfigBySta.renderImageRenderer,
238
253
  renderSvgView = _getRenderConfigBySta.renderSvgView,
239
- renderSpinner = _getRenderConfigBySta.renderSpinner,
254
+ renderLoading = _getRenderConfigBySta.renderLoading,
240
255
  renderPlayButton = _getRenderConfigBySta.renderPlayButton,
241
256
  renderBlanket = _getRenderConfigBySta.renderBlanket,
242
257
  renderProgressBar = _getRenderConfigBySta.renderProgressBar,
@@ -249,9 +264,12 @@ var CardViewBase = exports.CardViewBase = function CardViewBase(_ref) {
249
264
 
250
265
  // AI border shown while generating; cleared by the decoration on upload completion.
251
266
  /* eslint-disable @atlaskit/platform/no-preconditioning -- loading-specific gate (cc-maui-phase-2) layered on the MAUI experiment cohort during phased rollout; preconditioning is intentional and will be removed when the existing gates are cleaned up */
252
- var renderAIBorderOverride = !!isAIGenerating && (0, _fg.fg)('cc-maui-phase-2') && (0, _expValEquals.expValEquals)('cc-maui-experiment', 'isEnabled', true);
267
+ var renderAIBorderOverride = !!isAIGenerating && (0, _fg.fg)('cc-maui-phase-2') && (0, _expValEquals.expValEquals)('cc-maui-experiment', 'isEnabled', true) &&
268
+ // Last so the gates above are still evaluated, and their exposures still fire, on
269
+ // surfaces that suppress the overlay.
270
+ !suppressLoadingUI;
253
271
  /* eslint-enable @atlaskit/platform/no-preconditioning */
254
- var shouldDisplayBackground = !cardPreview || !disableOverlay || status === 'error' || status === 'failed-processing';
272
+ var shouldDisplayBackground = status === 'error' || status === 'failed-processing' || !suppressLoadingUI && (!cardPreview || !disableOverlay);
255
273
  var isPlayButtonClickable = shouldRenderPlayButton() && !!disableOverlay;
256
274
  var isTickBoxSelectable = !disableOverlay && !!selectable && !selected;
257
275
  var _ref4 = metadata || {},
@@ -291,6 +309,19 @@ var CardViewBase = exports.CardViewBase = function CardViewBase(_ref) {
291
309
  setDidSvgRender(true);
292
310
  onSvgLoad === null || onSvgLoad === void 0 || onSvgLoad();
293
311
  };
312
+
313
+ // Held back until the preview has rendered, then faded in over the card's surface.
314
+ var mediaMotion;
315
+ if (suppressLoadingUI) {
316
+ mediaMotion = didImageRender || didSvgRender ? 'entering' : 'hidden';
317
+ }
318
+ var renderLoadingPlaceholder = function renderLoadingPlaceholder() {
319
+ return /*#__PURE__*/_react.default.createElement(_loadingBar.LoadingBar, {
320
+ animationDisabled: disableAnimation,
321
+ testId: "media-card-loading",
322
+ interactionName: "media-card-loading"
323
+ });
324
+ };
294
325
  var contents = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_imageContainer.ImageContainer, {
295
326
  centerElements: didSvgRender && !(0, _fg.fg)('platform_media_card_image_render') // The whole centerElements styles can go after removing the flag
296
327
  ,
@@ -300,7 +331,8 @@ var CardViewBase = exports.CardViewBase = function CardViewBase(_ref) {
300
331
  progress: progress,
301
332
  mediaCardCursor: mediaCardCursor,
302
333
  selected: selected,
303
- source: cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source
334
+ source: cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source,
335
+ mediaMotion: mediaMotion
304
336
  }, renderTypeIcon && /*#__PURE__*/_react.default.createElement(_iconWrapper.IconWrapper, {
305
337
  breakpoint: breakpoint,
306
338
  hasTitleBox: hasVisibleTitleBox
@@ -309,17 +341,13 @@ var CardViewBase = exports.CardViewBase = function CardViewBase(_ref) {
309
341
  mediaType: mediaType,
310
342
  mimeType: mimeType,
311
343
  name: name
312
- }), iconMessage), renderSpinner && ((0, _expValEquals.expValEquals)('cc-maui-ai-edit-loading-experiment', 'isEnabled', true) ? /*#__PURE__*/_react.default.createElement(_loadingBar.LoadingBar, {
313
- animationDisabled: disableAnimation,
314
- testId: "media-card-loading",
315
- interactionName: "media-card-loading"
316
- }) : /*#__PURE__*/_react.default.createElement(_iconWrapper.IconWrapper, {
317
- breakpoint: breakpoint,
318
- hasTitleBox: hasVisibleTitleBox
319
- }, /*#__PURE__*/_react.default.createElement(_spinner.default, {
320
- testId: "media-card-loading",
344
+ }), iconMessage), renderLoading && (suppressLoadingUI ?
345
+ /*#__PURE__*/
346
+ // Nothing is drawn, but the interaction still has to be held for the
347
+ // same window as the indicator it replaces.
348
+ _react.default.createElement(_loadingHold.LoadingHold, {
321
349
  interactionName: "media-card-loading"
322
- }))), renderSvgView && identifier && (0, _mediaClient.isFileIdentifier)(identifier) && /*#__PURE__*/_react.default.createElement(_svgView.SvgView, {
350
+ }) : renderLoadingPlaceholder()), renderSvgView && identifier && (0, _mediaClient.isFileIdentifier)(identifier) && /*#__PURE__*/_react.default.createElement(_svgView.SvgView, {
323
351
  identifier: identifier,
324
352
  resizeMode: resizeMode || 'crop',
325
353
  onError: onSvgError,
@@ -97,6 +97,7 @@ var FileCard = exports.FileCard = function FileCard(_ref) {
97
97
  backgroundColor = _ref.backgroundColor,
98
98
  isAIGenerating = _ref.isAIGenerating,
99
99
  isCWR = _ref.isCWR,
100
+ hasLoadingMotion = _ref.hasLoadingMotion,
100
101
  onPreviewRender = _ref.onPreviewRender,
101
102
  shouldHideTooltip = _ref.shouldHideTooltip,
102
103
  mediaViewerItems = _ref.mediaViewerItems,
@@ -803,7 +804,8 @@ var FileCard = exports.FileCard = function FileCard(_ref) {
803
804
  shouldHideTooltip: shouldHideTooltip,
804
805
  overriddenCreationDate: overridenDate,
805
806
  isAIGenerating: isAIGenerating,
806
- isCWR: isCWR
807
+ isCWR: isCWR,
808
+ hasLoadingMotion: hasLoadingMotion
807
809
  });
808
810
  return isLazyWithOverride ? /*#__PURE__*/_react.default.createElement(_viewportDetector.ViewportDetector, {
809
811
  cardEl: cardElement,
@@ -87,7 +87,7 @@ var WrappedMediaCardAnalyticsErrorBoundary = /*#__PURE__*/function (_React$Compo
87
87
  }(_react.default.Component);
88
88
  (0, _defineProperty2.default)(WrappedMediaCardAnalyticsErrorBoundary, "displayName", 'MediaCardAnalyticsErrorBoundary');
89
89
  var packageName = "@atlaskit/media-card";
90
- var packageVersion = "81.10.18";
90
+ var packageVersion = "81.11.0";
91
91
 
92
92
  // @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18
93
93
  var MediaCardAnalyticsErrorBoundary = (0, _mediaCommon.withMediaAnalyticsContext)({
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.LoadingHold = void 0;
8
+ var _react = require("react");
9
+ var _interactionContext = _interopRequireDefault(require("@atlaskit/interaction-context"));
10
+ /**
11
+ * `useLayoutEffect` in SSR-safe form, matching `LoadingBar` and the DS interaction-tracing
12
+ * convention.
13
+ *
14
+ * @see https://hello.atlassian.net/wiki/spaces/DST/pages/2081696628/DSTDACI-010+-+Interaction+Tracing+hooks+in+DS+components
15
+ */
16
+ var useLayoutEffect = typeof window === 'undefined' ? _react.useEffect : _react.useLayoutEffect;
17
+ /**
18
+ * Holds the in-progress interaction while a card is loading, without drawing anything.
19
+ *
20
+ * `LoadingBar` and `Spinner` each own a hold for as long as they are mounted. Cards that
21
+ * express loading through motion instead still need the interaction held for the same window,
22
+ * so this stands in for them under the same `interactionName` — mounted and unmounted at the
23
+ * same points, so UFO traces stay comparable either way.
24
+ */
25
+ var LoadingHold = exports.LoadingHold = function LoadingHold(_ref) {
26
+ var interactionName = _ref.interactionName;
27
+ var interactionContext = (0, _react.useContext)(_interactionContext.default);
28
+ useLayoutEffect(function () {
29
+ if (interactionContext != null) {
30
+ return interactionContext.hold(interactionName);
31
+ }
32
+ }, [interactionContext, interactionName]);
33
+ return null;
34
+ };
@@ -2,10 +2,17 @@
2
2
  ._1bah1h6o{justify-content:center}
3
3
  ._1bsb1osq{width:100%}
4
4
  ._1e0c1txw{display:flex}
5
+ ._1o511hrf{animation-fill-mode:both}
6
+ ._1pglindk{animation-timing-function:var(--ds-easing-out-practical,cubic-bezier(.4,1,.6,1))}
5
7
  ._1reo15vq{overflow-x:hidden}
6
8
  ._2lx21bp4{flex-direction:column}
7
9
  ._4cvr1h6o{align-items:center}
8
10
  ._4t3i1osq{height:100%}
11
+ ._5sagi9qs{animation-duration:var(--ds-duration-medium,.2s)}
9
12
  ._c71l1osq{max-height:100%}
13
+ ._j7hq1bym{animation-name:var(--ds-keyframe-fade-in,FadeIn0to100)}
14
+ ._ju2515uc{animation-delay:var(--ds-duration-xlong,.4s)}
10
15
  ._kqswh2mm{position:relative}
11
- ._p12f1osq{max-width:100%}
16
+ ._p12f1osq{max-width:100%}
17
+ ._tzy4idpf{opacity:0}
18
+ @media (prefers-reduced-motion:reduce){._1bumglyw{animation:none}}
@@ -13,6 +13,12 @@ var _classnames = require("../../classnames");
13
13
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
14
14
  var imageContainerStyles = null;
15
15
  var imageContainerCenterStyles = null;
16
+
17
+ // Holds the preview back until it has decoded, so it can be faded in rather than appearing the
18
+ // instant it becomes displayable. Nothing is drawn in the meantime — consumers using this
19
+ // motion keep the node out of the layout until the preview is ready.
20
+ var mediaMotionHiddenStyles = null;
21
+ var mediaMotionEnteringStyles = null;
16
22
  var ImageContainer = exports.ImageContainer = function ImageContainer(_ref) {
17
23
  var children = _ref.children,
18
24
  mediaName = _ref.mediaName,
@@ -21,7 +27,8 @@ var ImageContainer = exports.ImageContainer = function ImageContainer(_ref) {
21
27
  selected = _ref.selected,
22
28
  source = _ref.source,
23
29
  centerElements = _ref.centerElements,
24
- mediaCardCursor = _ref.mediaCardCursor;
30
+ mediaCardCursor = _ref.mediaCardCursor,
31
+ mediaMotion = _ref.mediaMotion;
25
32
  return /*#__PURE__*/React.createElement("div", {
26
33
  "data-testid": _classnames.fileCardImageViewSelector
27
34
  /**
@@ -31,7 +38,7 @@ var ImageContainer = exports.ImageContainer = function ImageContainer(_ref) {
31
38
  */
32
39
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
33
40
  ,
34
- className: (0, _runtime.ax)(["_1reo15vq _18m915vq _2rko18qm _1e0c1txw _kqswh2mm _p12f1osq _1bsb1osq _4t3i1osq _c71l1osq", centerElements && "_2lx21bp4 _1bah1h6o _4cvr1h6o", _classnames.fileCardImageViewSelector]),
41
+ className: (0, _runtime.ax)(["_1reo15vq _18m915vq _2rko18qm _1e0c1txw _kqswh2mm _p12f1osq _1bsb1osq _4t3i1osq _c71l1osq", centerElements && "_2lx21bp4 _1bah1h6o _4cvr1h6o", mediaMotion === 'hidden' && "_tzy4idpf", mediaMotion === 'entering' && "_j7hq1bym _5sagi9qs _1pglindk _ju2515uc _1o511hrf _1bumglyw", _classnames.fileCardImageViewSelector]),
35
42
  "data-test-media-name": mediaName,
36
43
  "data-test-status": status,
37
44
  "data-test-progress": progress,
@@ -116,7 +116,7 @@ var MediaInlineCardLoader = exports.default = /*#__PURE__*/function (_React$Pure
116
116
  ErrorBoundary = _this$state.ErrorBoundary;
117
117
  var analyticsContext = {
118
118
  packageVersion: "@atlaskit/media-card",
119
- packageName: "81.10.18",
119
+ packageName: "81.11.0",
120
120
  componentName: 'mediaInlineCard',
121
121
  component: 'mediaInlineCard'
122
122
  };
@@ -6,8 +6,6 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.CardLoading = void 0;
8
8
  var _react = _interopRequireDefault(require("react"));
9
- var _spinner = _interopRequireDefault(require("@atlaskit/spinner/spinner"));
10
- var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
11
9
  var _loadingBar = require("../../card/ui/loadingBar/loadingBar");
12
10
  var _getDimensionsWithDefault = require("./getDimensionsWithDefault");
13
11
  var _lightCardWrappers = require("./lightCardWrappers");
@@ -21,9 +19,7 @@ var CardLoading = exports.CardLoading = function CardLoading(_ref) {
21
19
  "data-test-loading": true,
22
20
  dimensions: dimensions,
23
21
  "data-vc": "media-card-loading"
24
- }, (0, _expValEquals.expValEquals)('cc-maui-ai-edit-loading-experiment', 'isEnabled', true) ? /*#__PURE__*/_react.default.createElement(_loadingBar.LoadingBar, {
25
- interactionName: interactionName || 'media-card-loading'
26
- }) : /*#__PURE__*/_react.default.createElement(_spinner.default, {
22
+ }, /*#__PURE__*/_react.default.createElement(_loadingBar.LoadingBar, {
27
23
  interactionName: interactionName || 'media-card-loading'
28
24
  }));
29
25
  };
@@ -23,7 +23,7 @@ var _getMediaGlobalScope = require("./globalScope/getMediaGlobalScope");
23
23
  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; }
24
24
  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; }
25
25
  var packageName = "@atlaskit/media-card";
26
- var packageVersion = "81.10.18";
26
+ var packageVersion = "81.11.0";
27
27
  var SAMPLE_RATE = 0.05;
28
28
 
29
29
  /**
@@ -2,7 +2,7 @@ import { injectIntl } from 'react-intl';
2
2
  import { withMediaAnalyticsContext } from '@atlaskit/media-common';
3
3
  import { CardWithPerformanceObserver } from './CardWithPerformanceObserver';
4
4
  const packageName = "@atlaskit/media-card";
5
- const packageVersion = "81.10.18";
5
+ const packageVersion = "81.11.0";
6
6
  export const Card = withMediaAnalyticsContext({
7
7
  packageVersion,
8
8
  packageName,
@@ -6,7 +6,6 @@ import { isFileIdentifier } from '@atlaskit/media-client';
6
6
  import { messages } from '@atlaskit/media-ui/messages';
7
7
  import { MimeTypeIcon } from '@atlaskit/media-ui/mime-type-icon';
8
8
  import { fg } from '@atlaskit/platform-feature-flags/fg';
9
- import SpinnerIcon from '@atlaskit/spinner/spinner';
10
9
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
11
10
  import Tooltip from '@atlaskit/tooltip/Tooltip';
12
11
  import { isUploadError } from '../isUploadError';
@@ -26,6 +25,7 @@ import { PreviewUnavailable } from './ui/iconMessage/PreviewUnavailable';
26
25
  import { IconWrapper } from './ui/iconWrapper/iconWrapper';
27
26
  import { ImageRenderer } from './ui/imageRenderer';
28
27
  import { LoadingBar } from './ui/loadingBar/loadingBar';
28
+ import { LoadingHold } from './ui/loadingHold/loadingHold';
29
29
  import OpenMediaViewerButton from './ui/openMediaViewerButton/openMediaViewerButton';
30
30
  import { PlayButton } from './ui/playButton/playButton';
31
31
  import { ProgressBar } from './ui/progressBar/progressBar';
@@ -84,6 +84,7 @@ export const CardViewBase = ({
84
84
  traceId,
85
85
  isAIGenerating,
86
86
  isCWR,
87
+ hasLoadingMotion,
87
88
  backgroundColor
88
89
  }) => {
89
90
  const intl = useIntl();
@@ -92,6 +93,18 @@ export const CardViewBase = ({
92
93
  const divRef = useRef(null);
93
94
  const prevCardPreviewRef = useRef();
94
95
  const breakpoint = useBreakpoint(dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, divRef);
96
+ const isErrorStatus = status === 'error' || status === 'failed-processing';
97
+ // While the motion owns the loading presentation the card draws nothing of its own — no
98
+ // indicator, progress bar, type icon or background — so the consumer can open space into
99
+ // emptiness and fade the preview in over it. Errors keep their normal treatment, or a
100
+ // failure would be indistinguishable from empty space.
101
+ //
102
+ // Every consumer below derives from this, so gating it here enforces the gate at the
103
+ // component boundary rather than trusting callers to do it. The prop is the left operand
104
+ // because every media card in every product renders this component — reading the gate
105
+ // unconditionally would put all of them in its exposure population. `isErrorStatus` is
106
+ // checked after it, so cards that opted in still count towards that population.
107
+ const suppressLoadingUI = !!hasLoadingMotion && fg('aifc_page_create_defer_generated_visuals') && !isErrorStatus;
95
108
  useEffect(() => {
96
109
  // We should only switch didImageRender to false when cardPreview goes undefined, not when it is changed. as this method could be triggered after onImageLoad callback, falling on a race condition
97
110
  if (prevCardPreviewRef.current && !cardPreview) {
@@ -149,20 +162,22 @@ export const CardViewBase = ({
149
162
  ...defaultConfig,
150
163
  renderPlayButton: false,
151
164
  renderTypeIcon: false,
152
- renderSpinner: !didImageRender && !didSvgRender
165
+ renderLoading: !didImageRender && !didSvgRender
153
166
  };
154
167
  switch (status) {
155
168
  case 'uploading':
156
169
  return {
157
170
  ...defaultConfig,
158
- renderBlanket: !disableOverlay || mediaType !== 'video',
171
+ renderBlanket: !suppressLoadingUI && (!disableOverlay || mediaType !== 'video'),
159
172
  isFixedBlanket: true,
160
- renderProgressBar: !isAIGenerating
173
+ renderProgressBar: !isAIGenerating && !suppressLoadingUI,
174
+ renderTypeIcon: !suppressLoadingUI && defaultConfig.renderTypeIcon
161
175
  };
162
176
  case 'processing':
163
177
  return {
164
178
  ...defaultConfig,
165
- iconMessage: !didImageRender && !isZeroSize ? /*#__PURE__*/React.createElement(CreatingPreview, {
179
+ renderTypeIcon: !suppressLoadingUI && defaultConfig.renderTypeIcon,
180
+ iconMessage: !didImageRender && !isZeroSize && !suppressLoadingUI ? /*#__PURE__*/React.createElement(CreatingPreview, {
166
181
  disableAnimation: disableAnimation
167
182
  }) : undefined
168
183
  };
@@ -224,7 +239,7 @@ export const CardViewBase = ({
224
239
  iconMessage,
225
240
  renderImageRenderer,
226
241
  renderSvgView,
227
- renderSpinner,
242
+ renderLoading,
228
243
  renderPlayButton,
229
244
  renderBlanket,
230
245
  renderProgressBar,
@@ -238,9 +253,12 @@ export const CardViewBase = ({
238
253
 
239
254
  // AI border shown while generating; cleared by the decoration on upload completion.
240
255
  /* eslint-disable @atlaskit/platform/no-preconditioning -- loading-specific gate (cc-maui-phase-2) layered on the MAUI experiment cohort during phased rollout; preconditioning is intentional and will be removed when the existing gates are cleaned up */
241
- const renderAIBorderOverride = !!isAIGenerating && fg('cc-maui-phase-2') && expValEquals('cc-maui-experiment', 'isEnabled', true);
256
+ const renderAIBorderOverride = !!isAIGenerating && fg('cc-maui-phase-2') && expValEquals('cc-maui-experiment', 'isEnabled', true) &&
257
+ // Last so the gates above are still evaluated, and their exposures still fire, on
258
+ // surfaces that suppress the overlay.
259
+ !suppressLoadingUI;
242
260
  /* eslint-enable @atlaskit/platform/no-preconditioning */
243
- const shouldDisplayBackground = !cardPreview || !disableOverlay || status === 'error' || status === 'failed-processing';
261
+ const shouldDisplayBackground = status === 'error' || status === 'failed-processing' || !suppressLoadingUI && (!cardPreview || !disableOverlay);
244
262
  const isPlayButtonClickable = shouldRenderPlayButton() && !!disableOverlay;
245
263
  const isTickBoxSelectable = !disableOverlay && !!selectable && !selected;
246
264
  const {
@@ -280,6 +298,17 @@ export const CardViewBase = ({
280
298
  setDidSvgRender(true);
281
299
  onSvgLoad === null || onSvgLoad === void 0 ? void 0 : onSvgLoad();
282
300
  };
301
+
302
+ // Held back until the preview has rendered, then faded in over the card's surface.
303
+ let mediaMotion;
304
+ if (suppressLoadingUI) {
305
+ mediaMotion = didImageRender || didSvgRender ? 'entering' : 'hidden';
306
+ }
307
+ const renderLoadingPlaceholder = () => /*#__PURE__*/React.createElement(LoadingBar, {
308
+ animationDisabled: disableAnimation,
309
+ testId: "media-card-loading",
310
+ interactionName: "media-card-loading"
311
+ });
283
312
  const contents = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ImageContainer, {
284
313
  centerElements: didSvgRender && !fg('platform_media_card_image_render') // The whole centerElements styles can go after removing the flag
285
314
  ,
@@ -289,7 +318,8 @@ export const CardViewBase = ({
289
318
  progress: progress,
290
319
  mediaCardCursor: mediaCardCursor,
291
320
  selected: selected,
292
- source: cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source
321
+ source: cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source,
322
+ mediaMotion: mediaMotion
293
323
  }, renderTypeIcon && /*#__PURE__*/React.createElement(IconWrapper, {
294
324
  breakpoint: breakpoint,
295
325
  hasTitleBox: hasVisibleTitleBox
@@ -298,17 +328,13 @@ export const CardViewBase = ({
298
328
  mediaType: mediaType,
299
329
  mimeType: mimeType,
300
330
  name: name
301
- }), iconMessage), renderSpinner && (expValEquals('cc-maui-ai-edit-loading-experiment', 'isEnabled', true) ? /*#__PURE__*/React.createElement(LoadingBar, {
302
- animationDisabled: disableAnimation,
303
- testId: "media-card-loading",
304
- interactionName: "media-card-loading"
305
- }) : /*#__PURE__*/React.createElement(IconWrapper, {
306
- breakpoint: breakpoint,
307
- hasTitleBox: hasVisibleTitleBox
308
- }, /*#__PURE__*/React.createElement(SpinnerIcon, {
309
- testId: "media-card-loading",
331
+ }), iconMessage), renderLoading && (suppressLoadingUI ?
332
+ /*#__PURE__*/
333
+ // Nothing is drawn, but the interaction still has to be held for the
334
+ // same window as the indicator it replaces.
335
+ React.createElement(LoadingHold, {
310
336
  interactionName: "media-card-loading"
311
- }))), renderSvgView && identifier && isFileIdentifier(identifier) && /*#__PURE__*/React.createElement(SvgView, {
337
+ }) : renderLoadingPlaceholder()), renderSvgView && identifier && isFileIdentifier(identifier) && /*#__PURE__*/React.createElement(SvgView, {
312
338
  identifier: identifier,
313
339
  resizeMode: resizeMode || 'crop',
314
340
  onError: onSvgError,
@@ -78,6 +78,7 @@ export const FileCard = ({
78
78
  backgroundColor,
79
79
  isAIGenerating,
80
80
  isCWR,
81
+ hasLoadingMotion,
81
82
  onPreviewRender,
82
83
  shouldHideTooltip,
83
84
  mediaViewerItems,
@@ -718,7 +719,8 @@ export const FileCard = ({
718
719
  shouldHideTooltip: shouldHideTooltip,
719
720
  overriddenCreationDate: overridenDate,
720
721
  isAIGenerating: isAIGenerating,
721
- isCWR: isCWR
722
+ isCWR: isCWR,
723
+ hasLoadingMotion: hasLoadingMotion
722
724
  });
723
725
  return isLazyWithOverride ? /*#__PURE__*/React.createElement(ViewportDetector, {
724
726
  cardEl: cardElement,
@@ -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 = "81.10.18";
69
+ const packageVersion = "81.11.0";
70
70
 
71
71
  // @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18
72
72
  const MediaCardAnalyticsErrorBoundary = withMediaAnalyticsContext({
@@ -0,0 +1,29 @@
1
+ import { useContext, useEffect, useLayoutEffect as useRealLayoutEffect } from 'react';
2
+ import InteractionContext from '@atlaskit/interaction-context';
3
+
4
+ /**
5
+ * `useLayoutEffect` in SSR-safe form, matching `LoadingBar` and the DS interaction-tracing
6
+ * convention.
7
+ *
8
+ * @see https://hello.atlassian.net/wiki/spaces/DST/pages/2081696628/DSTDACI-010+-+Interaction+Tracing+hooks+in+DS+components
9
+ */
10
+ const useLayoutEffect = typeof window === 'undefined' ? useEffect : useRealLayoutEffect;
11
+ /**
12
+ * Holds the in-progress interaction while a card is loading, without drawing anything.
13
+ *
14
+ * `LoadingBar` and `Spinner` each own a hold for as long as they are mounted. Cards that
15
+ * express loading through motion instead still need the interaction held for the same window,
16
+ * so this stands in for them under the same `interactionName` — mounted and unmounted at the
17
+ * same points, so UFO traces stay comparable either way.
18
+ */
19
+ export const LoadingHold = ({
20
+ interactionName
21
+ }) => {
22
+ const interactionContext = useContext(InteractionContext);
23
+ useLayoutEffect(() => {
24
+ if (interactionContext != null) {
25
+ return interactionContext.hold(interactionName);
26
+ }
27
+ }, [interactionContext, interactionName]);
28
+ return null;
29
+ };
@@ -2,10 +2,17 @@
2
2
  ._1bah1h6o{justify-content:center}
3
3
  ._1bsb1osq{width:100%}
4
4
  ._1e0c1txw{display:flex}
5
+ ._1o511hrf{animation-fill-mode:both}
6
+ ._1pglindk{animation-timing-function:var(--ds-easing-out-practical,cubic-bezier(.4,1,.6,1))}
5
7
  ._1reo15vq{overflow-x:hidden}
6
8
  ._2lx21bp4{flex-direction:column}
7
9
  ._4cvr1h6o{align-items:center}
8
10
  ._4t3i1osq{height:100%}
11
+ ._5sagi9qs{animation-duration:var(--ds-duration-medium,.2s)}
9
12
  ._c71l1osq{max-height:100%}
13
+ ._j7hq1bym{animation-name:var(--ds-keyframe-fade-in,FadeIn0to100)}
14
+ ._ju2515uc{animation-delay:var(--ds-duration-xlong,.4s)}
10
15
  ._kqswh2mm{position:relative}
11
- ._p12f1osq{max-width:100%}
16
+ ._p12f1osq{max-width:100%}
17
+ ._tzy4idpf{opacity:0}
18
+ @media (prefers-reduced-motion:reduce){._1bumglyw{animation:none}}
@@ -5,6 +5,12 @@ import { ax, ix } from "@compiled/react/runtime";
5
5
  import { fileCardImageViewSelector } from '../../classnames';
6
6
  const imageContainerStyles = null;
7
7
  const imageContainerCenterStyles = null;
8
+
9
+ // Holds the preview back until it has decoded, so it can be faded in rather than appearing the
10
+ // instant it becomes displayable. Nothing is drawn in the meantime — consumers using this
11
+ // motion keep the node out of the layout until the preview is ready.
12
+ const mediaMotionHiddenStyles = null;
13
+ const mediaMotionEnteringStyles = null;
8
14
  export const ImageContainer = ({
9
15
  children,
10
16
  mediaName,
@@ -13,7 +19,8 @@ export const ImageContainer = ({
13
19
  selected,
14
20
  source,
15
21
  centerElements,
16
- mediaCardCursor
22
+ mediaCardCursor,
23
+ mediaMotion
17
24
  }) => /*#__PURE__*/React.createElement("div", {
18
25
  "data-testid": fileCardImageViewSelector
19
26
  /**
@@ -23,7 +30,7 @@ export const ImageContainer = ({
23
30
  */
24
31
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
25
32
  ,
26
- className: ax(["_1reo15vq _18m915vq _2rko18qm _1e0c1txw _kqswh2mm _p12f1osq _1bsb1osq _4t3i1osq _c71l1osq", centerElements && "_2lx21bp4 _1bah1h6o _4cvr1h6o", fileCardImageViewSelector]),
33
+ className: ax(["_1reo15vq _18m915vq _2rko18qm _1e0c1txw _kqswh2mm _p12f1osq _1bsb1osq _4t3i1osq _c71l1osq", centerElements && "_2lx21bp4 _1bah1h6o _4cvr1h6o", mediaMotion === 'hidden' && "_tzy4idpf", mediaMotion === 'entering' && "_j7hq1bym _5sagi9qs _1pglindk _ju2515uc _1o511hrf _1bumglyw", fileCardImageViewSelector]),
27
34
  "data-test-media-name": mediaName,
28
35
  "data-test-status": status,
29
36
  "data-test-progress": progress,
@@ -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: "81.10.18",
40
+ packageName: "81.11.0",
41
41
  componentName: 'mediaInlineCard',
42
42
  component: 'mediaInlineCard'
43
43
  };
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
- import SpinnerIcon from '@atlaskit/spinner/spinner';
3
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
2
  import { LoadingBar } from '../../card/ui/loadingBar/loadingBar';
5
3
  import { getDimensionsWithDefault } from './getDimensionsWithDefault';
6
4
  import { Wrapper } from './lightCardWrappers';
@@ -15,9 +13,7 @@ export const CardLoading = ({
15
13
  "data-test-loading": true,
16
14
  dimensions: dimensions,
17
15
  "data-vc": "media-card-loading"
18
- }, expValEquals('cc-maui-ai-edit-loading-experiment', 'isEnabled', true) ? /*#__PURE__*/React.createElement(LoadingBar, {
19
- interactionName: interactionName || 'media-card-loading'
20
- }) : /*#__PURE__*/React.createElement(SpinnerIcon, {
16
+ }, /*#__PURE__*/React.createElement(LoadingBar, {
21
17
  interactionName: interactionName || 'media-card-loading'
22
18
  }));
23
19
  };
@@ -12,7 +12,7 @@ import { extractErrorInfo } from './analytics/extractErrorInfo';
12
12
  import { getRenderErrorRequestMetadata } from './analytics/getRenderErrorRequestMetadata';
13
13
  import { getMediaGlobalScope } from './globalScope/getMediaGlobalScope';
14
14
  const packageName = "@atlaskit/media-card";
15
- const packageVersion = "81.10.18";
15
+ const packageVersion = "81.11.0";
16
16
  const SAMPLE_RATE = 0.05;
17
17
 
18
18
  /**
@@ -2,7 +2,7 @@ import { injectIntl } from 'react-intl';
2
2
  import { withMediaAnalyticsContext } from '@atlaskit/media-common';
3
3
  import { CardWithPerformanceObserver } from './CardWithPerformanceObserver';
4
4
  var packageName = "@atlaskit/media-card";
5
- var packageVersion = "81.10.18";
5
+ var packageVersion = "81.11.0";
6
6
  export var Card = withMediaAnalyticsContext({
7
7
  packageVersion: packageVersion,
8
8
  packageName: packageName,
@@ -10,7 +10,6 @@ import { isFileIdentifier } from '@atlaskit/media-client';
10
10
  import { messages } from '@atlaskit/media-ui/messages';
11
11
  import { MimeTypeIcon } from '@atlaskit/media-ui/mime-type-icon';
12
12
  import { fg } from '@atlaskit/platform-feature-flags/fg';
13
- import SpinnerIcon from '@atlaskit/spinner/spinner';
14
13
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
14
  import Tooltip from '@atlaskit/tooltip/Tooltip';
16
15
  import { isUploadError } from '../isUploadError';
@@ -30,6 +29,7 @@ import { PreviewUnavailable } from './ui/iconMessage/PreviewUnavailable';
30
29
  import { IconWrapper } from './ui/iconWrapper/iconWrapper';
31
30
  import { ImageRenderer } from './ui/imageRenderer';
32
31
  import { LoadingBar } from './ui/loadingBar/loadingBar';
32
+ import { LoadingHold } from './ui/loadingHold/loadingHold';
33
33
  import OpenMediaViewerButton from './ui/openMediaViewerButton/openMediaViewerButton';
34
34
  import { PlayButton } from './ui/playButton/playButton';
35
35
  import { ProgressBar } from './ui/progressBar/progressBar';
@@ -90,6 +90,7 @@ export var CardViewBase = function CardViewBase(_ref) {
90
90
  traceId = _ref.traceId,
91
91
  isAIGenerating = _ref.isAIGenerating,
92
92
  isCWR = _ref.isCWR,
93
+ hasLoadingMotion = _ref.hasLoadingMotion,
93
94
  backgroundColor = _ref.backgroundColor;
94
95
  var intl = useIntl();
95
96
  var _useState = useState(false),
@@ -103,6 +104,18 @@ export var CardViewBase = function CardViewBase(_ref) {
103
104
  var divRef = useRef(null);
104
105
  var prevCardPreviewRef = useRef();
105
106
  var breakpoint = useBreakpoint(dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, divRef);
107
+ var isErrorStatus = status === 'error' || status === 'failed-processing';
108
+ // While the motion owns the loading presentation the card draws nothing of its own — no
109
+ // indicator, progress bar, type icon or background — so the consumer can open space into
110
+ // emptiness and fade the preview in over it. Errors keep their normal treatment, or a
111
+ // failure would be indistinguishable from empty space.
112
+ //
113
+ // Every consumer below derives from this, so gating it here enforces the gate at the
114
+ // component boundary rather than trusting callers to do it. The prop is the left operand
115
+ // because every media card in every product renders this component — reading the gate
116
+ // unconditionally would put all of them in its exposure population. `isErrorStatus` is
117
+ // checked after it, so cards that opted in still count towards that population.
118
+ var suppressLoadingUI = !!hasLoadingMotion && fg('aifc_page_create_defer_generated_visuals') && !isErrorStatus;
106
119
  useEffect(function () {
107
120
  // We should only switch didImageRender to false when cardPreview goes undefined, not when it is changed. as this method could be triggered after onImageLoad callback, falling on a race condition
108
121
  if (prevCardPreviewRef.current && !cardPreview) {
@@ -157,18 +170,20 @@ export var CardViewBase = function CardViewBase(_ref) {
157
170
  var loadingConfig = _objectSpread(_objectSpread({}, defaultConfig), {}, {
158
171
  renderPlayButton: false,
159
172
  renderTypeIcon: false,
160
- renderSpinner: !didImageRender && !didSvgRender
173
+ renderLoading: !didImageRender && !didSvgRender
161
174
  });
162
175
  switch (status) {
163
176
  case 'uploading':
164
177
  return _objectSpread(_objectSpread({}, defaultConfig), {}, {
165
- renderBlanket: !disableOverlay || mediaType !== 'video',
178
+ renderBlanket: !suppressLoadingUI && (!disableOverlay || mediaType !== 'video'),
166
179
  isFixedBlanket: true,
167
- renderProgressBar: !isAIGenerating
180
+ renderProgressBar: !isAIGenerating && !suppressLoadingUI,
181
+ renderTypeIcon: !suppressLoadingUI && defaultConfig.renderTypeIcon
168
182
  });
169
183
  case 'processing':
170
184
  return _objectSpread(_objectSpread({}, defaultConfig), {}, {
171
- iconMessage: !didImageRender && !isZeroSize ? /*#__PURE__*/React.createElement(CreatingPreview, {
185
+ renderTypeIcon: !suppressLoadingUI && defaultConfig.renderTypeIcon,
186
+ iconMessage: !didImageRender && !isZeroSize && !suppressLoadingUI ? /*#__PURE__*/React.createElement(CreatingPreview, {
172
187
  disableAnimation: disableAnimation
173
188
  }) : undefined
174
189
  });
@@ -227,7 +242,7 @@ export var CardViewBase = function CardViewBase(_ref) {
227
242
  iconMessage = _getRenderConfigBySta.iconMessage,
228
243
  renderImageRenderer = _getRenderConfigBySta.renderImageRenderer,
229
244
  renderSvgView = _getRenderConfigBySta.renderSvgView,
230
- renderSpinner = _getRenderConfigBySta.renderSpinner,
245
+ renderLoading = _getRenderConfigBySta.renderLoading,
231
246
  renderPlayButton = _getRenderConfigBySta.renderPlayButton,
232
247
  renderBlanket = _getRenderConfigBySta.renderBlanket,
233
248
  renderProgressBar = _getRenderConfigBySta.renderProgressBar,
@@ -240,9 +255,12 @@ export var CardViewBase = function CardViewBase(_ref) {
240
255
 
241
256
  // AI border shown while generating; cleared by the decoration on upload completion.
242
257
  /* eslint-disable @atlaskit/platform/no-preconditioning -- loading-specific gate (cc-maui-phase-2) layered on the MAUI experiment cohort during phased rollout; preconditioning is intentional and will be removed when the existing gates are cleaned up */
243
- var renderAIBorderOverride = !!isAIGenerating && fg('cc-maui-phase-2') && expValEquals('cc-maui-experiment', 'isEnabled', true);
258
+ var renderAIBorderOverride = !!isAIGenerating && fg('cc-maui-phase-2') && expValEquals('cc-maui-experiment', 'isEnabled', true) &&
259
+ // Last so the gates above are still evaluated, and their exposures still fire, on
260
+ // surfaces that suppress the overlay.
261
+ !suppressLoadingUI;
244
262
  /* eslint-enable @atlaskit/platform/no-preconditioning */
245
- var shouldDisplayBackground = !cardPreview || !disableOverlay || status === 'error' || status === 'failed-processing';
263
+ var shouldDisplayBackground = status === 'error' || status === 'failed-processing' || !suppressLoadingUI && (!cardPreview || !disableOverlay);
246
264
  var isPlayButtonClickable = shouldRenderPlayButton() && !!disableOverlay;
247
265
  var isTickBoxSelectable = !disableOverlay && !!selectable && !selected;
248
266
  var _ref4 = metadata || {},
@@ -282,6 +300,19 @@ export var CardViewBase = function CardViewBase(_ref) {
282
300
  setDidSvgRender(true);
283
301
  onSvgLoad === null || onSvgLoad === void 0 || onSvgLoad();
284
302
  };
303
+
304
+ // Held back until the preview has rendered, then faded in over the card's surface.
305
+ var mediaMotion;
306
+ if (suppressLoadingUI) {
307
+ mediaMotion = didImageRender || didSvgRender ? 'entering' : 'hidden';
308
+ }
309
+ var renderLoadingPlaceholder = function renderLoadingPlaceholder() {
310
+ return /*#__PURE__*/React.createElement(LoadingBar, {
311
+ animationDisabled: disableAnimation,
312
+ testId: "media-card-loading",
313
+ interactionName: "media-card-loading"
314
+ });
315
+ };
285
316
  var contents = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ImageContainer, {
286
317
  centerElements: didSvgRender && !fg('platform_media_card_image_render') // The whole centerElements styles can go after removing the flag
287
318
  ,
@@ -291,7 +322,8 @@ export var CardViewBase = function CardViewBase(_ref) {
291
322
  progress: progress,
292
323
  mediaCardCursor: mediaCardCursor,
293
324
  selected: selected,
294
- source: cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source
325
+ source: cardPreview === null || cardPreview === void 0 ? void 0 : cardPreview.source,
326
+ mediaMotion: mediaMotion
295
327
  }, renderTypeIcon && /*#__PURE__*/React.createElement(IconWrapper, {
296
328
  breakpoint: breakpoint,
297
329
  hasTitleBox: hasVisibleTitleBox
@@ -300,17 +332,13 @@ export var CardViewBase = function CardViewBase(_ref) {
300
332
  mediaType: mediaType,
301
333
  mimeType: mimeType,
302
334
  name: name
303
- }), iconMessage), renderSpinner && (expValEquals('cc-maui-ai-edit-loading-experiment', 'isEnabled', true) ? /*#__PURE__*/React.createElement(LoadingBar, {
304
- animationDisabled: disableAnimation,
305
- testId: "media-card-loading",
306
- interactionName: "media-card-loading"
307
- }) : /*#__PURE__*/React.createElement(IconWrapper, {
308
- breakpoint: breakpoint,
309
- hasTitleBox: hasVisibleTitleBox
310
- }, /*#__PURE__*/React.createElement(SpinnerIcon, {
311
- testId: "media-card-loading",
335
+ }), iconMessage), renderLoading && (suppressLoadingUI ?
336
+ /*#__PURE__*/
337
+ // Nothing is drawn, but the interaction still has to be held for the
338
+ // same window as the indicator it replaces.
339
+ React.createElement(LoadingHold, {
312
340
  interactionName: "media-card-loading"
313
- }))), renderSvgView && identifier && isFileIdentifier(identifier) && /*#__PURE__*/React.createElement(SvgView, {
341
+ }) : renderLoadingPlaceholder()), renderSvgView && identifier && isFileIdentifier(identifier) && /*#__PURE__*/React.createElement(SvgView, {
314
342
  identifier: identifier,
315
343
  resizeMode: resizeMode || 'crop',
316
344
  onError: onSvgError,
@@ -89,6 +89,7 @@ export var FileCard = function FileCard(_ref) {
89
89
  backgroundColor = _ref.backgroundColor,
90
90
  isAIGenerating = _ref.isAIGenerating,
91
91
  isCWR = _ref.isCWR,
92
+ hasLoadingMotion = _ref.hasLoadingMotion,
92
93
  onPreviewRender = _ref.onPreviewRender,
93
94
  shouldHideTooltip = _ref.shouldHideTooltip,
94
95
  mediaViewerItems = _ref.mediaViewerItems,
@@ -795,7 +796,8 @@ export var FileCard = function FileCard(_ref) {
795
796
  shouldHideTooltip: shouldHideTooltip,
796
797
  overriddenCreationDate: overridenDate,
797
798
  isAIGenerating: isAIGenerating,
798
- isCWR: isCWR
799
+ isCWR: isCWR,
800
+ hasLoadingMotion: hasLoadingMotion
799
801
  });
800
802
  return isLazyWithOverride ? /*#__PURE__*/React.createElement(ViewportDetector, {
801
803
  cardEl: cardElement,
@@ -80,7 +80,7 @@ var WrappedMediaCardAnalyticsErrorBoundary = /*#__PURE__*/function (_React$Compo
80
80
  }(React.Component);
81
81
  _defineProperty(WrappedMediaCardAnalyticsErrorBoundary, "displayName", 'MediaCardAnalyticsErrorBoundary');
82
82
  var packageName = "@atlaskit/media-card";
83
- var packageVersion = "81.10.18";
83
+ var packageVersion = "81.11.0";
84
84
 
85
85
  // @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18
86
86
  var MediaCardAnalyticsErrorBoundary = withMediaAnalyticsContext({
@@ -0,0 +1,28 @@
1
+ import { useContext, useEffect, useLayoutEffect as useRealLayoutEffect } from 'react';
2
+ import InteractionContext from '@atlaskit/interaction-context';
3
+
4
+ /**
5
+ * `useLayoutEffect` in SSR-safe form, matching `LoadingBar` and the DS interaction-tracing
6
+ * convention.
7
+ *
8
+ * @see https://hello.atlassian.net/wiki/spaces/DST/pages/2081696628/DSTDACI-010+-+Interaction+Tracing+hooks+in+DS+components
9
+ */
10
+ var useLayoutEffect = typeof window === 'undefined' ? useEffect : useRealLayoutEffect;
11
+ /**
12
+ * Holds the in-progress interaction while a card is loading, without drawing anything.
13
+ *
14
+ * `LoadingBar` and `Spinner` each own a hold for as long as they are mounted. Cards that
15
+ * express loading through motion instead still need the interaction held for the same window,
16
+ * so this stands in for them under the same `interactionName` — mounted and unmounted at the
17
+ * same points, so UFO traces stay comparable either way.
18
+ */
19
+ export var LoadingHold = function LoadingHold(_ref) {
20
+ var interactionName = _ref.interactionName;
21
+ var interactionContext = useContext(InteractionContext);
22
+ useLayoutEffect(function () {
23
+ if (interactionContext != null) {
24
+ return interactionContext.hold(interactionName);
25
+ }
26
+ }, [interactionContext, interactionName]);
27
+ return null;
28
+ };
@@ -2,10 +2,17 @@
2
2
  ._1bah1h6o{justify-content:center}
3
3
  ._1bsb1osq{width:100%}
4
4
  ._1e0c1txw{display:flex}
5
+ ._1o511hrf{animation-fill-mode:both}
6
+ ._1pglindk{animation-timing-function:var(--ds-easing-out-practical,cubic-bezier(.4,1,.6,1))}
5
7
  ._1reo15vq{overflow-x:hidden}
6
8
  ._2lx21bp4{flex-direction:column}
7
9
  ._4cvr1h6o{align-items:center}
8
10
  ._4t3i1osq{height:100%}
11
+ ._5sagi9qs{animation-duration:var(--ds-duration-medium,.2s)}
9
12
  ._c71l1osq{max-height:100%}
13
+ ._j7hq1bym{animation-name:var(--ds-keyframe-fade-in,FadeIn0to100)}
14
+ ._ju2515uc{animation-delay:var(--ds-duration-xlong,.4s)}
10
15
  ._kqswh2mm{position:relative}
11
- ._p12f1osq{max-width:100%}
16
+ ._p12f1osq{max-width:100%}
17
+ ._tzy4idpf{opacity:0}
18
+ @media (prefers-reduced-motion:reduce){._1bumglyw{animation:none}}
@@ -5,6 +5,12 @@ import { ax, ix } from "@compiled/react/runtime";
5
5
  import { fileCardImageViewSelector } from '../../classnames';
6
6
  var imageContainerStyles = null;
7
7
  var imageContainerCenterStyles = null;
8
+
9
+ // Holds the preview back until it has decoded, so it can be faded in rather than appearing the
10
+ // instant it becomes displayable. Nothing is drawn in the meantime — consumers using this
11
+ // motion keep the node out of the layout until the preview is ready.
12
+ var mediaMotionHiddenStyles = null;
13
+ var mediaMotionEnteringStyles = null;
8
14
  export var ImageContainer = function ImageContainer(_ref) {
9
15
  var children = _ref.children,
10
16
  mediaName = _ref.mediaName,
@@ -13,7 +19,8 @@ export var ImageContainer = function ImageContainer(_ref) {
13
19
  selected = _ref.selected,
14
20
  source = _ref.source,
15
21
  centerElements = _ref.centerElements,
16
- mediaCardCursor = _ref.mediaCardCursor;
22
+ mediaCardCursor = _ref.mediaCardCursor,
23
+ mediaMotion = _ref.mediaMotion;
17
24
  return /*#__PURE__*/React.createElement("div", {
18
25
  "data-testid": fileCardImageViewSelector
19
26
  /**
@@ -23,7 +30,7 @@ export var ImageContainer = function ImageContainer(_ref) {
23
30
  */
24
31
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
25
32
  ,
26
- className: ax(["_1reo15vq _18m915vq _2rko18qm _1e0c1txw _kqswh2mm _p12f1osq _1bsb1osq _4t3i1osq _c71l1osq", centerElements && "_2lx21bp4 _1bah1h6o _4cvr1h6o", fileCardImageViewSelector]),
33
+ className: ax(["_1reo15vq _18m915vq _2rko18qm _1e0c1txw _kqswh2mm _p12f1osq _1bsb1osq _4t3i1osq _c71l1osq", centerElements && "_2lx21bp4 _1bah1h6o _4cvr1h6o", mediaMotion === 'hidden' && "_tzy4idpf", mediaMotion === 'entering' && "_j7hq1bym _5sagi9qs _1pglindk _ju2515uc _1o511hrf _1bumglyw", fileCardImageViewSelector]),
27
34
  "data-test-media-name": mediaName,
28
35
  "data-test-status": status,
29
36
  "data-test-progress": progress,
@@ -101,7 +101,7 @@ var MediaInlineCardLoader = /*#__PURE__*/function (_React$PureComponent) {
101
101
  ErrorBoundary = _this$state.ErrorBoundary;
102
102
  var analyticsContext = {
103
103
  packageVersion: "@atlaskit/media-card",
104
- packageName: "81.10.18",
104
+ packageName: "81.11.0",
105
105
  componentName: 'mediaInlineCard',
106
106
  component: 'mediaInlineCard'
107
107
  };
@@ -1,6 +1,4 @@
1
1
  import React from 'react';
2
- import SpinnerIcon from '@atlaskit/spinner/spinner';
3
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
2
  import { LoadingBar } from '../../card/ui/loadingBar/loadingBar';
5
3
  import { getDimensionsWithDefault } from './getDimensionsWithDefault';
6
4
  import { Wrapper } from './lightCardWrappers';
@@ -14,9 +12,7 @@ export var CardLoading = function CardLoading(_ref) {
14
12
  "data-test-loading": true,
15
13
  dimensions: dimensions,
16
14
  "data-vc": "media-card-loading"
17
- }, expValEquals('cc-maui-ai-edit-loading-experiment', 'isEnabled', true) ? /*#__PURE__*/React.createElement(LoadingBar, {
18
- interactionName: interactionName || 'media-card-loading'
19
- }) : /*#__PURE__*/React.createElement(SpinnerIcon, {
15
+ }, /*#__PURE__*/React.createElement(LoadingBar, {
20
16
  interactionName: interactionName || 'media-card-loading'
21
17
  }));
22
18
  };
@@ -16,7 +16,7 @@ import { extractErrorInfo } from './analytics/extractErrorInfo';
16
16
  import { getRenderErrorRequestMetadata } from './analytics/getRenderErrorRequestMetadata';
17
17
  import { getMediaGlobalScope } from './globalScope/getMediaGlobalScope';
18
18
  var packageName = "@atlaskit/media-card";
19
- var packageVersion = "81.10.18";
19
+ var packageVersion = "81.11.0";
20
20
  var SAMPLE_RATE = 0.05;
21
21
 
22
22
  /**
@@ -46,6 +46,7 @@ export interface CardViewProps {
46
46
  overriddenCreationDate?: number;
47
47
  readonly isAIGenerating?: boolean;
48
48
  readonly isCWR?: boolean;
49
+ readonly hasLoadingMotion?: boolean;
49
50
  }
50
51
  export type CardViewBaseProps = CardViewProps & WithAnalyticsEventsProps;
51
52
  type TraceTooltipVariant = 'preview-unavailable' | 'failed-to-load';
@@ -60,12 +61,12 @@ export interface RenderConfigByStatus {
60
61
  isFixedBlanket?: boolean;
61
62
  renderProgressBar?: boolean;
62
63
  renderAIBorder?: boolean;
63
- renderSpinner?: boolean;
64
+ renderLoading?: boolean;
64
65
  renderFailedTitleBox?: boolean;
65
66
  renderTickBox?: boolean;
66
67
  customTitleMessage?: MessageDescriptor;
67
68
  traceTooltipVariant?: TraceTooltipVariant;
68
69
  }
69
- export declare const CardViewBase: ({ identifier, innerRef, onImageLoad, onImageError, dimensions, onClick, onMouseEnter, onFocus, testId, metadata, status, selected, selectable, cardPreview, mediaCardCursor, shouldHideTooltip, progress, alt, resizeMode, onDisplayImage, nativeLazyLoad, forceSyncDisplay, actions, disableOverlay, titleBoxBgColor, titleBoxIcon, error, disableAnimation, openMediaViewerButtonRef, shouldOpenMediaViewer, overriddenCreationDate, onSvgError, onSvgLoad, traceId, isAIGenerating, isCWR, backgroundColor, }: CardViewBaseProps) => React.JSX.Element;
70
+ export declare const CardViewBase: ({ identifier, innerRef, onImageLoad, onImageError, dimensions, onClick, onMouseEnter, onFocus, testId, metadata, status, selected, selectable, cardPreview, mediaCardCursor, shouldHideTooltip, progress, alt, resizeMode, onDisplayImage, nativeLazyLoad, forceSyncDisplay, actions, disableOverlay, titleBoxBgColor, titleBoxIcon, error, disableAnimation, openMediaViewerButtonRef, shouldOpenMediaViewer, overriddenCreationDate, onSvgError, onSvgLoad, traceId, isAIGenerating, isCWR, hasLoadingMotion, backgroundColor, }: CardViewBaseProps) => React.JSX.Element;
70
71
  export declare const CardView: React.ForwardRefExoticComponent<Omit<CardViewProps, keyof WithAnalyticsEventsProps> & React.RefAttributes<any>>;
71
72
  export {};
@@ -40,6 +40,11 @@ export interface FileCardProps extends CardEventProps {
40
40
  readonly isAIGenerating?: boolean;
41
41
  /** Marks the card as part of the CWR (create-with-Rovo) infographics flow. */
42
42
  readonly isCWR?: boolean;
43
+ /**
44
+ * Drops the loading indicator and fades the preview in over the card's surface instead.
45
+ * Also behind `aifc_page_create_defer_generated_visuals`.
46
+ */
47
+ readonly hasLoadingMotion?: boolean;
43
48
  /** Callback fired when the media card's image preview has rendered. */
44
49
  readonly onPreviewRender?: (fileId: string) => void;
45
50
  /** Instance of file identifier. */
@@ -93,4 +98,4 @@ export interface FileCardProps extends CardEventProps {
93
98
  */
94
99
  readonly fallbackMediaNameFetcher?: (id: string) => Promise<string>;
95
100
  }
96
- export declare const FileCard: ({ appearance, resizeMode, isLazy, disableOverlay, featureFlags, identifier, ssr, dimensions, originalDimensions, contextId, alt, actions, shouldEnableDownloadButton, useInlinePlayer, shouldOpenMediaViewer, onFullscreenChange, selectable, selected, testId, titleBoxBgColor, titleBoxIcon, backgroundColor, isAIGenerating, isCWR, onPreviewRender, shouldHideTooltip, mediaViewerItems, onClick, onMouseEnter, onFocus, videoControlsWrapperRef, viewerOptions, includeHashForDuplicateFiles, ssrItemDetails, ssrFileState, ssrMediaItem, onError, mediaViewerExtensions, fallbackMediaNameFetcher, }: FileCardProps) => React.JSX.Element;
101
+ export declare const FileCard: ({ appearance, resizeMode, isLazy, disableOverlay, featureFlags, identifier, ssr, dimensions, originalDimensions, contextId, alt, actions, shouldEnableDownloadButton, useInlinePlayer, shouldOpenMediaViewer, onFullscreenChange, selectable, selected, testId, titleBoxBgColor, titleBoxIcon, backgroundColor, isAIGenerating, isCWR, hasLoadingMotion, onPreviewRender, shouldHideTooltip, mediaViewerItems, onClick, onMouseEnter, onFocus, videoControlsWrapperRef, viewerOptions, includeHashForDuplicateFiles, ssrItemDetails, ssrFileState, ssrMediaItem, onError, mediaViewerExtensions, fallbackMediaNameFetcher, }: FileCardProps) => React.JSX.Element;
@@ -0,0 +1,12 @@
1
+ export type LoadingHoldProps = {
2
+ interactionName?: string;
3
+ };
4
+ /**
5
+ * Holds the in-progress interaction while a card is loading, without drawing anything.
6
+ *
7
+ * `LoadingBar` and `Spinner` each own a hold for as long as they are mounted. Cards that
8
+ * express loading through motion instead still need the interaction held for the same window,
9
+ * so this stands in for them under the same `interactionName` — mounted and unmounted at the
10
+ * same points, so UFO traces stay comparable either way.
11
+ */
12
+ export declare const LoadingHold: ({ interactionName }: LoadingHoldProps) => null;
@@ -9,6 +9,11 @@ type ImageContainerProps = {
9
9
  progress?: number;
10
10
  selected?: boolean;
11
11
  source?: string;
12
+ /**
13
+ * Entering motion for the media preview: `hidden` while it is still loading, `entering`
14
+ * once it has rendered. Undefined opts out entirely.
15
+ */
16
+ mediaMotion?: 'hidden' | 'entering';
12
17
  };
13
- export declare const ImageContainer: ({ children, mediaName, status, progress, selected, source, centerElements, mediaCardCursor, }: ImageContainerProps) => JSX.Element;
18
+ export declare const ImageContainer: ({ children, mediaName, status, progress, selected, source, centerElements, mediaCardCursor, mediaMotion, }: ImageContainerProps) => JSX.Element;
14
19
  export {};
@@ -10,6 +10,7 @@ type ImageContainerProps = {
10
10
  progress?: number;
11
11
  selected?: boolean;
12
12
  source?: string;
13
+ mediaMotion?: 'hidden' | 'entering';
13
14
  };
14
15
  export declare const ImageContainer: (props: ImageContainerProps) => React.JSX.Element;
15
16
  export {};
@@ -70,6 +70,7 @@ export interface SharedCardProps {
70
70
  readonly titleBoxIcon?: TitleBoxIcon;
71
71
  readonly isAIGenerating?: boolean;
72
72
  readonly isCWR?: boolean;
73
+ readonly hasLoadingMotion?: boolean;
73
74
  readonly onPreviewRender?: (fileId: string) => void;
74
75
  readonly viewerOptions?: ViewerOptionsProps;
75
76
  /** Sets options for viewer **/
@@ -1,6 +1,7 @@
1
1
  // eslint-disable-line no-console
2
2
 
3
3
  import React, { type PropsWithChildren } from 'react';
4
+ import { IntlProvider } from 'react-intl';
4
5
 
5
6
  import { payloadPublisher } from '@atlassian/ufo/publisher';
6
7
 
@@ -149,14 +150,16 @@ export const MainWrapper = ({
149
150
  }: MainWrapperProps): React.JSX.Element => {
150
151
  enableMediaUfoLogger(payloadPublisher);
151
152
  return (
152
- <>
153
+ // `react-intl` is a peer dependency of this package — the card's loading bar localises its
154
+ // aria-label via `useIntl`, so examples need a provider in the ancestry.
155
+ <IntlProvider locale="en">
153
156
  {developmentOnly && <DevelopmentUseMessage />}
154
157
  {!disableFeatureFlagWrapper ? (
155
158
  <FeatureFlagsWrapper>{children}</FeatureFlagsWrapper>
156
159
  ) : (
157
160
  <>{children}</>
158
161
  )}
159
- </>
162
+ </IntlProvider>
160
163
  );
161
164
  };
162
165
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/media-card",
3
- "version": "81.10.19",
3
+ "version": "81.12.0",
4
4
  "description": "Includes all media card related components, CardView, CardViewSmall, Card...",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -50,9 +50,8 @@
50
50
  "@atlaskit/react-compiler-gating": "^0.2.0",
51
51
  "@atlaskit/react-ufo": "^7.10.0",
52
52
  "@atlaskit/section-message": "^10.2.0",
53
- "@atlaskit/spinner": "^20.4.0",
54
53
  "@atlaskit/theme": "^28.2.0",
55
- "@atlaskit/tmp-editor-statsig": "^192.0.0",
54
+ "@atlaskit/tmp-editor-statsig": "^193.0.0",
56
55
  "@atlaskit/tokens": "^16.12.0",
57
56
  "@atlaskit/tooltip": "^24.3.0",
58
57
  "@atlaskit/ufo": "^1.2.0",
@@ -106,6 +105,10 @@
106
105
  "wait-for-expect": "^1.2.0"
107
106
  },
108
107
  "platform-feature-flags": {
108
+ "aifc_page_create_defer_generated_visuals": {
109
+ "type": "boolean",
110
+ "referenceOnly": true
111
+ },
109
112
  "cc-maui-phase-2": {
110
113
  "type": "boolean"
111
114
  },