import {
ChevronDownIcon,
ChevronRightIcon,
FileIcon,
FolderIcon,
SearchIcon,
} from 'lucide-react';
import { useMemo, useState } from 'react';
import { buildFileTree, filterFiles } from '#/lib/file-tree.js';
import { cn } from '#/lib/utils.js';
const STATUS_MARK = { added: '+', deleted: '−', modified: '±' };
const STATUS_COLOR = {
added: 'text-foreground',
deleted: 'text-faint',
modified: 'text-faint',
};
/**
* One row per node, indented by depth. Directories carry their own open
* state, so closing one leaves the rest as they were.
*/
function Node({ node, depth, onPick, picked }) {
const [open, setOpen] = useState(true);
const pad = { paddingLeft: `${depth * 12 + 8}px` };
if (node.type === 'file') {
const status = node.file.status;
return (
);
}
const Chevron = open ? ChevronDownIcon : ChevronRightIcon;
return (
{open &&
node.children.map((child) => (
))}
);
}
/**
* The changed files of a commit, as the tree they came from, beside the
* diffs themselves. Picking one moves to it rather than opening a page: the
* diffs are all on this screen already.
*/
export function DiffTree({ files, onPick, picked }) {
const [filter, setFilter] = useState('');
const shown = useMemo(() => filterFiles(files, filter), [files, filter]);
const tree = useMemo(() => buildFileTree(shown), [shown]);
return (