@atlaskit/renderer
Version:
Renderer component
286 lines (281 loc) • 11.4 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
/**
* @jsxRuntime classic
* @jsx jsx
*/
/* eslint-disable jsdoc/check-tag-names */
/* eslint-disable @typescript-eslint/consistent-type-imports, @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766; jsx required at runtime for @jsxRuntime classic */
import { jsx, css } from '@emotion/react';
import { useContext, useState, useRef } from 'react';
import { Card, EmbedResizeMessageListener } from '@atlaskit/smart-card';
import { CardSSR } from '@atlaskit/smart-card/ssr';
import { SmartCardContext } from '@atlaskit/link-provider';
import { WidthConsumer, UnsupportedBlock, MediaSingle as UIMediaSingle, WidthContext } from '@atlaskit/editor-common/ui';
import { akEditorDefaultLayoutWidth, akEditorFullPageNarrowBreakout, akEditorFullWidthLayoutWidth, DEFAULT_EMBED_CARD_HEIGHT, DEFAULT_EMBED_CARD_WIDTH } from '@atlaskit/editor-shared-styles';
import { fg } from '@atlaskit/platform-feature-flags';
import { componentWithCondition } from '@atlaskit/platform-feature-flags-react';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { CardErrorBoundary } from './fallback';
import { SmartLinkDraggable, SMART_LINK_DRAG_TYPES, SMART_LINK_APPEARANCE } from '@atlaskit/editor-smart-link-draggable';
import { RendererCssClassName } from '../../consts';
import { FullPagePadding } from '../../ui/Renderer/style';
import { getCardClickHandler } from '../utils/getCardClickHandler';
import { AnalyticsContext } from '@atlaskit/analytics-next';
import { usePortal } from '../../ui/Renderer/PortalContext';
import BlockCard from './blockCard';
const embedCardWrapperStyles = css({
width: '100%',
height: '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
'> div': {
height: '100%'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
'.loader-wrapper': {
height: '100%'
},
margin: '0 auto'
});
const embedCardCenterWrapperStyles = css({
// Match MediaSingle calcMargin(layout) default for wide/full-width: 24px top/bottom (so wrapper participates in collapse)
// eslint-disable-next-line @atlaskit/design-system/use-tokens-space -- Matches editor-common MediaSingle calcMargin
margin: '24px 0'
});
// Legacy centering when platform_editor_flex_based_centering is off.
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
const uIMediaSingleLayoutStylesLegacy = css({
// eslint-disable-next-line @atlaskit/design-system/use-tokens-space
marginLeft: '50%',
transform: 'translateX(-50%)'
});
function EmbedCardInternal(props) {
var _smartLinks$frameStyl;
const {
url,
data,
eventHandlers,
layout,
width,
isInsideOfBlockNode,
rendererAppearance,
smartLinks,
isInsideOfInlineExtension,
onSetLinkTarget
} = props;
const portal = usePortal(props);
const embedIframeRef = useRef(null);
const onClick = getCardClickHandler(eventHandlers, url);
const {
actionOptions
} = smartLinks || {};
const platform = 'web';
const cardProps = {
url,
onClick,
container: portal,
platform,
frameStyle: (_smartLinks$frameStyl = smartLinks === null || smartLinks === void 0 ? void 0 : smartLinks.frameStyle) !== null && _smartLinks$frameStyl !== void 0 ? _smartLinks$frameStyl : 'show',
actionOptions,
CompetitorPrompt: smartLinks === null || smartLinks === void 0 ? void 0 : smartLinks.CompetitorPrompt
};
const [liveHeight, setLiveHeight] = useState(null);
const [aspectRatio, setAspectRatio] = useState();
const height = liveHeight || props.originalHeight;
// We start with height and width defined with default values
let originalHeight = DEFAULT_EMBED_CARD_HEIGHT;
let originalWidth = DEFAULT_EMBED_CARD_WIDTH;
// Then can override height and width with values from ADF if available
if (props.originalHeight && props.originalWidth) {
originalHeight = props.originalHeight;
originalWidth = props.originalWidth;
}
// Then we can override it with aspectRatio that is comming from iframely via `resolve()`
if (aspectRatio) {
originalHeight = 1;
originalWidth = aspectRatio;
}
// And finally if iframe sends live `height` events we use that as most precise measure.
const isHeightOnlyMode = !(props.originalHeight && props.originalWidth) || liveHeight;
if (height && isHeightOnlyMode) {
originalHeight = height;
originalWidth = undefined;
}
const padding = rendererAppearance === 'full-page' ? FullPagePadding * 2 : 0;
const [hasPreview, setPreviewAvailableState] = useState(true);
const cardContext = useContext(SmartCardContext);
const onResolve = ({
aspectRatio: resolvedAspectRatio
}) => {
const hasPreviewOnResolve = !!(cardContext && url && cardContext.extractors.getPreview(url, platform));
if (!hasPreviewOnResolve) {
setPreviewAvailableState(false);
}
setAspectRatio(resolvedAspectRatio);
};
const analyticsData = {
attributes: {
location: 'renderer'
},
// Below is added for the future implementation of Linking Platform namespaced analytic context
location: 'renderer'
};
return jsx(AnalyticsContext, {
data: analyticsData
}, jsx(WidthConsumer, null, ({
width: documentWidth
}) => {
const isFullWidth = rendererAppearance === 'full-width';
let containerWidth = documentWidth;
if (smartLinks !== null && smartLinks !== void 0 && smartLinks.ssr && !containerWidth) {
// EDM-8114: When we are rendering on SSR, we have no idea what the width is.
containerWidth = isFullWidth ? akEditorFullWidthLayoutWidth : akEditorDefaultLayoutWidth;
}
let nonFullWidthSize = containerWidth;
if (!isInsideOfBlockNode && rendererAppearance !== 'comment') {
const isContainerSizeGreaterThanMaxFullPageWidth = containerWidth - padding >= akEditorDefaultLayoutWidth;
if (isContainerSizeGreaterThanMaxFullPageWidth) {
nonFullWidthSize = akEditorDefaultLayoutWidth;
} else {
nonFullWidthSize = containerWidth - padding;
}
}
const lineLength = isFullWidth ? Math.min(akEditorFullWidthLayoutWidth, containerWidth - padding) : nonFullWidthSize;
const useStickySafeCentering = expValEquals('platform_editor_flex_based_centering', 'isEnabled', true);
const uiMediaSingleStyles = layout === 'full-width' || layout === 'wide' ? useStickySafeCentering ? undefined : uIMediaSingleLayoutStylesLegacy : '';
const onError = ({
err
}) => {
if (err) {
throw err;
}
};
let cardComponent;
if (smartLinks !== null && smartLinks !== void 0 && smartLinks.ssr && url && (fg('platform_ssr_smartlink_embeds') || fg('jfp-magma-ssr-iv-editor-links'))) {
var _smartLinks$frameStyl2;
const ssrCardProps = {
url,
onClick,
container: portal,
platform: platform,
frameStyle: (_smartLinks$frameStyl2 = smartLinks === null || smartLinks === void 0 ? void 0 : smartLinks.frameStyle) !== null && _smartLinks$frameStyl2 !== void 0 ? _smartLinks$frameStyl2 : 'show',
actionOptions
};
cardComponent = jsx(CardSSR, _extends({
appearance: "embed"
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
}, ssrCardProps, {
onResolve: onResolve,
inheritDimensions: true,
embedIframeRef: embedIframeRef,
onError: onError
}));
} else {
cardComponent = jsx(Card, _extends({
appearance: "embed"
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
}, cardProps, {
onResolve: onResolve,
inheritDimensions: true,
embedIframeRef: embedIframeRef,
onError: onError
}));
}
return (
// Ignored via go/ees005
jsx(SmartLinkDraggable, {
url: url || '',
appearance: SMART_LINK_APPEARANCE.EMBED,
source: SMART_LINK_DRAG_TYPES.RENDERER
}, jsx(CardErrorBoundary, _extends({
unsupportedComponent: UnsupportedBlock,
onSetLinkTarget: onSetLinkTarget
// eslint-disable-next-line react/jsx-props-no-spreading
}, cardProps), jsx(EmbedResizeMessageListener, {
embedIframeRef: embedIframeRef,
onHeightUpdate: setLiveHeight
}, (() => {
const useCenterWrapper = (layout === 'full-width' || layout === 'wide') && expValEquals('platform_editor_flex_based_centering', 'isEnabled', true);
const mediaSingle = jsx(UIMediaSingle, {
css: uiMediaSingleStyles,
layout: layout,
width: originalWidth,
containerWidth: containerWidth,
pctWidth: width,
height: originalHeight,
fullWidthMode: isFullWidth,
nodeType: "embedCard",
lineLength: isInsideOfBlockNode ? containerWidth : lineLength,
hasFallbackContainer: hasPreview,
isInsideOfInlineExtension: isInsideOfInlineExtension
}, jsx("div", {
css: embedCardWrapperStyles
}, jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
className: "embedCardView-content-wrap",
"data-embed-card": true,
"data-layout": layout,
"data-width": width,
"data-card-data": data ? JSON.stringify(data) : undefined,
"data-card-url": url,
"data-card-original-height": originalHeight
}, cardComponent)));
return useCenterWrapper ? jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
className: RendererCssClassName.EMBED_CARD_CENTER_WRAPPER + ' ' + RendererCssClassName.FLEX_CENTER_WRAPPER,
css: embedCardCenterWrapperStyles
}, mediaSingle) : mediaSingle;
})())))
);
}));
}
export const EmbedOrBlockCardInternal = ({
url,
data,
eventHandlers,
portal,
originalHeight,
originalWidth,
width: embedWidth,
layout,
rendererAppearance,
isInsideOfBlockNode,
smartLinks,
isInsideOfInlineExtension,
onSetLinkTarget
}) => {
const {
width
} = useContext(WidthContext);
const viewAsBlockCard = width && width <= akEditorFullPageNarrowBreakout;
return viewAsBlockCard ? jsx(BlockCard, {
url: url,
data: data,
eventHandlers: eventHandlers,
portal: portal,
layout: layout,
rendererAppearance: rendererAppearance,
smartLinks: smartLinks,
onSetLinkTarget: onSetLinkTarget
}) : jsx(EmbedCardInternal, {
url: url,
data: data,
eventHandlers: eventHandlers,
portal: portal,
originalHeight: originalHeight,
originalWidth: originalWidth,
width: embedWidth,
layout: layout,
rendererAppearance: rendererAppearance,
isInsideOfBlockNode: isInsideOfBlockNode,
smartLinks: smartLinks,
isInsideOfInlineExtension: isInsideOfInlineExtension,
onSetLinkTarget: onSetLinkTarget
});
};
const EmbedCardWithCondition = componentWithCondition(() => editorExperiment('platform_editor_preview_panel_responsiveness', true, {
exposure: true
}), EmbedOrBlockCardInternal, EmbedCardInternal);
export default EmbedCardWithCondition;