mirror of
https://github.com/primer/css.git
synced 2024-11-28 04:43:05 +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 {BorderBox, theme} from '@primer/components'
|
||||
import {withMDXLive} from 'mdx-live'
|
||||
import HTMLtoJSX from 'html-2-jsx'
|
||||
|
||||
const LANG_PATTERN = /\blanguage-\.?(erb|jsx|html)\b/
|
||||
|
||||
const converter = new HTMLtoJSX({
|
||||
indent: ' ',
|
||||
createClass: false
|
||||
})
|
||||
|
||||
const defaultTransform = code => `<React.Fragment>${code}</React.Fragment>`
|
||||
|
||||
const LiveEditor = withMDXLive('pre')
|
||||
|
||||
LiveEditor.defaultProps = {
|
||||
// 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) {
|
||||
// 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 html = unsafeInnerHTML ? unsafeInnerHTML.__html : React.Children.toArray(children).join('\n')
|
||||
const jsx = converter.convert(html)
|
||||
return <LiveEditor {...rest}>{jsx}</LiveEditor>
|
||||
const lang = getLanguage(props.className)
|
||||
rest.transformCode = getTransformForLanguage(lang)
|
||||
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