"use client"
/**
* Folder location picker — same search chrome + folder tree as Library secondary panel.
* Used by `new-library-item-form` inspector (selection, not navigation).
*/
import * as React from "react"
import { useLocation, useSearchParams } from "react-router-dom"
import { Button } from "@/components/ui/button"
import { SidebarNavLabel } from "@/components/ui/sidebar-nav-label"
import { Tip } from "@/components/ui/tip"
import { cn } from "@/lib/utils"
import type { LibraryFolder } from "@/lib/mock/library-folders"
import { LIBRARY_FOLDER_ICON_COLORS } from "@/lib/mock/library-folders"
import { LibraryFolderTreeBranch } from "@/components/data-views/library-folder-tree-branch"
import { outlineTreeBranchDepthStyle } from "@/components/data-views/outline-tree-menu"
import {
LIBRARY_FAVORITES_FOLDER_ID,
coerceLibraryNav,
parseLibraryNav,
} from "@/lib/library-nav"
function libraryFolderMatchesSearch(
folder: LibraryFolder,
folders: LibraryFolder[],
query: string,
): boolean {
const needle = query.trim().toLowerCase()
if (!needle) return true
if (folder.name.toLowerCase().includes(needle)) return true
return folders.some(
f => f.parentId === folder.id && libraryFolderMatchesSearch(f, folders, query),
)
}
function FolderPickerSearchInput({
value,
onChange,
}: {
value: string
onChange: (next: string) => void
}) {
return (
onChange(e.target.value)}
placeholder="Search folders…"
aria-label="Search folders"
className={cn(
"h-7 w-full rounded-md border border-border bg-background ps-7 pe-2 text-xs",
"placeholder:text-muted-foreground/70",
"focus:border-transparent focus:outline-none focus:ring-2 focus:ring-ring",
)}
/>
)
}
function FolderPickerScopeRow({
folder,
active,
onSelect,
}: {
folder: LibraryFolder
active: boolean
onSelect: () => void
}) {
return (
)
}
export interface LibraryFolderPickerPanelProps {
folders: LibraryFolder[]
value: string
onChange: (folderId: string) => void
onRequestNewFolder: () => void
}
export function LibraryFolderPickerPanel({
folders,
value,
onChange,
onRequestNewFolder,
}: LibraryFolderPickerPanelProps) {
const [query, setQuery] = React.useState("")
const { pathname } = useLocation()
const [searchParams] = useSearchParams()
const searchParamsKey = searchParams.toString()
const nav = React.useMemo(() => {
const parsed = parseLibraryNav(new URLSearchParams(searchParamsKey))
return coerceLibraryNav(parsed, folders)
}, [searchParamsKey, folders])
const favoritesFolder = React.useMemo(
() => folders.find(f => f.id === LIBRARY_FAVORITES_FOLDER_ID),
[folders],
)
const folderTreeRoots = React.useMemo(
() =>
folders
.filter(f => f.parentId === null && f.id !== LIBRARY_FAVORITES_FOLDER_ID)
.sort((a, b) => a.name.localeCompare(b.name)),
[folders],
)
const visibleRoots = React.useMemo(
() =>
folderTreeRoots.filter(f => libraryFolderMatchesSearch(f, folders, query)),
[folderTreeRoots, folders, query],
)
const showFavorites =
favoritesFolder &&
libraryFolderMatchesSearch(favoritesFolder, folders, query)
const pickFolder = React.useMemo(
() => ({
selectedFolderId: value,
onSelect: onChange,
searchQuery: query,
}),
[value, onChange, query],
)
const noop = React.useCallback(() => {}, [])
return (
{showFavorites && favoritesFolder ? (
onChange(favoritesFolder.id)}
/>
) : null}
{visibleRoots.length > 0 ? (
-
Folders
) : null}
{visibleRoots.map(folder => (
-
))}
{query.trim() && !showFavorites && visibleRoots.length === 0 ? (
- No folders match that search.
) : null}
)
}