diff --git a/packages/interface/src/components/explorer/Explorer.tsx b/packages/interface/src/components/explorer/Explorer.tsx index b3f40e3c4..aa70d89cd 100644 --- a/packages/interface/src/components/explorer/Explorer.tsx +++ b/packages/interface/src/components/explorer/Explorer.tsx @@ -18,11 +18,11 @@ import { } from 'phosphor-react'; import React, { memo, useLayoutEffect, useMemo, useRef, useState } from 'react'; -import { FileList } from '../explorer/FileList'; import { Inspector } from '../explorer/Inspector'; import { WithContextMenu } from '../layout/MenuOverlay'; import { TopBar } from '../layout/TopBar'; import ExplorerContextMenu from './ExplorerContextMenu'; +import { VirtualizedList } from './VirtualizedList'; interface Props { data: ExplorerData; @@ -39,37 +39,31 @@ export default function Explorer(props: Props) { } }); - return ( -
- - - -
- ); -} - -const ExplorerContent = (props: Props) => { const { selectedRowIndex, showInspector } = useExplorerStore((store) => ({ selectedRowIndex: store.selectedRowIndex, showInspector: store.showInspector })); return ( -
- -
- - {showInspector && ( -
- {props.data.items[selectedRowIndex]?.id && ( - +
+ +
+ +
+ + {showInspector && ( +
+ {props.data.items[selectedRowIndex]?.id && ( + + )} +
)}
- )} -
+
+
); -}; +} diff --git a/packages/interface/src/components/explorer/FileList.tsx b/packages/interface/src/components/explorer/VirtualizedList.tsx similarity index 63% rename from packages/interface/src/components/explorer/FileList.tsx rename to packages/interface/src/components/explorer/VirtualizedList.tsx index cfd811f07..52acfea46 100644 --- a/packages/interface/src/components/explorer/FileList.tsx +++ b/packages/interface/src/components/explorer/VirtualizedList.tsx @@ -1,7 +1,7 @@ import { ExplorerLayoutMode, useExplorerStore } from '@sd/client'; import { ExplorerContext, ExplorerItem, FilePath } from '@sd/core'; import { useVirtualizer } from '@tanstack/react-virtual'; -import React, { memo, useCallback, useLayoutEffect, useRef, useState } from 'react'; +import React, { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; import { useKey, useWindowSize } from 'rooks'; @@ -16,17 +16,47 @@ interface Props { data: ExplorerItem[]; } -export const FileList: React.FC = (props) => { - // const size = useWindowSize(); - const [goingUp, setGoingUp] = useState(false); +export const VirtualizedList: React.FC = ({ data, context }) => { + const scrollRef = useRef(null); + const innerRef = useRef(null); - const { selectedRowIndex, layoutMode } = useExplorerStore((state) => ({ - selectedRowIndex: state.selectedRowIndex, - layoutMode: state.layoutMode - })); + const [goingUp, setGoingUp] = useState(false); + const [width, setWidth] = useState(0); + + const { gridItemSize, layoutMode, listItemSize, selectedRowIndex } = useExplorerStore( + (state) => ({ + selectedRowIndex: state.selectedRowIndex, + gridItemSize: state.gridItemSize, + layoutMode: state.layoutMode, + listItemSize: state.listItemSize + }) + ); const set = useExplorerStore.getState().set; + useLayoutEffect(() => { + setWidth(innerRef.current?.offsetWidth || 0); + }, []); + + const amountOfColumns = Math.floor(width / gridItemSize) || 8, + amountOfRows = layoutMode === 'grid' ? Math.ceil(data.length / amountOfColumns) : data.length, + itemSize = layoutMode === 'grid' ? gridItemSize + 25 : listItemSize; + + const rowVirtualizer = useVirtualizer({ + count: amountOfRows, + getScrollElement: () => scrollRef.current, + overscan: 500, + estimateSize: () => itemSize, + measureElement: (index) => itemSize + }); + + // useEffect(() => { + // if (selectedRowIndex === 0 && goingUp) rowVirtualizer.scrollToIndex(0); + + // if (selectedRowIndex !== -1) + // rowVirtualizer.scrollToIndex(goingUp ? selectedRowIndex - 1 : selectedRowIndex); + // }, [goingUp, selectedRowIndex, rowVirtualizer]); + useKey('ArrowUp', (e) => { e.preventDefault(); setGoingUp(true); @@ -37,7 +67,7 @@ export const FileList: React.FC = (props) => { useKey('ArrowDown', (e) => { e.preventDefault(); setGoingUp(false); - if (selectedRowIndex !== -1 && selectedRowIndex !== (props.data.length ?? 1) - 1) + if (selectedRowIndex !== -1 && selectedRowIndex !== (data.length ?? 1) - 1) set({ selectedRowIndex: selectedRowIndex + 1 }); }); @@ -65,94 +95,58 @@ export const FileList: React.FC = (props) => { return (
- -
- ); -}; - -function Virtualizer({ items }: { items: ExplorerItem[] }) { - const parentRef = useRef(null); - const innerRef = useRef(null); - - const { gridItemSize, layoutMode, listItemSize, selectedRowIndex } = useExplorerStore( - (state) => ({ - selectedRowIndex: state.selectedRowIndex, - gridItemSize: state.gridItemSize, - layoutMode: state.layoutMode, - listItemSize: state.listItemSize - }) - ); - - const [width, setWidth] = useState(0); - - useLayoutEffect(() => { - setWidth(innerRef.current?.offsetWidth || 0); - }, []); - - const amountOfColumns = Math.floor(width / gridItemSize) || 8, - amountOfRows = layoutMode === 'grid' ? Math.ceil(items.length / amountOfColumns) : items.length, - itemSize = layoutMode === 'grid' ? gridItemSize + 25 : listItemSize; - - const rowVirtualizer = useVirtualizer({ - count: amountOfRows, - getScrollElement: () => parentRef.current, - overscan: 500, - estimateSize: () => itemSize, - measureElement: (index) => itemSize - }); - - return ( -
-
- {rowVirtualizer.getVirtualItems().map((virtualRow) => ( -
- {layoutMode === 'list' ? ( - - ) : ( - [...Array(amountOfColumns)].map((_, i) => { - const index = virtualRow.index * amountOfColumns + i; - const item = items[index]; - return ( -
-
- {item && ( - - )} +
+
+ {rowVirtualizer.getVirtualItems().map((virtualRow) => ( +
+ {layoutMode === 'list' ? ( + + ) : ( + [...Array(amountOfColumns)].map((_, i) => { + const index = virtualRow.index * amountOfColumns + i; + const item = data[index]; + return ( +
+
+ {item && ( + + )} +
-
- ); - }) - )} -
- ))} + ); + }) + )} +
+ ))} +
); -} +}; interface WrappedItemProps { item: ExplorerItem; @@ -176,23 +170,22 @@ const WrappedItem: React.FC = memo(({ item, index, isSelected, if (kind === 'list') { return ( ); } return ( ); }); diff --git a/packages/interface/src/components/layout/Sidebar.tsx b/packages/interface/src/components/layout/Sidebar.tsx index e2fbcbed9..dcc64fbb3 100644 --- a/packages/interface/src/components/layout/Sidebar.tsx +++ b/packages/interface/src/components/layout/Sidebar.tsx @@ -1,5 +1,5 @@ -import { LockClosedIcon, PhotoIcon } from '@heroicons/react/24/outline'; -import { CogIcon, PlusIcon } from '@heroicons/react/24/solid'; +import { CogIcon, LockClosedIcon, PhotoIcon } from '@heroicons/react/24/outline'; +import { PlusIcon } from '@heroicons/react/24/solid'; import { AppPropsContext, useCurrentLibrary,