mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-24 05:07:06 +08:00
feat(core): new all docs list ui (#12102)
### New all docs list ui close AF-2531, AF-2585, AF-2586, AF-2580 ### What changed - a new `display-menu` component - properties visibility - quick actions visibility - extend DocPropertyType definition - `showInDocList`: configure whether to show in doc and how to show (stack | inline) - `docListProperty`: define how to render property in doc - `groupHeader`: define how to render group header when grouped - implement all properties's `docListProperty` renderer and `groupHeader` renderer - new `docs-view` component - render doc in `card` | `list` view - split doc card into minimal components for reuse in list and card views, as well as visibility control - implement docs-list with `<Masonry />` and multi-view support - for list view, make masonry column count always `1` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Redesigned document explorer with multiple view modes (list, grid, masonry), grouping, selection, and multi-delete. - Added customizable display properties and quick actions (favorite, trash, split view, new tab, select) for documents. - Introduced new group header and document item components with improved styling and interaction. - Enabled dynamic rendering of document properties including tags, dates, users, templates, and themes. - Added filtering support for trash status and enhanced localization for UI elements. - Introduced drag handle size customization and expanded masonry layout configurability. - Added contextual "More" menu with document operations like favorite, info, duplicate, and trash. - Implemented shared context for explorer state management and multi-selection logic. - **Enhancements** - Improved virtual scrolling with active item tracking and configurable preload and debounce settings. - Responsive, theme-aware styling applied across explorer and property components. - Configurable UI elements and quick actions via user preferences. - Enhanced error messages for unsupported property types in filters. - Refined padding and layout calculations in masonry component for better visual consistency. - Avatar and date components refactored for explicit prop-driven rendering and customization. - **Bug Fixes** - Improved error messages for unsupported property types in filters. - **Documentation** - Added new localization keys and updated language completeness for new features. - **Chores** - Modularized workspace property types with list and group header display components. - Consolidated imports and enhanced code maintainability. - Added new CSS styling modules for explorer components and workspace property types. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,13 +1,22 @@
|
||||
import type { MasonryGroup, MasonryItem, MasonryItemXYWH } from './type';
|
||||
import type {
|
||||
MasonryGroup,
|
||||
MasonryItem,
|
||||
MasonryItemXYWH,
|
||||
MasonryPX,
|
||||
} from './type';
|
||||
|
||||
export const calcPX = (px: MasonryPX, totalWidth: number) =>
|
||||
typeof px === 'number' ? px : px(totalWidth);
|
||||
|
||||
export const calcColumns = (
|
||||
totalWidth: number,
|
||||
itemWidth: number | 'stretch',
|
||||
itemWidthMin: number,
|
||||
gapX: number,
|
||||
paddingX: number,
|
||||
_paddingX: MasonryPX,
|
||||
columns?: number
|
||||
) => {
|
||||
const paddingX = calcPX(_paddingX, totalWidth);
|
||||
const availableWidth = totalWidth - paddingX * 2;
|
||||
|
||||
if (columns) {
|
||||
@@ -47,7 +56,7 @@ export const calcLayout = (
|
||||
width: number;
|
||||
gapX: number;
|
||||
gapY: number;
|
||||
paddingX: number;
|
||||
paddingX: MasonryPX;
|
||||
paddingY: number;
|
||||
groupsGap: number;
|
||||
groupHeaderGapWithItems: number;
|
||||
@@ -60,12 +69,13 @@ export const calcLayout = (
|
||||
width,
|
||||
gapX,
|
||||
gapY,
|
||||
paddingX,
|
||||
paddingX: _paddingX,
|
||||
paddingY,
|
||||
groupsGap,
|
||||
groupHeaderGapWithItems,
|
||||
collapsedGroups,
|
||||
} = options;
|
||||
const paddingX = calcPX(_paddingX, totalWidth);
|
||||
|
||||
const layout = new Map<string, MasonryItemXYWH>();
|
||||
let finalHeight = paddingY;
|
||||
@@ -79,9 +89,9 @@ export const calcLayout = (
|
||||
// calculate group header
|
||||
const groupHeaderLayout: MasonryItemXYWH = {
|
||||
type: 'group',
|
||||
x: paddingX,
|
||||
x: 0,
|
||||
y: finalHeight,
|
||||
w: totalWidth - paddingX * 2,
|
||||
w: totalWidth,
|
||||
h: group.height,
|
||||
};
|
||||
layout.set(group.id, groupHeaderLayout);
|
||||
@@ -97,10 +107,11 @@ export const calcLayout = (
|
||||
const itemId = group.id ? `${group.id}:${item.id}` : item.id;
|
||||
const minHeight = Math.min(...heightStack);
|
||||
const minHeightIndex = heightStack.indexOf(minHeight);
|
||||
const hasGap = heightStack[minHeightIndex] ? gapY : 0;
|
||||
const x = minHeightIndex * (width + gapX) + paddingX;
|
||||
const y = minHeight + finalHeight;
|
||||
const y = finalHeight + minHeight + hasGap;
|
||||
|
||||
heightStack[minHeightIndex] += item.height + gapY;
|
||||
heightStack[minHeightIndex] += item.height + hasGap;
|
||||
layout.set(itemId, {
|
||||
type: 'item',
|
||||
x,
|
||||
@@ -117,7 +128,7 @@ export const calcLayout = (
|
||||
return { layout, height: finalHeight };
|
||||
};
|
||||
|
||||
export const calcSleep = (options: {
|
||||
export const calcActive = (options: {
|
||||
viewportHeight: number;
|
||||
scrollY: number;
|
||||
layoutMap: Map<MasonryItem['id'], MasonryItemXYWH>;
|
||||
@@ -125,7 +136,7 @@ export const calcSleep = (options: {
|
||||
}) => {
|
||||
const { viewportHeight, scrollY, layoutMap, preloadHeight } = options;
|
||||
|
||||
const sleepMap = new Map<MasonryItem['id'], boolean>();
|
||||
const activeMap = new Map<MasonryItem['id'], boolean>();
|
||||
|
||||
layoutMap.forEach((layout, id) => {
|
||||
const { y, h } = layout;
|
||||
@@ -134,10 +145,12 @@ export const calcSleep = (options: {
|
||||
y + h + preloadHeight > scrollY &&
|
||||
y - preloadHeight < scrollY + viewportHeight;
|
||||
|
||||
sleepMap.set(id, !isInView);
|
||||
if (isInView) {
|
||||
activeMap.set(id, true);
|
||||
}
|
||||
});
|
||||
|
||||
return sleepMap;
|
||||
return activeMap;
|
||||
};
|
||||
|
||||
export const calcSticky = (options: {
|
||||
|
||||
Reference in New Issue
Block a user