Files
suwayomi-material-you-webui/src/components/manga/MangaOptionButton.tsx
T

127 lines
4.3 KiB
TypeScript
Raw Normal View History

2023-12-25 21:37:45 +01:00
/*
* 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 { useTranslation } from 'react-i18next';
2024-04-07 15:21:25 +02:00
import { BaseSyntheticEvent, MouseEvent, TouchEvent, ChangeEvent, useMemo, forwardRef, ForwardedRef } from 'react';
2024-04-14 15:50:12 +02:00
import Button from '@mui/material/Button';
import Tooltip from '@mui/material/Tooltip';
2023-12-25 21:37:45 +01:00
import Checkbox from '@mui/material/Checkbox';
import IconButton from '@mui/material/IconButton';
import MoreVertIcon from '@mui/icons-material/MoreVert';
2024-03-31 23:34:40 +02:00
import { PopupState } from 'material-ui-popup-state/hooks';
2023-12-25 21:37:45 +01:00
import { bindTrigger } from 'material-ui-popup-state';
import { SelectableCollectionReturnType } from '@/components/collection/useSelectableCollection.ts';
2024-05-23 02:29:08 +02:00
import { MediaQuery } from '@/lib/ui/MediaQuery.tsx';
2024-07-08 18:02:50 +02:00
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
2023-12-25 21:37:45 +01:00
2024-04-07 15:21:25 +02:00
export const MangaOptionButton = forwardRef(
(
{
id,
selected,
handleSelection,
asCheckbox = false,
popupState,
}: {
id: number;
selected?: boolean | null;
2024-07-08 18:02:50 +02:00
handleSelection?: SelectableCollectionReturnType<MangaType['id']>['handleSelection'];
2024-04-07 15:21:25 +02:00
asCheckbox?: boolean;
popupState: PopupState;
},
ref: ForwardedRef<HTMLButtonElement | null>,
) => {
const { t } = useTranslation();
2023-12-25 21:37:45 +01:00
2024-05-23 02:29:08 +02:00
const isTouchDevice = MediaQuery.useIsTouchDevice();
2024-04-07 15:21:25 +02:00
const bindTriggerProps = useMemo(() => bindTrigger(popupState), [popupState]);
2023-12-25 21:37:45 +01:00
2024-04-07 15:21:25 +02:00
const preventDefaultAction = (e: BaseSyntheticEvent) => {
e.stopPropagation();
e.preventDefault();
};
2023-12-25 21:37:45 +01:00
2024-04-07 15:21:25 +02:00
const handleSelectionChange = (e: ChangeEvent, isSelected: boolean) => {
preventDefaultAction(e);
handleSelection?.(id, isSelected);
};
2023-12-25 21:37:45 +01:00
2024-04-07 15:21:25 +02:00
const handleClick = (e: MouseEvent | TouchEvent) => {
2024-05-23 02:29:08 +02:00
if (isTouchDevice) return;
2023-12-25 21:37:45 +01:00
2024-04-07 15:21:25 +02:00
preventDefaultAction(e);
popupState.open(e);
bindTriggerProps.onClick(e as any);
};
2023-12-25 21:37:45 +01:00
2024-04-07 15:21:25 +02:00
if (!handleSelection) {
2023-12-25 21:37:45 +01:00
return null;
}
2024-04-07 15:21:25 +02:00
const isSelected = selected !== null;
if (isSelected) {
if (!asCheckbox) {
return null;
}
return (
<Tooltip title={t(selected ? 'global.button.deselect' : 'global.button.select')}>
<Checkbox checked={selected} onMouseDown={preventDefaultAction} onChange={handleSelectionChange} />
</Tooltip>
);
}
if (asCheckbox) {
return (
<Tooltip title={t('global.button.options')}>
<IconButton
ref={ref}
2024-04-07 15:21:25 +02:00
{...bindTriggerProps}
onClick={handleClick}
onTouchStart={handleClick}
aria-label="more"
size="large"
onMouseDown={preventDefaultAction}
>
<MoreVertIcon />
</IconButton>
</Tooltip>
);
}
2023-12-25 21:37:45 +01:00
return (
<Tooltip title={t('global.button.options')}>
2024-04-07 15:21:25 +02:00
<Button
ref={ref}
2023-12-25 21:37:45 +01:00
{...bindTriggerProps}
onClick={handleClick}
2024-04-07 15:21:25 +02:00
onTouchStart={handleClick}
className="manga-option-button"
size="small"
variant="contained"
sx={{
minWidth: 'unset',
paddingX: '0',
paddingY: '2.5px',
2024-05-23 02:29:08 +02:00
visibility: popupState.isOpen ? 'visible' : 'hidden',
pointerEvents: 'none',
'@media not (pointer: fine)': {
visibility: 'hidden',
pointerEvents: undefined,
},
2024-04-07 15:21:25 +02:00
}}
onMouseDown={(e) => e.stopPropagation()}
2023-12-25 21:37:45 +01:00
>
<MoreVertIcon />
2024-04-07 15:21:25 +02:00
</Button>
2023-12-25 21:37:45 +01:00
</Tooltip>
);
2024-04-07 15:21:25 +02:00
},
);