MessageActionBar.tsx

  1import React, { useState } from "react";
  2
  3interface MessageActionBarProps {
  4  onCopy?: () => void;
  5  onShowUsage?: () => void;
  6}
  7
  8function MessageActionBar({ onCopy, onShowUsage }: MessageActionBarProps) {
  9  const [copyFeedback, setCopyFeedback] = useState(false);
 10
 11  const handleCopy = (e: React.MouseEvent) => {
 12    e.stopPropagation();
 13    if (onCopy) {
 14      onCopy();
 15      setCopyFeedback(true);
 16      setTimeout(() => setCopyFeedback(false), 1500);
 17    }
 18  };
 19
 20  const handleShowUsage = (e: React.MouseEvent) => {
 21    e.stopPropagation();
 22    if (onShowUsage) {
 23      onShowUsage();
 24    }
 25  };
 26
 27  return (
 28    <div
 29      className="message-action-bar"
 30      data-action-bar
 31      style={{
 32        position: "absolute",
 33        top: "8px",
 34        right: "8px",
 35        display: "flex",
 36        gap: "2px",
 37        background: "var(--bg-base)",
 38        border: "1px solid var(--border)",
 39        borderRadius: "4px",
 40        padding: "2px",
 41        zIndex: 10,
 42      }}
 43    >
 44      {onCopy && (
 45        <button
 46          onClick={handleCopy}
 47          title="Copy"
 48          style={{
 49            display: "flex",
 50            alignItems: "center",
 51            justifyContent: "center",
 52            width: "24px",
 53            height: "24px",
 54            borderRadius: "4px",
 55            border: "none",
 56            background: copyFeedback ? "var(--success-bg)" : "transparent",
 57            cursor: "pointer",
 58            color: copyFeedback ? "var(--success-text)" : "var(--text-secondary)",
 59            transition: "background-color 0.15s, color 0.15s",
 60          }}
 61          onMouseEnter={(e) => {
 62            if (!copyFeedback) {
 63              e.currentTarget.style.backgroundColor = "var(--bg-tertiary)";
 64            }
 65          }}
 66          onMouseLeave={(e) => {
 67            if (!copyFeedback) {
 68              e.currentTarget.style.backgroundColor = "transparent";
 69            }
 70          }}
 71        >
 72          {copyFeedback ? (
 73            <svg
 74              width="16"
 75              height="16"
 76              viewBox="0 0 24 24"
 77              fill="none"
 78              stroke="currentColor"
 79              strokeWidth="2"
 80              strokeLinecap="round"
 81              strokeLinejoin="round"
 82            >
 83              <polyline points="20 6 9 17 4 12"></polyline>
 84            </svg>
 85          ) : (
 86            <svg
 87              width="16"
 88              height="16"
 89              viewBox="0 0 24 24"
 90              fill="none"
 91              stroke="currentColor"
 92              strokeWidth="2"
 93              strokeLinecap="round"
 94              strokeLinejoin="round"
 95            >
 96              <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
 97              <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
 98            </svg>
 99          )}
100        </button>
101      )}
102      {onShowUsage && (
103        <button
104          onClick={handleShowUsage}
105          title="Usage Details"
106          style={{
107            display: "flex",
108            alignItems: "center",
109            justifyContent: "center",
110            width: "24px",
111            height: "24px",
112            borderRadius: "4px",
113            border: "none",
114            background: "transparent",
115            cursor: "pointer",
116            color: "var(--text-secondary)",
117            transition: "background-color 0.15s",
118          }}
119          onMouseEnter={(e) => {
120            e.currentTarget.style.backgroundColor = "var(--bg-tertiary)";
121          }}
122          onMouseLeave={(e) => {
123            e.currentTarget.style.backgroundColor = "transparent";
124          }}
125        >
126          <svg
127            width="16"
128            height="16"
129            viewBox="0 0 24 24"
130            fill="none"
131            stroke="currentColor"
132            strokeWidth="2"
133            strokeLinecap="round"
134            strokeLinejoin="round"
135          >
136            <circle cx="12" cy="12" r="10"></circle>
137            <line x1="12" y1="16" x2="12" y2="12"></line>
138            <line x1="12" y1="8" x2="12.01" y2="8"></line>
139          </svg>
140        </button>
141      )}
142    </div>
143  );
144}
145
146export default MessageActionBar;