@atlaskit/renderer
Version:
Renderer component
213 lines (209 loc) • 9.32 kB
JavaScript
/* eslint-disable @atlaskit/design-system/prefer-primitives, @atlaskit/design-system/consistent-css-prop-usage */
/**
* @jsxRuntime classic
* @jsx jsx
* @jsxFrag
*/
/* 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 React, { useState } from 'react';
import { WidthConsumer } from '@atlaskit/editor-common/ui';
import { RendererCssClassName } from '../../consts';
import { calcBreakoutWidth } from '@atlaskit/editor-common/utils';
import { useMultiBodiedExtensionActions } from './multiBodiedExtension/actions';
import { useMultiBodiedExtensionContext } from './multiBodiedExtension/context';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { calcBreakoutWidthCss } from '../utils/breakout';
const containerStyles = css({
// Remove top margin if MBE is the first on the doc/page (MBE can only be on the first level)
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-nested-selectors
'&:first-child > .ak-renderer-extension': {
marginTop: 0
},
// When patch is on, direct child is center wrapper (not extension); same first-child behaviour
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-nested-selectors
'&:first-child > .ak-renderer-sticky-safe-center-wrapper': {
marginTop: 0
}
});
const MultiBodiedExtensionChildrenContainer = ({
children
}) => {
return jsx("article", {
"data-testid": "multiBodiedExtension--frames"
}, children);
};
const MultiBodiedExtensionNavigation = ({
children
}) => {
return jsx("nav", {
"data-testid": "multiBodiedExtension-navigation"
}, children);
};
const MultiBodiedExtensionWrapperLegacy = ({
width,
path,
layout,
rendererAppearance,
children
}) => {
const isTopLevel = path.length < 1;
// we should only use custom layout for full-page appearance
const canUseCustomLayout = expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? rendererAppearance === 'full-page' : true;
const isCustomLayout = isTopLevel && ['wide', 'full-width'].includes(layout) && canUseCustomLayout;
const centerAlignClass = isCustomLayout ? RendererCssClassName.EXTENSION_CENTER_ALIGN : '';
// This hierarchy is copied from regular extension (see extension.tsx)
return jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
className: `${RendererCssClassName.EXTENSION} ${centerAlignClass}`,
style: {
width: (expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? isCustomLayout : isTopLevel) ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values
calcBreakoutWidth(layout, width) : expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? undefined : '100%'
},
"data-layout": layout,
"data-testid": "multiBodiedExtension--wrapper-renderer"
}, jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
className: `${RendererCssClassName.EXTENSION_OVERFLOW_CONTAINER}`
}, children));
};
const MultiBodiedExtensionWrapperNext = ({
path,
layout,
rendererAppearance,
children
}) => {
const isTopLevel = path.length < 1;
// we should only use custom layout for full-page appearance
const canUseCustomLayout = expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? rendererAppearance === 'full-page' : true;
const isCustomLayout = isTopLevel && ['wide', 'full-width'].includes(layout) && canUseCustomLayout;
const centerAlignClass = isCustomLayout ? RendererCssClassName.EXTENSION_CENTER_ALIGN : '';
// This hierarchy is copied from regular extension (see extension.tsx)
return jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
className: `${RendererCssClassName.EXTENSION} ${centerAlignClass}`,
style: {
width: (expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? isCustomLayout : isTopLevel) ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values
calcBreakoutWidthCss(layout) : expValEquals('platform_editor_remove_important_in_render_ext', 'isEnabled', true) ? undefined : '100%'
},
"data-layout": layout,
"data-testid": "multiBodiedExtension--wrapper-renderer"
}, jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
className: `${RendererCssClassName.EXTENSION_OVERFLOW_CONTAINER}`
}, children));
};
const MultiBodiedExtension = props => {
var _extensionContext$pri;
const {
children,
layout = 'default',
path = [],
parameters,
extensionType,
extensionKey,
content,
marks,
localId,
rendererAppearance
} = props;
const [activeChildIndex, setActiveChildIndex] = useState(0);
const {
loading,
extensionContext
} = useMultiBodiedExtensionContext({
extensionType,
extensionKey
});
const actions = useMultiBodiedExtensionActions({
updateActiveChild: setActiveChildIndex,
children,
childrenContainer: jsx(MultiBodiedExtensionChildrenContainer, null, children),
allowBodiedOverride: extensionContext === null || extensionContext === void 0 ? void 0 : (_extensionContext$pri = extensionContext.privateProps) === null || _extensionContext$pri === void 0 ? void 0 : _extensionContext$pri.__allowBodiedOverride
});
const renderContent = React.useCallback(() => {
var _marks$find, _marks$find$attrs;
if (loading || !extensionContext) {
return null;
}
const {
NodeRenderer,
privateProps
} = extensionContext;
const fragmentLocalId = marks === null || marks === void 0 ? void 0 : (_marks$find = marks.find(m => m.type.name === 'fragment')) === null || _marks$find === void 0 ? void 0 : (_marks$find$attrs = _marks$find.attrs) === null || _marks$find$attrs === void 0 ? void 0 : _marks$find$attrs.localId;
const node = {
type: 'multiBodiedExtension',
extensionKey,
extensionType,
parameters,
content,
localId,
fragmentLocalId
};
if (privateProps.__allowBodiedOverride) {
return jsx(NodeRenderer, {
node: node,
actions: actions
});
} else {
return jsx(React.Fragment, null, jsx(MultiBodiedExtensionNavigation, null, jsx(NodeRenderer, {
node: node,
actions: actions
})), jsx(MultiBodiedExtensionChildrenContainer, null, children));
}
}, [loading, extensionContext, marks, extensionKey, extensionType, parameters, content, localId, actions, children]);
// make the frame visible
// eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression
const containerActiveFrameStyles = css`
& [data-extension-frame='true']:nth-of-type(${activeChildIndex + 1}) {
display: block;
}
`;
if (expValEquals('platform_editor_renderer_extension_width_fix', 'isEnabled', true)) {
const isTopLevel = path.length < 1;
const useCenterWrapper = isTopLevel && ['wide', 'full-width'].includes(layout) && expValEquals('platform_editor_flex_based_centering', 'isEnabled', true);
const wrapper = jsx(MultiBodiedExtensionWrapperNext, {
layout: layout,
path: path,
rendererAppearance: rendererAppearance
}, renderContent());
return jsx("section", {
css: [containerStyles, containerActiveFrameStyles],
"data-testid": "multiBodiedExtension--container",
"data-multiBodiedExtension-container": true,
"data-active-child-index": activeChildIndex,
"data-layout": layout,
"data-local-id": localId,
"data-node-type": "multiBodiedExtension"
}, useCenterWrapper ? jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
className: RendererCssClassName.STICKY_SAFE_CENTER_WRAPPER + ' ' + RendererCssClassName.FLEX_CENTER_WRAPPER
}, wrapper) : wrapper);
}
const isTopLevel = path.length < 1;
const useCenterWrapper = isTopLevel && ['wide', 'full-width'].includes(layout) && expValEquals('platform_editor_flex_based_centering', 'isEnabled', true);
return jsx("section", {
css: [containerStyles, containerActiveFrameStyles],
"data-testid": "multiBodiedExtension--container",
"data-multiBodiedExtension-container": true,
"data-active-child-index": activeChildIndex,
"data-layout": layout,
"data-local-id": localId
}, jsx(WidthConsumer, null, ({
width
}) => {
const wrapper = jsx(MultiBodiedExtensionWrapperLegacy, {
layout: layout,
width: width,
path: path,
rendererAppearance: rendererAppearance
}, renderContent());
return useCenterWrapper ? jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
className: RendererCssClassName.STICKY_SAFE_CENTER_WRAPPER + ' ' + RendererCssClassName.FLEX_CENTER_WRAPPER
}, wrapper) : wrapper;
}));
};
export default MultiBodiedExtension;