From bff550885232ba15407c682425e79677445f95d6 Mon Sep 17 00:00:00 2001 From: Cats Juice Date: Thu, 7 Nov 2024 12:03:45 +0800 Subject: [PATCH] refactor(mobile): impl all-docs masonry with css grid, close AF-1598 --- .../mobile/views/all-docs/doc/masonry.css.ts | 36 ++++++---------- .../src/mobile/views/all-docs/doc/masonry.tsx | 42 +++++++++++-------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/packages/frontend/core/src/mobile/views/all-docs/doc/masonry.css.ts b/packages/frontend/core/src/mobile/views/all-docs/doc/masonry.css.ts index 52222b115082f..c1e5b2f46b3a0 100644 --- a/packages/frontend/core/src/mobile/views/all-docs/doc/masonry.css.ts +++ b/packages/frontend/core/src/mobile/views/all-docs/doc/masonry.css.ts @@ -1,28 +1,16 @@ import { style } from '@vanilla-extract/css'; -export const invisibleWrapper = style({ - position: 'absolute', - padding: 'inherit', - width: '100%', - height: 0, - overflow: 'hidden', - visibility: 'hidden', - pointerEvents: 'none', -}); -export const invisibleList = style({ - width: `calc(50% - 17px / 2)`, -}); -export const stacks = style({ - position: 'relative', - width: '100%', - display: 'flex', - gap: 17, - padding: 16, +export const paddingX = 16; +export const columnGap = 17; + +export const masonry = style({ + padding: `16px ${paddingX}px`, + columnGap: columnGap, }); -export const stack = style({ - width: 0, - flex: 1, - display: 'flex', - flexDirection: 'column', - gap: 10, +export const masonryItem = style({ + display: 'grid', + gridTemplateRows: '1fr auto', + breakInside: 'avoid', + marginBottom: 10, }); +export const space = style({ width: '100%', height: 16 }); diff --git a/packages/frontend/core/src/mobile/views/all-docs/doc/masonry.tsx b/packages/frontend/core/src/mobile/views/all-docs/doc/masonry.tsx index 254cfca0bbe5b..52faa91242ac1 100644 --- a/packages/frontend/core/src/mobile/views/all-docs/doc/masonry.tsx +++ b/packages/frontend/core/src/mobile/views/all-docs/doc/masonry.tsx @@ -1,10 +1,10 @@ +import { useGlobalEvent } from '@affine/core/mobile/hooks/use-global-events'; import type { DocMeta } from '@blocksuite/affine/store'; -import { useMemo } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { DocCard } from '../../../components'; import * as styles from './masonry.css'; -// TODO(@CatsJuice): Large amount docs performance export const MasonryDocs = ({ items, showTags, @@ -12,25 +12,31 @@ export const MasonryDocs = ({ items: DocMeta[]; showTags?: boolean; }) => { - // card preview is loaded lazily, it's meaningless to calculate height - const stacks = useMemo(() => { - return items.reduce( - (acc, item, i) => { - acc[i % 2].push(item); - return acc; - }, - [[], []] as [DocMeta[], DocMeta[]] + const [columnCount, setColumnCount] = useState(2); + + const updateColumnCount = useCallback(() => { + const maxCardWidth = 220; + const windowWidth = window.innerWidth; + const newColumnCount = Math.floor( + (windowWidth - styles.paddingX * 2 - styles.columnGap) / maxCardWidth ); - }, [items]); + setColumnCount(Math.max(newColumnCount, 2)); + }, []); + + useGlobalEvent('resize', updateColumnCount); + useEffect(() => { + updateColumnCount(); + }, [updateColumnCount]); return ( -
- {stacks.map((stack, i) => ( - +
+ {items.map(item => ( + ))}
);