mirror of
https://github.com/primer/css.git
synced 2024-11-30 19:53:11 +03:00
convert HTML to JSX transparently 😎
This commit is contained in:
parent
2626cf574f
commit
919d48747e
@ -1,25 +1,58 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import {BorderBox, theme} from '@primer/components'
|
||||||
import {withMDXLive} from 'mdx-live'
|
import {withMDXLive} from 'mdx-live'
|
||||||
import HTMLtoJSX from 'html-2-jsx'
|
import HTMLtoJSX from 'html-2-jsx'
|
||||||
|
|
||||||
|
const LANG_PATTERN = /\blanguage-\.?(erb|jsx|html)\b/
|
||||||
|
|
||||||
const converter = new HTMLtoJSX({
|
const converter = new HTMLtoJSX({
|
||||||
indent: ' ',
|
indent: ' ',
|
||||||
createClass: false
|
createClass: false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const defaultTransform = code => `<React.Fragment>${code}</React.Fragment>`
|
||||||
|
|
||||||
const LiveEditor = withMDXLive('pre')
|
const LiveEditor = withMDXLive('pre')
|
||||||
|
|
||||||
LiveEditor.defaultProps = {
|
LiveEditor.defaultProps = {
|
||||||
// match ```html and ```jsx fenced code blocks, with or without "."
|
// match ```html and ```jsx fenced code blocks, with or without "."
|
||||||
match: /\blanguage-\.?(html|jsx)\b/
|
match: LANG_PATTERN,
|
||||||
|
style: {
|
||||||
|
padding: 0
|
||||||
|
},
|
||||||
|
previewStyle: {
|
||||||
|
backgroundColor: theme.colors.white,
|
||||||
|
padding: theme.space[3]
|
||||||
|
},
|
||||||
|
editorStyle: {
|
||||||
|
fontFamily: theme.fonts.mono,
|
||||||
|
fontSize: theme.fontSizes[1],
|
||||||
|
padding: theme.space[3]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CodeExample(props) {
|
export default function CodeExample(props) {
|
||||||
// for some reason, some fenced code blocks get unsafeInnerHTML and others
|
|
||||||
// get children; we need to handle both and convert them to a single string
|
|
||||||
// that we can sanitize
|
|
||||||
const {unsafeInnerHTML, children, ...rest} = props
|
const {unsafeInnerHTML, children, ...rest} = props
|
||||||
const html = unsafeInnerHTML ? unsafeInnerHTML.__html : React.Children.toArray(children).join('\n')
|
const lang = getLanguage(props.className)
|
||||||
const jsx = converter.convert(html)
|
rest.transformCode = getTransformForLanguage(lang)
|
||||||
return <LiveEditor {...rest}>{jsx}</LiveEditor>
|
const code = unsafeInnerHTML
|
||||||
|
? unsafeInnerHTML.__html
|
||||||
|
: React.Children.toArray(children).join('\n')
|
||||||
|
rest.children = code
|
||||||
|
return (
|
||||||
|
<BorderBox bg="gray.1" my={4}>
|
||||||
|
<LiveEditor {...rest} />
|
||||||
|
</BorderBox>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLanguage(className) {
|
||||||
|
const match = className.match(LANG_PATTERN)
|
||||||
|
return match ? match[1] : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTransformForLanguage(lang) {
|
||||||
|
return lang === 'jsx'
|
||||||
|
? defaultTransform
|
||||||
|
: html => defaultTransform(converter.convert(html))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user