Files
dndbeyond_src/ddb_main/tools/js/CharacterSheet/components/Senses/Senses.tsx
T

232 lines
6.5 KiB
TypeScript

import clsx from "clsx";
import React from "react";
import {
BoxBackground,
ThemedSenseRowBoxSvg,
ThemedSenseRowSmallBoxSvg,
ThemedSenseRowMinimalSvg,
} from "@dndbeyond/character-components/es";
import {
CharacterTheme,
Constants,
FormatUtils,
RuleDataUtils,
SenseInfo,
} from "@dndbeyond/character-rules-engine/es";
import { TypeScriptUtils } from "../../../Shared/utils";
import styles from "./styles.module.css";
interface Props {
passivePerception: number;
passiveInvestigation: number;
passiveInsight: number;
senses: SenseInfo;
rowStyle: "small" | "normal" | "minimal";
onClick?: () => void;
theme: CharacterTheme;
}
export default class Senses extends React.PureComponent<Props> {
static defaultProps = {
rowStyle: "normal",
};
handleClick = (evt: React.MouseEvent): void => {
const { onClick } = this.props;
if (onClick) {
evt.stopPropagation();
evt.nativeEvent.stopImmediatePropagation();
onClick();
}
};
getSenseSummary = (senseKey: Constants.SenseTypeEnum): string | null => {
const { senses } = this.props;
let senseValue = senses[senseKey];
if (!senseValue) {
return null;
}
return `${RuleDataUtils.getSenseTypeLabel(
senseKey
)} ${FormatUtils.renderDistance(senseValue)}`;
};
renderSummaryInfo = (): React.ReactNode => {
let senseKeys: Array<Constants.SenseTypeEnum> = [
Constants.SenseTypeEnum.BLINDSIGHT,
Constants.SenseTypeEnum.DARKVISION,
Constants.SenseTypeEnum.TREMORSENSE,
Constants.SenseTypeEnum.TRUESIGHT,
];
let senseSummaries: Array<string> = senseKeys
.map((senseKey) => this.getSenseSummary(senseKey))
.filter(TypeScriptUtils.isNotNullOrUndefined);
return (
<div
className={clsx([
styles.summary,
!senseSummaries.length && styles.summaryEmpty,
])}
>
{!senseSummaries.length
? "Additional Sense Types"
: senseSummaries.join(", ")}
</div>
);
};
render() {
const {
passiveInsight,
passiveInvestigation,
passivePerception,
rowStyle,
theme,
} = this.props;
let isMinimal = false;
let StyleComponent: React.ComponentType<any> = ThemedSenseRowBoxSvg;
if (rowStyle === "small") {
StyleComponent = ThemedSenseRowSmallBoxSvg;
} else if (rowStyle === "minimal") {
StyleComponent = ThemedSenseRowMinimalSvg;
isMinimal = true;
}
return (
<div className={styles.senses} onClick={this.handleClick}>
{isMinimal ? (
<div className={styles.minimalRow}>
<div className={styles.minimalItem}>
<div className={styles.minimalCallout}>
<BoxBackground
StyleComponent={StyleComponent}
theme={{
...theme,
themeColor: `${theme?.themeColor}80`,
}}
/>
<div className={styles.calloutValue}>{passivePerception}</div>
</div>
<div
className={clsx([
styles.calloutLabel,
styles.minimalCalloutLabel,
])}
>
Perception
</div>
</div>
<div className={styles.minimalItem}>
<div className={styles.minimalCallout}>
<BoxBackground
StyleComponent={StyleComponent}
theme={{
...theme,
themeColor: `${theme?.themeColor}80`,
}}
/>
<div className={styles.calloutValue}>
{passiveInvestigation}
</div>
</div>
<div
className={clsx([
styles.calloutLabel,
styles.minimalCalloutLabel,
])}
>
Investigation
</div>
</div>
<div className={styles.minimalItem}>
<div className={styles.minimalCallout}>
<BoxBackground
StyleComponent={StyleComponent}
theme={{
...theme,
themeColor: `${theme?.themeColor}80`,
}}
/>
<div className={styles.calloutValue}>{passiveInsight}</div>
</div>
<div
className={clsx([
styles.calloutLabel,
styles.minimalCalloutLabel,
])}
>
Insight
</div>
</div>
</div>
) : (
<div>
<div className={styles.callout}>
<BoxBackground
StyleComponent={StyleComponent}
theme={{
...theme,
themeColor: `${theme?.themeColor}80`,
}}
/>
<div className={styles.calloutValue}>{passivePerception}</div>
<div
className={clsx([
styles.calloutLabel,
styles.regularCalloutLabel,
])}
>
Passive Perception
</div>
</div>
<div className={styles.callout}>
<BoxBackground
StyleComponent={StyleComponent}
theme={{
...theme,
themeColor: `${theme?.themeColor}80`,
}}
/>
<div className={styles.calloutValue}>{passiveInvestigation}</div>
<div
className={clsx([
styles.calloutLabel,
styles.regularCalloutLabel,
])}
>
Passive Investigation
</div>
</div>
<div className={styles.callout}>
<BoxBackground
StyleComponent={StyleComponent}
theme={{
...theme,
themeColor: `${theme?.themeColor}80`,
}}
/>
<div className={styles.calloutValue}>{passiveInsight}</div>
<div
className={clsx([
styles.calloutLabel,
styles.regularCalloutLabel,
])}
>
Passive Insight
</div>
</div>
</div>
)}
{this.renderSummaryInfo()}
</div>
);
}
}