-
Notifications
You must be signed in to change notification settings - Fork 10
Description
Issue:
First of all, amazing package! I've been searching for a proper React Native markdown renderer for a while.
I have a feature request regarding the layout behavior. I'm using this package in an AI chat app where I render individual chat bubbles for user and AI messages. However, the onLayout function and contentSize state in the main Markdown component is causing my chat bubbles to expand to full screen height instead of wrapping their content naturally.
Request:
Would it be possible to provide either:
- A lightweight version of the Markdown component without the wrapping onLayout View, or
- An option/prop to disable the layout measurement
I don't need the table and image features that rely on contentSize, so the layout measurement isn't necessary for my use case.
Alternative:
Should I just copy the Markdown.tsx source and remove the layout logic myself, then disable tables/images via
customRenderers? Or is there a better approach you'd recommend?
<TestMarkdown
markdown={content}
customRenderers={{
ImageRenderer: () => null,
TableRenderer: () => null,
}}
customStyles={{
text: styles.markdownText
}}
/>
import { Definition, Root } from "mdast"
import { useMemo } from "react"
import remarkGfm from "remark-gfm"
import remarkParse from "remark-parse"
import { unified } from "unified"
import { visit } from "unist-util-visit"
import { MarkdownContextProvider } from "react-native-remark/src/context"
import { defaultRenderers } from "react-native-remark/src/renderers"
import { Renderers } from "react-native-remark/src/renderers/renderers"
import { RootRenderer } from "react-native-remark/src/renderers/root"
import { Theme, defaultTheme } from "react-native-remark/src/themes"
import { Styles, mergeStyles } from "react-native-remark/src/themes/themes"
const parser = unified().use(remarkParse).use(remarkGfm)
function extractDefinitions(tree: Root): Record<string, Definition> {
const definitions: Record<string, Definition> = {}
visit(tree, "definition", (node: Definition) => {
definitions[node.identifier] = node
})
return definitions
}
export type MarkdownProps = {
markdown: string
theme?: Theme
customRenderers?: Partial<Renderers>
customStyles?: Partial<Styles>
onCodeCopy?: (code: string) => void
onLinkPress?: (url: string) => void
}
export const TestMarkdown = ({
markdown,
theme,
customRenderers,
customStyles,
onCodeCopy,
onLinkPress,
}: MarkdownProps) => {
const tree = useMemo(() => parser.parse(markdown), [markdown])
const activeTheme = theme ?? defaultTheme
const renderers = useMemo(
() => ({
...defaultRenderers,
...activeTheme.renderers,
...customRenderers,
}),
[activeTheme.renderers, customRenderers],
)
const definitions = useMemo(() => extractDefinitions(tree), [tree])
// const colorScheme = useColorScheme()
// const mode = colorScheme === "dark" ? "dark" : "light"
const mode = "light"
const mergedStyles = mergeStyles(activeTheme.global, activeTheme[mode], customStyles)
return (
<MarkdownContextProvider
tree={tree}
renderers={renderers}
definitions={definitions}
contentSize={{ width: 0, height: 0 }}
styles={mergedStyles}
onCodeCopy={onCodeCopy}
onLinkPress={onLinkPress}
>
<RootRenderer node={tree} />
</MarkdownContextProvider>
)
}Use Case:
Chat bubbles that should size themselves based on content length rather than filling available space.