"use client"; import { Fragment, useCallback, useEffect, useState } from "react"; import { IconFolder, IconBox, IconChevronRight } from "@tabler/icons-react"; import { Popover, PopoverContent, PopoverTrigger } from "@kandev/ui/popover"; import { Tooltip, TooltipContent, TooltipTrigger } from "@kandev/ui/tooltip"; import { cn } from "@/lib/utils"; import { listDirectory, type DirectoryListing } from "@/lib/api/domains/fs-api"; type FolderPickerProps = { /** Currently chosen absolute path; empty when nothing is picked. */ value: string; /** Called with the absolute path when the user chooses a folder. */ onChange: (path: string) => void; placeholder?: string; }; /** * Folder picker for repo-less tasks. Drives GET /api/v1/fs/list-dir on the * local kandev backend (browsers can't enumerate the host filesystem). The * trigger lives in the chip row and the popover handles browse + commit. */ export function FolderPicker({ value, onChange, placeholder }: FolderPickerProps) { const [open, setOpen] = useState(false); const { listing, loading, error, load } = useDirectoryListing(open, value); const leaf = leafName(value); const triggerLabel = leaf || placeholder || "scratch workspace"; const hasValue = !!value; const triggerClass = cn( "h-7 inline-flex items-center gap-1.5 rounded-md px-2.5 text-xs cursor-pointer", "border border-border/60 transition-colors", hasValue ? "bg-primary/10 text-foreground hover:bg-primary/15" : "bg-muted/30 text-muted-foreground hover:bg-muted/60", ); const trigger = ( ); return ( {hasValue ? ( {trigger} {value} ) : ( trigger )} void load(p)} /> void load(p)} />