2023-09-07 16:30:43 +03:00
|
|
|
|
2023-12-15 17:34:50 +03:00
|
|
|
import clsx from 'clsx';
|
2023-09-07 16:30:43 +03:00
|
|
|
import { useMemo } from 'react';
|
|
|
|
|
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';
|
|
|
|
import Label from './Label';
|
|
|
|
|
|
|
|
export interface TristateProps
|
|
|
|
extends Omit<CheckboxProps, 'value' | 'setValue'> {
|
|
|
|
value: boolean | null
|
|
|
|
setValue?: (newValue: boolean | null) => void
|
|
|
|
}
|
|
|
|
|
2023-09-09 20:36:55 +03:00
|
|
|
function Tristate({
|
2023-10-14 23:46:36 +03:00
|
|
|
id, disabled, tooltip, label,
|
2023-12-18 12:25:39 +03:00
|
|
|
className,
|
2023-11-27 13:50:56 +03:00
|
|
|
value, setValue,
|
|
|
|
...restProps
|
2023-09-09 20:36:55 +03:00
|
|
|
}: TristateProps) {
|
2023-09-07 16:30:43 +03:00
|
|
|
const cursor = useMemo(
|
|
|
|
() => {
|
|
|
|
if (disabled) {
|
|
|
|
return 'cursor-not-allowed';
|
|
|
|
} else if (setValue) {
|
|
|
|
return 'cursor-pointer';
|
|
|
|
} else {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
}, [disabled, setValue]);
|
2023-12-15 17:34:50 +03:00
|
|
|
|
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-09-09 20:36:55 +03:00
|
|
|
setValue(null);
|
|
|
|
} else if (value === null) {
|
|
|
|
setValue(true);
|
2023-09-07 16:30:43 +03:00
|
|
|
} else {
|
2023-09-09 20:36:55 +03:00
|
|
|
setValue(false);
|
2023-09-07 16:30:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2023-12-05 01:22:44 +03:00
|
|
|
<button type='button' id={id}
|
2023-12-15 17:34:50 +03:00
|
|
|
className={clsx(
|
|
|
|
'flex items-center gap-2 text-start',
|
|
|
|
'outline-none',
|
2023-12-18 12:25:39 +03:00
|
|
|
cursor,
|
|
|
|
className
|
2023-12-15 17:34:50 +03:00
|
|
|
)}
|
2023-12-05 01:22:44 +03:00
|
|
|
title={tooltip}
|
|
|
|
disabled={disabled}
|
|
|
|
onClick={handleClick}
|
|
|
|
{...restProps}
|
|
|
|
>
|
2023-12-15 17:34:50 +03:00
|
|
|
<div className={clsx(
|
|
|
|
'w-4 h-4',
|
|
|
|
'border rounded-sm',
|
|
|
|
{
|
|
|
|
'clr-primary': value !== false,
|
|
|
|
'clr-app': value === false
|
|
|
|
}
|
|
|
|
)}>
|
2023-12-05 01:22:44 +03:00
|
|
|
{value ? <div className='mt-[1px] ml-[1px]'><CheckboxCheckedIcon /></div> : null}
|
|
|
|
{value == null ? <div className='mt-[1px] ml-[1px]'><CheckboxNullIcon /></div> : null}
|
|
|
|
</div>
|
2023-12-15 17:34:50 +03:00
|
|
|
<Label className={cursor} text={label} htmlFor={id} />
|
2023-12-05 01:22:44 +03:00
|
|
|
</button>);
|
2023-09-07 16:30:43 +03:00
|
|
|
}
|
|
|
|
|
2023-12-13 14:32:57 +03:00
|
|
|
export default Tristate;
|