86 lines
2.5 KiB
Vue
86 lines
2.5 KiB
Vue
<template>
|
||
<div class="input-bar">
|
||
<div class="input-box">
|
||
<textarea
|
||
ref="ta"
|
||
v-model="text"
|
||
class="ta"
|
||
:disabled="disabled"
|
||
rows="1"
|
||
placeholder="输入消息,Enter 发送,Shift+Enter 换行"
|
||
@input="autoGrow"
|
||
@keydown.enter.exact.prevent="submit"
|
||
></textarea>
|
||
<button class="send" :disabled="disabled || !text.trim()" @click="submit">
|
||
<span v-if="!disabled">➤</span>
|
||
<span v-else class="spinner"></span>
|
||
</button>
|
||
</div>
|
||
<p class="tip">小鑫可以读写文件、分析 Excel、执行命令(危险操作需你审批)</p>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, nextTick } from "vue";
|
||
|
||
defineProps<{ disabled?: boolean }>();
|
||
const emit = defineEmits<{ send: [text: string] }>();
|
||
|
||
const text = ref("");
|
||
const ta = ref<HTMLTextAreaElement | null>(null);
|
||
|
||
function autoGrow() {
|
||
const el = ta.value;
|
||
if (!el) return;
|
||
el.style.height = "auto";
|
||
el.style.height = Math.min(el.scrollHeight, 160) + "px";
|
||
}
|
||
|
||
function submit() {
|
||
const v = text.value.trim();
|
||
if (!v) return;
|
||
emit("send", v);
|
||
text.value = "";
|
||
nextTick(autoGrow);
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.input-bar {
|
||
padding: 12px 20px 16px;
|
||
}
|
||
.input-box {
|
||
display: flex; align-items: flex-end; gap: 10px;
|
||
background: var(--surface);
|
||
border: 1px solid var(--border);
|
||
border-radius: 16px;
|
||
padding: 8px 8px 8px 16px;
|
||
box-shadow: var(--shadow);
|
||
transition: border-color 0.15s, box-shadow 0.15s;
|
||
}
|
||
.input-box:focus-within {
|
||
border-color: var(--primary);
|
||
box-shadow: var(--shadow), 0 0 0 3px var(--primary-soft);
|
||
}
|
||
.ta {
|
||
flex: 1; resize: none; border: none; outline: none;
|
||
background: transparent; color: var(--text);
|
||
font: inherit; font-size: 14.5px; line-height: 1.5;
|
||
max-height: 160px; padding: 6px 0;
|
||
}
|
||
.ta:disabled { opacity: 0.6; }
|
||
.send {
|
||
width: 42px; height: 42px; flex-shrink: 0; border: none; border-radius: 12px;
|
||
background: var(--primary); color: #fff; cursor: pointer; font-size: 16px;
|
||
display: grid; place-items: center; transition: 0.15s;
|
||
}
|
||
.send:hover:not(:disabled) { background: var(--primary-hover); }
|
||
.send:disabled { background: var(--text-dim); cursor: not-allowed; }
|
||
.spinner {
|
||
width: 16px; height: 16px; border: 2px solid rgba(255,255,255,0.4);
|
||
border-top-color: #fff; border-radius: 50%; animation: spin 0.7s linear infinite;
|
||
}
|
||
@keyframes spin { to { transform: rotate(360deg); } }
|
||
.tip { text-align: center; font-size: 12px; color: var(--text-dim); margin: 8px 0 0; }
|
||
</style>
|