diff --git a/src/data/common.css b/src/data/common.css new file mode 100644 index 0000000..728c160 --- /dev/null +++ b/src/data/common.css @@ -0,0 +1,9 @@ +.modifier-toggle { + padding-right: 10px; + transform: translateY(-1px); + display: inline-block; +} + +.modifier-toggle.collapsed { + transform: translate(-5px, -5px) rotate(-90deg); +} diff --git a/src/data/common.tsx b/src/data/common.tsx index f9f58fb..f7ba494 100644 --- a/src/data/common.tsx +++ b/src/data/common.tsx @@ -5,7 +5,14 @@ import { GenericClickable } from "features/clickables/clickable"; import { GenericConversion } from "features/conversion"; -import { CoercableComponent, jsx, OptionsFunc, Replace, setDefault } from "features/feature"; +import { + CoercableComponent, + jsx, + JSXFunction, + OptionsFunc, + Replace, + setDefault +} from "features/feature"; import { displayResource } from "features/resources/resource"; import { createTreeNode, @@ -14,16 +21,21 @@ import { TreeNode, TreeNodeOptions } from "features/trees/tree"; +import { Modifier } from "game/modifiers"; +import { Persistent, persistent } from "game/persistence"; import player from "game/player"; -import Decimal, { DecimalSource } from "util/bignum"; +import Decimal, { DecimalSource, format } from "util/bignum"; import { Computable, + convertComputable, GetComputableType, GetComputableTypeWithDefault, processComputable, ProcessedComputable } from "util/computed"; +import { renderJSX } from "util/vue"; import { computed, Ref, unref } from "vue"; +import "./common.css"; export interface ResetButtonOptions extends ClickableOptions { conversion: GenericConversion; @@ -177,3 +189,68 @@ export function createLayerTreeNode( }; }) as unknown as LayerTreeNode; } + +export function createCollapsibleModifierSections( + sections: { + title: string; + subtitle?: string; + modifier: Required; + base?: Computable; + unit?: string; + baseText?: Computable; + visible?: Computable; + }[] +): [JSXFunction, Persistent[]] { + const processedBase = sections.map(s => convertComputable(s.base)); + const processedBaseText = sections.map(s => convertComputable(s.baseText)); + const processedVisible = sections.map(s => convertComputable(s.visible)); + const collapsed = sections.map(() => persistent(false)); + const jsxFunc = jsx(() => { + const sectionJSX = sections.map((s, i) => { + if (unref(processedVisible[i]) === false) return null; + const header = ( +

(collapsed[i].value = !collapsed[i].value)} + style="cursor: pointer" + > + + ▼ + + {s.title} + {s.subtitle ? ({s.subtitle}) : null} +

+ ); + + const modifiers = unref(collapsed[i]) ? null : ( + <> +
+ + {format(unref(processedBase[i]) ?? 1)} + {s.unit} + + + {renderJSX(unref(processedBaseText[i]) ?? "Base")} + +
+ {renderJSX(unref(s.modifier.description))} + + ); + + return ( + <> + {i === 0 ? null :
} +
+ {header} +
+ {modifiers} +
+ Total: {format(s.modifier.apply(unref(processedBase[i]) ?? 1))} + {s.unit} +
+ + ); + }); + return <>{sectionJSX}; + }); + return [jsxFunc, collapsed]; +}