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

72 lines
1.8 KiB
TypeScript
Raw Normal View History

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
}
function Tristate({
2023-10-14 23:46:36 +03:00
id, disabled, tooltip, label,
dimensions = 'w-fit',
value, setValue,
...restProps
}: 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]);
const bgColor = useMemo(
() => {
return value !== false ? 'clr-primary' : 'clr-app'
}, [value]);
function handleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
event.preventDefault();
if (disabled || !setValue) {
return;
}
if (value === false) {
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 (
<button type='button' id={id}
className={`flex items-center clr-outline focus:outline-dotted focus:outline-1 ${dimensions}`}
2023-09-07 16:30:43 +03:00
title={tooltip}
disabled={disabled}
onClick={handleClick}
{...restProps}
2023-09-07 16:30:43 +03:00
>
<div className={`w-4 h-4 shrink-0 mt-0.5 border rounded-sm ${bgColor} ${cursor}`} >
{value ? <div className='mt-[1px] ml-[1px]'><CheckboxCheckedIcon /></div> : null}
{value == null ? <div className='mt-[1px] ml-[1px]'><CheckboxNullIcon /></div> : null}
</div>
{label ?
2023-09-07 16:30:43 +03:00
<Label
className={`${cursor} px-2 text-start`}
text={label}
htmlFor={id}
/> : null}
2023-09-07 16:30:43 +03:00
</button>
);
}
export default Tristate;