78 lines
2.1 KiB
TypeScript
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>
|
|
);
|
|
}
|