@atlaskit/renderer
Version:
Renderer component
219 lines (218 loc) • 8.81 kB
JavaScript
/* eslint-disable @atlaskit/ui-styling-standard/no-imported-style-values */
/* eslint-disable @atlaskit/ui-styling-standard/no-unsafe-values */
/* eslint-disable @atlaskit/ui-styling-standard/no-nested-selectors */
/**
* @jsxRuntime classic
* @jsx jsx
*/
import React, { forwardRef, useMemo } from 'react';
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
import { css, jsx } from '@emotion/react';
import { akEditorTableCellMinWidth, blockNodesVerticalMargin, overflowShadow } from '@atlaskit/editor-shared-styles';
import { CodeBlockSharedCssClassName } from '@atlaskit/editor-common/styles';
import { useBidiWarnings } from '../../../hooks/use-bidi-warnings';
import { RendererCssClassName } from '../../../../consts';
const codeBlockSharedStyles = css({
[`.${CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPED}
> .${CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER}
> .${CodeBlockSharedCssClassName.CODEBLOCK_CONTENT}`]: {
marginRight: "var(--ds-space-100, 8px)",
code: {
display: 'block',
wordBreak: 'break-word',
whiteSpace: 'pre-wrap'
}
},
[`.${CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER}
> .${CodeBlockSharedCssClassName.CODEBLOCK_CONTENT}`]: {
display: 'flex',
flex: 1,
code: {
flexGrow: 1,
whiteSpace: 'pre'
}
},
[`.${CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER}`]: {
position: 'relative',
backgroundColor: "var(--ds-surface-raised, #FFFFFF)",
borderRadius: "var(--ds-radius-small, 3px)",
margin: `${blockNodesVerticalMargin} 0 0 0`,
fontFamily: "var(--ds-font-family-code, \"Atlassian Mono\", ui-monospace, Menlo, \"Segoe UI Mono\", \"Ubuntu Mono\", monospace)",
minWidth: `${akEditorTableCellMinWidth}px`,
cursor: 'pointer',
clear: 'both',
'--ds--code--bg-color': 'transparent',
'.code-block-gutter-pseudo-element::before': {
content: '"attr(data-label)"'
},
/* This is necessary to allow for arrow key navigation in/out of code blocks in Firefox. */
whiteSpace: 'normal',
[`.${CodeBlockSharedCssClassName.CODEBLOCK_START}`]: {
position: 'absolute',
visibility: 'hidden',
height: '1.5rem',
top: '0px',
left: '0px'
},
[`${CodeBlockSharedCssClassName.CODEBLOCK_END}`]: {
position: 'absolute',
visibility: 'hidden',
height: '1.5rem',
bottom: '0px',
right: '0px'
},
[`.${CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER}`]: {
position: 'relative',
backgroundColor: "var(--ds-background-neutral, #0515240F)",
display: 'flex',
borderRadius: "var(--ds-radius-small, 3px)",
width: '100%',
counterReset: 'line',
overflowX: 'auto',
backgroundImage: 'var(--ak-renderer-codeblock-content-wrapper-bg-img)',
backgroundRepeat: 'no-repeat',
backgroundAttachment: 'local, local, local, local, scroll, scroll, scroll, scroll',
backgroundSize: `${"var(--ds-space-300, 24px)"} 100%,
${"var(--ds-space-300, 24px)"} 100%,
${"var(--ds-space-100, 8px)"} 100%,
${"var(--ds-space-100, 8px)"} 100%,
${"var(--ds-space-100, 8px)"} 100%,
1px 100%,
${"var(--ds-space-100, 8px)"} 100%,
1px 100%`,
backgroundPosition: `0 0,
0 0,
100% 0,
100% 0,
100% 0,
100% 0,
0 0,
0 0`,
/* Be careful if refactoring this; it is needed to keep arrow key navigation in Firefox consistent with other browsers. */
overflowY: 'hidden'
},
[`.${CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER}`]: {
backgroundColor: "var(--ds-background-neutral, #0515240F)",
position: 'relative',
width: 'var(--lineNumberGutterWidth, 2rem)',
padding: "var(--ds-space-100, 8px)",
flexShrink: 0,
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
fontSize: `${14 / 16}rem`,
boxSizing: 'content-box'
},
// This is a fix of marker of list item with code block.
// The list item marker in Chrome is aligned by the baseline of the text,
// that's why we need to add a text (content: "1") to the line number gutter to align
// the list item marker with the text.
// Without it, the list item marker will be aligned by the bottom of the code block.
[`.${CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER}::before`]: {
content: '"1"',
visibility: 'hidden',
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
fontSize: `${14 / 16}rem`,
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
lineHeight: '1.5rem'
},
[`.${CodeBlockSharedCssClassName.CODEBLOCK_CONTENT}`]: {
code: {
tabSize: 4,
cursor: 'text',
color: "var(--ds-text, #292A2E)",
borderRadius: "var(--ds-radius-small, 3px)",
margin: "var(--ds-space-100, 8px)",
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
fontSize: `${14 / 16}rem`,
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
lineHeight: '1.5rem'
}
},
[`.${CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER_LINE_NUMBER_WIDGET}`]: {
pointerEvents: 'none',
userSelect: 'none',
width: 'var(--lineNumberGutterWidth, 2rem)',
left: 0,
position: 'absolute',
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
fontSize: `${14 / 16}rem`,
padding: `0px ${"var(--ds-space-100, 8px)"}`,
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
lineHeight: '1.5rem',
textAlign: 'right',
color: "var(--ds-text-subtlest, #6B6E76)",
boxSizing: 'content-box'
}
}
});
const lightWeightCodeBlockStyles = css({
[`.${CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER}`]: {
cursor: 'text'
}
});
export const LightWeightCodeBlockCssClassName = {
CONTAINER: 'light-weight-code-block'
};
/**
* @private
* @deprecated styles are moved to RendererStyleContainer
*/
export const getLightWeightCodeBlockStylesForRootRendererStyleSheet = () => {
// We overwrite the rule that clears margin-top for first nested codeblocks, as
// our lightweight codeblock dom structure will always nest the codeblock inside
// an extra container div which would constantly be targeted. Now, top-level
// lightweight codeblock containers will not be targeted.
// NOTE: This must be added after other .code-block styles in the root
// Renderer stylesheet.
// eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression -- needs manual remediation
return css`
.${RendererCssClassName.DOCUMENT}
> .${LightWeightCodeBlockCssClassName.CONTAINER}
.${CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER} {
margin-top: ${blockNodesVerticalMargin};
}
`;
};
const LightWeightCodeBlock = /*#__PURE__*/forwardRef(({
text,
codeBidiWarningTooltipEnabled = true,
hideLineNumbers = false,
className
}, ref) => {
const textRows = useMemo(() => (text !== null && text !== void 0 ? text : '').split('\n'), [text]);
const {
renderBidiWarnings
} = useBidiWarnings({
enableWarningTooltip: codeBidiWarningTooltipEnabled
});
const classNames = [LightWeightCodeBlockCssClassName.CONTAINER, className].join(' ');
const codeBlockBackgroundImage = overflowShadow({
leftCoverWidth: "var(--ds-space-300, 24px)"
});
return jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
className: classNames,
ref: ref
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
,
css: [codeBlockSharedStyles, lightWeightCodeBlockStyles],
style: {
'--ak-renderer-codeblock-content-wrapper-bg-img': codeBlockBackgroundImage
}
}, jsx("div", {
className: CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER
}, jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
className: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER
}, !hideLineNumbers && jsx("div", {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
className: CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER
}, textRows.map((_, index) =>
// Ignored via go/ees005
// eslint-disable-next-line react/no-array-index-key
jsx("span", {
key: index
}))), jsx("div", {
className: CodeBlockSharedCssClassName.CODEBLOCK_CONTENT
}, jsx("code", null, renderBidiWarnings(text))))));
});
export default LightWeightCodeBlock;