Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/components/ui/input/InputCheckboxWithDescription.tsx
T

60 lines
1.8 KiB
TypeScript

import clsx from "clsx";
import { ReactNode, useEffect, useState } from "react";
import HintTooltip from "../tooltips/HintTooltip";
import { Checkbox } from "~/ui/components/Checkbox";
interface Props {
name?: string;
title?: string | ReactNode;
description: string | ReactNode;
value?: boolean;
setValue?: React.Dispatch<React.SetStateAction<boolean>>;
className?: string;
help?: string;
disabled?: boolean;
autoFocus?: boolean;
}
export default function InputCheckboxWithDescription({ name, title, value, setValue, description, className, help, disabled = false, autoFocus }: Props) {
// Subframe's Checkbox is always controlled; keep the original internal state that also
// supports the uncontrolled (setValue-only) usage and mirrors changes back.
const [checked, setChecked] = useState(value ?? false);
useEffect(() => {
if (value !== checked) {
setChecked(value ?? false);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [value]);
useEffect(() => {
if (setValue && value !== checked) {
setValue(checked);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [checked]);
// Title + optional help tooltip rendered into Subframe's label slot.
const labelContent: ReactNode = (
<span className="flex items-center space-x-1">
<span>{title}</span>
{help && <HintTooltip text={help} />}
</span>
);
return (
<div className={clsx("relative flex items-start pb-4 pt-2", className)}>
<Checkbox
id={name}
name={name}
label={labelContent}
description={description}
checked={checked}
onCheckedChange={(next) => setChecked(Boolean(next))}
disabled={disabled}
autoFocus={autoFocus}
className="w-full"
/>
</div>
);
}