UNPKG

react-intlayer

Version:

Easily internationalize i18n your React applications with type-safe multilingual content management.

198 lines (195 loc) 5.26 kB
'use client'; import { compileMarkdown } from "./processor.mjs"; import { useMarkdownContext } from "./MarkdownProvider.mjs"; import { Fragment, jsx } from "react/jsx-runtime"; //#region src/markdown/MarkdownRenderer.tsx /** * Renders markdown content to JSX with the provided components and options. * * This function does not use context from MarkdownProvider. Use `useMarkdownRenderer` * hook if you want to leverage provider context. * * @param content - The markdown string to render * @param props - Configuration options for rendering * @param props.components - Component overrides for HTML tags * @param props.wrapper - Wrapper component for multiple children * @returns JSX element representing the rendered markdown * * @example * ```tsx * import { renderMarkdown } from '@intlayer/react-intlayer/markdown'; * * const markdown = '# Hello World\n\nThis is **bold** text.'; * const jsx = renderMarkdown(markdown, { * components: { * h1: ({ children }) => <h1 className="title">{children}</h1>, * }, * forceBlock: true, * }); * ``` */ const renderMarkdown = (content, { components, wrapper, forceBlock, forceInline, preserveFrontmatter, tagfilter } = {}) => { return compileMarkdown(content, { components, forceBlock, forceInline, wrapper, forceWrapper: !!wrapper, preserveFrontmatter, tagfilter }); }; /** * Hook that returns a function to render markdown content. * * This hook considers the configuration from the `MarkdownProvider` context if available, * falling back to the provided props or default behavior. * * @param props - Optional configuration that will override context values * @param props.components - Component overrides for HTML tags (overrides context) * @param props.wrapper - Wrapper component (overrides context) * @returns A function that takes markdown content and returns JSX * * @example * ```tsx * import { useMarkdownRenderer } from '@intlayer/react-intlayer/markdown'; * * function MyComponent() { * const renderMarkdown = useMarkdownRenderer({ * components: { * h1: ({ children }) => <h1 className="custom">{children}</h1>, * }, * }); * * return ( * <div> * {renderMarkdown('# Hello\n\nThis is **markdown**')} * </div> * ); * } * ``` * * @example * ```tsx * // With MarkdownProvider context * function App() { * return ( * <MarkdownProvider * components={{ h1: CustomHeading }} * forceBlock={true} * > * <MyComponent /> * </MarkdownProvider> * ); * } * ``` */ const useMarkdownRenderer = ({ components, wrapper, forceBlock, forceInline, preserveFrontmatter, tagfilter } = {}) => { const context = useMarkdownContext(); return (content) => { if (context) return context.renderMarkdown(content, { forceBlock, forceInline, preserveFrontmatter, tagfilter }, components, wrapper); return renderMarkdown(content, { components, wrapper, forceBlock, forceInline, preserveFrontmatter, tagfilter }); }; }; /** * React component that renders markdown content to JSX. * * This component uses the `renderMarkdown` function from the `MarkdownProvider` context * if available. Otherwise, it falls back to the default compiler with provided components * and options. You can also provide a custom `renderMarkdown` function prop to override * all rendering behavior. * * @example * ```tsx * import { MarkdownRenderer } from '@intlayer/react-intlayer/markdown'; * * function MyComponent() { * return ( * <MarkdownRenderer> * {`# Hello World * * This is a paragraph with **bold** and *italic* text. * * - List item 1 * - List item 2`} * </MarkdownRenderer> * ); * } * ``` * * @example * ```tsx * // With custom components * <MarkdownRenderer * components={{ * h1: ({ children }) => <h1 className="text-4xl font-bold">{children}</h1>, * a: ({ href, children }) => ( * <a href={href} className="text-blue-500 hover:underline"> * {children} * </a> * ), * }} * forceBlock={true} * > * {markdownContent} * </MarkdownRenderer> * ``` * * @example * ```tsx * // With MarkdownProvider context * function App() { * return ( * <MarkdownProvider * components={{ h1: CustomHeading }} * forceBlock={true} * > * <MarkdownRenderer> * {markdownContent} * </MarkdownRenderer> * </MarkdownProvider> * ); * } * ``` */ const MarkdownRenderer = ({ children = "", components, wrapper, forceBlock, forceInline, preserveFrontmatter, tagfilter, renderMarkdown }) => { const context = useMarkdownContext(); if (renderMarkdown) return /* @__PURE__ */ jsx(Fragment, { children: renderMarkdown(children, { components, wrapper, forceBlock, forceInline, preserveFrontmatter, tagfilter }) }); if (context) return /* @__PURE__ */ jsx(Fragment, { children: context.renderMarkdown(children, { forceBlock, forceInline, preserveFrontmatter, tagfilter }, components, wrapper) }); return /* @__PURE__ */ jsx(Fragment, { children: compileMarkdown(children, { components, forceBlock, forceInline, wrapper, forceWrapper: !!wrapper, preserveFrontmatter, tagfilter }) }); }; //#endregion export { MarkdownRenderer, renderMarkdown, useMarkdownRenderer }; //# sourceMappingURL=MarkdownRenderer.mjs.map