import { css, cx } from "@emotion/css"; import type { Node, Paragraph } from "@yozora/ast"; import { ImageReferenceType, ImageType } from "@yozora/ast"; import React from "react"; import { astClasses } from "../context"; import { NodesRenderer } from "../NodesRenderer"; /** * Render `paragraph`. * * @see https://www.npmjs.com/package/@yozora/ast#paragraph * @see https://www.npmjs.com/package/@yozora/tokenizer-paragraph */ export class ParagraphRenderer extends React.Component { public override shouldComponentUpdate(nextProps: Readonly): boolean { const props = this.props; return props.children !== nextProps.children; } public override render(): React.ReactElement { const childNodes: Node[] = this.props.children; // If there are some image / imageReferences element in the paragraph, // then wrapper the content with div to avoid the warnings such as: // // validateDOMNesting(...):
cannot appear as a descendant of

. const notValidParagraph: boolean = childNodes.some( child => child.type === ImageType || child.type === ImageReferenceType, ); if (notValidParagraph) { return (

); } return (

); } } const paragraphCls: string = cx( astClasses.paragraph, css({ overflow: "hidden", padding: 0, margin: "0px 0px 1.25em 0px", marginBottom: "1em", lineHeight: "1.8", hyphens: "auto", wordBreak: "normal", overflowWrap: "anywhere", "> :last-child": { marginBottom: 0, }, }), ); const paragraphDisplayCls: string = cx( paragraphCls, css({ display: "flex", alignItems: "center", justifyContent: "center", padding: "1rem 0", margin: 0, }), );