Skip to content

Commit

Permalink
Refactor: Combine existing Code component with the Markdown Code comp…
Browse files Browse the repository at this point in the history
…onent #613 (#812)
  • Loading branch information
ryanoglesby08 authored and sapegin committed Feb 12, 2018
1 parent f7143ea commit b3a1390
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 118 deletions.
21 changes: 17 additions & 4 deletions src/rsg-components/Code/Code.spec.js
@@ -1,9 +1,22 @@
import React from 'react';
import { CodeRenderer } from './CodeRenderer';

it('renderer should render code', () => {
const code = '<button>OK</button>';
const actual = shallow(<CodeRenderer classes={{}}>{code}</CodeRenderer>);
describe('Code blocks', () => {
it('should render code', () => {
const code = '<button>OK</button>';
const actual = shallow(<CodeRenderer classes={{}}>{code}</CodeRenderer>);

expect(actual).toMatchSnapshot();
expect(actual).toMatchSnapshot();
});

it('should render code to be highlighted', () => {
const code = '<button>OK</button>';
const actual = render(
<CodeRenderer classes={{}} className="lang-html">
{code}
</CodeRenderer>
);

expect(actual).toMatchSnapshot();
});
});
18 changes: 10 additions & 8 deletions src/rsg-components/Code/CodeRenderer.js
@@ -1,29 +1,31 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import Styled from 'rsg-components/Styled';

const styles = ({ fontFamily }) => ({
code: {
display: 'inline',
fontFamily: fontFamily.monospace,
fontSize: 'inherit',
color: 'inherit',
background: 'transparent',
whiteSpace: 'inherit',
},
});

export function CodeRenderer({ classes, className, children }) {
return (
<span className={className}>
<code className={classes.code}>{children}</code>
</span>
);
}
const classNames = cx(className, classes.code);

const isHighlighted = className && className.indexOf('lang-') !== -1;
if (isHighlighted) {
return <code className={classNames} dangerouslySetInnerHTML={{ __html: children }} />;
}
return <code className={classNames}>{children}</code>;
}
CodeRenderer.propTypes = {
classes: PropTypes.object.isRequired,
className: PropTypes.string,
children: PropTypes.node,
children: PropTypes.node.isRequired,
};

export default Styled(styles)(CodeRenderer);
22 changes: 16 additions & 6 deletions src/rsg-components/Code/__snapshots__/Code.spec.js.snap
@@ -1,9 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renderer should render code 1`] = `
<span>
<code>
&lt;button&gt;OK&lt;/button&gt;
</code>
</span>
exports[`Code blocks should render code 1`] = `
<code
className=""
>
&lt;button&gt;OK&lt;/button&gt;
</code>
`;

exports[`Code blocks should render code to be highlighted 1`] = `
<code
class="lang-html"
>
<button>
OK
</button>
</code>
`;
40 changes: 6 additions & 34 deletions src/rsg-components/Markdown/Markdown.js
@@ -1,4 +1,3 @@
import React from 'react';
import PropTypes from 'prop-types';
import { compiler } from 'markdown-to-jsx';
import mapValues from 'lodash/mapValues';
Expand All @@ -10,25 +9,14 @@ import Para, { styles as paraStyles } from 'rsg-components/Para';
import MarkdownHeading from 'rsg-components/Markdown/MarkdownHeading';
import List from 'rsg-components/Markdown/List';
import Blockquote from 'rsg-components/Markdown/Blockquote';
import Pre from 'rsg-components/Markdown/Pre';
import Code from 'rsg-components/Code';

// We’re explicitly specifying Webpack loaders here so we could skip specifying them in Webpack configuration.
// That way we could avoid clashes between our loaders and user loaders.
// eslint-disable-next-line import/no-unresolved
require('!!../../../loaders/style-loader!../../../loaders/css-loader!highlight.js/styles/tomorrow.css');

// Code blocks with server-side syntax highlight
function Code({ children, className }) {
const isHighlighted = className && className.indexOf('lang-') !== -1;
if (isHighlighted) {
return <code className={className} dangerouslySetInnerHTML={{ __html: children }} />;
}
return <code className={className}>{children}</code>;
}
Code.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
};

// Custom CSS classes for each tag: <em> → <em className={s.em}> + custom components
const getBaseOverrides = memoize(classes => {
const styleOverrides = mapValues(classes, value => ({
Expand Down Expand Up @@ -110,9 +98,9 @@ const getBaseOverrides = memoize(classes => {
},
code: {
component: Code,
props: {
className: classes.code,
},
},
pre: {
component: Pre,
},
};
}, () => 'getBaseOverrides');
Expand All @@ -129,7 +117,7 @@ const getInlineOverrides = memoize(classes => {
};
}, () => 'getInlineOverrides');

const styles = ({ space, fontFamily, fontSize, color, borderRadius }) => ({
const styles = ({ space, fontFamily, fontSize, color }) => ({
base: {
color: color.base,
fontFamily: fontFamily.base,
Expand All @@ -147,22 +135,6 @@ const styles = ({ space, fontFamily, fontSize, color, borderRadius }) => ({
borderColor: color.border,
borderStyle: 'solid',
},
code: {
fontFamily: fontFamily.monospace,
fontSize: 'inherit',
color: 'inherit',
background: 'transparent',
whiteSpace: 'inherit',
},
pre: {
composes: '$para',
backgroundColor: color.codeBackground,
border: [[1, color.border, 'solid']],
padding: [[space[1], space[2]]],
fontSize: fontSize.small,
borderRadius,
whiteSpace: 'pre',
},
table: {
composes: '$para',
borderCollapse: 'collapse',
Expand Down
11 changes: 11 additions & 0 deletions src/rsg-components/Markdown/Pre/Pre.spec.js
@@ -0,0 +1,11 @@
import React from 'react';

import Pre from './index';

describe('Markdown Pre', () => {
it('should render a pre', () => {
const actual = render(<Pre>This is pre-formatted text.</Pre>);

expect(actual).toMatchSnapshot();
});
});
30 changes: 30 additions & 0 deletions src/rsg-components/Markdown/Pre/PreRenderer.js
@@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';

import Styled from 'rsg-components/Styled';

const styles = ({ space, color, fontSize, fontFamily, borderRadius }) => ({
pre: {
fontFamily: fontFamily.base,
fontSize: fontSize.small,
lineHeight: 1.5,
color: color.base,
whiteSpace: 'pre',
backgroundColor: color.codeBackground,
padding: [[space[1], space[2]]],
border: [[1, color.border, 'solid']],
borderRadius,
marginTop: 0,
marginBottom: space[2],
},
});

export function PreRenderer({ classes, children }) {
return <pre className={classes.pre}>{children}</pre>;
}
PreRenderer.propTypes = {
classes: PropTypes.object.isRequired,
children: PropTypes.node.isRequired,
};

export default Styled(styles)(PreRenderer);
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Markdown Pre should render a pre 1`] = `
<pre
class="rsg--pre-0"
>
This is pre-formatted text.
</pre>
`;
1 change: 1 addition & 0 deletions src/rsg-components/Markdown/Pre/index.js
@@ -0,0 +1 @@
export { default } from 'rsg-components/Markdown/Pre/PreRenderer';

0 comments on commit b3a1390

Please sign in to comment.