ConceptPortal-public/rsconcept/frontend/src/components/Common/CheckboxTristate.tsx

84 lines
2.0 KiB
TypeScript
Raw Normal View History

import clsx from 'clsx';
2023-09-07 16:30:43 +03:00
import { useMemo } from 'react';
2023-12-21 00:12:24 +03:00
import { globalIDs } from '@/utils/constants';
2023-09-10 20:17:18 +03:00
import { CheckboxCheckedIcon, CheckboxNullIcon } from '../Icons';
2023-09-07 16:30:43 +03:00
import { CheckboxProps } from './Checkbox';
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> {
2023-12-28 14:04:44 +03:00
value: boolean | null;
setValue?: (newValue: boolean | null) => void;
2023-09-07 16:30:43 +03:00
}
function CheckboxTristate({
id,
disabled,
label,
title,
className,
value,
setValue,
...restProps
}: CheckboxTristateProps) {
2023-12-28 14:04:44 +03:00
const cursor = useMemo(() => {
2023-09-07 16:30:43 +03:00
if (disabled) {
return 'cursor-not-allowed';
} else if (setValue) {
return 'cursor-pointer';
} else {
2023-12-28 14:04:44 +03:00
return '';
2023-09-07 16:30:43 +03:00
}
}, [disabled, setValue]);
2023-09-07 16:30:43 +03:00
function handleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
event.preventDefault();
if (disabled || !setValue) {
return;
}
if (value === false) {
2023-12-28 14:04:44 +03:00
setValue(null);
} else if (value === null) {
setValue(true);
2023-09-07 16:30:43 +03:00
} else {
setValue(false);
2023-09-07 16:30:43 +03:00
}
}
return (
2023-12-28 14:04:44 +03:00
<button
type='button'
id={id}
className={clsx('flex items-center gap-2 text-start', 'outline-none', cursor, className)}
disabled={disabled}
onClick={handleClick}
data-tooltip-id={title ? globalIDs.tooltip : undefined}
data-tooltip-content={title}
{...restProps}
>
<div
className={clsx('w-4 h-4', 'border rounded-sm', {
'clr-primary': value !== false,
'clr-app': value === false
})}
>
{value ? (
<div className='mt-[1px] ml-[1px]'>
<CheckboxCheckedIcon />
</div>
) : null}
{value == null ? (
<div className='mt-[1px] ml-[1px]'>
<CheckboxNullIcon />
</div>
) : null}
</div>
2023-12-30 19:43:24 +03:00
<label className={clsx('text-sm whitespace-nowrap', cursor)} htmlFor={id}>
{label}
</label>
2023-12-28 14:04:44 +03:00
</button>
);
2023-09-07 16:30:43 +03:00
}
export default CheckboxTristate;