diff options
Diffstat (limited to 'packages/dev-tools-pages/ts/components/Code.tsx')
-rw-r--r-- | packages/dev-tools-pages/ts/components/Code.tsx | 106 |
1 files changed, 75 insertions, 31 deletions
diff --git a/packages/dev-tools-pages/ts/components/Code.tsx b/packages/dev-tools-pages/ts/components/Code.tsx index 5a03e79ac..ce4443357 100644 --- a/packages/dev-tools-pages/ts/components/Code.tsx +++ b/packages/dev-tools-pages/ts/components/Code.tsx @@ -4,12 +4,13 @@ import styled from 'styled-components'; import { colors } from 'ts/variables'; import BaseButton from './Button'; -var highlight = require('highlighter')(); - interface CodeProps { children: React.ReactNode; language?: string; light?: boolean; + diff?: boolean; + gutter?: Array<number>; + gutterLength?: number; } interface CodeState { @@ -30,37 +31,73 @@ const Button = styled(BaseButton)` const Base = styled.div < - CodeProps > - ` + CodeProps > + ` color: ${props => (props.language === undefined ? colors.white : 'inherit')}; background-color: ${props => - props.light ? 'rgba(255,255,255,.15)' : props.language === undefined ? colors.black : colors.lightGray}; + props.light ? 'rgba(255,255,255,.15)' : props.language === undefined ? colors.black : '#F1F4F5'}; white-space: ${props => (props.language === undefined ? 'nowrap' : '')}; position: relative; + + ${props => + props.diff + ? ` + background-color: #E9ECED; + display: flex; + padding-top: 1.5rem; + padding-bottom: 1.5rem; + ` + : ` + padding: 1.5rem; + `} + + overflow-y: scroll; + -webkit-overflow-scrolling: touch; + &:hover ${Button} { opacity: 1; } `; -const StyledCode = styled.code` - padding-top: 1.5rem; - padding-bottom: 1.5rem; - display: block; - overflow-y: scroll; - -webkit-overflow-scrolling: touch; +const StyledCodeDiff = + styled.code < + any > + ` + ::before { + content: ''; + width: calc(.75rem + ${props => props.gutterLength}ch); + background-color: #e2e5e6; + position: absolute; + top: 0; + left: 0; + bottom: 0; + } - - .diff-addition { - background-color: #d2e9e0; - padding: 0.3125rem; + [class^='line-'] { display: inline-block; width: 100%; + position: relative; + padding-right: 1.5rem; + padding-left: calc(2.25rem + ${props => props.gutterLength}ch); + ::before { + content: attr(data-test); + font-size: 0.875rem; + width: ${props => props.gutterLength}; + padding-left: .375rem; + padding-right: .375rem; + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + z-index: 1; + } } - .diff-deletion { - background-color: #ebdcdc; - padding: 0.3125rem; - display: inline-block; - width: 100%; + + .line-addition { + background-color: rgba(0, 202, 105, 0.1); + } + .line-deletion { + background-color: rgba(255, 0, 0, 0.07); } `; @@ -88,13 +125,16 @@ class Code extends React.Component<CodeProps, CodeState> { } async componentDidMount() { - const { language, children } = this.props; + const { language, children, diff, gutter } = this.props; + + const code = children as string; if (language !== undefined) { - const { default: hljs } = await System.import(/* webpackChunkName: 'highlightjs' */ 'ts/highlight'); + const { default: highlight } = await System.import(/* webpackChunkName: 'highlightjs' */ 'ts/highlight'); - const hlCode = hljs(children as string, language); - this.setState({ hlCode }); + this.setState({ + hlCode: highlight(language, code, diff, gutter), + }); } } @@ -115,16 +155,20 @@ class Code extends React.Component<CodeProps, CodeState> { }; render() { - const { language, light, children } = this.props; + const { language, light, diff, children, gutterLength } = this.props; + const { hlCode } = this.state; + + const Code = diff ? StyledCodeDiff : 'code'; return ( - <Base language={language} light={light}> + <Base language={language} diff={diff} light={light}> <StyledPre> - {this.state.hlCode !== undefined ? ( - <StyledCode dangerouslySetInnerHTML={{ __html: this.state.hlCode }} /> - ) : ( - <StyledCode>{this.props.children}</StyledCode> - )} + <Code + gutterLength={gutterLength} + dangerouslySetInnerHTML={hlCode ? { __html: this.state.hlCode } : null} + > + {hlCode === undefined ? children : null} + </Code> </StyledPre> {navigator.userAgent !== 'ReactSnap' ? <Button onClick={this.handleCopy}>Copy</Button> : null} {!('clipboard' in navigator) ? ( |