import * as React from "react"; import JsxParser from "react-jsx-parser"; import { Tooltip } from "@dndbeyond/character-common-components/es"; import { CharacterTheme, Constants, EntityLimitedUseContract, LevelScaleContract, SnippetContextData, SnippetData, SnippetUtils, } from "@dndbeyond/character-rules-engine/es"; import { HtmlContent } from "~/components/HtmlContent"; interface Props { snippetData: SnippetData; levelScale?: LevelScaleContract | null; classLevel?: number | null; limitedUse?: EntityLimitedUseContract | null; className: string; parseSnippet: boolean; theme?: CharacterTheme; proficiencyBonus: number; } export default class Snippet extends React.PureComponent { static defaultProps = { className: "", parseSnippet: true, }; convertSnippetToHtml = (snippetString: string): string => { const { levelScale, classLevel, limitedUse, snippetData, proficiencyBonus, theme, } = this.props; let contextData: SnippetContextData = {}; if (levelScale) { contextData.levelScale = levelScale; } if (classLevel) { contextData.classLevel = classLevel; } if (limitedUse) { contextData.limitedUse = limitedUse; } const snippetChunks = SnippetUtils.generateSnippetChunks( snippetString, contextData, snippetData, proficiencyBonus ); const htmlChunkString: string = snippetChunks .map((contentChunk) => { switch (contentChunk.type) { case Constants.SnippetContentChunkTypeEnum.TAG: switch (contentChunk.data.type) { case Constants.SnippetTagDataTypeEnum.ERROR: let messageParts: Array = []; if (contentChunk.data.raw.trim()) { messageParts.push(contentChunk.data.raw); } messageParts.push(contentChunk.data.value); return `${messageParts.join(" - ")}`; case Constants.SnippetTagDataTypeEnum.NUMBER: return `${contentChunk.data.value.toLocaleString()}`; case Constants.SnippetTagDataTypeEnum.STRING: default: return `${contentChunk.data.value}`; } case Constants.SnippetContentChunkTypeEnum.TEXT: default: return contentChunk.data; } }) .join(""); const finalHtmlString: string = htmlChunkString .replace(/[{}]/g, "") .replace(/\s*\n+?\s*\n*/g, "

"); return `

${finalHtmlString}

`; }; render() { const { children, className, parseSnippet, theme } = this.props; if (!children) { return null; } let classNames: Array = ["ddbc-snippet", className]; if (parseSnippet) { classNames.push("ddbc-snippet--parsed"); } else { classNames.push("ddbc-snippet--unparsed"); } if (theme?.isDarkMode) { classNames.push("ddbc-snippet--dark-mode"); } let contentNode: React.ReactNode; if (typeof children === "string") { if (parseSnippet) { contentNode = ( ); } else { contentNode = ( ); } } return
{contentNode}
; } }