Feature/make selection logic reusable (#515)

* Introduce "selectable collection" hook

* Extract "select all" button into component

* Make "SelectionFABActionItem" reusable

Was to tightly coupled to chapters

* Make "SelectionFAB" reusable

Was to tightly coupled to chapters
This commit is contained in:
schroda
2023-12-25 21:20:00 +01:00
committed by GitHub
parent c8747d6db4
commit c115fcd573
6 changed files with 219 additions and 139 deletions

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { Tooltip } from '@mui/material';
import Checkbox from '@mui/material/Checkbox';
import { useTranslation } from 'react-i18next';
export const SelectableCollectionSelectAll = ({
areAllItemsSelected,
areNoItemsSelected,
onChange,
}: {
areAllItemsSelected: boolean;
areNoItemsSelected: boolean;
onChange: (checked: boolean) => void;
}) => {
const { t } = useTranslation();
return (
<Tooltip title={t(!areAllItemsSelected ? 'global.button.select_all' : 'global.button.clear')}>
<Checkbox
sx={{ padding: '8px' }}
checked={areAllItemsSelected}
indeterminate={!areNoItemsSelected && !areAllItemsSelected}
onChange={(_, checked) => onChange(checked)}
/>
</Tooltip>
);
};

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { useState } from 'react';
export const useSelectableCollection = <Id extends number | string>(totalCount: number) => {
const [selectedItemIds, setSelectedItemIds] = useState<Id[]>([]);
const areAllItemsSelected = selectedItemIds.length === totalCount;
const areNoItemsSelected = !selectedItemIds.length;
const handleSelection = (id: Id, selected: boolean) => {
const deselect = !selected;
if (deselect) {
setSelectedItemIds(selectedItemIds.filter((selectedItemId) => selectedItemId !== id));
return;
}
setSelectedItemIds([...new Set([...selectedItemIds, id])]);
};
const handleSelectAll = (selectAll: boolean, itemIds: Id[]) => {
switch (selectAll) {
case true:
setSelectedItemIds([...itemIds]);
break;
case false:
setSelectedItemIds([]);
break;
default:
break;
}
};
return { selectedItemIds, handleSelection, handleSelectAll, areAllItemsSelected, areNoItemsSelected };
};