'use client'; import clsx from 'clsx'; import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; import { FolderNode, FolderTree } from '@/models/FolderTree'; import { labelFolderNode } from '@/utils/labels'; import { IconFolder, IconFolderClosed, IconFolderEmpty, IconFolderOpened } from '../Icons'; import { CProps } from '../props'; import MiniButton from '../ui/MiniButton'; interface SelectLocationProps extends CProps.Styling { value: string; folderTree: FolderTree; prefix: string; dense?: boolean; onClick: (event: CProps.EventMouse, target: FolderNode) => void; } function SelectLocation({ value, folderTree, dense, prefix, onClick, className, style }: SelectLocationProps) { const activeNode = useMemo(() => folderTree.at(value), [folderTree, value]); const items = useMemo(() => folderTree.getTree(), [folderTree]); const [folded, setFolded] = useState(items); useLayoutEffect(() => { setFolded(items.filter(item => item !== activeNode && (!activeNode || !activeNode.hasPredecessor(item)))); }, [items, activeNode]); const onFoldItem = useCallback( (target: FolderNode, showChildren: boolean) => { setFolded(prev => items.filter(item => { if (item === target) { return !showChildren; } if (!showChildren && item.hasPredecessor(target)) { return true; } else { return prev.includes(item); } }) ); }, [items] ); const handleClickFold = useCallback( (event: CProps.EventMouse, target: FolderNode, showChildren: boolean) => { event.preventDefault(); event.stopPropagation(); onFoldItem(target, showChildren); }, [onFoldItem] ); return (
{items.map((item, index) => !item.parent || !folded.includes(item.parent) ? (
5 ? 5 : item.rank) * 0.5 + 0.5}rem` }} onClick={event => onClick(event, item)} > {item.children.size > 0 ? ( ) : ( ) ) : ( ) } onClick={event => handleClickFold(event, item, folded.includes(item))} /> ) : (
{item.filesInside ? ( ) : ( )}
)}
{labelFolderNode(item)}
) : null )}
); } export default SelectLocation;