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 { DocumentsList, DocumentsGrid } from '../DocumentsView';
|
||||||
import type { DragEvent, ReactNode, RefObject } from 'react';
|
import type { DragEvent, ReactNode, RefObject } from 'react';
|
||||||
import type {
|
import type {
|
||||||
@@ -162,7 +168,6 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
|||||||
const showingSearchResults = Array.isArray(searchResultIds);
|
const showingSearchResults = Array.isArray(searchResultIds);
|
||||||
const rows = showingSearchResults && searchDocuments ? searchDocuments : documents;
|
const rows = showingSearchResults && searchDocuments ? searchDocuments : documents;
|
||||||
|
|
||||||
const searchResultCount = Array.isArray(searchResultIds) ? searchResultIds.length : 0;
|
|
||||||
|
|
||||||
const viewId = useMemo(() => {
|
const viewId = useMemo(() => {
|
||||||
if (showingSearchResults) {
|
if (showingSearchResults) {
|
||||||
@@ -185,9 +190,7 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
|||||||
const headerTitle = showingSearchResults
|
const headerTitle = showingSearchResults
|
||||||
? 'Search results'
|
? 'Search results'
|
||||||
: currentFolderName || 'Documents';
|
: currentFolderName || 'Documents';
|
||||||
const headerSubtitle = showingSearchResults
|
const headerSubtitle = null;
|
||||||
? `${searchResultCount} matching document${searchResultCount === 1 ? '' : 's'}`
|
|
||||||
: null;
|
|
||||||
const headerActions = useMemo(
|
const headerActions = useMemo(
|
||||||
() => createDocumentsTableHeaderActions({
|
() => createDocumentsTableHeaderActions({
|
||||||
viewMode,
|
viewMode,
|
||||||
@@ -320,7 +323,6 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
|||||||
const suppressDocumentClickRef = useRef(false);
|
const suppressDocumentClickRef = useRef(false);
|
||||||
const isGridView = viewMode === 'grid';
|
const isGridView = viewMode === 'grid';
|
||||||
const isDeskView = viewMode === 'desk';
|
const isDeskView = viewMode === 'desk';
|
||||||
const gridIconSize = DEFAULT_GRID_ICON_SIZE;
|
|
||||||
|
|
||||||
const { openPreview } = usePreviewContext();
|
const { openPreview } = usePreviewContext();
|
||||||
|
|
||||||
@@ -472,6 +474,13 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
|||||||
onEntryPointer,
|
onEntryPointer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [iconSizes] = useState({
|
||||||
|
list: DEFAULT_LIST_ICON_SIZE,
|
||||||
|
grid: DEFAULT_GRID_ICON_SIZE,
|
||||||
|
desk: DEFAULT_DESKTOP_CARD_SIZE,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
const renderBody = () => {
|
const renderBody = () => {
|
||||||
const hasEntries = entries.length > 0;
|
const hasEntries = entries.length > 0;
|
||||||
const isSearchEmpty = (showingSearchResults || isFilterActive) && !hasDocumentEntries && !isSearchLoading;
|
const isSearchEmpty = (showingSearchResults || isFilterActive) && !hasDocumentEntries && !isSearchLoading;
|
||||||
@@ -494,12 +503,12 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
|||||||
|
|
||||||
switch (viewMode) {
|
switch (viewMode) {
|
||||||
case 'desk':
|
case 'desk':
|
||||||
return <DesktopWorkspace {...viewProps} defaultCardSize={DEFAULT_DESKTOP_CARD_SIZE} />;
|
return <DesktopWorkspace {...viewProps} defaultCardSize={iconSizes.desk} />;
|
||||||
case 'grid':
|
case 'grid':
|
||||||
return <DocumentsGrid {...viewProps} iconSize={gridIconSize} />;
|
return <DocumentsGrid {...viewProps} iconSize={iconSizes.grid} />;
|
||||||
case 'list':
|
case 'list':
|
||||||
default:
|
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}
|
header={headerConfig}
|
||||||
onBreadcrumbClick={onBreadcrumbNavigate}
|
onBreadcrumbClick={onBreadcrumbNavigate}
|
||||||
/>
|
/>
|
||||||
<section
|
<div className="documents-panel-wrapper">
|
||||||
ref={scrollRef}
|
<section
|
||||||
className={`documents-panel documents-panel--view-${panelVariant}`}
|
ref={scrollRef}
|
||||||
onClick={handleSectionClick}
|
className={`documents-panel documents-panel--view-${panelVariant}`}
|
||||||
>
|
onClick={handleSectionClick}
|
||||||
{renderBody()}
|
>
|
||||||
</section>
|
{renderBody()}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -806,3 +806,11 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--muted);
|
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