import { visuallyHidden } from "@mui/utils"; import clsx from "clsx"; import React, { useContext } from "react"; import { connect, DispatchProp } from "react-redux"; import { AlignmentContract, Background, CharacterTraits, Constants, SizeContract, rulesEngineSelectors, CharacterTheme, CharacterFeaturesManager, SnippetData, RuleData, AbilityLookup, DataOriginRefData, FeatManager, Action, ActionUtils, Spell, SpellUtils, } from "@dndbeyond/character-rules-engine/es"; import { InfoItem } from "~/components/InfoItem"; import { NumberDisplay } from "~/components/NumberDisplay"; import { TabFilter } from "~/components/TabFilter"; import { useSidebar } from "~/contexts/Sidebar"; import { PaneInfo } from "~/contexts/Sidebar/Sidebar"; import { PaneComponentEnum } from "~/subApps/sheet/components/Sidebar/types"; import { CharacterFeaturesManagerContext } from "~/tools/js/Shared/managers/CharacterFeaturesManagerContext"; import { handleActionUseSet, handleSpellUseSet, } from "../../../../../handlers/commonHandlers"; import { appEnvSelectors } from "../../../Shared/selectors"; import { PaneIdentifierUtils } from "../../../Shared/utils"; import BackgroundDetail from "../../components/BackgroundDetail"; import ContentGroup from "../../components/ContentGroup"; import TraitContent from "../../components/TraitContent"; import { SheetAppState } from "../../typings"; import styles from "./styles.module.css"; const DEFAULT_VALUE = "--"; interface Props extends DispatchProp { isVertical: boolean; background: Background | null; alignment: AlignmentContract | null; height: string | null; weight: number | null; size: SizeContract | null; faith: string | null; skin: string | null; eyes: string | null; hair: string | null; age: number | null; gender: string | null; traits: CharacterTraits; isReadonly: boolean; theme: CharacterTheme; characterFeaturesManager: CharacterFeaturesManager; snippetData: SnippetData; ruleData: RuleData; abilityLookup: AbilityLookup; dataOriginRefData: DataOriginRefData; proficiencyBonus: number; paneContext: PaneInfo; } class Description extends React.PureComponent { static defaultProps = { isVertical: false, }; handlePhysicalCharacteristicsClick = (): void => { const { paneContext: { paneHistoryStart }, isReadonly, } = this.props; if (!isReadonly) { paneHistoryStart(PaneComponentEnum.DESCRIPTION); } }; handleBackgroundClick = (): void => { const { paneContext: { paneHistoryStart }, } = this.props; paneHistoryStart(PaneComponentEnum.BACKGROUND); }; handleFeatClick = (feat: FeatManager): void => { const { paneContext: { paneHistoryStart }, } = this.props; paneHistoryStart( PaneComponentEnum.FEAT_DETAIL, PaneIdentifierUtils.generateFeat(feat.getId()) ); }; handleTraitShow = (key: Constants.TraitTypeEnum): void => { const { paneContext: { paneHistoryStart }, isReadonly, } = this.props; if (!isReadonly) { paneHistoryStart( PaneComponentEnum.TRAIT, PaneIdentifierUtils.generateTrait(key) ); } }; handleActionClick = (action: Action): void => { const { paneContext: { paneHistoryStart }, } = this.props; const mappingId = ActionUtils.getMappingId(action); const mappingEntityTypeId = ActionUtils.getMappingEntityTypeId(action); if (mappingId !== null && mappingEntityTypeId !== null) { paneHistoryStart( PaneComponentEnum.ACTION, PaneIdentifierUtils.generateAction(mappingId, mappingEntityTypeId) ); } }; handleSpellDetailClick = (spell: Spell): void => { const { paneContext: { paneHistoryStart }, } = this.props; const mappingId = SpellUtils.getMappingId(spell); if (mappingId !== null) { paneHistoryStart( PaneComponentEnum.CHARACTER_SPELL_DETAIL, PaneIdentifierUtils.generateCharacterSpell(mappingId) ); } }; handleClick = (e: React.MouseEvent, onClick: Function): void => { e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); onClick(); }; renderDescriptionItem = ( value: number | string | null, fallback: string = DEFAULT_VALUE ): React.ReactNode => { return value === null ? fallback : value; }; render() { const { dispatch, background, characterFeaturesManager, snippetData, ruleData, abilityLookup, dataOriginRefData, isReadonly, proficiencyBonus, theme, isVertical, size, height, weight, alignment, gender, eyes, hair, skin, age, faith, traits, } = this.props; const infoItemProps = { role: "listitem", inline: isVertical, }; return (

Description

handleActionUseSet(action, uses, dispatch) } onSpellUseSet={(spell, uses) => handleSpellUseSet(spell, uses, dispatch) } snippetData={snippetData} ruleData={ruleData} abilityLookup={abilityLookup} dataOriginRefData={dataOriginRefData} isReadonly={isReadonly} proficiencyBonus={proficiencyBonus} theme={theme} /> ), }, { label: "Characteristics", content: ( <>
this.handleClick( e, this.handlePhysicalCharacteristicsClick ) } > {alignment === null ? DEFAULT_VALUE : alignment.name} {this.renderDescriptionItem(gender)} {this.renderDescriptionItem(eyes)} {this.renderDescriptionItem(size ? size.name : null)} {this.renderDescriptionItem(height)} {this.renderDescriptionItem(faith)} {this.renderDescriptionItem(hair)} {this.renderDescriptionItem(skin)} {this.renderDescriptionItem(age)} {weight === null ? ( DEFAULT_VALUE ) : ( )}
), }, ...(traits !== null ? [ { label: "Appearance", content: ( ), }, ] : []), ]} />
); } } function mapStateToProps(state: SheetAppState) { return { background: rulesEngineSelectors.getBackgroundInfo(state), alignment: rulesEngineSelectors.getAlignment(state), height: rulesEngineSelectors.getHeight(state), weight: rulesEngineSelectors.getWeight(state), size: rulesEngineSelectors.getSize(state), faith: rulesEngineSelectors.getFaith(state), skin: rulesEngineSelectors.getSkin(state), eyes: rulesEngineSelectors.getEyes(state), hair: rulesEngineSelectors.getHair(state), age: rulesEngineSelectors.getAge(state), gender: rulesEngineSelectors.getGender(state), traits: rulesEngineSelectors.getCharacterTraits(state), isReadonly: appEnvSelectors.getIsReadonly(state), snippetData: rulesEngineSelectors.getSnippetData(state), ruleData: rulesEngineSelectors.getRuleData(state), abilityLookup: rulesEngineSelectors.getAbilityLookup(state), dataOriginRefData: rulesEngineSelectors.getDataOriginRefData(state), proficiencyBonus: rulesEngineSelectors.getProficiencyBonus(state), }; } const DescriptionWrapper = (props) => { const { characterFeaturesManager } = useContext( CharacterFeaturesManagerContext ); const { pane } = useSidebar(); return ( ); }; export default connect(mapStateToProps)(DescriptionWrapper);