fix(core): select all in page list group header does not need to enable selection (#4869)

This commit is contained in:
Peng Xiao
2023-11-09 20:01:36 +08:00
committed by GitHub
parent 839f500979
commit d0b014543c
5 changed files with 153 additions and 21 deletions

View File

@@ -3,6 +3,7 @@ import * as Toolbar from '@radix-ui/react-toolbar';
import clsx from 'clsx';
import {
type CSSProperties,
type HTMLAttributes,
type MouseEventHandler,
type PropsWithChildren,
type ReactNode,
@@ -16,13 +17,11 @@ interface FloatingToolbarProps {
open?: boolean;
}
interface FloatingToolbarButtonProps {
interface FloatingToolbarButtonProps extends HTMLAttributes<HTMLButtonElement> {
icon: ReactNode;
onClick: MouseEventHandler;
type?: 'danger' | 'default';
label?: ReactNode;
className?: string;
style?: CSSProperties;
}
interface FloatingToolbarItemProps {}
@@ -40,7 +39,12 @@ export function FloatingToolbar({
<Popover.Portal>
{/* always pop up on top for now */}
<Popover.Content side="top" className={styles.popoverContent}>
<Toolbar.Root className={clsx(styles.root)}>{children}</Toolbar.Root>
<Toolbar.Root
data-testid="floating-toolbar"
className={clsx(styles.root)}
>
{children}
</Toolbar.Root>
</Popover.Content>
</Popover.Portal>
</Popover.Root>
@@ -62,6 +66,7 @@ export function FloatingToolbarButton({
className,
style,
label,
...props
}: FloatingToolbarButtonProps) {
return (
<Toolbar.Button
@@ -72,6 +77,7 @@ export function FloatingToolbarButton({
className
)}
style={style}
{...props}
>
<div className={styles.buttonIcon}>{icon}</div>
{label}

View File

@@ -119,19 +119,18 @@ export const PageGroupHeader = ({ id, items, label }: PageGroupProps) => {
[id, setCollapseState]
);
const selectionState = useAtomValue(selectionStateAtom);
const [selectionState, setSelectionActive] = useAtom(selectionStateAtom);
const selectedItems = useMemo(() => {
const selectedPageIds = selectionState.selectedPageIds ?? [];
return items.filter(item => selectedPageIds.includes(item.id));
}, [items, selectionState.selectedPageIds]);
const allSelected = useMemo(() => {
return items.every(
item => selectionState.selectedPageIds?.includes(item.id)
);
}, [items, selectionState.selectedPageIds]);
const allSelected = selectedItems.length === items.length;
const onSelectAll = useCallback(() => {
// also enable selection active
setSelectionActive(true);
const nonCurrentGroupIds =
selectionState.selectedPageIds?.filter(
id => !items.map(item => item.id).includes(id)
@@ -142,12 +141,18 @@ export const PageGroupHeader = ({ id, items, label }: PageGroupProps) => {
: [...nonCurrentGroupIds, ...items.map(item => item.id)];
selectionState.onSelectedPageIdsChange?.(newSelectedPageIds);
}, [items, selectionState, allSelected]);
}, [setSelectionActive, selectionState, allSelected, items]);
const t = useAFFiNEI18N();
return label ? (
<div data-testid="page-list-group-header" className={styles.header}>
<div
data-testid="page-list-group-header"
className={styles.header}
data-group-id={id}
data-group-items-count={items.length}
data-group-selected-items-count={selectedItems.length}
>
<div
role="button"
onClick={onExpandedClicked}
@@ -166,15 +171,13 @@ export const PageGroupHeader = ({ id, items, label }: PageGroupProps) => {
</div>
) : null}
<div className={styles.spacer} />
{selectionState.selectionActive ? (
<button className={styles.selectAllButton} onClick={onSelectAll}>
{t[
allSelected
? 'com.affine.page.group-header.clear'
: 'com.affine.page.group-header.select-all'
]()}
</button>
) : null}
<button className={styles.selectAllButton} onClick={onSelectAll}>
{t[
allSelected
? 'com.affine.page.group-header.clear'
: 'com.affine.page.group-header.select-all'
]()}
</button>
</div>
) : null;
};

View File

@@ -101,6 +101,7 @@ const PageListHeaderCheckbox = () => {
return (
<div
data-testid="page-list-header-selection-checkbox"
className={styles.headerTitleSelectionIconWrapper}
onClick={onActivateSelection}
>