mirror of
https://github.com/zadam/trilium.git
synced 2025-12-20 22:34:23 +01:00
Some checks are pending
Checks / main (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Dev / Test development (push) Waiting to run
Dev / Build Docker image (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile) (push) Blocked by required conditions
Dev / Check Docker build (Dockerfile.alpine) (push) Blocked by required conditions
/ Check Docker build (Dockerfile) (push) Waiting to run
/ Check Docker build (Dockerfile.alpine) (push) Waiting to run
/ Build Docker images (Dockerfile, ubuntu-24.04-arm, linux/arm64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.alpine, ubuntu-latest, linux/amd64) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v7) (push) Blocked by required conditions
/ Build Docker images (Dockerfile.legacy, ubuntu-24.04-arm, linux/arm/v8) (push) Blocked by required conditions
/ Merge manifest lists (push) Blocked by required conditions
playwright / E2E tests on linux-arm64 (push) Waiting to run
playwright / E2E tests on linux-x64 (push) Waiting to run
59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
import "./Collapsible.css";
|
|
|
|
import clsx from "clsx";
|
|
import { ComponentChildren, HTMLAttributes } from "preact";
|
|
import { useRef, useState } from "preact/hooks";
|
|
|
|
import { useElementSize, useUniqueName } from "./hooks";
|
|
import Icon from "./Icon";
|
|
|
|
interface CollapsibleProps extends Pick<HTMLAttributes<HTMLDivElement>, "className"> {
|
|
title: string;
|
|
children: ComponentChildren;
|
|
initiallyExpanded?: boolean;
|
|
}
|
|
|
|
export default function Collapsible({ initiallyExpanded, ...restProps }: CollapsibleProps) {
|
|
const [ expanded, setExpanded ] = useState(initiallyExpanded);
|
|
return <ExternallyControlledCollapsible {...restProps} expanded={expanded} setExpanded={setExpanded} />;
|
|
}
|
|
|
|
export function ExternallyControlledCollapsible({ title, children, className, expanded, setExpanded }: Omit<CollapsibleProps, "initiallyExpanded"> & {
|
|
expanded: boolean | undefined;
|
|
setExpanded: (expanded: boolean) => void
|
|
}) {
|
|
const bodyRef = useRef<HTMLDivElement>(null);
|
|
const innerRef = useRef<HTMLDivElement>(null);
|
|
const { height } = useElementSize(innerRef) ?? {};
|
|
const contentId = useUniqueName();
|
|
|
|
return (
|
|
<div className={clsx("collapsible", className, expanded && "expanded")}>
|
|
<button
|
|
className="collapsible-title"
|
|
onClick={() => setExpanded(!expanded)}
|
|
aria-expanded={expanded}
|
|
aria-controls={contentId}
|
|
>
|
|
<Icon className="arrow" icon="bx bx-chevron-right" />
|
|
{title}
|
|
</button>
|
|
|
|
<div
|
|
id={contentId}
|
|
ref={bodyRef}
|
|
className="collapsible-body"
|
|
style={{ height: expanded ? height : "0" }}
|
|
aria-hidden={!expanded}
|
|
>
|
|
<div
|
|
ref={innerRef}
|
|
className="collapsible-inner-body"
|
|
>
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|