File size: 2,948 Bytes
f0743f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import React, { useEffect, useState, useRef } from 'react';
import { Button, Label, Input, EditIcon, SaveIcon } from '@librechat/client';

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 handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Escape') {
      setIsEditing(false);
      setNewName(name);
    }
    if (e.key === 'Enter') {
      saveName();
    }
  };

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

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

  return (
    <div className="flex items-center">
      <div
        style={{
          display: 'grid',
          gridTemplateColumns: '1fr auto',
          alignItems: 'center',
        }}
        className="gap-2"
      >
        {isEditing ? (
          <>
            <Input
              type="text"
              value={newName ?? ''}
              onChange={handleInputChange}
              onKeyDown={handleKeyDown}
              ref={inputRef}
              className="flex w-full max-w-none rounded-lg text-2xl font-bold transition duration-200"
              style={{
                whiteSpace: 'nowrap',
                textOverflow: 'ellipsis',
              }}
            />

            <Button
              onClick={handleSaveClick}
              variant="ghost"
              size="sm"
              className="h-10 flex-shrink-0"
              aria-label="Save prompt name"
            >
              <SaveIcon className="icon-md" />
            </Button>
          </>
        ) : (
          <>
            <Label
              className="text-2xl font-bold"
              style={{
                overflow: 'hidden',
                whiteSpace: 'nowrap',
                textOverflow: 'ellipsis',
              }}
            >
              {newName}
            </Label>
            <Button
              onClick={handleEditClick}
              variant="ghost"
              size="sm"
              aria-label="Edit prompt name"
              className="h-10 flex-shrink-0"
            >
              <EditIcon className="icon-md" />
            </Button>
          </>
        )}
      </div>
    </div>
  );
};

export default PromptName;