Last active
November 27, 2019 12:01
-
-
Save davo/cb346bf84ceedc1de6ece2d7da4de00d to your computer and use it in GitHub Desktop.
FrameSpy - Refactor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react' | |
import { addPropertyControls, ControlType, FrameProps, Frame } from 'framer' | |
import reactElementToJSXString from 'react-element-to-jsx-string' | |
import Highlight, { defaultProps } from 'prism-react-renderer' | |
import { themes } from './themes' | |
import Clipboard from 'react-clipboard.js' | |
// @steveruizok | |
// Define type of property | |
type Props = Partial<FrameProps> & | |
Partial<{ | |
target: React.ReactNodeArray | |
theme: string | |
fontSize: number | |
lineHeight: number | |
tabStop: number | |
sortProps: boolean | |
showFunctions: boolean | |
showDefaultProps: boolean | |
useBooleanShorthandSyntax: boolean | |
useFragmentShortSyntax: boolean | |
}> | |
export const FrameSpy = (props: Props) => { | |
const { | |
target, | |
theme, | |
tabStop, | |
fontSize, | |
lineHeight, | |
sortProps, | |
showFunctions, | |
showDefaultProps, | |
useFragmentShortSyntax, | |
useBooleanShorthandSyntax, | |
...rest | |
} = props | |
const [node] = target | |
if (!node) { | |
return ( | |
<DefaultContainer {...rest}> | |
<h1>🕵️♀️ FrameSpy</h1> | |
<p>Connect a Frame to spy on its JSX.</p> | |
</DefaultContainer> | |
) | |
} | |
const codeString = reactElementToJSXString(node, { | |
tabStop, | |
sortProps, | |
showFunctions, | |
showDefaultProps, | |
useFragmentShortSyntax, | |
useBooleanShorthandSyntax, | |
}) | |
return ( | |
<Frame {...rest} background={themes[theme].plain.backgroundColor}> | |
<div style={containerStyle}> | |
<Highlight {...defaultProps} code={codeString} theme={themes[theme]} language='jsx'> | |
{({ className, style, tokens, getLineProps, getTokenProps }) => ( | |
<pre | |
className={className} | |
style={{ | |
...style, | |
fontSize: `${fontSize}rem`, | |
lineHeight: `${lineHeight}rem`, | |
}}> | |
{tokens.map((line, i) => ( | |
<div {...getLineProps({ line, key: i })}> | |
{line.map((token, key) => ( | |
<span {...getTokenProps({ token, key })} /> | |
))} | |
</div> | |
))} | |
</pre> | |
)} | |
</Highlight> | |
<Clipboard data-clipboard-text={codeString} style={clipboard}> | |
Copy to Clipboard | |
</Clipboard> | |
</div> | |
</Frame> | |
) | |
} | |
FrameSpy.defaultProps = { | |
height: 280, | |
width: 296, | |
target: [], | |
showDefaultProps: true, | |
sortProps: false, | |
showFunctions: false, | |
useBooleanShorthandSyntax: true, | |
useFragmentShortSyntax: true, | |
tabStop: 2, | |
fontSize: 1, | |
lineHeight: 1.5, | |
theme: 'dracula', | |
} | |
addPropertyControls(FrameSpy, { | |
target: { type: ControlType.ComponentInstance, title: 'Target' }, | |
theme: { | |
type: ControlType.Enum, | |
options: Object.keys(themes), | |
title: 'Theme', | |
}, | |
showDefaultProps: { | |
type: ControlType.Boolean, | |
title: 'Default Props', | |
defaultValue: false, | |
}, | |
sortProps: { | |
type: ControlType.Boolean, | |
title: 'Sort Props', | |
defaultValue: false, | |
}, | |
showFunctions: { | |
type: ControlType.Boolean, | |
title: 'Show Functions', | |
defaultValue: false, | |
}, | |
useBooleanShorthandSyntax: { | |
type: ControlType.Boolean, | |
title: 'Boolean Shorthand', | |
defaultValue: true, | |
}, | |
useFragmentShortSyntax: { | |
type: ControlType.Boolean, | |
title: 'Fragment Shorthand', | |
defaultValue: true, | |
}, | |
fontSize: { | |
type: ControlType.Number, | |
title: 'Font Size', | |
defaultValue: 1, | |
min: 0.5, | |
max: 5, | |
unit: 'rem', | |
step: 0.1, | |
displayStepper: true, | |
}, | |
lineHeight: { | |
type: ControlType.Number, | |
title: 'Line Height', | |
defaultValue: 1.5, | |
min: 0.5, | |
max: 5, | |
unit: 'rem', | |
step: 0.1, | |
displayStepper: true, | |
}, | |
tabStop: { | |
type: ControlType.Number, | |
title: 'Tab Stop', | |
min: 2, | |
max: 8, | |
defaultValue: 2, | |
}, | |
}) | |
type DefaultContainerProps = Partial<FrameProps> | |
// A component for our default container | |
const DefaultContainer = (props: DefaultContainerProps) => { | |
const { children, style, ...rest } = props | |
return ( | |
<Frame | |
{...rest} | |
style={{ | |
...emptyState, | |
...style, | |
}}> | |
<>{children}</> | |
</Frame> | |
) | |
} | |
const emptyState: React.CSSProperties = { | |
color: '#8855FF', | |
background: 'rgba(136, 85, 255, 0.1)', | |
overflow: 'hidden', | |
padding: 16, | |
fontSize: 16, | |
lineHeight: 1.3, | |
textAlign: 'left', | |
} | |
const containerStyle: React.CSSProperties = { | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
width: '100%', | |
height: '100%', | |
overflow: 'scroll', | |
padding: '0 8px', | |
} | |
const clipboard: React.CSSProperties = { | |
cursor: 'pointer', | |
backgroundColor: 'none', | |
background: 'none', | |
border: 'none', | |
outline: 'none', | |
color: '#0099ff', | |
position: 'fixed', | |
top: '8px', | |
right: '12px', | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment