From c692578da70c7fd05f922380572199d3a935d3a3 Mon Sep 17 00:00:00 2001
From: thepaperpilot <thepaperpilot@gmail.com>
Date: Sat, 30 Apr 2022 16:42:03 -0500
Subject: [PATCH] Made createCollapsibleModifierSections utility function

---
 src/data/common.css |  9 +++++
 src/data/common.tsx | 81 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100644 src/data/common.css

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<T extends LayerTreeNodeOptions>(
         };
     }) as unknown as LayerTreeNode<T>;
 }
+
+export function createCollapsibleModifierSections(
+    sections: {
+        title: string;
+        subtitle?: string;
+        modifier: Required<Modifier>;
+        base?: Computable<DecimalSource>;
+        unit?: string;
+        baseText?: Computable<CoercableComponent>;
+        visible?: Computable<boolean>;
+    }[]
+): [JSXFunction, Persistent<boolean>[]] {
+    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<boolean>(false));
+    const jsxFunc = jsx(() => {
+        const sectionJSX = sections.map((s, i) => {
+            if (unref(processedVisible[i]) === false) return null;
+            const header = (
+                <h3
+                    onClick={() => (collapsed[i].value = !collapsed[i].value)}
+                    style="cursor: pointer"
+                >
+                    <span class={"modifier-toggle" + (unref(collapsed[i]) ? " collapsed" : "")}>
+                        ▼
+                    </span>
+                    {s.title}
+                    {s.subtitle ? <span class="subtitle"> ({s.subtitle})</span> : null}
+                </h3>
+            );
+
+            const modifiers = unref(collapsed[i]) ? null : (
+                <>
+                    <div class="modifier-container">
+                        <span class="modifier-amount">
+                            {format(unref(processedBase[i]) ?? 1)}
+                            {s.unit}
+                        </span>
+                        <span class="modifier-description">
+                            {renderJSX(unref(processedBaseText[i]) ?? "Base")}
+                        </span>
+                    </div>
+                    {renderJSX(unref(s.modifier.description))}
+                </>
+            );
+
+            return (
+                <>
+                    {i === 0 ? null : <br />}
+                    <div>
+                        {header}
+                        <br />
+                        {modifiers}
+                        <hr />
+                        Total: {format(s.modifier.apply(unref(processedBase[i]) ?? 1))}
+                        {s.unit}
+                    </div>
+                </>
+            );
+        });
+        return <>{sectionJSX}</>;
+    });
+    return [jsxFunc, collapsed];
+}