forked from profectus/Profectus
Make modifier section take options func and display bad numbers in red
This commit is contained in:
parent
dcb3bc949d
commit
909c7a5f5e
2 changed files with 111 additions and 31 deletions
|
@ -256,9 +256,11 @@ export interface Section {
|
||||||
* Takes an array of modifier "sections", and creates a JSXFunction that can render all those sections, and allow each section to be collapsed.
|
* Takes an array of modifier "sections", and creates a JSXFunction that can render all those sections, and allow each section to be collapsed.
|
||||||
* Also returns a list of persistent refs that are used to control which sections are currently collapsed.
|
* Also returns a list of persistent refs that are used to control which sections are currently collapsed.
|
||||||
* @param sectionsFunc A function that returns the sections to display.
|
* @param sectionsFunc A function that returns the sections to display.
|
||||||
|
* @param smallerIsBetter Determines whether numbers larger or smaller than the base should be displayed as red.
|
||||||
*/
|
*/
|
||||||
export function createCollapsibleModifierSections(
|
export function createCollapsibleModifierSections(
|
||||||
sectionsFunc: () => Section[]
|
sectionsFunc: () => Section[],
|
||||||
|
smallerIsBetter = false
|
||||||
): [JSXFunction, Persistent<Record<number, boolean>>] {
|
): [JSXFunction, Persistent<Record<number, boolean>>] {
|
||||||
const sections: Section[] = [];
|
const sections: Section[] = [];
|
||||||
const processed:
|
const processed:
|
||||||
|
@ -326,6 +328,9 @@ export function createCollapsibleModifierSections(
|
||||||
const hasPreviousSection = !firstVisibleSection;
|
const hasPreviousSection = !firstVisibleSection;
|
||||||
firstVisibleSection = false;
|
firstVisibleSection = false;
|
||||||
|
|
||||||
|
const base = unref(processed.base[i]) ?? 1;
|
||||||
|
const total = s.modifier.apply(base);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{hasPreviousSection ? <br /> : null}
|
{hasPreviousSection ? <br /> : null}
|
||||||
|
@ -335,11 +340,20 @@ export function createCollapsibleModifierSections(
|
||||||
{modifiers}
|
{modifiers}
|
||||||
<hr />
|
<hr />
|
||||||
<div class="modifier-container">
|
<div class="modifier-container">
|
||||||
<span class="modifier-description">
|
<span class="modifier-description">Total</span>
|
||||||
Total
|
<span
|
||||||
</span>
|
class="modifier-amount"
|
||||||
<span class="modifier-amount">
|
style={
|
||||||
{format(s.modifier.apply(unref(processed.base[i]) ?? 1))}
|
(
|
||||||
|
smallerIsBetter === true
|
||||||
|
? Decimal.gt(total, base ?? 1)
|
||||||
|
: Decimal.lt(total, base ?? 1)
|
||||||
|
)
|
||||||
|
? "color: var(--danger)"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{formatSmall(total)}
|
||||||
{s.unit}
|
{s.unit}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -52,6 +52,8 @@ export interface AdditiveModifierOptions {
|
||||||
description?: Computable<CoercableComponent> | undefined;
|
description?: Computable<CoercableComponent> | undefined;
|
||||||
/** A computable that will be processed and passed directly into the returned modifier. */
|
/** A computable that will be processed and passed directly into the returned modifier. */
|
||||||
enabled?: Computable<boolean> | undefined;
|
enabled?: Computable<boolean> | undefined;
|
||||||
|
/** Determines if numbers larger or smaller than 0 should be displayed as red. */
|
||||||
|
smallerIsBetter?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +64,7 @@ export function createAdditiveModifier<T extends AdditiveModifierOptions>(
|
||||||
optionsFunc: () => T
|
optionsFunc: () => T
|
||||||
): ModifierFromOptionalParams<T["description"], T["enabled"]> {
|
): ModifierFromOptionalParams<T["description"], T["enabled"]> {
|
||||||
return createLazyProxy(() => {
|
return createLazyProxy(() => {
|
||||||
const { addend, description, enabled } = optionsFunc();
|
const { addend, description, enabled, smallerIsBetter } = optionsFunc();
|
||||||
|
|
||||||
const processedAddend = convertComputable(addend);
|
const processedAddend = convertComputable(addend);
|
||||||
const processedDescription = convertComputable(description);
|
const processedDescription = convertComputable(description);
|
||||||
|
@ -82,7 +84,18 @@ export function createAdditiveModifier<T extends AdditiveModifierOptions>(
|
||||||
{renderJSX(unref(processedDescription)!)}
|
{renderJSX(unref(processedDescription)!)}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
<span class="modifier-amount">
|
<span
|
||||||
|
class="modifier-amount"
|
||||||
|
style={
|
||||||
|
(
|
||||||
|
smallerIsBetter === true
|
||||||
|
? Decimal.gt(unref(processedAddend), 0)
|
||||||
|
: Decimal.lt(unref(processedAddend), 0)
|
||||||
|
)
|
||||||
|
? "color: var(--danger)"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
>
|
||||||
{Decimal.gte(unref(processedAddend), 0) ? "+" : ""}
|
{Decimal.gte(unref(processedAddend), 0) ? "+" : ""}
|
||||||
{formatSmall(unref(processedAddend))}
|
{formatSmall(unref(processedAddend))}
|
||||||
</span>
|
</span>
|
||||||
|
@ -100,6 +113,8 @@ export interface MultiplicativeModifierOptions {
|
||||||
description?: Computable<CoercableComponent> | undefined;
|
description?: Computable<CoercableComponent> | undefined;
|
||||||
/** A computable that will be processed and passed directly into the returned modifier. */
|
/** A computable that will be processed and passed directly into the returned modifier. */
|
||||||
enabled?: Computable<boolean> | undefined;
|
enabled?: Computable<boolean> | undefined;
|
||||||
|
/** Determines if numbers larger or smaller than 1 should be displayed as red. */
|
||||||
|
smallerIsBetter?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,7 +125,7 @@ export function createMultiplicativeModifier<T extends MultiplicativeModifierOpt
|
||||||
optionsFunc: () => T
|
optionsFunc: () => T
|
||||||
): ModifierFromOptionalParams<T["description"], T["enabled"]> {
|
): ModifierFromOptionalParams<T["description"], T["enabled"]> {
|
||||||
return createLazyProxy(() => {
|
return createLazyProxy(() => {
|
||||||
const { multiplier, description, enabled } = optionsFunc();
|
const { multiplier, description, enabled, smallerIsBetter } = optionsFunc();
|
||||||
|
|
||||||
const processedMultiplier = convertComputable(multiplier);
|
const processedMultiplier = convertComputable(multiplier);
|
||||||
const processedDescription = convertComputable(description);
|
const processedDescription = convertComputable(description);
|
||||||
|
@ -130,7 +145,18 @@ export function createMultiplicativeModifier<T extends MultiplicativeModifierOpt
|
||||||
{renderJSX(unref(processedDescription)!)}
|
{renderJSX(unref(processedDescription)!)}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
<span class="modifier-amount">
|
<span
|
||||||
|
class="modifier-amount"
|
||||||
|
style={
|
||||||
|
(
|
||||||
|
smallerIsBetter === true
|
||||||
|
? Decimal.gt(unref(processedMultiplier), 1)
|
||||||
|
: Decimal.lt(unref(processedMultiplier), 1)
|
||||||
|
)
|
||||||
|
? "color: var(--danger)"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
>
|
||||||
×{formatSmall(unref(processedMultiplier))}
|
×{formatSmall(unref(processedMultiplier))}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -149,6 +175,8 @@ export interface ExponentialModifierOptions {
|
||||||
enabled?: Computable<boolean> | undefined;
|
enabled?: Computable<boolean> | undefined;
|
||||||
/** Add 1 before calculating, then remove it afterwards. This prevents low numbers from becoming lower. */
|
/** Add 1 before calculating, then remove it afterwards. This prevents low numbers from becoming lower. */
|
||||||
supportLowNumbers?: boolean;
|
supportLowNumbers?: boolean;
|
||||||
|
/** Determines if numbers larger or smaller than 1 should be displayed as red. */
|
||||||
|
smallerIsBetter?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,7 +187,8 @@ export function createExponentialModifier<T extends ExponentialModifierOptions>(
|
||||||
optionsFunc: () => T
|
optionsFunc: () => T
|
||||||
): ModifierFromOptionalParams<T["description"], T["enabled"]> {
|
): ModifierFromOptionalParams<T["description"], T["enabled"]> {
|
||||||
return createLazyProxy(() => {
|
return createLazyProxy(() => {
|
||||||
const { exponent, description, enabled, supportLowNumbers } = optionsFunc();
|
const { exponent, description, enabled, supportLowNumbers, smallerIsBetter } =
|
||||||
|
optionsFunc();
|
||||||
|
|
||||||
const processedExponent = convertComputable(exponent);
|
const processedExponent = convertComputable(exponent);
|
||||||
const processedDescription = convertComputable(description);
|
const processedDescription = convertComputable(description);
|
||||||
|
@ -200,7 +229,18 @@ export function createExponentialModifier<T extends ExponentialModifierOptions>(
|
||||||
{supportLowNumbers ? " (+1 effective)" : null}
|
{supportLowNumbers ? " (+1 effective)" : null}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
<span class="modifier-amount">
|
<span
|
||||||
|
class="modifier-amount"
|
||||||
|
style={
|
||||||
|
(
|
||||||
|
smallerIsBetter === true
|
||||||
|
? Decimal.gt(unref(processedExponent), 1)
|
||||||
|
: Decimal.lt(unref(processedExponent), 1)
|
||||||
|
)
|
||||||
|
? "color: var(--danger)"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
>
|
||||||
^{formatSmall(unref(processedExponent))}
|
^{formatSmall(unref(processedExponent))}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -252,35 +292,50 @@ export function createSequentialModifier<
|
||||||
}) as unknown as S;
|
}) as unknown as S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** An object that configures a modifier section via {@link createModifierSection}. */
|
||||||
|
export interface ModifierSectionOptions {
|
||||||
|
/** The header for the section. */
|
||||||
|
title: string;
|
||||||
|
/** Smaller text that appears in the header after the title. */
|
||||||
|
subtitle?: string;
|
||||||
|
/** The modifier to render. */
|
||||||
|
modifier: WithRequired<Modifier, "description">;
|
||||||
|
/** The base value that'll be passed into the modifier. Defaults to 1. */
|
||||||
|
base?: DecimalSource;
|
||||||
|
/** The unit of the value being modified, if any. */
|
||||||
|
unit?: string;
|
||||||
|
/** The label to use for the base value. Defaults to "Base". */
|
||||||
|
baseText?: CoercableComponent;
|
||||||
|
/** Determines if numbers larger or smaller than the base should be displayed as red. */
|
||||||
|
smallerIsBetter?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a JSX element that displays a modifier.
|
* Create a JSX element that displays a modifier.
|
||||||
* Intended to be used with the output from {@link createSequentialModifier}.
|
* Intended to be used with the output from {@link createSequentialModifier}.
|
||||||
* @param title The header for the section.
|
* @param options Modifier section options.
|
||||||
* @param subtitle Smaller text that appears in the header after the title.
|
|
||||||
* @param modifier The modifier to render.
|
|
||||||
* @param base The base value that'll be passed into the modifier.
|
|
||||||
* @param unit The unit of the value being modified, if any.
|
|
||||||
* @param baseText The label to use for the base value.
|
|
||||||
*/
|
*/
|
||||||
export function createModifierSection(
|
export function createModifierSection({
|
||||||
title: string,
|
title,
|
||||||
subtitle: string,
|
subtitle,
|
||||||
modifier: WithRequired<Modifier, "description">,
|
modifier,
|
||||||
base: DecimalSource = 1,
|
base,
|
||||||
unit = "",
|
unit,
|
||||||
baseText: CoercableComponent = "Base"
|
baseText,
|
||||||
) {
|
smallerIsBetter
|
||||||
|
}: ModifierSectionOptions) {
|
||||||
|
const total = modifier.apply(base ?? 1);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3>
|
<h3>
|
||||||
{title}
|
{title}
|
||||||
{subtitle ? <span class="subtitle"> ({subtitle})</span> : null}
|
{subtitle == null ? null : <span class="subtitle"> ({subtitle})</span>}
|
||||||
</h3>
|
</h3>
|
||||||
<br />
|
<br />
|
||||||
<div class="modifier-container">
|
<div class="modifier-container">
|
||||||
<span class="modifier-description">{renderJSX(baseText)}</span>
|
<span class="modifier-description">{renderJSX(baseText ?? "Base")}</span>
|
||||||
<span class="modifier-amount">
|
<span class="modifier-amount">
|
||||||
{formatSmall(base)}
|
{formatSmall(base ?? 1)}
|
||||||
{unit}
|
{unit}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -288,8 +343,19 @@ export function createModifierSection(
|
||||||
<hr />
|
<hr />
|
||||||
<div class="modifier-container">
|
<div class="modifier-container">
|
||||||
<span class="modifier-description">Total</span>
|
<span class="modifier-description">Total</span>
|
||||||
<span class="modifier-amount">
|
<span
|
||||||
{formatSmall(modifier.apply(base))}
|
class="modifier-amount"
|
||||||
|
style={
|
||||||
|
(
|
||||||
|
smallerIsBetter === true
|
||||||
|
? Decimal.gt(total, base ?? 1)
|
||||||
|
: Decimal.lt(total, base ?? 1)
|
||||||
|
)
|
||||||
|
? "color: var(--danger)"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{formatSmall(total)}
|
||||||
{unit}
|
{unit}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue