chore: consolidate platform split checks
Some checks failed
Dependency Audit / dependency-audit (push) Has been cancelled
Module Matrix / module-matrix (push) Has been cancelled

This commit is contained in:
2026-07-10 12:51:19 +02:00
parent 150b720f12
commit 635d25c74c
216 changed files with 23336 additions and 4077 deletions

View File

@@ -1,5 +1,6 @@
import { Folder, FolderOpen } from "lucide-react";
import type { CSSProperties, DragEvent as ReactDragEvent, MouseEvent as ReactMouseEvent, ReactNode } from "react";
import { i18nMessage } from "../i18n/LanguageContext";
export type ExplorerTreeNodeContext = {
depth: number;
@@ -9,7 +10,7 @@ export type ExplorerTreeNodeContext = {
disabled: boolean;
};
type ExplorerTreeProps<T> = {
export type ExplorerTreeProps<T> = {
nodes: T[];
getNodeId: (node: T) => string;
getNodeLabel: (node: T) => string;
@@ -21,6 +22,11 @@ type ExplorerTreeProps<T> = {
disabled?: boolean;
depth?: number;
className?: string;
childrenBaseClassName?: string;
nodeContainerClassName?: string;
nodeWrapBaseClassName?: string;
toggleBaseClassName?: string;
nodeButtonBaseClassName?: string;
renderToggleIcon?: (node: T, context: ExplorerTreeNodeContext) => ReactNode;
renderNodeContent?: (node: T, context: ExplorerTreeNodeContext) => ReactNode;
getNodeWrapClassName?: (node: T, context: ExplorerTreeNodeContext) => string | undefined;
@@ -47,6 +53,11 @@ export default function ExplorerTree<T>({
disabled = false,
depth = 1,
className = "",
childrenBaseClassName = "explorer-tree-children file-tree-children",
nodeContainerClassName = "",
nodeWrapBaseClassName = "explorer-tree-node-wrap file-tree-node-wrap",
toggleBaseClassName = "explorer-tree-toggle file-tree-toggle",
nodeButtonBaseClassName = "explorer-tree-node file-tree-node",
renderToggleIcon,
renderNodeContent,
getNodeWrapClassName,
@@ -63,7 +74,7 @@ export default function ExplorerTree<T>({
if (nodes.length === 0) return null;
return (
<div className={["explorer-tree-children", "file-tree-children", className].filter(Boolean).join(" ")}>
<div className={[childrenBaseClassName, className].filter(Boolean).join(" ")}>
{nodes.map((node) => {
const nodeId = getNodeId(node);
const children = getNodeChildren(node);
@@ -74,14 +85,13 @@ export default function ExplorerTree<T>({
const draggable = getNodeDraggable?.(node, context) ?? false;
return (
<div key={nodeId}>
<div key={nodeId} className={nodeContainerClassName}>
<div
className={[
"explorer-tree-node-wrap",
"file-tree-node-wrap",
active ? "is-active" : "",
getNodeWrapClassName?.(node, context) ?? ""
].filter(Boolean).join(" ")}
nodeWrapBaseClassName,
active ? "is-active" : "",
getNodeWrapClassName?.(node, context) ?? ""].
filter(Boolean).join(" ")}
style={getNodeWrapStyle?.(node, context) ?? { paddingLeft: `${Math.min(depth * 14, 56)}px` }}
draggable={draggable && !disabled}
onContextMenu={onContextMenu ? (event) => onContextMenu(event, node, context) : undefined}
@@ -89,59 +99,64 @@ export default function ExplorerTree<T>({
onDragEnd={draggable && onDragEnd ? (event) => onDragEnd(event, node, context) : undefined}
onDragOver={onDragOver ? (event) => onDragOver(event, node, context) : undefined}
onDragLeave={onDragLeave ? (event) => onDragLeave(event, node, context) : undefined}
onDrop={onDrop ? (event) => onDrop(event, node, context) : undefined}
>
onDrop={onDrop ? (event) => onDrop(event, node, context) : undefined}>
<button
type="button"
className="explorer-tree-toggle file-tree-toggle"
className={toggleBaseClassName}
onClick={(event) => {
event.stopPropagation();
if (hasChildren) onToggle(node, context);
}}
disabled={disabled || !hasChildren}
aria-label={`${expanded ? "Collapse" : "Expand"} ${getNodeLabel(node)}`}
aria-expanded={hasChildren ? expanded : undefined}
>
aria-label={i18nMessage("i18n:govoplan-core.value_value.dca59cc0", { value0: expanded ? "i18n:govoplan-core.collapse.9cf188d3" : "i18n:govoplan-core.expand.9869e506", value1: getNodeLabel(node) })}
aria-expanded={hasChildren ? expanded : undefined}>
{renderToggleIcon?.(node, context) ?? (expanded ? <FolderOpen size={15} aria-hidden="true" /> : <Folder size={15} aria-hidden="true" />)}
</button>
<button
type="button"
className={["explorer-tree-node", "file-tree-node", getNodeButtonClassName?.(node, context) ?? ""].filter(Boolean).join(" ")}
className={[nodeButtonBaseClassName, getNodeButtonClassName?.(node, context) ?? ""].filter(Boolean).join(" ")}
onClick={() => onOpen(node, context)}
disabled={disabled}
>
disabled={disabled}>
{renderNodeContent?.(node, context) ?? <span>{getNodeLabel(node)}</span>}
</button>
</div>
{hasChildren && expanded && (
<ExplorerTree
nodes={children}
getNodeId={getNodeId}
getNodeLabel={getNodeLabel}
getNodeChildren={getNodeChildren}
activeId={activeId}
expandedIds={expandedIds}
onOpen={onOpen}
onToggle={onToggle}
disabled={disabled}
depth={depth + 1}
renderToggleIcon={renderToggleIcon}
renderNodeContent={renderNodeContent}
getNodeWrapClassName={getNodeWrapClassName}
getNodeWrapStyle={getNodeWrapStyle}
getNodeButtonClassName={getNodeButtonClassName}
getNodeDraggable={getNodeDraggable}
onContextMenu={onContextMenu}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
onDragOver={onDragOver}
onDragLeave={onDragLeave}
onDrop={onDrop}
/>
)}
</div>
);
{hasChildren && expanded &&
<ExplorerTree
nodes={children}
getNodeId={getNodeId}
getNodeLabel={getNodeLabel}
getNodeChildren={getNodeChildren}
activeId={activeId}
expandedIds={expandedIds}
onOpen={onOpen}
onToggle={onToggle}
disabled={disabled}
depth={depth + 1}
childrenBaseClassName={childrenBaseClassName}
nodeContainerClassName={nodeContainerClassName}
nodeWrapBaseClassName={nodeWrapBaseClassName}
toggleBaseClassName={toggleBaseClassName}
nodeButtonBaseClassName={nodeButtonBaseClassName}
renderToggleIcon={renderToggleIcon}
renderNodeContent={renderNodeContent}
getNodeWrapClassName={getNodeWrapClassName}
getNodeWrapStyle={getNodeWrapStyle}
getNodeButtonClassName={getNodeButtonClassName}
getNodeDraggable={getNodeDraggable}
onContextMenu={onContextMenu}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
onDragOver={onDragOver}
onDragLeave={onDragLeave}
onDrop={onDrop} />
}
</div>);
})}
</div>
);
</div>);
}