feat: Add an icon size slider component and implement dynamic icon sizing for document views, while refactoring the documents panel layout.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
|
||||
interface IconSizeSliderProps {
|
||||
scale: number;
|
||||
onChange: (scale: number) => void;
|
||||
min?: number;
|
||||
max?: number;
|
||||
}
|
||||
|
||||
const IconSizeSlider: React.FC<IconSizeSliderProps> = ({
|
||||
scale,
|
||||
onChange,
|
||||
min = 0.5,
|
||||
max = 2,
|
||||
}) => {
|
||||
return (
|
||||
<div className="icon-size-slider">
|
||||
<input
|
||||
type="range"
|
||||
className="icon-size-slider__input"
|
||||
min={min}
|
||||
max={max}
|
||||
step="any"
|
||||
value={scale}
|
||||
onChange={(e) => onChange(parseFloat(e.target.value))}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default IconSizeSlider;
|
||||
@@ -1,4 +1,10 @@
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import React, {
|
||||
useCallback,
|
||||
useMemo,
|
||||
useState,
|
||||
useRef,
|
||||
useEffect,
|
||||
} from 'react';
|
||||
import { DocumentsList, DocumentsGrid } from '../DocumentsView';
|
||||
import type { DragEvent, ReactNode, RefObject } from 'react';
|
||||
import type {
|
||||
@@ -162,7 +168,6 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
const showingSearchResults = Array.isArray(searchResultIds);
|
||||
const rows = showingSearchResults && searchDocuments ? searchDocuments : documents;
|
||||
|
||||
const searchResultCount = Array.isArray(searchResultIds) ? searchResultIds.length : 0;
|
||||
|
||||
const viewId = useMemo(() => {
|
||||
if (showingSearchResults) {
|
||||
@@ -185,9 +190,7 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
const headerTitle = showingSearchResults
|
||||
? 'Search results'
|
||||
: currentFolderName || 'Documents';
|
||||
const headerSubtitle = showingSearchResults
|
||||
? `${searchResultCount} matching document${searchResultCount === 1 ? '' : 's'}`
|
||||
: null;
|
||||
const headerSubtitle = null;
|
||||
const headerActions = useMemo(
|
||||
() => createDocumentsTableHeaderActions({
|
||||
viewMode,
|
||||
@@ -320,7 +323,6 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
const suppressDocumentClickRef = useRef(false);
|
||||
const isGridView = viewMode === 'grid';
|
||||
const isDeskView = viewMode === 'desk';
|
||||
const gridIconSize = DEFAULT_GRID_ICON_SIZE;
|
||||
|
||||
const { openPreview } = usePreviewContext();
|
||||
|
||||
@@ -472,6 +474,13 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
onEntryPointer,
|
||||
};
|
||||
|
||||
const [iconSizes] = useState({
|
||||
list: DEFAULT_LIST_ICON_SIZE,
|
||||
grid: DEFAULT_GRID_ICON_SIZE,
|
||||
desk: DEFAULT_DESKTOP_CARD_SIZE,
|
||||
});
|
||||
|
||||
|
||||
const renderBody = () => {
|
||||
const hasEntries = entries.length > 0;
|
||||
const isSearchEmpty = (showingSearchResults || isFilterActive) && !hasDocumentEntries && !isSearchLoading;
|
||||
@@ -494,12 +503,12 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
|
||||
switch (viewMode) {
|
||||
case 'desk':
|
||||
return <DesktopWorkspace {...viewProps} defaultCardSize={DEFAULT_DESKTOP_CARD_SIZE} />;
|
||||
return <DesktopWorkspace {...viewProps} defaultCardSize={iconSizes.desk} />;
|
||||
case 'grid':
|
||||
return <DocumentsGrid {...viewProps} iconSize={gridIconSize} />;
|
||||
return <DocumentsGrid {...viewProps} iconSize={iconSizes.grid} />;
|
||||
case 'list':
|
||||
default:
|
||||
return <DocumentsList {...viewProps} iconSize={DEFAULT_LIST_ICON_SIZE} />;
|
||||
return <DocumentsList {...viewProps} iconSize={iconSizes.list} />;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -519,13 +528,15 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
header={headerConfig}
|
||||
onBreadcrumbClick={onBreadcrumbNavigate}
|
||||
/>
|
||||
<section
|
||||
ref={scrollRef}
|
||||
className={`documents-panel documents-panel--view-${panelVariant}`}
|
||||
onClick={handleSectionClick}
|
||||
>
|
||||
{renderBody()}
|
||||
</section>
|
||||
<div className="documents-panel-wrapper">
|
||||
<section
|
||||
ref={scrollRef}
|
||||
className={`documents-panel documents-panel--view-${panelVariant}`}
|
||||
onClick={handleSectionClick}
|
||||
>
|
||||
{renderBody()}
|
||||
</section>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -805,4 +805,12 @@
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.documents-panel-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
}
|
||||
Reference in New Issue
Block a user