@atlaskit/renderer
Version:
Renderer component
218 lines (214 loc) • 12.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.renderExtension = exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _react = require("@emotion/react");
var _react2 = _interopRequireWildcard(require("react"));
var _analytics = require("@atlaskit/editor-common/analytics");
var _ExtensionRenderer = _interopRequireDefault(require("../../ui/ExtensionRenderer"));
var _ui = require("@atlaskit/editor-common/ui");
var _utils = require("@atlaskit/editor-common/utils");
var _consts = require("../../consts");
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
var _breakout = require("../utils/breakout");
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
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); }
/**
* @jsxRuntime classic
* @jsx jsx
*/
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
var viewportSizes = ['small', 'medium', 'default', 'large', 'xlarge'];
// Mirrors sizes from https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/forge/xen-editor-provider/src/render/renderers/ForgeUIExtension.tsx
var macroHeights = {
small: '112px',
medium: '262px',
default: '262px',
large: '524px',
xlarge: '1048px'
};
var getViewportSize = function getViewportSize(extensionId, extensionViewportSizes) {
if (!Array.isArray(extensionViewportSizes) || !extensionId) {
return;
}
var extension = extensionViewportSizes.find(function (extension) {
return extension.extensionId === extensionId;
});
if (extension) {
var viewportSize = extension.viewportSize && viewportSizes.includes(extension.viewportSize) ? extension.viewportSize : 'default';
return macroHeights[viewportSize];
}
};
var containerStyle = (0, _react.css)({
containerType: 'inline-size'
});
/**
* Fires an analytics event once on mount when a bodied extension is rendered as an inline element.
* The node is stored in a ref to avoid re-firing if the node reference changes.
*/
var FireExtensionAsInlineAnalytics = function FireExtensionAsInlineAnalytics(_ref) {
var fireAnalyticsEvent = _ref.fireAnalyticsEvent,
node = _ref.node;
var nodeRef = (0, _react2.useRef)(node);
(0, _react2.useEffect)(function () {
fireAnalyticsEvent({
action: _analytics.ACTION.RENDERED,
actionSubject: _analytics.ACTION_SUBJECT.EXTENSION_AS_INLINE,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.EXTENSION_BODIED,
attributes: {
extensionKey: nodeRef.current.extensionKey,
extensionType: nodeRef.current.extensionType
},
eventType: _analytics.EVENT_TYPE.OPERATIONAL
});
}, [fireAnalyticsEvent]);
return null;
};
var renderExtension = exports.renderExtension = function renderExtension(content, layout) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var removeOverflow = arguments.length > 3 ? arguments[3] : undefined;
var extensionId = arguments.length > 4 ? arguments[4] : undefined;
var extensionViewportSizes = arguments.length > 5 ? arguments[5] : undefined;
var nodeHeight = arguments.length > 6 ? arguments[6] : undefined;
var localId = arguments.length > 7 ? arguments[7] : undefined;
var shouldDisplayExtensionAsInline = arguments.length > 8 ? arguments[8] : undefined;
var node = arguments.length > 9 ? arguments[9] : undefined;
var isInsideOfInlineExtension = arguments.length > 10 ? arguments[10] : undefined;
var overflowContainerClass = !removeOverflow ? _consts.RendererCssClassName.EXTENSION_OVERFLOW_CONTAINER : '';
// by default, we assume the extension is at top level, (direct child of doc node)
var _ref2 = options || {},
_ref2$isTopLevel = _ref2.isTopLevel,
isTopLevel = _ref2$isTopLevel === void 0 ? true : _ref2$isTopLevel,
rendererAppearance = _ref2.rendererAppearance,
fireAnalyticsEvent = _ref2.fireAnalyticsEvent;
// we should only use custom layout for full-page appearance
var canUseCustomLayout = (0, _expValEquals.expValEquals)('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? rendererAppearance === 'full-page' : true;
var isCustomLayout = isTopLevel && ['wide', 'full-width'].includes(layout) && canUseCustomLayout;
var centerAlignClass = isCustomLayout ? _consts.RendererCssClassName.EXTENSION_CENTER_ALIGN : '';
/**
* To reduce cumulative layout shift, we check installed manifest values (viewportSize) for Forge and extension node parameters
* for Connect (legacy). As Connect is being phased out, we want Forge to also start to store its expected height
* in node parameters, especially for dynamic content macros. LegacyMacroStyledElements implements logic similar to here
* as the extension handler in CFE for legacy macros and Connect.
*/
var viewportSize = getViewportSize(extensionId, extensionViewportSizes);
var extensionHeight = nodeHeight || viewportSize;
var isInline = (shouldDisplayExtensionAsInline === null || shouldDisplayExtensionAsInline === void 0 ? void 0 : shouldDisplayExtensionAsInline(node)) && (0, _expValEquals.expValEquals)('platform_editor_render_bodied_extension_as_inline', 'isEnabled', true);
var inlineClassName = isInline ? _consts.RendererCssClassName.EXTENSION_AS_INLINE : '';
var asInlineAnalytics = isInline && fireAnalyticsEvent && node && (0, _platformFeatureFlags.fg)('platform_editor_render_inline_extension_analytics') ? (0, _react.jsx)(FireExtensionAsInlineAnalytics, {
fireAnalyticsEvent: fireAnalyticsEvent,
node: node
}) : null;
if ((0, _expValEquals.expValEquals)('platform_editor_renderer_extension_width_fix', 'isEnabled', true)) {
var extensionDiv = (0, _react.jsx)("div", {
ref: options.handleRef
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
,
className: "".concat(_consts.RendererCssClassName.EXTENSION, " ").concat(inlineClassName, " ").concat(options.shadowClassNames, " ").concat(centerAlignClass),
style: {
width: isInline ? undefined : ((0, _expValEquals.expValEquals)('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? isCustomLayout : isTopLevel) ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values
(0, _breakout.calcBreakoutWidthCss)(layout) : (0, _expValEquals.expValEquals)('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? undefined : '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
minHeight: isInline ? undefined : extensionHeight && "".concat(extensionHeight, "px")
},
"data-layout": layout,
"data-local-id": localId,
"data-testid": "extension--wrapper",
"data-node-type": "extension"
}, (0, _react.jsx)("div", {
tabIndex: options.tabIndex
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
,
className: "".concat(_consts.RendererCssClassName.EXTENSION_INNER_WRAPPER, " ").concat(overflowContainerClass),
css: [!isInsideOfInlineExtension && (0, _platformFeatureFlags.fg)('platform_fix_macro_renders_in_layouts') && containerStyle]
}, asInlineAnalytics, content));
return centerAlignClass && (0, _expValEquals.expValEquals)('platform_editor_flex_based_centering', 'isEnabled', true) ? (0, _react.jsx)("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
className: _consts.RendererCssClassName.STICKY_SAFE_CENTER_WRAPPER + ' ' + _consts.RendererCssClassName.FLEX_CENTER_WRAPPER
}, extensionDiv) : extensionDiv;
}
return (0, _react.jsx)(_ui.WidthConsumer, null, function (_ref3) {
var width = _ref3.width;
var extensionDiv = (0, _react.jsx)("div", {
ref: options.handleRef
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
,
className: "".concat(_consts.RendererCssClassName.EXTENSION, " ").concat(inlineClassName, " ").concat(options.shadowClassNames, " ").concat(centerAlignClass),
style: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
width: isInline ? undefined : ((0, _expValEquals.expValEquals)('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? isCustomLayout : isTopLevel) ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
(0, _utils.calcBreakoutWidth)(layout, width) : (0, _expValEquals.expValEquals)('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? undefined : '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
minHeight: isInline ? undefined : "".concat(extensionHeight, "px")
},
"data-layout": layout,
"data-local-id": localId
}, (0, _react.jsx)("div", {
tabIndex: options.tabIndex
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
,
className: "".concat(_consts.RendererCssClassName.EXTENSION_INNER_WRAPPER, " ").concat(overflowContainerClass),
css: [!isInsideOfInlineExtension && (0, _platformFeatureFlags.fg)('platform_fix_macro_renders_in_layouts') && containerStyle]
}, asInlineAnalytics, content));
return centerAlignClass && (0, _expValEquals.expValEquals)('platform_editor_flex_based_centering', 'isEnabled', true) ? (0, _react.jsx)("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
className: _consts.RendererCssClassName.STICKY_SAFE_CENTER_WRAPPER + ' ' + _consts.RendererCssClassName.FLEX_CENTER_WRAPPER
}, extensionDiv) : extensionDiv;
});
};
var Extension = function Extension(props) {
var text = props.text,
_props$layout = props.layout,
layout = _props$layout === void 0 ? 'default' : _props$layout,
handleRef = props.handleRef,
shadowClassNames = props.shadowClassNames,
_props$path = props.path,
path = _props$path === void 0 ? [] : _props$path,
extensionViewportSizes = props.extensionViewportSizes,
parameters = props.parameters,
nodeHeight = props.nodeHeight,
localId = props.localId,
isInsideOfInlineExtension = props.isInsideOfInlineExtension;
return (0, _react.jsx)(_ExtensionRenderer.default
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, (0, _extends2.default)({}, props, {
type: "extension"
}), function (_ref4) {
var result = _ref4.result;
try {
// Return the result directly if it's a valid JSX.Element
if (result && /*#__PURE__*/_react2.default.isValidElement(result)) {
return renderExtension(result, layout, {
isTopLevel: path.length < 1,
handleRef: handleRef,
shadowClassNames: shadowClassNames,
tabIndex: props.tabIndex,
rendererAppearance: props.rendererAppearance
}, undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (e) {
/** We don't want this error to block renderer */
/** We keep rendering the default content */
}
// Always return default content if anything goes wrong
return renderExtension(text || 'extension', layout, {
isTopLevel: path.length < 1,
handleRef: handleRef,
shadowClassNames: shadowClassNames,
tabIndex: props.tabIndex,
rendererAppearance: props.rendererAppearance
}, undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
});
};
var _default_1 = (0, _ui.overflowShadow)(Extension, {
overflowSelector: ".".concat(_consts.RendererCssClassName.EXTENSION_OVERFLOW_CONTAINER)
});
var _default = exports.default = _default_1;