summaryrefslogtreecommitdiff
path: root/src/components/CollapsibleItemGroup.tsx
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2026-09-11 09:05:14 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2026-09-11 09:05:14 -0400
commitd2bfdafa92f3d31cc5392bf8a5a1f1df5c2358ce (patch)
tree102c12dc843ce64dd21599c2cf8ae3d5a3bd0104 /src/components/CollapsibleItemGroup.tsx
parent904e2e6131071c3b132d3148947b613c2830b1bb (diff)
downloaddecky-lsfg-vk-d2bfdafa92f3d31cc5392bf8a5a1f1df5c2358ce.tar.gz
decky-lsfg-vk-d2bfdafa92f3d31cc5392bf8a5a1f1df5c2358ce.zip
flatpak correctness, ui alignment, tests
Diffstat (limited to 'src/components/CollapsibleItemGroup.tsx')
-rw-r--r--src/components/CollapsibleItemGroup.tsx79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/components/CollapsibleItemGroup.tsx b/src/components/CollapsibleItemGroup.tsx
new file mode 100644
index 0000000..a66a8ba
--- /dev/null
+++ b/src/components/CollapsibleItemGroup.tsx
@@ -0,0 +1,79 @@
+import { ButtonItem, Field, PanelSectionRow } from "@decky/ui";
+import { type RefObject } from "react";
+import { RiArrowDownSFill, RiArrowUpSFill } from "react-icons/ri";
+
+export interface CollapsibleItem {
+ id: string;
+ label: string;
+ description: string;
+}
+
+export const collapsibleItemGroupStyles = `
+ .LSFG_GameGroupCollapseButton_Container > div > div > div > button,
+ .LSFG_GameGroupCollapseButton_Container > div > div > div > div > button {
+ height: 24px !important;
+ min-height: 24px !important;
+ padding: 0 !important;
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ }
+
+ .LSFG_GameGroupCollapseButton_Container svg {
+ display: block;
+ margin: 0;
+ }
+`;
+
+interface Props {
+ title: string;
+ items: CollapsibleItem[];
+ collapsed: boolean;
+ onToggle: () => void;
+ onSelect: (id: string) => void;
+ toggleRef?: RefObject<HTMLDivElement>;
+}
+
+export function CollapsibleItemGroup({
+ title,
+ items,
+ collapsed,
+ onToggle,
+ onSelect,
+ toggleRef,
+}: Props) {
+ if (items.length === 0) return null;
+
+ return (
+ <>
+ <PanelSectionRow>
+ <Field label={`${title} (${items.length})`} bottomSeparator="none" />
+ </PanelSectionRow>
+ <PanelSectionRow>
+ <div
+ ref={toggleRef}
+ className="LSFG_GameGroupCollapseButton_Container"
+ style={{ marginTop: "-2px", marginBottom: "4px" }}
+ >
+ <ButtonItem
+ layout="below"
+ bottomSeparator={collapsed ? "standard" : "none"}
+ onClick={onToggle}
+ >
+ {collapsed ? <RiArrowDownSFill /> : <RiArrowUpSFill />}
+ </ButtonItem>
+ </div>
+ </PanelSectionRow>
+ {!collapsed && items.map((item) => (
+ <PanelSectionRow key={item.id}>
+ <Field
+ label={item.label}
+ description={item.description}
+ onActivate={() => onSelect(item.id)}
+ highlightOnFocus
+ />
+ </PanelSectionRow>
+ ))}
+ </>
+ );
+}