From 31d07fdac80a2a546646b1eb232fa7dd6319ce83 Mon Sep 17 00:00:00 2001 From: August Skare Date: Mon, 19 Nov 2018 17:27:00 +0100 Subject: rename all files and directories to lowercase --- packages/dev-tools-pages/ts/components/code.tsx | 203 ++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 packages/dev-tools-pages/ts/components/code.tsx (limited to 'packages/dev-tools-pages/ts/components/code.tsx') diff --git a/packages/dev-tools-pages/ts/components/code.tsx b/packages/dev-tools-pages/ts/components/code.tsx new file mode 100644 index 000000000..8415f1179 --- /dev/null +++ b/packages/dev-tools-pages/ts/components/code.tsx @@ -0,0 +1,203 @@ +import * as React from 'react'; +import styled from 'styled-components'; + +import { colors } from 'ts/variables'; + +import { Button as BaseButton } from './Button'; + +const isTouch = Boolean( + 'ontouchstart' in window || + (window as any).navigator.maxTouchPoints > 0 || + (window as any).navigator.msMaxTouchPoints > 0, +); + +interface CodeProps { + language?: string; + isLight?: boolean; + isDiff?: boolean; + gutter?: Array; + gutterLength?: number; + canCopy?: boolean; + isEtc?: boolean; +} + +interface CodeState { + hlCode?: string; + didCopy?: boolean; +} + +const Button = styled(BaseButton)` + opacity: ${isTouch ? '1' : '0'}; + position: absolute; + top: 1rem; + right: 1rem; + transition: opacity 0.2s; + :focus { + opacity: 1; + } +`; + +const Container = styled.div` + position: relative; + &:hover ${Button} { + opacity: 1; + } +`; + +const Base = + styled.div < + CodeProps > + ` + font-size: .875rem; + color: ${props => (props.language === undefined ? colors.white : 'inherit')}; + background-color: ${props => + props.isLight ? 'rgba(255,255,255,.15)' : props.language === undefined ? colors.black : '#F1F4F5'}; + white-space: ${props => (props.language === undefined ? 'nowrap' : '')}; + position: relative; + + ${props => + props.isDiff + ? ` + background-color: #E9ECED; + display: flex; + padding-top: 1.5rem; + padding-bottom: 1.5rem; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + ` + : ``} +`; + +const CodeDiff: React.StatelessComponent = ({ gutterLength, ...props }) => ; +const StyledCodeDiff = styled(CodeDiff)` + ::before { + content: ''; + width: calc(0.75rem + ${props => props.gutterLength}ch); + background-color: #e2e5e6; + position: absolute; + top: 0; + left: 0; + bottom: 0; + } + + [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-gutter); + + width: ${props => props.gutterLength}; + padding-left: 0.375rem; + padding-right: 0.375rem; + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + z-index: 1; + } + } + + .line-addition { + background-color: rgba(0, 202, 105, 0.1); + } + .line-deletion { + background-color: rgba(255, 0, 0, 0.07); + } +`; + +const StyledPre = + styled.pre < + CodeProps > + ` + margin: 0; + ${props => + !props.isDiff + ? ` + padding: 1.5rem; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + ` + : ``}; +`; + +const StyledCopyInput = styled.textarea` + opacity: 0; + height: 0; + position: absolute; + top: 0; + right: 0; + z-index: -1; +`; + +class Code extends React.Component { + public state: CodeState = {}; + private readonly _code = React.createRef(); + public componentDidMount(): void { + // _onMountAsync is only setting state, so no point in handling the promise + // tslint:disable-next-line:no-floating-promises + this._onMountAsync(); + } + public render(): React.ReactNode { + const { language, isLight, isDiff, children, gutterLength, canCopy } = this.props; + const { hlCode } = this.state; + + return ( + + + + {hlCode === undefined ? ( + {children} + ) : ( + + )} + + {!('clipboard' in navigator) ? ( + + ); + } + private async _onMountAsync(): Promise { + const { language, children, isDiff, gutter, isEtc } = this.props; + + const code = children as string; + + if (language !== undefined) { + const { highlight } = await System.import(/* webpackChunkName: 'highlightjs' */ 'ts/highlight'); + + this.setState({ + hlCode: highlight({ language, code, isDiff, gutter, isEtc }), + }); + } + } + private readonly _handleCopyAsync = async () => { + try { + if ('clipboard' in navigator) { + await (navigator as any).clipboard.writeText(this.props.children); + this.setState({ didCopy: true }); + } else { + const lastActive = document.activeElement as HTMLElement; + this._code.current.focus(); + this._code.current.select(); + document.execCommand('copy'); + lastActive.focus(); + this.setState({ didCopy: true }); + } + } catch (error) { + this.setState({ didCopy: false }); + } + }; +} + +export { Code }; -- cgit v1.2.3