2025-05-28 15:36:51 -07:00

213 lines
5.3 KiB
TypeScript

import * as React from "react";
import { Tooltip } from "@dndbeyond/character-common-components/es";
import {
Note,
FormatUtils,
Constants,
NoteUtils,
CharacterTheme,
} from "@dndbeyond/character-rules-engine/es";
import { NumberDisplay } from "~/components/NumberDisplay";
import Damage from "../Damage";
import { AoeTypeIcon, DisadvantageIcon } from "../Icons";
import { AoeTypePropType } from "../Icons/IconConstants";
interface Props {
notes: Array<Note>;
className: string;
theme: CharacterTheme;
}
export default class NoteComponents extends React.PureComponent<Props> {
static defaultProps = {
className: "",
};
renderPlainText = (note: Note): React.ReactNode => {
const { theme } = this.props;
let classNames: Array<string> = [
"ddbc-note-components__component",
"ddbc-note-components__component--plain",
];
if (note.data.displayIntention) {
classNames.push(
`ddbc-note-components__component--${note.data.displayIntention}`
);
}
if (theme.isDarkMode) {
classNames.push("ddbc-note-components__component--dark-mode");
}
return <span className={classNames.join(" ")}>{note.data.text}</span>;
};
renderTooltip = (note: Note): React.ReactNode => {
const { theme } = this.props;
let classNames: Array<string> = [
"ddbc-note-components__component",
"ddbc-note-components__component--tooltip",
];
if (note.data.displayIntention) {
classNames.push(
`ddbc-note-components__component--${note.data.displayIntention}`
);
}
if (theme.isDarkMode) {
classNames.push("ddbc-note-components__component--dark-mode");
}
return (
<Tooltip
className={classNames.join(" ")}
title={note.data.tooltip}
tippyOpts={note.data.tooltipOpts}
isDarkMode={theme.isDarkMode}
>
{note.data.text}
</Tooltip>
);
};
renderDistance = (note: Note): React.ReactNode => {
const { theme } = this.props;
let classNames: Array<string> = [
"ddbc-note-components__component",
"ddbc-note-components__component--distance",
];
return (
<span className={classNames.join(" ")}>
<NumberDisplay type="distanceInFt" number={note.data.distance} />
</span>
);
};
renderAoeIcon = (note: Note): React.ReactNode => {
const { theme } = this.props;
let classNames: Array<string> = [
"ddbc-note-components__component",
"ddbc-note-components__component--aoe-icon",
];
return (
<span className={classNames.join(" ")}>
<AoeTypeIcon
type={FormatUtils.slugify(note.data.type) as AoeTypePropType}
themeMode={theme?.isDarkMode ? "gray" : "dark"}
/>
</span>
);
//`
};
renderDamage = (note: Note): React.ReactNode => {
const { theme } = this.props;
let classNames: Array<string> = [
"ddbc-note-components__component",
"ddbc-note-components__component--damage",
];
return (
<span className={classNames.join(" ")}>
<Damage
theme={theme}
type={note.data.type}
damage={note.data.damage}
info={note.data.info}
/>
</span>
);
};
renderDisadvantageIcon = (note: Note): React.ReactNode => {
const { theme } = this.props;
let classNames: Array<string> = [
"ddbc-note-components__component",
"ddbc-note-components__component--disadvantage-icon",
];
return (
<span className={classNames.join(" ")}>
<DisadvantageIcon theme={theme} />
</span>
);
};
renderGroup = (
notes: Array<Note> | null,
separator: string = " ",
key: string | number | null = null
): React.ReactNode => {
if (notes === null) {
return null;
}
return (
<React.Fragment key={key ? key : "start-note-group-key"}>
{notes.map((note, idx): React.ReactNode => {
if (note === null) {
return null;
}
return (
<React.Fragment key={`${NoteUtils.getType(note)}-${idx}`}>
{this.renderNote(note)}
{idx + 1 < notes.length ? separator : ""}
</React.Fragment>
);
})}
</React.Fragment>
);
};
renderNote = (note: Note | null): React.ReactNode => {
if (note === null) {
return null;
}
switch (NoteUtils.getType(note)) {
case Constants.NoteTypeEnum.PLAIN_TEXT:
return this.renderPlainText(note);
case Constants.NoteTypeEnum.TOOLTIP:
return this.renderTooltip(note);
case Constants.NoteTypeEnum.DISTANCE:
return this.renderDistance(note);
case Constants.NoteTypeEnum.AOE_ICON:
return this.renderAoeIcon(note);
case Constants.NoteTypeEnum.DAMAGE:
return this.renderDamage(note);
case Constants.NoteTypeEnum.DISADVANTAGE_ICON:
return this.renderDisadvantageIcon(note);
case Constants.NoteTypeEnum.GROUP:
return this.renderGroup(
note.data.notes,
note.data.separator,
note.data.key
);
default:
// not implement
}
return null;
};
render() {
const { notes, className } = this.props;
let classNames: Array<string> = [className, "ddbc-note-components"];
return (
<div className={classNames.join(" ")}>
{this.renderGroup(notes, ", ")}
</div>
);
}
}