Files
Crm-Frontend/src/components/ui/InPlaceInput/InPlaceInputDesktop.tsx
2025-09-05 14:25:36 +04:00

87 lines
2.3 KiB
TypeScript

import React, { FC, ReactNode, useEffect, useRef, useState } from "react";
import { TextInput } from "@mantine/core";
import { Styles } from "@mantine/core/lib/core/styles-api/styles-api.types";
type Props = {
value?: string;
onChange: (value: string) => void;
placeholder?: string;
getChildren: (startEditing: () => void) => ReactNode;
inputStyles?: Styles<any>;
};
const InPlaceInputDesktop: FC<Props> = ({
onChange,
placeholder,
inputStyles,
getChildren,
value = "",
}) => {
const [isWriting, setIsWriting] = useState<boolean>(false);
const [localValue, setLocalValue] = useState<string>(value);
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (isWriting && inputRef.current) {
inputRef.current.focus();
}
}, [isWriting]);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
isWriting &&
inputRef.current &&
!inputRef.current.contains(event.target as Node)
) {
onCompleteCreating();
}
};
document.addEventListener("mousedown", handleClickOutside);
return () =>
document.removeEventListener("mousedown", handleClickOutside);
}, [isWriting, localValue]);
const onStartCreating = () => {
setLocalValue(localValue);
setIsWriting(true);
};
const onCancelCreating = () => {
setLocalValue(localValue);
setIsWriting(false);
};
const onCompleteCreating = () => {
const val = localValue.trim();
if (val) {
onChange(val);
}
setIsWriting(false);
};
if (isWriting) {
return (
<TextInput
ref={inputRef}
placeholder={placeholder}
variant={"unstyled"}
value={localValue}
onChange={e => setLocalValue(e.target.value)}
onKeyDown={e => {
e.stopPropagation();
if (e.key === "Enter") onCompleteCreating();
if (e.key === "Escape") onCancelCreating();
}}
styles={inputStyles}
miw={150}
/>
);
}
return getChildren(onStartCreating);
};
export default InPlaceInputDesktop;