feat(doclist): implement dynamic grid layout for icons view using CSS variables
Replace fixed Tailwind grid column classes with a responsive CSS grid that leverages tile width variables per icon size. Grid columns now adapt automatically via `auto-fit` and `minmax`, and grid gaps are centralized for consistency. This update enhances layout flexibility, maintainability, and responsiveness in the icons view.
This commit is contained in:
parent
53993aa3c6
commit
8104afa3e3
1 changed files with 29 additions and 8 deletions
|
|
@ -8,6 +8,7 @@ import type {
|
||||||
Folder,
|
Folder,
|
||||||
IconSize,
|
IconSize,
|
||||||
} from '@/types/documents';
|
} from '@/types/documents';
|
||||||
|
import { formatDocumentSize } from '@/components/doclist/formatSize';
|
||||||
import { Button } from '@headlessui/react';
|
import { Button } from '@headlessui/react';
|
||||||
import { DocumentTile } from './DocumentTile';
|
import { DocumentTile } from './DocumentTile';
|
||||||
import { FolderIcon } from '../window/finderIcons';
|
import { FolderIcon } from '../window/finderIcons';
|
||||||
|
|
@ -26,13 +27,27 @@ interface IconsViewProps {
|
||||||
onMergeIntoFolder: (sources: DocumentListDocument[], target: DocumentListDocument) => void;
|
onMergeIntoFolder: (sources: DocumentListDocument[], target: DocumentListDocument) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const COLS: Record<IconSize, string> = {
|
const TILE_WIDTH_PX: Record<IconSize, number> = {
|
||||||
sm: 'grid-cols-3 sm:grid-cols-5 md:grid-cols-7 lg:grid-cols-8',
|
sm: 112,
|
||||||
md: 'grid-cols-2 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6',
|
md: 136,
|
||||||
lg: 'grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5',
|
lg: 162,
|
||||||
xl: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4',
|
xl: 192,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function responsiveGridTemplate(iconSize: IconSize): string {
|
||||||
|
const width = TILE_WIDTH_PX[iconSize];
|
||||||
|
return `repeat(auto-fit, minmax(${width}px, 1fr))`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gridGap = '12px';
|
||||||
|
|
||||||
|
function gridStyle(iconSize: IconSize): React.CSSProperties {
|
||||||
|
return {
|
||||||
|
gridTemplateColumns: responsiveGridTemplate(iconSize),
|
||||||
|
gap: gridGap,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function FolderGridRow({
|
function FolderGridRow({
|
||||||
folder,
|
folder,
|
||||||
collapsed,
|
collapsed,
|
||||||
|
|
@ -84,7 +99,7 @@ function FolderGridRow({
|
||||||
<FolderIcon className="w-3.5 h-3.5 text-accent" />
|
<FolderIcon className="w-3.5 h-3.5 text-accent" />
|
||||||
{folder.name}
|
{folder.name}
|
||||||
<span className="text-[10px] font-normal text-muted ml-1">
|
<span className="text-[10px] font-normal text-muted ml-1">
|
||||||
{folder.documents.length} • {(totalSize / 1024 / 1024).toFixed(1)} MB
|
{folder.documents.length} • {formatDocumentSize(totalSize)}
|
||||||
</span>
|
</span>
|
||||||
<svg
|
<svg
|
||||||
className={`w-3 h-3 transition-transform ${collapsed ? '-rotate-90' : ''}`}
|
className={`w-3 h-3 transition-transform ${collapsed ? '-rotate-90' : ''}`}
|
||||||
|
|
@ -119,7 +134,10 @@ function FolderGridRow({
|
||||||
leaveFrom="opacity-100 max-h-[2000px]"
|
leaveFrom="opacity-100 max-h-[2000px]"
|
||||||
leaveTo="opacity-0 max-h-0"
|
leaveTo="opacity-0 max-h-0"
|
||||||
>
|
>
|
||||||
<div className={`grid gap-2 sm:gap-3 p-2 ${COLS[iconSize]}`}>
|
<div
|
||||||
|
className="grid p-2"
|
||||||
|
style={gridStyle(iconSize)}
|
||||||
|
>
|
||||||
{folder.documents.map((doc) => (
|
{folder.documents.map((doc) => (
|
||||||
<DocumentTile
|
<DocumentTile
|
||||||
key={`${doc.type}-${doc.id}`}
|
key={`${doc.type}-${doc.id}`}
|
||||||
|
|
@ -166,7 +184,10 @@ export function IconsView({
|
||||||
onClick={handleBackgroundClick}
|
onClick={handleBackgroundClick}
|
||||||
className="flex-1 min-h-0 overflow-y-auto p-3"
|
className="flex-1 min-h-0 overflow-y-auto p-3"
|
||||||
>
|
>
|
||||||
<div className={`grid gap-2 sm:gap-3 ${COLS[iconSize]}`}>
|
<div
|
||||||
|
className="grid"
|
||||||
|
style={gridStyle(iconSize)}
|
||||||
|
>
|
||||||
{folders.map((folder) => (
|
{folders.map((folder) => (
|
||||||
<FolderGridRow
|
<FolderGridRow
|
||||||
key={folder.id}
|
key={folder.id}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue