Skip to content

Commit

Permalink
feat: add new Playground component
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronauck committed Jul 1, 2019
1 parent c52d45f commit 7bf03b2
Show file tree
Hide file tree
Showing 17 changed files with 261 additions and 124 deletions.
1 change: 1 addition & 0 deletions core/gatsby-theme-docz/gatsby-browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './src/index.css'
10 changes: 5 additions & 5 deletions core/gatsby-theme-docz/gatsby-config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const path = require('path')
const { getDoczConfig } = require('./lib/utils/parseConfig')

const getMdPlugins = () => {
const getRemarkPlugins = () => {
let plugins = []

try {
Expand All @@ -16,7 +16,7 @@ const getMdPlugins = () => {
return plugins
}

const getHastPlugins = rootPath => {
const getRehypePlugins = rootPath => {
let plugins = []

try {
Expand All @@ -34,13 +34,13 @@ const getHastPlugins = rootPath => {
module.exports = opts => {
const config = getDoczConfig(opts)
const { paths } = config
const mdPlugins = getMdPlugins()
const hastPlugins = getHastPlugins(paths.root)
const mdPlugins = getRemarkPlugins()
const hastPlugins = getRehypePlugins(paths.root)

return {
plugins: [
{
resolve: 'gatsby-mdx',
resolve: 'gatsby-plugin-mdx',
options: {
extensions: ['.md', '.mdx'],
remarkPlugins:
Expand Down
116 changes: 88 additions & 28 deletions core/gatsby-theme-docz/src/components/Code/index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,94 @@
/** @jsx jsx */
import { useConfig } from 'docz'
import { jsx, Styled } from 'theme-ui'
import Highlight, { defaultProps } from 'prism-react-renderer'
import { get } from 'lodash/fp'
import { jsx, useColorMode } from 'theme-ui'
import AceEditor from 'react-ace'

export const Code = ({ codeString, language = 'jsx' }) => {
const config = useConfig()
const theme = get('themeConfig.prismjs', config)
import 'brace/theme/dracula'
import 'brace/theme/textmate'
import 'brace/mode/jsx'
import 'brace/ext/language_tools'
import 'brace/ext/searchbox'

import * as styles from './styles'

const languages = [
'javascript',
'java',
'python',
'xml',
'ruby',
'sass',
'markdown',
'mysql',
'json',
'html',
'handlebars',
'golang',
'csharp',
'elixir',
'typescript',
'css',
]

languages.forEach(lang => {
require(`brace/mode/${lang}`)
require(`brace/snippets/${lang}`)
})

const themes = {
light: 'textmate',
dark: 'dracula',
}

const getLanguage = lang => {
const defaultLanguage = 'jsx'
if (typeof lang === 'string') return defaultLanguage

const language = getter(lang, 'props.props.className') || defaultLanguage
const result = language.replace('language-', '')

if (result === 'js' || result === 'javascript') return 'jsx'
if (result === 'ts' || result === 'tsx' || result === 'typescript') {
return 'text/typescript'
}
return result
}

export const Code = ({
className,
codeString,
language = 'jsx',
readOnly,
onChange,
}) => {
const [colorMode] = useColorMode()
const lang = getLanguage(language)
return (
<Highlight
{...defaultProps}
theme={theme}
code={codeString}
language={language}
>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<Styled.pre className={className} style={style}>
{tokens.map((line, i) => {
if (line.length === 1 && line[0].empty) return null
return (
<div key={line} {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token, key })} />
))}
</div>
)
})}
</Styled.pre>
)}
</Highlight>
<AceEditor
className={className}
sx={styles.editor}
value={codeString}
mode={lang}
readOnly={readOnly}
onChange={onChange}
highlightActiveLine={false}
theme={themes[colorMode]}
name="code-editor"
fontSize={16}
style={{
width: 'calc(100% - 2px)',
height: 200,
}}
setOptions={{
tabSize: 2,
minLines: 5,
maxLines: 20,
wrap: true,
autoScrollEditorIntoView: true,
printMargin: false,
}}
editorProps={{
$blockScrolling: Infinity,
}}
/>
)
}
8 changes: 7 additions & 1 deletion core/gatsby-theme-docz/src/components/Code/styles.js
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
export const line = {}
export const editor = {
borderRadius: 'radius',
border: '1px solid #000',
borderColor: 'border',
lineHeight: '1.4em',
fontFamily: 'monospace',
}
10 changes: 6 additions & 4 deletions core/gatsby-theme-docz/src/components/Icons/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export { default as ChevronDown } from 'react-feather/dist/icons/chevron-down'
export { default as ChevronUp } from 'react-feather/dist/icons/chevron-up'
export { default as Clipboard } from 'react-feather/dist/icons/clipboard'
export { default as Code } from 'react-feather/dist/icons/code'
export { default as Edit } from 'react-feather/dist/icons/edit-2'
export { default as Sun } from 'react-feather/dist/icons/sun'
export { default as Menu } from 'react-feather/dist/icons/menu'
export { default as Github } from 'react-feather/dist/icons/github'
export { default as Menu } from 'react-feather/dist/icons/menu'
export { default as Search } from 'react-feather/dist/icons/search'
export { default as ChevronUp } from 'react-feather/dist/icons/chevron-up'
export { default as ChevronDown } from 'react-feather/dist/icons/chevron-down'
export { default as Sun } from 'react-feather/dist/icons/sun'
46 changes: 46 additions & 0 deletions core/gatsby-theme-docz/src/components/Playground/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/** @jsx jsx */
import { jsx } from 'theme-ui'
import { useState } from 'react'
import { LiveProvider, LiveError, LivePreview } from 'react-live'
import copy from 'copy-text-to-clipboard'

import * as styles from './styles'
import * as Icons from '../Icons'
import { Code } from '../Code'

export const Playground = ({ code: initialCode, scope }) => {
const [code, setCode] = useState(() => initialCode)
const [showingCode, setShowingCode] = useState(false)

const transformCode = code => {
if (code.startsWith('()') || code.startsWith('class')) return code
return `<React.Fragment>${code}</React.Fragment>`
}

const toggleCode = () => {
setShowingCode(s => !s)
}

return (
<LiveProvider code={code} scope={scope} transformCode={transformCode}>
<div sx={styles.previewWrapper}>
<LivePreview sx={styles.preview(showingCode)} />
<div sx={styles.buttons}>
<button sx={styles.button} onClick={() => copy(code)}>
<Icons.Clipboard size={12} />
</button>
<button sx={styles.button} onClick={toggleCode}>
<Icons.Code size={12} />
</button>
</div>
</div>
<LiveError sx={styles.error} />
<Code
sx={styles.editor(showingCode)}
codeString={code}
onChange={setCode}
language="jsx"
/>
</LiveProvider>
)
}
25 changes: 25 additions & 0 deletions core/gatsby-theme-docz/src/components/Playground/machine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Machine, assign } from 'xstate'

const actions = {
changeCode: assign((ctx, ev) => ({
code: ev.data,
})),
}

const machine = Machine({
id: 'playground',
initial: 'idle',
states: {
idle: {
on: {
CHANGE: {
actions: ['changeCode'],
},
},
},
},
})

export default machine.withConfig({
actions,
})
54 changes: 54 additions & 0 deletions core/gatsby-theme-docz/src/components/Playground/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as mixins from '~utils/mixins'

const border = {
border: '1px solid black',
borderColor: 'playground.border',
}

export const editor = showingCode => ({
...border,
display: showingCode ? 'block' : 'none',
m: 0,
mt: '-1px',
borderRadius: '0 0 5px 5px',
})

export const error = {
m: 0,
py: 2,
px: 3,
bg: '#FF4757',
fontSize: 1,
color: 'white',
}

export const previewWrapper = {
position: 'relative',
}

export const preview = showingCode => ({
...border,
m: 0,
p: 4,
bg: 'playground.bg',
borderRadius: showingCode ? '5px 5px 0 0' : '5px',
})

export const buttons = {
zIndex: 9,
position: 'absolute',
bottom: -24,
right: 6,
}

export const button = {
...mixins.ghostButton,
py: 1,
p: 2,
bg: 'border',
color: 'muted',
borderRadius: '0 0 3px 3px',
'& ~ &': {
ml: 1,
},
}
8 changes: 7 additions & 1 deletion core/gatsby-theme-docz/src/components/Pre/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
import { jsx } from 'theme-ui'
import { preToCodeBlock } from 'mdx-utils'

import * as styles from './styles'
import { Code } from '../Code'

export const Pre = preProps => {
const props = preToCodeBlock(preProps)
if (props) {
return <Code {...props} />
return (
<div sx={styles.wrapper}>
<Code {...props} readOnly />
<span sx={styles.language}>{props.language}</span>
</div>
)
} else {
return <pre {...preProps} />
}
Expand Down
4 changes: 3 additions & 1 deletion core/gatsby-theme-docz/src/components/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as headings from './Headings'

import { Pre } from './Pre'
import { Layout } from './Layout'
import { Playground } from './Playground'
import { Pre } from './Pre'
import { Props } from './Props'

export const componentsMap = {
...headings,
playground: Playground,
pre: Pre,
layout: Layout,
props: Props,
Expand Down
1 change: 1 addition & 0 deletions core/gatsby-theme-docz/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import url('https://fonts.googleapis.com/css?family=Inconsolata&display=swap');
10 changes: 5 additions & 5 deletions core/gatsby-theme-docz/src/theme/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ import { toTheme } from '@theme-ui/typography'
import { merge } from 'lodash/fp'

import * as modes from './modes'
import prismjs from './prismjs'

moraga.headerWeight = 700
const typography = toTheme(moraga)

export default merge(typography, {
prismjs,
initialColorMode: 'light',
colors: {
...modes.light,
modes: {
dark: modes.dark,
},
},
fonts: {
monospace: 'Inconsolata',
},
fontSizes: [12, 14, 16, 20, 24, 32, 48, 64],
fontWeights: {
body: 400,
Expand Down Expand Up @@ -83,14 +84,13 @@ export default merge(typography, {
fontFamily: 'monospace',
},
pre: {
p: 3,
my: 4,
fontFamily: 'monospace',
textAlign: 'left',
borderRadius: 'radius',
'.token-line': {
lineHeight: '1.3em',
height: '1.3em',
lineHeight: '1.5em',
height: '1.5em',
},
},
},
Expand Down
Loading

0 comments on commit 7bf03b2

Please sign in to comment.