@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
239 lines (228 loc) • 12.3 kB
JavaScript
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
var _excluded = ["children"];
var _templateObject, _templateObject2, _templateObject3;
/**
* @jsxRuntime classic
* @jsx jsx
*/
import React from 'react';
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
import { css, jsx } from '@emotion/react';
import { akEditorDefaultLayoutWidth, akEditorFullPageMaxWidth, akEditorFullWidthLayoutWidth } from '@atlaskit/editor-shared-styles';
import { nonWrappedLayouts } from '../../utils';
import { calcBreakoutWidth, calcWideWidth } from '../../utils/breakout';
function float(layout) {
switch (layout) {
case 'wrap-right':
return 'right';
case 'wrap-left':
return 'left';
default:
return 'none';
}
}
function getWidthIfFullWidthMode(originalWidth, containerWidth, isInsideOfInlineExtension) {
if (isInsideOfInlineExtension) {
return originalWidth > akEditorFullWidthLayoutWidth ? "".concat(Math.min(containerWidth, akEditorFullWidthLayoutWidth), "px") : "".concat(originalWidth, "px");
}
return originalWidth > akEditorFullWidthLayoutWidth ? '100%' : "".concat(originalWidth, "px");
}
function getWidthIfDefaultMode(originalWidth, containerWidth, isInsideOfInlineExtension) {
if (isInsideOfInlineExtension) {
return originalWidth > akEditorFullPageMaxWidth ? "".concat(Math.min(containerWidth, akEditorDefaultLayoutWidth), "px") : "".concat(originalWidth, "px");
}
return originalWidth > akEditorFullPageMaxWidth ? '100%' : "".concat(originalWidth, "px");
}
/**
* Calculates the image width for non-resized images.
*
* If an image has not been resized using the pctWidth attribute,
* then an image in wide or full-width can not be wider than the image's
* original width.
*/
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/max-params
export function calcLegacyWidth(layout, width) {
var containerWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var fullWidthMode = arguments.length > 3 ? arguments[3] : undefined;
var isResized = arguments.length > 4 ? arguments[4] : undefined;
var isInsideOfInlineExtension = arguments.length > 5 ? arguments[5] : undefined;
switch (layout) {
case 'align-start':
case 'align-end':
case 'wrap-right':
case 'wrap-left':
return width > containerWidth / 2 ? 'calc(50% - 12px)' : "".concat(width, "px");
case 'wide':
return isInsideOfInlineExtension ? calcWideWidth(containerWidth, Infinity, "".concat(containerWidth, "px")) : calcWideWidth(containerWidth);
case 'full-width':
return calcBreakoutWidth(layout, containerWidth);
default:
return isResized ? "".concat(width, "px") : fullWidthMode ? getWidthIfFullWidthMode(width, containerWidth, isInsideOfInlineExtension) : getWidthIfDefaultMode(width, containerWidth, isInsideOfInlineExtension);
}
}
/**
* Calculates the image width for non-resized images.
*
* If an image has not been resized using the pctWidth attribute,
* then an image in wide or full-width can not be wider than the image's
* original width.
*/
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/max-params
export function calcLegacyWidthForInline(layout, width) {
var containerWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var fullWidthMode = arguments.length > 3 ? arguments[3] : undefined;
var isResized = arguments.length > 4 ? arguments[4] : undefined;
switch (layout) {
case 'align-start':
case 'align-end':
case 'wrap-right':
case 'wrap-left':
return width > containerWidth / 2 ? 'calc(50% - 12px)' : "".concat(width, "px");
case 'wide':
return calcWideWidth(containerWidth, Infinity, "".concat(containerWidth, "px"));
case 'full-width':
return calcBreakoutWidth(layout, containerWidth);
default:
return isResized ? "".concat(width, "px") : fullWidthMode ? getWidthIfFullWidthMode(width, containerWidth) : getWidthIfDefaultMode(width, containerWidth);
}
}
/**
* Calculates the image width for previously resized images.
*
* Wide and full-width images are always that size (960px and 100%); there is
* no distinction between max-width and width.
*/
export function calcResizedWidth(layout, width) {
var containerWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
switch (layout) {
case 'wide':
return calcWideWidth(containerWidth);
case 'full-width':
return calcBreakoutWidth(layout, containerWidth);
default:
return "".concat(width, "px");
}
}
function calcMaxWidth(layout, containerWidth) {
switch (layout) {
case 'wide':
return calcWideWidth(containerWidth);
case 'full-width':
return calcBreakoutWidth(layout, containerWidth);
default:
return '100%';
}
}
function calcMargin(layout) {
switch (layout) {
case 'wrap-right':
return '12px auto 12px 12px';
case 'wrap-left':
return '12px 12px 12px auto';
default:
return '24px auto';
}
}
function isImageAligned(layout) {
switch (layout) {
case 'align-end':
return 'margin-right: 0';
case 'align-start':
return 'margin-left: 0';
default:
return '';
}
}
/**
* Reduces the given CSS width value to the next lowest even pixel value if the value is in px.
* This is to mitigate subpixel rendering issues of embedded smart links.
*
* @param widthValue CSS width value to be rounded
* @returns Reduced CSS width value where px value given, or otherwise the original value
*/
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function roundToClosestEvenPxValue(widthValue) {
try {
if (widthValue.endsWith('px')) {
var pxWidth = parseInt(widthValue.slice(0, -2));
return "".concat(pxWidth - pxWidth % 2, "px");
}
return widthValue;
} catch (_unused) {
return widthValue;
}
}
/**
* Can't use `.attrs` to handle highly dynamic styles because we are still
* supporting `styled-components` v1.
*/
export var MediaSingleDimensionHelper = function MediaSingleDimensionHelper(_ref) {
var _ref$containerWidth = _ref.containerWidth,
containerWidth = _ref$containerWidth === void 0 ? 0 : _ref$containerWidth,
fullWidthMode = _ref.fullWidthMode,
isResized = _ref.isResized,
layout = _ref.layout,
mediaSingleWidth = _ref.mediaSingleWidth,
width = _ref.width,
isExtendedResizeExperienceOn = _ref.isExtendedResizeExperienceOn,
_ref$isNestedNode = _ref.isNestedNode,
isNestedNode = _ref$isNestedNode === void 0 ? false : _ref$isNestedNode,
_ref$isInsideOfInline = _ref.isInsideOfInlineExtension,
isInsideOfInlineExtension = _ref$isInsideOfInline === void 0 ? false : _ref$isInsideOfInline;
var calculatedWidth = roundToClosestEvenPxValue(isExtendedResizeExperienceOn ? "".concat(mediaSingleWidth || width, "px") : mediaSingleWidth ? calcResizedWidth(layout, width || 0, containerWidth) : calcLegacyWidth(layout, width || 0, containerWidth, fullWidthMode, isResized, isInsideOfInlineExtension));
var calculatedMaxWidth = roundToClosestEvenPxValue(isExtendedResizeExperienceOn ? "".concat(containerWidth, "px") : calcMaxWidth(layout, containerWidth));
// eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression -- Needs manual remediation
return css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n\t\t/* For nested rich media items, set max-width to 100% */\n\t\ttr &,\n\t\t[data-layout-column] &,\n\t\t[data-node-type='expand'] &,\n\t\t[data-panel-type] &,\n\t\tli & {\n\t\t\tmax-width: 100%;\n\t\t}\n\n\t\twidth: ", ";\n\t\t", "\n\t\tmax-width: ", ";\n\n\t\t", "\n\n\t\t&:not(.is-resizing) {\n\t\t\ttransition: width 100ms ease-in;\n\t\t}\n\n\t\tfloat: ", ";\n\t\tmargin: ", ";\n\n\t\t&[class*='not-resizing'] {\n\t\t\t", "\n\t\t}\n\n\t\t", ";\n\t"])), calculatedWidth, layout === 'full-width' &&
/* This causes issues for new experience where we don't strip layout attributes
when copying top-level node and pasting into a table/layout,
because full-width layout will remain, causing node to be edge-to-edge */
!isExtendedResizeExperienceOn && css({
minWidth: '100%'
}), calculatedMaxWidth, isExtendedResizeExperienceOn && "&[class*='is-resizing'] {\n .new-file-experience-wrapper {\n box-shadow: none !important;\n }\n\n ".concat(!isNestedNode && nonWrappedLayouts.includes(layout) && "margin-left: 50%;\n transform: translateX(-50%);", "\n }"), float(layout), calcMargin(layout), isNestedNode ? /* Make nested node appear responsive when resizing table cell */"max-width: 100%;" : nonWrappedLayouts.includes(layout) && "margin-left: 50%;\n transform: translateX(-50%);", isImageAligned(layout));
};
var RenderFallbackContainer = function RenderFallbackContainer(_ref2) {
var hasFallbackContainer = _ref2.hasFallbackContainer,
paddingBottom = _ref2.paddingBottom,
height = _ref2.height;
return (// eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression -- Needs manual remediation
css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n\t\t", "\n\t"])), hasFallbackContainer ? "\n &::after {\n content: '';\n display: block;\n ".concat(height ? "height: ".concat(height, "px;") : paddingBottom ? "padding-bottom: ".concat(paddingBottom, ";") : '', "\n\n /* Fixes extra padding problem in Firefox */\n font-size: 0;\n line-height: 0;\n }\n ") : '')
);
};
// eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression -- Needs manual remediation
export var mediaWrapperStyle = function mediaWrapperStyle(props) {
return css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n\tposition: relative;\n\n\t", "\n\n\t/* Editor */\n & > figure {\n\t\tposition: ", ";\n\t\theight: 100%;\n\t\twidth: 100%;\n\t}\n\n\t// Comments on media project adds comment badge as child of the media wrapper,\n\t// thus we need to exclude it so that style is applied to intended div\n\t// remove [data-comment-badge='true'] when ff platform_editor_add_media_from_url is cleaned up\n\t& > div:not([data-comment-badge='true'], [data-media-badges='true']) {\n\t\tposition: ", ";\n\t\theight: 100%;\n\t\twidth: 100%;\n\t}\n\n\t& * [data-mark-annotation-type='inlineComment'] {\n\t\twidth: 100%;\n\t\theight: 100%;\n\t}\n\n\t&[data-node-type='embedCard'] > div {\n\t\twidth: 100%;\n\t}\n\n\t/* Renderer */\n\t[data-node-type='media'] {\n\t\tposition: static !important;\n\n\t\t> div {\n\t\t\tposition: absolute;\n\t\t\theight: 100%;\n\t\t}\n\t}\n"])), RenderFallbackContainer(props), props.hasFallbackContainer ? 'absolute' : 'relative', props.hasFallbackContainer ? 'absolute' : 'relative');
};
export var MediaWrapper = function MediaWrapper(_ref3) {
var children = _ref3.children,
rest = _objectWithoutProperties(_ref3, _excluded);
return (
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
jsx("div", {
css: mediaWrapperStyle(rest)
}, children)
);
};
MediaWrapper.displayName = 'WrapperMediaSingle';
/*
There was an issue with a small, intermittent white gap appearing between the images due to a small pixel difference in browser rendering.
The solution implemented below was adapted from: https://stackoverflow.com/a/68885576
It suggests adding an absolute div on top which matches the width and height and setting the border on that div.
*/
export var MediaBorderGapFiller = function MediaBorderGapFiller(_ref4) {
var borderColor = _ref4.borderColor;
return jsx("div", {
style: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
position: 'absolute',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
inset: '0px',
border: "0.5px solid ".concat(borderColor),
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
borderRadius: '1px'
}
});
};