2023-08-02 18:24:17 +03:00
|
|
|
import { useRef } from 'react';
|
|
|
|
|
2023-07-15 17:46:19 +03:00
|
|
|
import Label from './Label';
|
|
|
|
|
2023-07-20 17:11:03 +03:00
|
|
|
export interface CheckboxProps {
|
|
|
|
id?: string
|
|
|
|
label?: string
|
2023-07-15 17:46:19 +03:00
|
|
|
required?: boolean
|
|
|
|
disabled?: boolean
|
|
|
|
widthClass?: string
|
2023-07-31 22:38:58 +03:00
|
|
|
tooltip?: string
|
2023-07-16 20:25:55 +03:00
|
|
|
value?: boolean
|
2023-07-15 17:46:19 +03:00
|
|
|
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
|
|
|
|
}
|
|
|
|
|
2023-09-04 20:37:55 +03:00
|
|
|
function Checkbox({ id, required, disabled, tooltip, label, widthClass = 'w-fit', value, onChange }: CheckboxProps) {
|
2023-08-02 18:24:17 +03:00
|
|
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
|
|
|
|
|
|
const cursor = disabled ? 'cursor-not-allowed' : 'cursor-pointer';
|
|
|
|
|
2023-08-29 15:17:16 +03:00
|
|
|
function handleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
|
2023-08-02 18:24:17 +03:00
|
|
|
event.preventDefault();
|
|
|
|
if (!disabled) {
|
|
|
|
inputRef.current?.click();
|
|
|
|
}
|
2023-09-04 20:37:55 +03:00
|
|
|
}
|
2023-08-02 18:24:17 +03:00
|
|
|
|
2023-07-15 17:46:19 +03:00
|
|
|
return (
|
2023-08-29 15:17:16 +03:00
|
|
|
<button
|
2023-09-04 20:37:55 +03:00
|
|
|
className={'flex [&:not(:first-child)]:mt-3 clr-outline focus:outline-dotted focus:outline-1 ' + widthClass}
|
2023-08-29 15:17:16 +03:00
|
|
|
title={tooltip}
|
|
|
|
disabled={disabled}
|
|
|
|
onClick={handleClick}
|
|
|
|
>
|
2023-08-02 18:24:17 +03:00
|
|
|
<input id={id} type='checkbox' ref={inputRef}
|
|
|
|
className={`relative peer w-4 h-4 shrink-0 mt-0.5 border rounded-sm appearance-none clr-checkbox ${cursor}`}
|
2023-07-15 17:46:19 +03:00
|
|
|
required={required}
|
|
|
|
disabled={disabled}
|
2023-07-16 20:25:55 +03:00
|
|
|
checked={value}
|
2023-07-15 17:46:19 +03:00
|
|
|
onChange={onChange}
|
2023-09-04 19:12:27 +03:00
|
|
|
tabIndex={-1}
|
2023-07-15 17:46:19 +03:00
|
|
|
/>
|
2023-08-02 18:24:17 +03:00
|
|
|
{ label &&
|
|
|
|
<Label
|
2023-09-04 20:37:55 +03:00
|
|
|
className={`${cursor} px-2`}
|
2023-07-15 17:46:19 +03:00
|
|
|
text={label}
|
|
|
|
required={required}
|
|
|
|
htmlFor={id}
|
2023-07-20 17:11:03 +03:00
|
|
|
/>}
|
2023-07-15 17:46:19 +03:00
|
|
|
<svg
|
|
|
|
className='absolute hidden w-3 h-3 mt-1 ml-0.5 text-white pointer-events-none peer-checked:block'
|
|
|
|
viewBox='0 0 512 512'
|
|
|
|
fill='currentColor'
|
|
|
|
>
|
|
|
|
<path d='M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7l233.4-233.3c12.5-12.5 32.8-12.5 45.3 0z' />
|
|
|
|
</svg>
|
2023-08-29 15:17:16 +03:00
|
|
|
</button>
|
2023-07-15 17:46:19 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-07-25 20:27:29 +03:00
|
|
|
export default Checkbox;
|