import { Tooltip } from "@dndbeyond/character-common-components/es"; import { AbilityManager, CharacterTheme, FormatUtils, SituationalSavingThrowInfo, SituationalSavingThrowInfoLookup, } from "@dndbeyond/character-rules-engine/es"; import { RollTypes } from "@dndbeyond/pocket-dimension-dice/constants"; import { RollContext } from "@dndbeyond/pocket-dimension-dice/types"; import { NumberDisplay } from "~/components/NumberDisplay"; import a11yStyles from "~/styles/accessibility.module.css"; import BoxBackground from "../BoxBackground"; import { DigitalDiceWrapper } from "../Dice"; import { ProficiencyLevelIcon } from "../Icons"; import { ThemedSavingThrowSelectionBoxSvg, ThemedSavingThrowSelectionSmallBoxSvg, ThemedSavingThrowRowBoxSvg, ThemedSavingThrowRowSmallBoxSvg, NegativeBonusNegativeSvg, PositiveBonusPositiveSvg, DarkModePositiveBonusPositiveSvg, DarkModeNegativeBonusNegativeSvg, } from "../Svg"; interface Props { abilities: Array; situationalBonusSavingThrowsLookup: SituationalSavingThrowInfoLookup; onClick?: (ability: AbilityManager) => void; rowStyle?: "small" | "normal"; className?: string; diceEnabled?: boolean; theme: CharacterTheme; rollContext: RollContext; } export default function SavingThrowsSummary({ abilities, situationalBonusSavingThrowsLookup, onClick = (ability: AbilityManager) => {}, theme, rollContext, className = "", diceEnabled = false, rowStyle = "normal", }: Props) { const handleClick = ( ability: AbilityManager, evt: React.MouseEvent ): void => { if (onClick) { evt.stopPropagation(); evt.nativeEvent.stopImmediatePropagation(); onClick(ability); } }; return (
{abilities.map((ability) => { let situationalBonusSavingThrows: Array = []; let maxOptBonus: number = 0; if (situationalBonusSavingThrowsLookup) { situationalBonusSavingThrows = situationalBonusSavingThrowsLookup[ability.getId()]; if ( situationalBonusSavingThrows && situationalBonusSavingThrows.length ) { let situationalBonusSavingThrowsValues: Array = situationalBonusSavingThrows.map((optBonus) => optBonus.value); maxOptBonus = Math.max(...situationalBonusSavingThrowsValues); } } let situationalBonusClasses: Array = [ "ddbc-saving-throws-summary__ability-situational", ]; let IconComponent: React.ComponentType | null = null; if (maxOptBonus < 0) { situationalBonusClasses.push( "ddbc-saving-throws-summary__ability-situational--bonus-neg" ); IconComponent = theme?.isDarkMode ? DarkModeNegativeBonusNegativeSvg : NegativeBonusNegativeSvg; } else { situationalBonusClasses.push( "ddbc-saving-throws-summary__ability-situational--bonus-pos" ); IconComponent = theme?.isDarkMode ? DarkModePositiveBonusPositiveSvg : PositiveBonusPositiveSvg; } let StyleComponent: React.ComponentType = ThemedSavingThrowRowBoxSvg; let SelectionBox = ThemedSavingThrowSelectionBoxSvg; if (rowStyle === "small") { StyleComponent = ThemedSavingThrowRowSmallBoxSvg; SelectionBox = ThemedSavingThrowSelectionSmallBoxSvg; } const modifier = ability.getSave(); return (
handleClick(ability, event)} >

{ability.getLabel()} Saving Throw

{ability.getName()}
0 ? `+${modifier}` : modifier !== 0 ? modifier : "" }`} rollType={RollTypes.Save} action={ability.getName()} isDiceEnabled={diceEnabled} entityId={String(rollContext.entityId)} entityType={String(rollContext.entityType)} name={String(rollContext.name)} >
{situationalBonusSavingThrows && situationalBonusSavingThrows.length > 0 && ( )}
); })}
); }