chore: transfer repo
This commit is contained in:
93
components/ui/Checkbox.tsx
Normal file
93
components/ui/Checkbox.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
'use client';
|
||||
|
||||
import React, { forwardRef, useState } from 'react';
|
||||
|
||||
export interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
label?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
({ label, className = '', onChange, ...props }, ref) => {
|
||||
// Keep track of focus state for styling
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
|
||||
// Handle click on the custom checkbox
|
||||
const handleClick = () => {
|
||||
if (props.disabled) return;
|
||||
|
||||
// Create a synthetic event to pass to the onChange handler
|
||||
const syntheticEvent = {
|
||||
target: {
|
||||
name: props.name,
|
||||
checked: !props.checked,
|
||||
type: 'checkbox'
|
||||
}
|
||||
} as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
// Call the onChange handler with the synthetic event
|
||||
if (onChange) {
|
||||
onChange(syntheticEvent);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`flex items-center ${className}`}>
|
||||
<div
|
||||
className="relative flex items-center cursor-pointer"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
ref={ref}
|
||||
className="sr-only"
|
||||
onFocus={() => setIsFocused(true)}
|
||||
onBlur={() => setIsFocused(false)}
|
||||
onChange={onChange}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={`
|
||||
h-5 w-5 rounded-sm flex items-center justify-center
|
||||
${props.checked
|
||||
? 'bg-primary border-primary'
|
||||
: 'bg-white border-gray-300'
|
||||
}
|
||||
${isFocused ? 'ring-2 ring-primary/30' : ''}
|
||||
${props.disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
|
||||
border transition-colors
|
||||
`}
|
||||
>
|
||||
{props.checked && (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="w-3 h-3 text-white"
|
||||
>
|
||||
<polyline points="20 6 9 17 4 12" />
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={props.id}
|
||||
className={`ml-2 text-sm ${props.disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`}
|
||||
onClick={!props.disabled ? handleClick : undefined}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Checkbox.displayName = 'Checkbox';
|
||||
Reference in New Issue
Block a user