UNPKG

@atlaskit/renderer

Version:
284 lines (277 loc) • 11.5 kB
import _extends from "@babel/runtime/helpers/extends"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; /** * @jsxRuntime classic * @jsx jsx */ import { default as React, Fragment, useCallback, useContext, useMemo, useEffect } from 'react'; // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 import { css, jsx } from '@emotion/react'; import { injectIntl } from 'react-intl'; import { MediaSingle as UIMediaSingle, WidthContext } from '@atlaskit/editor-common/ui'; import { fg } from '@atlaskit/platform-feature-flags'; import { akEditorFullWidthLayoutWidth, akEditorDefaultLayoutWidth, akEditorWideLayoutWidth } from '@atlaskit/editor-shared-styles'; import { isSSR } from '@atlaskit/editor-common/core-utils'; import { FullPagePadding } from '../../../ui/Renderer/style'; import { useAnnotationRangeDispatch } from '../../../ui/annotations/contexts/AnnotationRangeContext'; import { useAnnotationHoverDispatch } from '../../../ui/annotations/contexts/AnnotationHoverContext'; var DEFAULT_WIDTH = 250; var DEFAULT_HEIGHT = 200; var uiMediaSingleBaseStyles = css({ transition: 'all 0.1s linear' }); var uiMediaSingleLayoutStyles = css({ // eslint-disable-next-line @atlaskit/design-system/use-tokens-space marginLeft: '50%', transform: 'translateX(-50%)' }); var isMediaElement = function isMediaElement(media) { if (!media) { return false; } // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any var _ref = media.props || {}, nodeType = _ref.nodeType, type = _ref.type; // Use this to perform a rough check // better than assume the first item in children is media return nodeType === 'media' || ['external', 'file', 'link'].indexOf(type) >= 0; }; var _checkForMediaElement = function checkForMediaElement(children) { var _React$Children$toArr = React.Children.toArray(children), _React$Children$toArr2 = _slicedToArray(_React$Children$toArr, 1), media = _React$Children$toArr2[0]; // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any if (media && !isMediaElement(media) && media.props.children) { // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any return _checkForMediaElement(media.props.children); } return media; }; // returns the existing container width if available (non SSR mode), otherwise // we return a default width value export var getMediaContainerWidth = function getMediaContainerWidth(currentContainerWidth, layout) { if (!currentContainerWidth) { // SSR mode fallback to default layout width switch (layout) { case 'full-width': return akEditorFullWidthLayoutWidth; case 'wide': return akEditorWideLayoutWidth; default: return akEditorDefaultLayoutWidth; } } return currentContainerWidth; }; var MediaSingleWithChildren = function MediaSingleWithChildren(props) { var rendererAppearance = props.rendererAppearance, featureFlags = props.featureFlags, isInsideOfBlockNode = props.isInsideOfBlockNode, layout = props.layout, widthAttr = props.width, widthType = props.widthType, _props$allowCaptions = props.allowCaptions, allowCaptions = _props$allowCaptions === void 0 ? false : _props$allowCaptions, _props$isInsideOfInli = props.isInsideOfInlineExtension, isInsideOfInlineExtension = _props$isInsideOfInli === void 0 ? false : _props$isInsideOfInli, dataAttributes = props.dataAttributes, media = props.media, caption = props.caption, editorAppearance = props.editorAppearance; var _React$useState = React.useState({ width: 0, height: 0 }), _React$useState2 = _slicedToArray(_React$useState, 2), externalImageDimensions = _React$useState2[0], setExternalImageDimensions = _React$useState2[1]; var ref = React.useRef(null); var onExternalImageLoaded = React.useCallback(function (_ref2) { var width = _ref2.width, height = _ref2.height; setExternalImageDimensions({ width: width, height: height }); }, []); // Ignored via go/ees005 // eslint-disable-next-line prefer-const var _media$props = media.props, _media$props$width = _media$props.width, width = _media$props$width === void 0 ? DEFAULT_WIDTH : _media$props$width, _media$props$height = _media$props.height, height = _media$props$height === void 0 ? DEFAULT_HEIGHT : _media$props$height, type = _media$props.type; if (type === 'external') { var stateWidth = externalImageDimensions.width, stateHeight = externalImageDimensions.height; if (width === null) { width = stateWidth || DEFAULT_WIDTH; } if (height === null) { height = stateHeight || DEFAULT_HEIGHT; } } if (width === null) { width = DEFAULT_WIDTH; height = DEFAULT_HEIGHT; } var isFullPage = rendererAppearance === 'full-page'; var isFullWidth = rendererAppearance === 'full-width'; var padding = isFullPage ? FullPagePadding * 2 : 0; var calcDimensions = useCallback(function (mediaContainerWidth) { var containerWidth = getMediaContainerWidth(mediaContainerWidth, layout); var cardDimensions = {}; if (fg('media-perf-uplift-mutation-fix')) { var maxWidth = widthAttr && typeof widthAttr === 'number' && widthType === 'pixel' ? widthAttr : containerWidth; cardDimensions = { width: "".concat(maxWidth, "px"), height: "100%" }; } else { var _maxWidth = isSSR() && widthAttr && typeof widthAttr === 'number' ? Math.max(widthAttr, containerWidth) : containerWidth; var maxHeight = height / width * _maxWidth; cardDimensions = { width: "".concat(_maxWidth, "px"), height: "".concat(maxHeight, "px") }; } var nonFullWidthSize = containerWidth; if (!isInsideOfBlockNode && rendererAppearance !== 'comment') { var isContainerSizeGreaterThanMaxFullPageWidth = containerWidth - padding >= akEditorDefaultLayoutWidth; if (isContainerSizeGreaterThanMaxFullPageWidth) { nonFullWidthSize = akEditorDefaultLayoutWidth; } else { nonFullWidthSize = containerWidth - padding; } } var minWidth = Math.min(akEditorFullWidthLayoutWidth, containerWidth - padding); var lineLength = isFullWidth ? minWidth : nonFullWidthSize; return { cardDimensions: cardDimensions, lineLength: lineLength }; }, [height, isFullWidth, isInsideOfBlockNode, layout, padding, rendererAppearance, width, widthAttr, widthType]); var originalDimensions = useMemo(function () { return { width: width, height: height }; }, [height, width]); var _useAnnotationRangeDi = useAnnotationRangeDispatch(), setHoverTarget = _useAnnotationRangeDi.setHoverTarget; var _useAnnotationHoverDi = useAnnotationHoverDispatch(), cancelTimeout = _useAnnotationHoverDi.cancelTimeout, initiateTimeout = _useAnnotationHoverDi.initiateTimeout, setIsWithinRange = _useAnnotationHoverDi.setIsWithinRange; var isFullPageRenderer = isFullPage || isFullWidth; useEffect(function () { var mediaSingleElement = ref.current; var handleMouseEnter = function handleMouseEnter(event) { cancelTimeout(); if (event.buttons === 0) { // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting setHoverTarget && setHoverTarget(event.target); setIsWithinRange(true); } }; var handleMouseLeave = function handleMouseLeave() { initiateTimeout(); }; if (mediaSingleElement && isFullPageRenderer) { // Ignored via go/ees005 // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners mediaSingleElement.addEventListener('mouseenter', handleMouseEnter); // Ignored via go/ees005 // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners mediaSingleElement.addEventListener('mouseleave', handleMouseLeave); } return function () { if (mediaSingleElement && isFullPageRenderer) { // Ignored via go/ees005 // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners mediaSingleElement.removeEventListener('mouseenter', handleMouseEnter); // Ignored via go/ees005 // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners mediaSingleElement.removeEventListener('mouseleave', handleMouseLeave); } }; }, [setHoverTarget, isFullPageRenderer, cancelTimeout, initiateTimeout, setIsWithinRange]); // Note: in SSR mode the `window` object is not defined, // therefore width here is 0, see: // packages/editor/editor-common/src/ui/WidthProvider/index.tsx var _useContext = useContext(WidthContext), renderWidth = _useContext.width; var containerWidth = getMediaContainerWidth(renderWidth, layout); var _useMemo = useMemo(function () { return calcDimensions(containerWidth); }, [calcDimensions, containerWidth]), cardDimensions = _useMemo.cardDimensions, lineLength = _useMemo.lineLength; var renderMediaSingle = function renderMediaSingle() { var mediaComponent = /*#__PURE__*/React.cloneElement(media, { resizeMode: 'stretchy-fit', cardDimensions: cardDimensions, originalDimensions: originalDimensions, onExternalImageLoaded: onExternalImageLoaded, disableOverlay: true, featureFlags: featureFlags, mediaSingleElement: ref.current }); var uiMediaSingleStyles = layout === 'full-width' || layout === 'wide' ? [uiMediaSingleBaseStyles, uiMediaSingleLayoutStyles] : [uiMediaSingleBaseStyles]; return jsx(UIMediaSingle, { css: uiMediaSingleStyles, handleMediaSingleRef: ref, layout: layout, width: width, height: height, lineLength: isInsideOfBlockNode ? containerWidth : lineLength, containerWidth: containerWidth // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , size: { width: widthAttr, widthType: widthType }, fullWidthMode: isFullWidth, isInsideOfInlineExtension: isInsideOfInlineExtension, dataAttributes: dataAttributes, editorAppearance: editorAppearance, isInRenderer: true }, jsx(Fragment, null, mediaComponent), allowCaptions && caption); }; return renderMediaSingle(); }; var MediaSingle = function MediaSingle(props) { var children = props.children; var media; var _React$Children$toArr3 = React.Children.toArray(children), _React$Children$toArr4 = _slicedToArray(_React$Children$toArr3, 2), node = _React$Children$toArr4[0], caption = _React$Children$toArr4[1]; if (!isMediaElement(node)) { // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any var mediaElement = _checkForMediaElement(node.props.children); if (!mediaElement) { return node; } media = mediaElement; } else { media = node; } // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading return jsx(MediaSingleWithChildren, _extends({}, props, { media: media, caption: caption })); }; // eslint-disable-next-line @typescript-eslint/ban-types var _default_1 = injectIntl(MediaSingle); export default _default_1;