File size: 2,770 Bytes
aa2e6af
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import React, { useEffect, useState, useRef } from 'react';
import { EditIcon, SaveIcon } from '~/components/svg';

type Props = {
  name?: string;
  onSave: (newName: string) => void;
};

const PromptName: React.FC<Props> = ({ name, onSave }) => {
  const inputRef = useRef<HTMLInputElement>(null);
  const blurTimeoutRef = useRef<NodeJS.Timeout>();
  const [isEditing, setIsEditing] = useState(false);
  const [newName, setNewName] = useState(name);

  const handleEditClick = () => {
    setIsEditing(true);
  };

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setNewName(e.target.value);
  };

  const saveName = () => {
    const savedName = newName?.trim();
    onSave(savedName || '');
    setIsEditing(false);
  };

  const handleSaveClick: React.MouseEventHandler<HTMLButtonElement> = () => {
    saveName();
    clearTimeout(blurTimeoutRef.current);
  };

  const handleBlur = () => {
    blurTimeoutRef.current = setTimeout(() => {
      if (document.activeElement !== inputRef.current) {
        setIsEditing(false);
        setNewName(name);
      }
    }, 200);
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Escape') {
      setIsEditing(false);
      setNewName(name);
    }
    if (e.key === 'Enter' || e.key === 'Tab') {
      saveName();
    }
  };

  useEffect(() => {
    if (isEditing) {
      inputRef.current?.focus();
    }
  }, [isEditing]);

  useEffect(() => {
    setNewName(name);
  }, [name]);

  return (
    <div className="mb-1 flex flex-row items-center font-bold sm:text-xl md:mb-0 md:text-2xl">
      {isEditing ? (
        <div className="mb-1 flex items-center md:mb-0">
          <input
            type="text"
            value={newName ?? ''}
            onChange={handleInputChange}
            onBlur={handleBlur}
            onKeyDown={handleKeyDown}
            ref={inputRef}
            className="mr-2 w-56 rounded-md border bg-transparent p-2 focus:outline-none dark:border-gray-600 md:w-auto"
            autoFocus={true}
          />
          <button
            type="button"
            onClick={handleSaveClick}
            className="rounded p-2 hover:bg-gray-300/50 dark:hover:bg-gray-700"
          >
            <SaveIcon className="icon-md" size="1.2em" />
          </button>
        </div>
      ) : (
        <div className="mb-1 flex items-center md:mb-0">
          <span className="border border-transparent p-2">{newName}</span>
          <button
            type="button"
            onClick={handleEditClick}
            className="rounded p-2 hover:bg-gray-300/50 dark:hover:bg-gray-700"
          >
            <EditIcon className="icon-md" />
          </button>
        </div>
      )}
    </div>
  );
};

export default PromptName;