UNPKG

@atlaskit/renderer

Version:
286 lines (281 loc) • 11.4 kB
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;