Files
suwayomi-material-you-webui/src/base/components/buttons/ValueRotationButton.tsx
2026-06-02 13:41:17 +02:00

109 lines
3.8 KiB
TypeScript

/*
* 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 type { ReactNode } from 'react';
import { useMemo } from 'react';
import Button from '@mui/material/Button';
import { useLingui } from '@lingui/react/macro';
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
import { getNextRotationValue } from '@/base/utils/ValueRotationButton.utils.ts';
import { Superscript } from '@/base/components/texts/Superscript.tsx';
import type { ValueToDisplayData } from '@/base/Base.types.ts';
export interface ValueRotationButtonBaseProps<Value extends string | number> {
tooltip?: string;
value: Value;
defaultValue?: Value;
values: Value[];
setValue: (value: Value) => void;
valueToDisplayData: ValueToDisplayData<Value>;
}
export interface ValueRotationButtonDefaultableProps<Value extends string | number> extends OptionalProperty<
ValueRotationButtonBaseProps<Value>,
'value'
> {
isDefaultable?: boolean;
onDefault?: () => void;
}
export type ValueRotationButtonProps<Value extends string | number> =
| (ValueRotationButtonBaseProps<Value> & PropertiesNever<ValueRotationButtonDefaultableProps<Value>>)
| ValueRotationButtonDefaultableProps<Value>;
export const ValueRotationButton = <Value extends string | number>({
tooltip,
value,
defaultValue,
values,
setValue,
valueToDisplayData,
isDefaultable,
onDefault,
defaultIcon,
}: ValueRotationButtonProps<Value> & { defaultIcon?: ReactNode }) => {
const { t } = useLingui();
const isDefault = value === undefined;
const indexOfValue = useMemo(() => {
if (isDefault) {
return -1;
}
return values.indexOf(value);
}, [value, values]);
return (
<CustomTooltip title={tooltip}>
{isDefault ? (
<Button
onClick={() => setValue(values[0])}
sx={{ justifyContent: 'start', textTransform: 'unset', flexGrow: 1 }}
variant="contained"
startIcon={defaultIcon}
size="large"
>
{defaultValue === undefined ? (
t`Default`
) : (
<Superscript
superscript={`(${t`Default`})`}
text={
typeof valueToDisplayData[defaultValue].title === 'string'
? valueToDisplayData[defaultValue].title
: t(valueToDisplayData[defaultValue].title)
}
/>
)}
</Button>
) : (
<Button
onClick={() => {
const nextValue = getNextRotationValue(indexOfValue, values, isDefaultable);
if (nextValue === undefined) {
onDefault?.();
return;
}
setValue(nextValue);
}}
sx={{ justifyContent: 'start', textTransform: 'unset', flexGrow: 1 }}
variant="contained"
startIcon={valueToDisplayData[value].icon}
size="large"
>
{typeof valueToDisplayData[value].title === 'string'
? valueToDisplayData[value].title
: t(valueToDisplayData[value].title)}
</Button>
)}
</CustomTooltip>
);
};