2025-08-05 22:29:17 +03:00
|
|
|
import { Tooltip } from "bootstrap";
|
2025-12-23 13:06:33 +02:00
|
|
|
import { ComponentChildren, CSSProperties } from "preact";
|
|
|
|
|
import { useCallback, useEffect, useMemo, useRef } from "preact/hooks";
|
2025-12-21 13:19:42 +02:00
|
|
|
|
|
|
|
|
import { escapeQuotes } from "../../services/utils";
|
2025-08-19 23:34:25 +03:00
|
|
|
import { useUniqueName } from "./hooks";
|
2025-08-05 22:29:17 +03:00
|
|
|
|
2025-08-03 21:18:18 +03:00
|
|
|
interface FormCheckboxProps {
|
2025-08-27 16:16:25 +03:00
|
|
|
name?: string;
|
2025-08-07 19:20:35 +03:00
|
|
|
label: string | ComponentChildren;
|
2025-08-05 15:13:09 +03:00
|
|
|
/**
|
|
|
|
|
* If set, the checkbox label will be underlined and dotted, indicating a hint. When hovered, it will show the hint text.
|
|
|
|
|
*/
|
|
|
|
|
hint?: string;
|
|
|
|
|
currentValue: boolean;
|
2025-08-05 18:05:41 +03:00
|
|
|
disabled?: boolean;
|
2025-08-03 21:18:18 +03:00
|
|
|
onChange(newValue: boolean): void;
|
2025-08-18 09:34:16 +03:00
|
|
|
containerStyle?: CSSProperties;
|
2025-08-03 21:18:18 +03:00
|
|
|
}
|
|
|
|
|
|
2025-12-21 13:19:42 +02:00
|
|
|
export default function FormCheckbox({ name, disabled, label, currentValue, onChange, hint, containerStyle }: FormCheckboxProps) {
|
2025-08-05 22:29:17 +03:00
|
|
|
const labelRef = useRef<HTMLLabelElement>(null);
|
2025-08-25 18:41:48 +03:00
|
|
|
const id = useUniqueName(name);
|
2025-08-05 22:29:17 +03:00
|
|
|
|
2025-08-10 17:19:39 +03:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (!hint || !labelRef.current) return;
|
2025-12-21 13:19:42 +02:00
|
|
|
|
2025-08-10 17:19:39 +03:00
|
|
|
const tooltipInstance = Tooltip.getOrCreateInstance(labelRef.current, {
|
|
|
|
|
html: true,
|
2025-12-24 12:59:13 +02:00
|
|
|
customClass: "tooltip-top"
|
2025-08-10 17:19:39 +03:00
|
|
|
});
|
2025-12-21 13:19:42 +02:00
|
|
|
|
2025-08-10 17:19:39 +03:00
|
|
|
return () => tooltipInstance?.dispose();
|
2025-12-24 12:59:13 +02:00
|
|
|
}, [hint]);
|
2025-08-10 17:19:39 +03:00
|
|
|
|
2025-12-21 13:19:42 +02:00
|
|
|
const labelStyle = useMemo(() =>
|
2025-08-10 17:19:39 +03:00
|
|
|
hint ? { textDecoration: "underline dotted var(--main-text-color)" } : undefined,
|
2025-12-21 13:19:42 +02:00
|
|
|
[hint]
|
2025-08-10 17:19:39 +03:00
|
|
|
);
|
2025-12-21 13:19:42 +02:00
|
|
|
|
2025-08-10 17:19:39 +03:00
|
|
|
const handleChange = useCallback((e: Event) => {
|
|
|
|
|
onChange((e.target as HTMLInputElement).checked);
|
|
|
|
|
}, [onChange]);
|
2025-12-21 13:19:42 +02:00
|
|
|
|
2025-08-10 17:19:39 +03:00
|
|
|
const titleText = useMemo(() => hint ? escapeQuotes(hint) : undefined, [hint]);
|
2025-08-05 22:29:17 +03:00
|
|
|
|
2025-08-03 21:18:18 +03:00
|
|
|
return (
|
2025-09-12 13:50:06 +03:00
|
|
|
<div className={`form-checkbox ${disabled ? "disabled" : ""}`} style={containerStyle}>
|
2025-08-05 15:13:09 +03:00
|
|
|
<label
|
|
|
|
|
className="form-check-label tn-checkbox"
|
2025-08-10 17:19:39 +03:00
|
|
|
style={labelStyle}
|
|
|
|
|
title={titleText}
|
2025-08-05 22:29:17 +03:00
|
|
|
ref={labelRef}
|
|
|
|
|
>
|
2025-08-03 21:18:18 +03:00
|
|
|
<input
|
2025-08-19 22:54:15 +03:00
|
|
|
id={id}
|
2025-08-03 21:18:18 +03:00
|
|
|
className="form-check-input"
|
|
|
|
|
type="checkbox"
|
2025-08-19 22:54:15 +03:00
|
|
|
name={id}
|
2025-08-03 21:18:18 +03:00
|
|
|
checked={currentValue || false}
|
|
|
|
|
value="1"
|
2025-08-05 18:05:41 +03:00
|
|
|
disabled={disabled}
|
2025-08-10 17:19:39 +03:00
|
|
|
onChange={handleChange} />
|
2025-08-03 21:18:18 +03:00
|
|
|
{label}
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2025-12-21 13:19:42 +02:00
|
|
|
}
|