forked from Leaf/amber-ui
改进 输入
This commit is contained in:
parent
3c0ceb7e31
commit
e57690d596
@ -16,22 +16,39 @@
|
|||||||
<div class="absolute bottom-0 left-0 right-0 pb-5">
|
<div class="absolute bottom-0 left-0 right-0 pb-5">
|
||||||
<div
|
<div
|
||||||
ref="inputContainer"
|
ref="inputContainer"
|
||||||
class="mx-auto w-full max-w-2xl outline-none input-text input-bg rounded-full flex pl-5 pr-5 bg-white shadow-lg items-center"
|
class="mx-auto w-2xl max-w-2xl outline-none input-color input-bg rounded-full flex pl-5 pr-5 bg-white shadow-lg items-center p-4 pb-4"
|
||||||
>
|
>
|
||||||
<div class="overflow-x-hidden h-full w-full flex items-center">
|
<div class="overflow-x-hidden h-full w-full flex items-center">
|
||||||
<n-scrollbar>
|
<n-scrollbar class="max-h-96">
|
||||||
<div
|
<div
|
||||||
ref="inputText"
|
ref="inputText"
|
||||||
|
:class="{ 'has-placeholder': isPlaceholderVisible }"
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
class="input-text max-w-full outline-none"
|
placeholder="请输入文本..."
|
||||||
|
class="input-text max-w-full outline-none text-lg text-pretty pl-2"
|
||||||
@input="updateInputHeight"
|
@input="updateInputHeight"
|
||||||
>
|
></div>
|
||||||
<p>content</p>
|
|
||||||
</div>
|
|
||||||
</n-scrollbar>
|
</n-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div
|
||||||
<button>按钮</button>
|
ref="actionContainer"
|
||||||
|
class="flex [&>button]:ml-2 pr-4 justify-end"
|
||||||
|
>
|
||||||
|
<n-button tertiary circle size="large">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon><DocumentAttachOutline /></n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
<n-button tertiary circle size="large">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon><MicOutline /></n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
<n-button tertiary circle size="large" v-show="showSendBtn">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon><SendOutline /></n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -42,6 +59,11 @@
|
|||||||
import { useMessage } from "naive-ui";
|
import { useMessage } from "naive-ui";
|
||||||
import { useUserStore } from "../../stores/user";
|
import { useUserStore } from "../../stores/user";
|
||||||
import { InputHTMLAttributes, onMounted, ref } from "vue";
|
import { InputHTMLAttributes, onMounted, ref } from "vue";
|
||||||
|
import {
|
||||||
|
SendOutline,
|
||||||
|
MicOutline,
|
||||||
|
DocumentAttachOutline,
|
||||||
|
} from "@vicons/ionicons5";
|
||||||
|
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@ -49,28 +71,70 @@ const userStore = useUserStore();
|
|||||||
const inputMessage = ref("");
|
const inputMessage = ref("");
|
||||||
const inputContainer: any = ref(null);
|
const inputContainer: any = ref(null);
|
||||||
const inputText: InputHTMLAttributes | null = ref(null);
|
const inputText: InputHTMLAttributes | null = ref(null);
|
||||||
|
const actionContainer: any = ref(null);
|
||||||
|
const isPlaceholderVisible = ref(true);
|
||||||
|
const triggerTimes = ref(0);
|
||||||
|
const showSendBtn = ref(false)
|
||||||
|
const content = ref("")
|
||||||
|
|
||||||
function updateInputHeight() {
|
function updateInputHeight() {
|
||||||
if (!inputText?.value || !inputContainer.value) {
|
if (!inputText?.value || !inputContainer.value || !actionContainer.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const input = inputText.value;
|
const input = inputText.value;
|
||||||
const container = inputContainer.value;
|
const container = inputContainer.value;
|
||||||
|
const action = actionContainer.value;
|
||||||
|
|
||||||
|
content.value = input.innerText;
|
||||||
|
const trimContent = input.innerText.trim();
|
||||||
|
|
||||||
|
const isEmpty = trimContent === "";
|
||||||
|
isPlaceholderVisible.value = isEmpty;
|
||||||
|
if (isEmpty || trimContent.length < 30) {
|
||||||
|
triggerTimes.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trimContent.length > 30) {
|
||||||
|
triggerTimes.value = 10;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取元素实际占用高度
|
// 获取元素实际占用高度
|
||||||
const height = input.scrollHeight;
|
const height = input.scrollHeight;
|
||||||
|
|
||||||
const lines = input.innerText.split("\n").length;
|
const lines = input.innerText.split("\n").length;
|
||||||
|
|
||||||
if (lines > 2 || height > 50) {
|
if (lines > 3 || height > 50) {
|
||||||
|
triggerTimes.value += 1;
|
||||||
|
} else {
|
||||||
|
triggerTimes.value -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggerTimes.value > 8) {
|
||||||
container.classList.add("rounded-lg");
|
container.classList.add("rounded-lg");
|
||||||
container.classList.remove("rounded-full");
|
container.classList.remove("rounded-full");
|
||||||
container.classList.add("p-4")
|
container.classList.remove("max-w-2xl");
|
||||||
|
container.classList.remove("w-2xl");
|
||||||
|
container.classList.add("flex-col");
|
||||||
|
action.classList.add("w-full");
|
||||||
|
action.classList.add("text-right");
|
||||||
|
action.classList.add("pt-4");
|
||||||
|
action.classList.add("pb-0");
|
||||||
|
action.classList.add("mt-2");
|
||||||
|
showSendBtn.value = true
|
||||||
} else {
|
} else {
|
||||||
container.classList.remove("rounded-lg");
|
container.classList.remove("rounded-lg");
|
||||||
container.classList.add("rounded-full");
|
container.classList.add("rounded-full");
|
||||||
container.classList.remove("p-4")
|
container.classList.remove("flex-col");
|
||||||
|
container.classList.add("w-2xl");
|
||||||
|
container.classList.add("max-w-2xl");
|
||||||
|
|
||||||
|
action.classList.remove("w-full");
|
||||||
|
action.classList.remove("text-right");
|
||||||
|
action.classList.remove("pt-4");
|
||||||
|
action.classList.remove("pt-0");
|
||||||
|
action.classList.remove("mt-2");
|
||||||
|
showSendBtn.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,22 +144,42 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.input-text {
|
.input-color {
|
||||||
color: #d4d4d4;
|
color: #3a3a3a;
|
||||||
}
|
}
|
||||||
.input-bg {
|
.input-bg {
|
||||||
background-color: #1e1f20;
|
background-color: #eeeeee;
|
||||||
}
|
}
|
||||||
.input-text {
|
.input-text {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding-right: 10px; /* 为按钮区域留出一些空间 */
|
padding-right: 10px; /* 为按钮区域留出一些空间 */
|
||||||
}
|
}
|
||||||
button {
|
.input-text {
|
||||||
padding: 5px 10px;
|
position: relative;
|
||||||
border: none;
|
}
|
||||||
background-color: #007bff;
|
|
||||||
color: white;
|
.input-text.has-placeholder::before {
|
||||||
border-radius: 5px;
|
content: attr(placeholder);
|
||||||
cursor: pointer;
|
color: #999; /* 可以自定义颜色 */
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
pointer-events: none; /* 确保用户点击时不会触发 placeholder */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding: 8px; /* 根据实际布局调整内边距 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 如果是暗黑模式 */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.input-color {
|
||||||
|
color: #d4d4d4;
|
||||||
|
}
|
||||||
|
.input-bg {
|
||||||
|
background-color: #1e1f20;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user