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

78 lines
2.1 KiB
TypeScript

import clsx from "clsx";
import { ReactNode, useEffect, useState } from "react";
import HintTooltip from "~/components/ui/tooltips/HintTooltip";
import { Checkbox } from "~/ui/components/Checkbox";
interface Props {
name: string;
title: string | ReactNode;
value?: boolean;
setValue?: React.Dispatch<React.SetStateAction<boolean>>;
className?: string;
help?: string;
required?: boolean;
disabled?: boolean;
description?: ReactNode;
readOnly?: boolean;
autoFocus?: boolean;
}
export default function InputCheckboxInline({
name,
title,
value,
setValue,
description,
className,
help,
required,
disabled = false,
readOnly,
autoFocus,
}: Props) {
// useImperativeHandle(ref, () => ({ input }));
// const input = useRef<HTMLInputElement>(null);
// Subframe's Checkbox is always controlled. The original field could be used uncontrolled
// (value omitted, only setValue), so the shim holds the checked state internally and mirrors
// both directions — keeps the public API (controlled + uncontrolled) intact.
const [checked, setChecked] = useState(value ?? false);
useEffect(() => {
if (value !== undefined && value !== checked) {
setChecked(value);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [value]);
// Rich label content rendered into Subframe's label slot (the original right-hand label).
const labelContent: ReactNode = (
<span className="flex items-center space-x-1">
<span>
{title}
{description}
{required && <span className="ml-1 text-red-600">*</span>}
</span>
{help && <HintTooltip text={help} />}
</span>
);
return (
<div className={clsx(className, "")}>
<Checkbox
id={name}
name={name}
label={labelContent}
checked={checked}
onCheckedChange={(next) => {
const isChecked = Boolean(next);
setChecked(isChecked);
setValue?.(isChecked);
}}
disabled={disabled || readOnly}
autoFocus={autoFocus}
className="sm:col-span-6"
/>
</div>
);
}