refactor: checkbox ui component (#4665)

This commit is contained in:
Aaryan Khandelwal 2024-05-31 15:05:28 +05:30 committed by GitHub
parent a9d9cbcb72
commit bf4f97d7f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 23 deletions

View File

@ -3,15 +3,26 @@ import * as React from "react";
import { cn } from "../../helpers"; import { cn } from "../../helpers";
export interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> { export interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> {
intermediate?: boolean; containerClassName?: string;
className?: string; iconClassName?: string;
indeterminate?: boolean;
} }
const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => { const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
const { id, name, checked, intermediate = false, disabled, className = "", ...rest } = props; const {
id,
name,
checked,
indeterminate = false,
disabled,
containerClassName,
iconClassName,
className,
...rest
} = props;
return ( return (
<div className={cn("relative w-full flex gap-2", className)}> <div className={cn("relative w-full flex gap-2", containerClassName)}>
<input <input
id={id} id={id}
ref={ref} ref={ref}
@ -19,22 +30,27 @@ const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>((props, ref)
name={name} name={name}
checked={checked} checked={checked}
className={cn( className={cn(
"appearance-none shrink-0 w-4 h-4 border rounded-[3px] focus:outline-1 focus:outline-offset-4 focus:outline-custom-primary-50", "appearance-none shrink-0 size-4 border rounded-[3px] focus:outline-1 focus:outline-offset-4 focus:outline-custom-primary-50 cursor-pointer",
{ {
"border-custom-border-200 bg-custom-background-80 cursor-not-allowed": disabled, "border-custom-border-200 bg-custom-background-80 cursor-not-allowed": disabled,
"cursor-pointer border-custom-border-300 hover:border-custom-border-400 bg-white": !disabled, "border-custom-border-300 hover:border-custom-border-400 bg-transparent": !disabled,
"border-custom-primary-40 bg-custom-primary-100 hover:bg-custom-primary-200": "border-custom-primary-40 hover:border-custom-primary-40 bg-custom-primary-100 hover:bg-custom-primary-200":
!disabled && (checked || intermediate), !disabled && (checked || indeterminate),
} },
className
)} )}
disabled={disabled} disabled={disabled}
{...rest} {...rest}
/> />
<svg <svg
className={cn("absolute w-4 h-4 p-0.5 pointer-events-none outline-none hidden stroke-white", { className={cn(
"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 size-4 p-0.5 pointer-events-none outline-none hidden stroke-white",
{
block: checked, block: checked,
"stroke-custom-text-400 opacity-40": disabled, "stroke-custom-text-400 opacity-40": disabled,
})} },
iconClassName
)}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
@ -46,10 +62,14 @@ const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>((props, ref)
<polyline points="20 6 9 17 4 12" /> <polyline points="20 6 9 17 4 12" />
</svg> </svg>
<svg <svg
className={cn("absolute w-4 h-4 p-0.5 pointer-events-none outline-none stroke-white hidden", { className={cn(
"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 size-4 p-0.5 pointer-events-none outline-none stroke-white hidden",
{
"stroke-custom-text-400 opacity-40": disabled, "stroke-custom-text-400 opacity-40": disabled,
block: intermediate && !checked, block: indeterminate && !checked,
})} },
iconClassName
)}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 8 8" viewBox="0 0 8 8"
fill="none" fill="none"

View File

@ -80,7 +80,7 @@ export const EmailNotificationForm: FC<IEmailNotificationFormProps> = (props) =>
control={control} control={control}
name="property_change" name="property_change"
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<Checkbox checked={value} onChange={() => onChange(!value)} className="mx-2" /> <Checkbox checked={value} onChange={() => onChange(!value)} containerClassName="mx-2" />
)} )}
/> />
</div> </div>
@ -99,12 +99,12 @@ export const EmailNotificationForm: FC<IEmailNotificationFormProps> = (props) =>
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<Checkbox <Checkbox
checked={value} checked={value}
intermediate={!value && watch("issue_completed")} indeterminate={!value && watch("issue_completed")}
onChange={() => { onChange={() => {
setValue("issue_completed", !value, { shouldDirty: true }); setValue("issue_completed", !value, { shouldDirty: true });
onChange(!value); onChange(!value);
}} }}
className="mx-2" containerClassName="mx-2"
/> />
)} )}
/> />
@ -120,7 +120,7 @@ export const EmailNotificationForm: FC<IEmailNotificationFormProps> = (props) =>
control={control} control={control}
name="issue_completed" name="issue_completed"
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<Checkbox checked={value} onChange={() => onChange(!value)} className="mx-2" /> <Checkbox checked={value} onChange={() => onChange(!value)} containerClassName="mx-2" />
)} )}
/> />
</div> </div>
@ -137,7 +137,7 @@ export const EmailNotificationForm: FC<IEmailNotificationFormProps> = (props) =>
control={control} control={control}
name="comment" name="comment"
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<Checkbox checked={value} onChange={() => onChange(!value)} className="mx-2" /> <Checkbox checked={value} onChange={() => onChange(!value)} containerClassName="mx-2" />
)} )}
/> />
</div> </div>
@ -154,7 +154,7 @@ export const EmailNotificationForm: FC<IEmailNotificationFormProps> = (props) =>
control={control} control={control}
name="mention" name="mention"
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<Checkbox checked={value} onChange={() => onChange(!value)} className="mx-2" /> <Checkbox checked={value} onChange={() => onChange(!value)} containerClassName="mx-2" />
)} )}
/> />
</div> </div>