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; }; const InPlaceInputDesktop: FC = ({ onChange, placeholder, inputStyles, getChildren, value = "", }) => { const [isWriting, setIsWriting] = useState(false); const [localValue, setLocalValue] = useState(value); const inputRef = useRef(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 ( 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;