Concept jsx usage

This commit is contained in:
Endeavorance 2025-03-17 20:48:37 -04:00
parent bf444ccb1a
commit d769e298b1
7 changed files with 92 additions and 20 deletions

View file

@ -0,0 +1,40 @@
import classNames from "classnames";
import React from "react";
interface SectionProps {
type: string;
title: string;
content: string;
preInfo?: React.ReactNode;
info?: React.ReactNode;
componentId?: string;
leftCornerTag?: React.ReactNode;
rightCornerTag?: React.ReactNode;
}
export function Section({
type,
title,
content,
preInfo,
info,
componentId,
leftCornerTag,
rightCornerTag,
}: SectionProps) {
const sectionClasses = classNames("section", type);
const headerClasses = classNames("section-header", `${type}-header`);
const contentClasses = classNames("section-content", `${type}-content`);
return <section className={sectionClasses} data-component-id={componentId}>
<div className={headerClasses}>
{preInfo}
<h2>{title}</h2>
{info}
</div>
<div className="section-tag section-tag--left">{leftCornerTag}</div>
<div className="section-tag section-tag--right">{rightCornerTag}</div>
<div className={contentClasses} dangerouslySetInnerHTML={{ __html: content }} />
</section>
}

View file

@ -1,14 +0,0 @@
import type { Rule } from "@proscenium/playbill";
import { renderMarkdown } from "#lib";
import { Section } from "./base/section";
export async function RuleSection(rule: Rule): Promise<string> {
const renderedMarkdown = await renderMarkdown(rule.description);
return Section({
title: rule.name,
componentId: rule.id,
content: renderedMarkdown,
type: "rule",
});
}

View file

@ -0,0 +1,11 @@
import type { Rule } from "@proscenium/playbill";
import { Section } from "./base/react-section";
export function RuleSection(rule: Rule) {
return <Section
title={rule.name}
componentId={rule.id}
content={rule.description}
type="rule"
/>;
}

View file

@ -1,6 +1,6 @@
import type { Playbill } from "@proscenium/playbill";
import { Playbill } from "@proscenium/playbill";
import sortBy from "lodash-es/sortBy";
import { html } from "#lib";
import { html, renderMarkdown } from "#lib";
import { GlossaryTable } from "./component/glossary";
import { PageHeader } from "./component/header";
import { ItemCard } from "./component/item";
@ -8,15 +8,21 @@ import { MethodSection } from "./component/method";
import { ResourceSection } from "./component/resource";
import { RuleSection } from "./component/rule";
import { SpeciesSection } from "./component/species";
import { renderToString } from "react-dom/server";
interface HTMLRenderOptions {
styles?: string;
}
export async function renderPlaybillToHTML(
playbill: Playbill,
playbillToRender: Playbill,
opts: HTMLRenderOptions = {},
): Promise<string> {
// Make a copy of the playbill to avoid modifying the original
// and compile all description markdown
const playbill = Playbill.fromSerialized(playbillToRender.serialize());
await playbill.processComponents(renderMarkdown);
// Render various resources
const resources = (
await Promise.all(Object.values(playbill.resources).map(ResourceSection))
@ -47,7 +53,7 @@ export async function renderPlaybillToHTML(
).join("\n");
const rulesByOrder = sortBy(Object.values(playbill.rules), "order");
const rules = (await Promise.all(rulesByOrder.map(RuleSection))).join("\n");
const rules = rulesByOrder.map(RuleSection);
const glossaryHTML = await GlossaryTable(playbill.glossary);
// Prepare stylesheet
@ -144,7 +150,7 @@ export async function renderPlaybillToHTML(
</article>
<article id="rules" class="view">
${rules}
${renderToString(rules)}
</article>
<article id="glossary" class="view">