UNPKG

react-code-block

Version:

Set of unstyled UI components to build powerful code blocks in React.

81 lines 3.9 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { Highlight } from 'prism-react-renderer'; import React, { useMemo } from 'react'; import { LineContext, RootContext, useLineContext, useRootContext, } from './contexts.js'; import { forwardRef, parseWordHighlights, shouldHighlightLine, shouldHighlightToken, splitStringByWords, } from './shared/utils.js'; /** * Top-level root component which contains all the sub-components to construct a code block. * * API Reference: {@link https://react-code-block.netlify.app/api-reference#codeblock} */ const CodeBlock = ({ code, words = [], lines = [], children, ...props }) => { const parsedWords = useMemo(() => parseWordHighlights(words), [words]); return (_jsx(RootContext.Provider, { value: { code: code.trim(), words: parsedWords, lines, ...props }, children: children })); }; const Code = ({ as, children, ...props }, ref) => { const { lines, words, ...highlightProps } = useRootContext(); const Tag = as ?? 'pre'; return (_jsx(Highlight, { ...highlightProps, children: (highlight) => (_jsx(Tag, { ...props, ref: ref, children: highlight.tokens.map((line, i) => { const lineNumber = i + 1; const isLineHighlighted = shouldHighlightLine(lineNumber, lines); return (_jsx(LineContext.Provider, { value: { highlight, line, lineNumber }, children: typeof children === 'function' ? children({ isLineHighlighted, lineNumber }, i) : children }, i)); }) })) })); }; const LineContent = ({ as, children, className, ...rest }, ref) => { const { highlight, line } = useLineContext(); const { getLineProps } = highlight; const Tag = as ?? 'div'; return (_jsx(Tag, { ...getLineProps({ line, className }), ...rest, ref: ref, children: children })); }; const Token = ({ as, children = ({ children }) => _jsx("span", { children: children }), className, ...rest }, ref) => { const { words } = useRootContext(); const { line, highlight, lineNumber } = useLineContext(); const { getTokenProps } = highlight; const Tag = as ?? 'span'; return (_jsx(React.Fragment, { children: line.map((token, key) => { const { children: contentWithSpaces, ...props } = getTokenProps({ token, className, }); const content = words.length ? splitStringByWords(contentWithSpaces, words) : [contentWithSpaces]; return (_jsx(React.Fragment, { children: content.map((content, i) => (_jsx(Tag, { ...props, ...rest, ref: ref, children: children({ children: content, isTokenHighlighted: shouldHighlightToken(content, lineNumber, words), }) }, i))) }, key)); }) })); }; const LineNumber = ({ as, ...props }, ref) => { const { lineNumber } = useLineContext(); const Tag = as ?? 'span'; return (_jsx(Tag, { ...props, ref: ref, children: lineNumber })); }; /** * Container which contains code to render each line of the code. * * API Reference: {@link https://react-code-block.netlify.app/api-reference#codeblockcode} */ CodeBlock.Code = forwardRef(Code); /** * Container for a single line of the code. * * API Reference: {@link https://react-code-block.netlify.app/api-reference#codeblocklinecontent} */ CodeBlock.LineContent = forwardRef(LineContent); /** * Renders a syntax-highlighted token from the current line. * * API Reference: {@link https://react-code-block.netlify.app/api-reference#codeblocktoken} */ CodeBlock.Token = forwardRef(Token); /** * Renders the line number for the current line. * * API Reference: {@link https://react-code-block.netlify.app/api-reference#codeblocklinenumber} */ CodeBlock.LineNumber = forwardRef(LineNumber); export { CodeBlock }; //# sourceMappingURL=code-block.js.map