feat: 프롬프트 입력창을 Univer 위 오버레이로 변경 및 기본적으로 항상 표시되도록 개선\n\n- 프롬프트 입력창을 Univer 시트 위에 반투명 오버레이로 구현\n- 우하단 플로팅 버튼으로 토글 가능 (기본값: 항상 표시)\n- 입력창 디자인을 컴팩트하게 개선, 반응형 오버레이 적용\n- 기존 하단 고정 방식 제거, Univer 전체 화면 활용\n- 사용자 경험 및 접근성 향상
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useAppStore } from "../../stores/useAppStore";
|
||||
import { aiProcessor } from "../../utils/aiProcessor";
|
||||
import { Button } from "../ui/button";
|
||||
|
||||
interface PromptInputProps {
|
||||
value: string;
|
||||
@@ -176,45 +177,43 @@ const PromptInput: React.FC<PromptInputProps> = ({
|
||||
}, [cellAddressToInsert, onChange, setCellAddressToInsert]);
|
||||
|
||||
return (
|
||||
<div className="w-[60%] mx-auto bg-white z-10 flex flex-col items-center py-4 px-2">
|
||||
<div className="w-full max-w-3xl flex items-end gap-2">
|
||||
<div className="w-full z-10 flex flex-col items-center">
|
||||
<div className="w-full flex items-end gap-3">
|
||||
<textarea
|
||||
ref={textareaRef}
|
||||
className="flex-1 resize-none rounded-lg border border-gray-300 bg-gray-50 px-4 py-3 text-base text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-400 disabled:bg-gray-100 disabled:cursor-not-allowed min-h-[48px] max-h-32 shadow-sm"
|
||||
placeholder="질문을 입력하세요.
|
||||
예시) A1부터 A10까지 합계를 구해서 B1에 입력하는 수식을 입력해줘
|
||||
|
||||
💡 팁: 시트에서 셀을 선택하면 자동으로 주소가 입력됩니다"
|
||||
className="flex-1 resize-none rounded-xl border border-gray-300 bg-white px-4 py-3 text-sm text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-400 disabled:bg-gray-100 disabled:cursor-not-allowed min-h-[44px] max-h-28 shadow-sm"
|
||||
placeholder="AI에게 명령하세요...
|
||||
예: A1부터 A10까지 합계를 B1에 입력해줘"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
disabled={isProcessing}
|
||||
maxLength={maxLength}
|
||||
rows={5}
|
||||
rows={3}
|
||||
/>
|
||||
<div style={{ width: "1rem" }} />
|
||||
|
||||
{/* 버튼들을 세로로 배치 */}
|
||||
<div className="flex flex-col gap-3">
|
||||
{/* 히스토리 버튼 - 맨 위 */}
|
||||
{/* 버튼들을 세로로 배치 - 오버레이에 맞게 컴팩트 */}
|
||||
<div className="flex flex-col gap-2">
|
||||
{/* 히스토리 버튼 */}
|
||||
{onHistoryToggle && (
|
||||
<button
|
||||
className="px-4 py-2 rounded-lg text-gray-600 border border-gray-300 hover:bg-gray-50 font-semibold text-base shadow transition disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center gap-2"
|
||||
className="px-2 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded-lg shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center gap-1"
|
||||
onClick={onHistoryToggle}
|
||||
disabled={isProcessing}
|
||||
aria-label="작업 히스토리 보기"
|
||||
>
|
||||
📝
|
||||
{historyCount !== undefined && historyCount > 0 && (
|
||||
<span className="text-xs bg-blue-500 text-white rounded-full px-2 py-0.5 min-w-[20px] h-5 flex items-center justify-center">
|
||||
<span className="text-xs bg-blue-500 text-white rounded-full px-1.5 py-0.5 min-w-[16px] h-4 flex items-center justify-center text-[10px]">
|
||||
{historyCount > 99 ? "99+" : historyCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{/* UNDO 버튼 - 중간 */}
|
||||
{/* UNDO 버튼 */}
|
||||
<button
|
||||
className="px-4 py-2 rounded-lg text-gray-600 border border-gray-300 hover:bg-gray-50 font-semibold text-base shadow transition disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center gap-2"
|
||||
className="px-2 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded-lg shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors disabled:opacity-60 disabled:cursor-not-allowed flex items-center justify-center"
|
||||
onClick={() => {
|
||||
// TODO: UNDO 기능 구현
|
||||
console.log("🔄 UNDO 버튼 클릭");
|
||||
@@ -225,25 +224,25 @@ const PromptInput: React.FC<PromptInputProps> = ({
|
||||
↶
|
||||
</button>
|
||||
|
||||
{/* 전송하기 버튼 - 맨 아래 */}
|
||||
<button
|
||||
className="px-6 py-2 rounded-lg text-white font-semibold text-base shadow transition disabled:opacity-60 disabled:cursor-not-allowed"
|
||||
style={{
|
||||
background: isProcessing
|
||||
? "#6b7280"
|
||||
: "linear-gradient(90deg, #a18fff 0%, #6f6fff 100%)",
|
||||
}}
|
||||
{/* 전송하기 버튼 */}
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className={`text-xs px-3 py-1.5 ${
|
||||
isProcessing || !value.trim()
|
||||
? "bg-gray-400 text-white cursor-not-allowed border-gray-400"
|
||||
: "bg-green-500 hover:bg-green-600 text-white border-green-500"
|
||||
}`}
|
||||
onClick={handleExecute}
|
||||
disabled={isProcessing || !value.trim()}
|
||||
>
|
||||
{isProcessing ? "처리 중..." : "전송하기"}
|
||||
</button>
|
||||
{isProcessing ? "처리중" : "전송"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full max-w-3xl flex justify-between items-center mt-1 px-1">
|
||||
<div className="w-full flex justify-between items-center mt-2 px-1">
|
||||
<span className="text-xs text-gray-500">
|
||||
Press Enter to send, Shift+Enter for new line | 시트에서 셀 클릭하여
|
||||
주소 자동 입력
|
||||
시트에서 셀 클릭시 자동 입력 | Enter로 전송
|
||||
</span>
|
||||
<span className="text-xs text-gray-400">
|
||||
{value.length}/{maxLength}
|
||||
|
||||
Reference in New Issue
Block a user