-
-
Save dalcib/dc989b4f298f40b48899a1c3201ee45f to your computer and use it in GitHub Desktop.
MDX in React-native
This file contains hidden or 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
// The actual components that will be rendered with markdown. You may need to change or add components, | |
// this list is not fully tested. Some components may also never be used by MDX. | |
// Copied from https://github.com/mientjan/react-native-markdown-renderer and heavily modified. | |
import React from 'react' | |
import { Text, TouchableOpacity, View } from 'react-native' | |
import FitImage from 'react-native-fit-image' | |
import openUrl from './openUrl' | |
import { styles } from './styles' | |
const components = { | |
div: ({ children }) => <View style={styles.div}>{children}</View>, | |
wrapper: ({ children }) => <View style={styles.div}>{children}</View>, | |
textgroup: ({ children }) => { | |
return <Text style={styles.text}>{children}</Text> | |
}, | |
inline: ({ children }) => { | |
return <Text>{children}</Text> | |
}, | |
text: ({ children }) => { | |
return <Text>{children}</Text> | |
}, | |
span: ({ children }) => { | |
return <Text>{children}</Text> | |
}, | |
strong: ({ children }) => { | |
return <Text style={styles.strong}>{children}</Text> | |
}, | |
a: ({ href, children }) => { | |
return ( | |
<TouchableOpacity style={styles.link} onPress={() => openUrl(href)}> | |
{children} | |
</TouchableOpacity> | |
) | |
}, | |
em: ({ children }) => { | |
return <Text style={styles.em}>{children}</Text> | |
}, | |
h1: ({ children }) => { | |
return ( | |
<View style={styles.headingContainer}> | |
<Text style={[styles.heading, styles.heading1]}> | |
{children} | |
</Text> | |
</View> | |
) | |
}, | |
h2: ({ children }) => { | |
return ( | |
<View style={styles.headingContainer}> | |
<Text style={[styles.heading, styles.heading2]}> | |
{children} | |
</Text> | |
</View> | |
) | |
}, | |
h3: ({ children }) => ( | |
<View style={styles.headingContainer}> | |
<Text style={[styles.heading, styles.heading3]}> | |
{children} | |
</Text> | |
</View> | |
), | |
h4: ({ children }) => ( | |
<View style={styles.headingContainer}> | |
<Text style={[styles.heading, styles.heading4]}> | |
{children} | |
</Text> | |
</View> | |
), | |
h5: ({ children }) => ( | |
<View style={styles.headingContainer}> | |
<Text style={[styles.heading, styles.heading5]}> | |
{children} | |
</Text> | |
</View> | |
), | |
h6: ({ children }) => ( | |
<View style={styles.headingContainer}> | |
<Text style={[styles.heading, styles.heading6]}> | |
{children} | |
</Text> | |
</View> | |
), | |
p: ({ children }) => <View style={styles.paragraph}>{children}</View>, | |
blockquote: ({ children }) => <View style={styles.blockquote}>{children}</View>, | |
inlineCode: ({ children }) => { | |
return <Text style={styles.codeInline}>{children}</Text> | |
}, | |
code: ({ children }) => { | |
return <Text style={styles.codeBlock}>{children}</Text> | |
}, | |
pre: ({ children }) => <View style={styles.pre}>{children}</View>, | |
ul: ({ children }) => { | |
return <View style={[styles.list, styles.listUnordered]}>{children}</View> | |
}, | |
ol: ({ children }) => { | |
return <View style={[styles.list, styles.listOrdered]}>{children}</View> | |
}, | |
li: ({ children }) => { | |
return ( | |
<View style={styles.listUnorderedItem}> | |
<Text style={styles.listUnorderedItemIcon}>{'\u00B7'}</Text> | |
<View style={[styles.listItem]}>{children}</View> | |
</View> | |
) | |
}, | |
table: ({ children }) => <View style={[styles.table]}>{children}</View>, | |
thead: ({ children }) => <View style={[styles.tableHeader]}>{children}</View>, | |
tbody: ({ children }) => <View>{children}</View>, | |
th: ({ children }) => { | |
return <View style={[styles.tableHeaderCell]}>{children}</View> | |
}, | |
tr: ({ children }) => { | |
return <View style={[styles.tableRow]}>{children}</View> | |
}, | |
td: ({ children }) => { | |
return <View style={[styles.tableRowCell]}>{children}</View> | |
}, | |
hr: ({ children }) => { | |
return <View style={[styles.hr]} /> | |
}, | |
br: ({ children }) => <Text>{'\n'}</Text>, | |
img: ({ src, children }) => { | |
return <FitImage indicator={true} style={styles.image} source={{ uri: src }} /> | |
}, | |
} | |
export default components |
This file contains hidden or 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
// Use your MDX content with this component. | |
import React from 'react' | |
import MDX from '@mdx-js/runtime' | |
import components from '../utils/markdown/markdown' | |
// Renders a cimple loading spinner as a test | |
import Loading from './Loading' | |
const mdxComponents = { | |
...components, | |
Loading: Loading, // Add the custom component to the default markdown HTML components | |
} | |
// Add variables here if needed. | |
const scope = {} | |
// Children is an MDX string | |
const MdxContent = ({ children, style = {} }) => { | |
return ( | |
<View style={style}> | |
<MDX components={mdxComponents} scope={scope}> | |
{children} | |
</MDX> | |
</View> | |
) | |
} | |
export default MdxContent |
This file contains hidden or 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
// To open URLs from Markdown links. Modify as needed. Untested. | |
// Copied from https://github.com/mientjan/react-native-markdown-renderer | |
import { Linking } from 'react-native'; | |
export default function openUrl(url) { | |
if( url ) { | |
Linking.openURL(url); | |
} | |
} |
This file contains hidden or 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
// Add this to the root of your project. | |
// Adds Node libs that are needed, plus an fs implementation. | |
// mdx-runtime needs these. | |
// Yes, this works with Expo. | |
const libs = require('node-libs-react-native') | |
libs['fs'] = require.resolve('react-native-level-fs') | |
module.exports = { | |
resolver: { | |
extraNodeModules: libs, | |
}, | |
} |
This file contains hidden or 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
// Styles used for the components. Change to your liking. Some styles may | |
// be superfluous or not working, this list is not tested. | |
// Copied from https://github.com/mientjan/react-native-markdown-renderer and modified slightly. | |
import { StyleSheet } from 'react-native' | |
export const styles = StyleSheet.create({ | |
root: {}, | |
view: {}, | |
codeBlock: { | |
borderWidth: 1, | |
borderColor: '#CCCCCC', | |
backgroundColor: '#f5f5f5', | |
padding: 10, | |
borderRadius: 4, | |
}, | |
codeInline: { | |
borderWidth: 1, | |
borderColor: '#CCCCCC', | |
backgroundColor: '#f5f5f5', | |
padding: 10, | |
borderRadius: 4, | |
}, | |
del: { | |
backgroundColor: '#000000', | |
}, | |
em: { | |
fontStyle: 'italic', | |
}, | |
headingContainer: { | |
flexDirection: 'row', | |
}, | |
heading: {}, | |
heading1: { | |
fontSize: 32, | |
}, | |
heading2: { | |
fontSize: 24, | |
}, | |
heading3: { | |
fontSize: 18, | |
}, | |
heading4: { | |
fontSize: 16, | |
}, | |
heading5: { | |
fontSize: 13, | |
}, | |
heading6: { | |
fontSize: 11, | |
}, | |
hr: { | |
backgroundColor: '#000000', | |
height: 1, | |
}, | |
blockquote: { | |
paddingHorizontal: 20, | |
paddingVertical: 10, | |
margin: 20, | |
backgroundColor: '#CCCCCC', | |
}, | |
inlineCode: { | |
borderRadius: 3, | |
borderWidth: 1, | |
fontFamily: 'Courier', | |
fontWeight: 'bold', | |
}, | |
list: {}, | |
listItem: { | |
flex: 1, | |
flexWrap: 'wrap', | |
// backgroundColor: 'green', | |
}, | |
listUnordered: {}, | |
listUnorderedItem: { | |
flexDirection: 'row', | |
justifyContent: 'flex-start', | |
}, | |
listUnorderedItemIcon: { | |
marginLeft: 10, | |
marginRight: 10, | |
lineHeight: 30, | |
}, | |
listUnorderedItemText: { | |
fontSize: 20, | |
lineHeight: 20, | |
}, | |
listOrdered: {}, | |
listOrderedItem: { | |
flexDirection: 'row', | |
}, | |
listOrderedItemIcon: { | |
marginLeft: 10, | |
marginRight: 10, | |
lineHeight: 30, | |
}, | |
listOrderedItemText: { | |
fontWeight: 'bold', | |
lineHeight: 20, | |
}, | |
div: {}, | |
paragraph: { | |
marginTop: 10, | |
marginBottom: 10, | |
flexWrap: 'wrap', | |
flexDirection: 'row', | |
alignItems: 'flex-start', | |
justifyContent: 'flex-start', | |
}, | |
hardbreak: { | |
width: '100%', | |
height: 1, | |
}, | |
strong: { | |
fontWeight: 'bold', | |
}, | |
table: { | |
borderWidth: 1, | |
borderColor: '#000000', | |
borderRadius: 3, | |
}, | |
tableHeader: {}, | |
tableHeaderCell: { | |
flex: 1, | |
// color: '#000000', | |
padding: 5, | |
// backgroundColor: 'green', | |
}, | |
tableRow: { | |
borderBottomWidth: 1, | |
borderColor: '#000000', | |
flexDirection: 'row', | |
}, | |
tableRowCell: { | |
flex: 1, | |
padding: 5, | |
}, | |
text: {}, | |
strikethrough: { | |
textDecorationLine: 'line-through', | |
}, | |
pre: {}, | |
link: {}, | |
image: { | |
flex: 1, | |
}, | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment