'use client'; import clsx from 'clsx'; import { AnimatePresence, motion } from 'framer-motion'; import { useCallback, useLayoutEffect, useMemo, useState } from 'react'; import { IconFolder, IconFolderClosed, IconFolderEmpty, IconFolderOpened, IconFolderTree } from '@/components/Icons'; import BadgeHelp from '@/components/info/BadgeHelp'; import { CProps } from '@/components/props'; import MiniButton from '@/components/ui/MiniButton'; import { FolderNode, FolderTree } from '@/models/FolderTree'; import { HelpTopic } from '@/models/miscellaneous'; import { animateSideAppear, animateSideView } from '@/styling/animations'; import { globals, PARAMETER, prefixes } from '@/utils/constants'; import { describeFolderNode, labelFolderNode } from '@/utils/labels'; interface LibraryTableProps { folders: FolderTree; currentFolder: string; setFolder: React.Dispatch>; toggleFolderMode: () => void; } function LibraryFolders({ folders, currentFolder, setFolder, toggleFolderMode }: LibraryTableProps) { const activeNode = useMemo(() => folders.at(currentFolder), [folders, currentFolder]); const items = useMemo(() => folders.getTree(), [folders]); 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 handleSetValue = useCallback( (event: CProps.EventMouse, target: FolderNode) => { event.preventDefault(); event.stopPropagation(); setFolder(target.getPath()); }, [setFolder] ); const handleClickFold = useCallback( (event: CProps.EventMouse, target: FolderNode, showChildren: boolean) => { event.preventDefault(); event.stopPropagation(); onFoldItem(target, showChildren); }, [onFoldItem] ); return (
} title='Переключение в режим Поиск' onClick={toggleFolderMode} />
{items.map((item, index) => !item.parent || !folded.includes(item.parent) ? ( 5 ? 5 : item.rank) * 0.5 + 0.5}rem` }} data-tooltip-id={globals.tooltip} data-tooltip-html={describeFolderNode(item)} onClick={event => handleSetValue(event, item)} initial={{ ...animateSideAppear.initial }} animate={{ ...animateSideAppear.animate }} exit={{ ...animateSideAppear.exit }} > {item.children.size > 0 ? ( ) : ( ) ) : ( ) } onClick={event => handleClickFold(event, item, folded.includes(item))} /> ) : (
{item.filesInside ? ( ) : ( )}
)}
{labelFolderNode(item)}
) : null )}
); } export default LibraryFolders;