@atlaskit/renderer
Version:
Renderer component
155 lines (153 loc) • 6.78 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
/**
* @jsxRuntime classic
* @jsx jsx
*/
// eslint-disable-next-line @typescript-eslint/consistent-type-imports, @atlaskit/ui-styling-standard/use-compiled -- emotion jsx pragma; go/DSP-18766
import { css, jsx } from '@emotion/react'; // oxlint-ignore @typescript-eslint/consistent-type-imports -- classic @jsx jsx factory + jsx.JSX.Element types
import React from 'react';
import memoizeOne from 'memoize-one';
import { getNodeRenderer } from '@atlaskit/editor-common/extensions';
import { WithProviders } from '@atlaskit/editor-common/provider-factory';
import { getExtensionRenderer } from '@atlaskit/editor-common/utils';
var inlineExtensionStyle = css({
display: 'inline-block',
maxWidth: '100%',
verticalAlign: 'middle',
// 0px margin top is important here.
// When running on server-side emotion will generate style tags before elements.
// This caused packages/editor/editor-common/src/styles/shared/block-marks.ts to override the margin-top.
// However as soon as the styles are extracted to <head> it adds back the margin.
// The timing is tricky as it happens to be when UFO collects the dimension for the placeholder for TTVC calculation.
// This resulted 1px mismatch on the image. Further cause everything on page to shift by 1px.
// es-lint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
margin: "0px 1px ".concat("var(--ds-space-050, 4px)"),
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
'& .rich-media-item': {
maxWidth: '100%'
}
});
var plainTextMacroStyle = css({
display: 'inline',
verticalAlign: 'baseline',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'[data-macro-body]': {
display: 'inline'
}
});
/** Renders extension (macro) nodes inside the ADF renderer. */
export default function ExtensionRenderer(props) {
var extensionHandlers = props.extensionHandlers,
rendererContext = props.rendererContext,
extensionType = props.extensionType,
extensionKey = props.extensionKey,
parameters = props.parameters,
content = props.content,
text = props.text,
type = props.type,
localId = props.localId,
marks = props.marks,
actions = props.actions,
children = props.children;
var isMounted = React.useRef(true);
var localGetNodeRenderer = React.useMemo(function () {
return memoizeOne(getNodeRenderer);
}, []);
var _React$useState = React.useState(null),
_React$useState2 = _slicedToArray(_React$useState, 2),
extensionProvider = _React$useState2[0],
setExtensionProvider = _React$useState2[1];
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var handleProvider = React.useCallback(function (_name, providerPromise) {
providerPromise && providerPromise.then(function (provider) {
if (isMounted.current) {
setExtensionProvider(provider);
}
});
}, []);
var renderExtensionNode = React.useCallback(function (extensionProvider) {
var _marks$find, _node$parameters;
var fragmentLocalId = marks === null || marks === void 0 || (_marks$find = marks.find(function (m) {
return m.type.name === 'fragment';
})) === null || _marks$find === void 0 || (_marks$find = _marks$find.attrs) === null || _marks$find === void 0 ? void 0 : _marks$find.localId;
var node = {
type: type,
extensionKey: extensionKey,
extensionType: extensionType,
parameters: parameters,
content: content || text,
localId: localId,
fragmentLocalId: fragmentLocalId
};
var isPlainTextMacro = Boolean(node === null || node === void 0 || (_node$parameters = node.parameters) === null || _node$parameters === void 0 || (_node$parameters = _node$parameters.macroParams) === null || _node$parameters === void 0 ? void 0 : _node$parameters.__bodyContent);
var result = null;
try {
if (extensionHandlers && extensionHandlers[extensionType]) {
var render = getExtensionRenderer(extensionHandlers[extensionType]);
result = render(node, rendererContext.adDoc);
}
if (!result && extensionProvider) {
var NodeRenderer = localGetNodeRenderer(extensionProvider, extensionType, extensionKey);
if (node.type === 'multiBodiedExtension') {
result = jsx(NodeRenderer, {
node: node,
actions: actions
});
} else if (node.type === 'inlineExtension') {
result = jsx(InlineNodeRendererWrapper, {
isPlainTextMacro: isPlainTextMacro
}, jsx(NodeRenderer, {
node: node
}));
} else {
result = jsx(NodeRenderer, {
node: node
});
}
}
} catch (_unused) {
/** We don't want this error to block renderer */
/** We keep rendering the default content */
}
return children({
node: node,
result: result
});
}, [actions, children, content, extensionHandlers, extensionKey, extensionType, localGetNodeRenderer, localId, marks, parameters, rendererContext === null || rendererContext === void 0 ? void 0 : rendererContext.adDoc, text, type]);
var setupAndRenderExtensionNode = React.useCallback(function (providers) {
if (!extensionProvider && providers.extensionProvider) {
handleProvider('extensionProvider', providers.extensionProvider);
}
return renderExtensionNode(extensionProvider);
}, [extensionProvider, handleProvider, renderExtensionNode]);
React.useEffect(function () {
isMounted.current = true;
return function () {
isMounted.current = false;
};
}, []);
if (!props.providers) {
return setupAndRenderExtensionNode({});
}
return jsx(WithProviders
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
, {
providers: ['extensionProvider'],
providerFactory: props.providers,
renderNode: setupAndRenderExtensionNode
});
}
export var InlineNodeRendererWrapper = function InlineNodeRendererWrapper(_ref) {
var children = _ref.children,
isPlainTextMacro = _ref.isPlainTextMacro,
ssrPlaceholder = _ref.ssrPlaceholder,
ssrPlaceholderReplace = _ref.ssrPlaceholderReplace;
return jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
className: "inline-extension-renderer ".concat(isPlainTextMacro ? 'plain-text-macro' : ''),
css: [inlineExtensionStyle, isPlainTextMacro && plainTextMacroStyle],
"data-ssr-placeholder": ssrPlaceholder,
"data-ssr-placeholder-replace": ssrPlaceholderReplace
}, children);
};