Files
aggios.app/front-end-dash.aggios.app/components/ui/Checkbox.tsx
2025-12-08 21:47:38 -03:00

70 lines
2.6 KiB
TypeScript

"use client";
import { InputHTMLAttributes, forwardRef, useState } from "react";
interface CheckboxProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string | React.ReactNode;
error?: string;
}
const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
({ label, error, className = "", onChange, checked: controlledChecked, ...props }, ref) => {
const [isChecked, setIsChecked] = useState(controlledChecked || false);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setIsChecked(e.target.checked);
if (onChange) {
onChange(e);
}
};
const checked = controlledChecked !== undefined ? controlledChecked : isChecked;
return (
<div className="w-full">
<label className="flex items-start gap-3 cursor-pointer group">
<div className="relative flex items-center justify-center mt-0.5">
<input
ref={ref}
type="checkbox"
className={`
appearance-none w-[18px] h-[18px] border rounded-sm
border-[#E5E5E5] dark:border-gray-600 bg-white dark:bg-gray-700
checked:border-[#FF3A05]
focus:outline-none focus:border-[#FF3A05]
transition-colors cursor-pointer
${className}
`}
style={{
background: checked ? 'var(--gradient-primary)' : undefined,
}}
checked={checked}
onChange={handleChange}
{...props}
/>
<i
className={`ri-check-line absolute text-white text-[14px] pointer-events-none transition-opacity ${checked ? 'opacity-100' : 'opacity-0'
}`}
/>
</div>
{label && (
<span className="text-[14px] text-[#000000] dark:text-white select-none">
{label}
</span>
)}
</label>
{error && (
<p className="mt-1 text-[13px] text-[#FF3A05] flex items-center gap-1">
<i className="ri-error-warning-line" />
{error}
</p>
)}
</div>
);
}
);
Checkbox.displayName = "Checkbox";
export default Checkbox;