diff --git a/src/display/components/collapsible.css b/src/display/components/collapsible.css
new file mode 100644
index 0000000000000000000000000000000000000000..8bc1d8f7618e32d10fb5304057510d2e831e9bc3
--- /dev/null
+++ b/src/display/components/collapsible.css
@@ -0,0 +1,76 @@
+.collapsible-content {
+    overflow: hidden;
+    transition: height 0.2s ease-in-out;
+    border-bottom: 1px solid #dee2e6 !important;
+}
+
+.collapsible-content-padding {
+    padding: 20px 20px 20px 30px;
+}
+
+.collapsible-rotate-center {
+    -moz-transition: all 0.2s linear;
+    -webkit-transition: all 0.2s linear;
+    font-size: 4em;
+    transition: all 0.2s linear;
+}
+.collapsible-rotate-center.down {
+    transform: rotate(-90deg);
+}
+.collapsible-rotate-center.up {
+    transform: rotate(90deg);
+}
+
+.collapsible-button {
+    position: relative;
+    display: flex;
+    align-items: center;
+    width: 100%;
+    font-size: 1.2rem;
+    background-color: transparent;
+    border-bottom: 1px solid gray;
+    color: black;
+    padding-left: 25px;
+}
+
+.collapsible-button:not(.collapsed) {
+    background-color: aliceblue;
+    color: royalblue;
+}
+
+.collapsible-button.collapsed:hover {
+    background-color: transparent;
+}
+
+.collapsible-button:hover {
+    background-color: aliceblue;
+}
+
+.collapsible-button.collapsed:focus {
+    border-color: lightblue;
+    background-color: white;
+}
+
+.collapsible-button.collapsed:focus {
+    border-color: lightblue;
+}
+
+.collapsible-button::after {
+    content: "\276E";
+    margin-left: auto;
+    transition: all 0.2s linear;
+    transform: rotate(90deg);
+}
+
+.collapsible-button:not(.collapsed)::after {
+    transform: rotate(-90deg);
+}
+
+.collapsible-card {
+    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
+    transition: 0.3s;
+}
+
+.collapsible-card:hover {
+    box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
+}
diff --git a/src/display/components/collapsible.tsx b/src/display/components/collapsible.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..b4dd7e419a06dd66c7a881b7ba5e4ff589543a90
--- /dev/null
+++ b/src/display/components/collapsible.tsx
@@ -0,0 +1,65 @@
+import React, { useEffect, useRef, useState } from "react";
+import "./collapsible.css";
+
+interface CollapsibleProps {
+    open?: boolean;
+    header: string | React.ReactNode;
+    children?: React.ReactNode | React.ReactNode[];
+}
+
+// Implementation details at nhttps://medium.com/edonec/build-a-react-collapsible-component-from-scratch-using-react-hooks-typescript-73dfd02c9208
+function Collapsible({ open, header, children }: CollapsibleProps) {
+    const [isOpen, setIsOpen] = useState(open);
+    const [height, setHeight] = useState<number | undefined>(
+        open ? undefined : 0
+    );
+
+    const toggleOpen = () => {
+        setIsOpen((prev) => !prev);
+    };
+
+    const ref = useRef<HTMLDivElement>(null);
+
+    useEffect(() => {
+        if (!height || !isOpen || !ref.current) return undefined;
+        const resizeObserver = new ResizeObserver((el) => {
+            setHeight(el[0].contentRect.height);
+        });
+        resizeObserver.observe(ref.current);
+        return () => {
+            resizeObserver.disconnect();
+        };
+    }, [height, isOpen]);
+
+    useEffect(() => {
+        if (isOpen) setHeight(ref.current?.getBoundingClientRect().height);
+        else setHeight(0);
+    }, [isOpen]);
+
+    return (
+        <>
+            <div className={"collapsible-card"}>
+                <div>
+                    <button
+                        type="button"
+                        className={`collapsible-button ${
+                            isOpen ? "" : "collapsed"
+                        }`}
+                        onClick={toggleOpen}
+                    >
+                        {header}
+                    </button>
+                </div>
+                <div className={"collapsible-content"} style={{ height }}>
+                    <div ref={ref}>
+                        <div className={"collapsible-content-padding"}>
+                            {children}
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </>
+    );
+}
+
+export default Collapsible;