import { useMemo } from "react"; import { View } from "react-native"; import { StyleSheet, withUnistyles } from "react-native-unistyles"; import { ChevronRight } from "lucide-react-native"; import { SPACING, type Theme } from "@/styles/theme"; import { inlineUnistylesStyle } from "@/styles/unistyles-inline-style"; // Shared presentation primitives for the app's directory trees. Both the Files // explorer (server-loaded listings) and the Changes view (client-built from diff // paths) render different data, but their ROWS should look identical — same // indentation, guide lines, and chevron. Keep those here so the two trees can't // drift apart. export const TREE_INDENT_PER_LEVEL = 16; /** Left padding for a tree row at `depth`. Shared by folder rows and file headers * in the Changes tree so their indentation can't drift apart. */ export function treeRowPaddingLeft(depth: number): number { return SPACING[3] + depth * TREE_INDENT_PER_LEVEL; } const foregroundMutedIconColorMapping = (theme: Theme) => ({ color: theme.colors.foregroundMuted }); const ThemedChevronRight = withUnistyles(ChevronRight); /** * Vertical guide lines connecting nested rows to their ancestors — one line per * ancestor depth level, positioned absolutely within the (relative) row. Renders * nothing at depth 0. */ export function TreeIndentGuides({ depth }: { depth: number }) { const guides = useMemo( () => Array.from({ length: depth }, (_, index) => ({ key: index, style: [ styles.indentGuide, inlineUnistylesStyle({ left: SPACING[3] + index * TREE_INDENT_PER_LEVEL + 4 }), ], })), [depth], ); return ( <> {guides.map((guide) => ( ))} ); } /** Rotating disclosure chevron for a directory row (points right; rotates down when expanded). */ export function TreeChevron({ expanded }: { expanded: boolean }) { return ( ); } const styles = StyleSheet.create((theme: Theme) => ({ indentGuide: { position: "absolute", top: 0, bottom: 0, width: 1, backgroundColor: theme.colors.surface2, }, chevron: { width: 16, height: 16, alignItems: "center", justifyContent: "center", flexShrink: 0, }, chevronExpanded: { transform: [{ rotate: "90deg" }], }, })); // Stable module-level style ref so TreeChevron passes a constant array, not one created // per render — satisfies react-perf (no inline-array prop) without a per-render useMemo. const CHEVRON_EXPANDED_STYLE = [styles.chevron, styles.chevronExpanded];