style(highlight-textarea): 优化文本域样式和功能

This commit is contained in:
renxiaodong
2025-09-13 14:05:39 +08:00
parent 493ba8b99c
commit e198fa3433
2 changed files with 44 additions and 37 deletions

View File

@ -110,7 +110,7 @@ const generateHighlightedHtml = (): string => {
const levelStyle = props.levelMap?.get(wordInfo.risk_level); const levelStyle = props.levelMap?.get(wordInfo.risk_level);
const color = levelStyle?.color || '#F64B31'; const color = levelStyle?.color || '#F64B31';
return `<span class="text-14px font-400 lh-22px" style="color: ${color};">${escapeHtml(match)}</span>`; return `<span class="text-14px font-400 lh-22px font-family-regular" style="color: ${color};">${escapeHtml(match)}</span>`;
}); });
}; };
@ -174,6 +174,7 @@ const handleCompositionUpdate = () => {
font-size: 14px; font-size: 14px;
line-height: 22px; line-height: 22px;
font-weight: 400; font-weight: 400;
font-family: $font-family-regular;
//border: 1px solid #d7d7d9; //border: 1px solid #d7d7d9;
border-radius: 4px; border-radius: 4px;
resize: none; resize: none;
@ -209,15 +210,20 @@ const handleCompositionUpdate = () => {
resize: none; resize: none;
@include textarea-padding; @include textarea-padding;
overflow-y: auto; overflow-y: auto;
} &.ant-input-disabled {
background: #f2f3f5 !important;
-webkit-text-fill-color: rgba(0, 0, 0, 0.25) !important;
}
.arco-textarea-word-limit {
z-index: 2;
} }
&.ant-input-textarea-show-count {
&.arco-textarea-disabled { &::after {
.arco-textarea { position: absolute;
background: #f2f3f5; z-index: 2;
font-size: 12px;
right: 10px;
bottom: 6px;
user-select: none;
} }
} }
} }

View File

@ -1,12 +1,12 @@
<template> <template>
<div class="highlight-textarea-container"> <div class="highlight-textarea-container">
<a-textarea <TextArea
ref="textareaWrapRef" ref="textareaWrapRef"
v-model="inputValue" v-model:value="inputValue"
placeholder="请输入作品描述" placeholder="请输入作品描述"
:disabled="disabled" :disabled="disabled"
show-word-limit showCount
:max-length="1000" :maxlength="1000"
size="large" size="large"
class="textarea-input h-full w-full" class="textarea-input h-full w-full"
@input="handleInput" @input="handleInput"
@ -25,7 +25,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { Input } from 'ant-design-vue'; import { Input } from 'ant-design-vue';
const {TextArea} = Input
const { TextArea } = Input;
import { ref, computed, watch, defineProps, defineEmits, onMounted, onUnmounted } from 'vue'; import { ref, computed, watch, defineProps, defineEmits, onMounted, onUnmounted } from 'vue';
import { escapeRegExp } from './constants'; import { escapeRegExp } from './constants';
@ -69,8 +70,8 @@ watch(
); );
// 处理输入事件 // 处理输入事件
const handleInput = (value: string) => { const handleInput = (e) => {
emit('update:modelValue', value); emit('update:modelValue', e.currentTarget.value);
}; };
const escapeHtml = (str: string): string => { const escapeHtml = (str: string): string => {
@ -109,14 +110,12 @@ const generateHighlightedHtml = (): string => {
const levelStyle = props.levelMap?.get(wordInfo.risk_level); const levelStyle = props.levelMap?.get(wordInfo.risk_level);
const color = levelStyle?.color || '#F64B31'; const color = levelStyle?.color || '#F64B31';
return `<span class="text-14px font-400 lh-22px" style="color: ${color};">${escapeHtml(match)}</span>`; return `<span class="text-14px font-400 lh-22px font-family-regular" style="color: ${color};">${escapeHtml(match)}</span>`;
}); });
}; };
onMounted(() => { onMounted(() => {
nativeTextarea = nativeTextarea = textareaWrapRef.value?.$el?.querySelector?.('textarea.ant-input');
(textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') ||
document.querySelector('.textarea-input .arco-textarea');
if (nativeTextarea) { if (nativeTextarea) {
nativeTextarea.addEventListener('scroll', handleTextareaScroll); nativeTextarea.addEventListener('scroll', handleTextareaScroll);
@ -146,6 +145,7 @@ const handleTextareaScroll = (e: Event) => {
const handleCompositionUpdate = () => { const handleCompositionUpdate = () => {
if (!nativeTextarea) return; if (!nativeTextarea) return;
console.log('handleCompositionUpdate', nativeTextarea.value);
// 使用 rAF 等待浏览器把最新字符写入 textarea.value 再读取 // 使用 rAF 等待浏览器把最新字符写入 textarea.value 再读取
requestAnimationFrame(() => { requestAnimationFrame(() => {
if (!nativeTextarea) return; if (!nativeTextarea) return;
@ -173,8 +173,9 @@ const handleCompositionUpdate = () => {
height: 100%; height: 100%;
font-size: 14px; font-size: 14px;
line-height: 22px; line-height: 22px;
font-weight: 400px; font-weight: 400;
border: 1px solid #d7d7d9; font-family: $font-family-regular;
//border: 1px solid #d7d7d9;
border-radius: 4px; border-radius: 4px;
resize: none; resize: none;
white-space: pre-wrap; white-space: pre-wrap;
@ -192,43 +193,43 @@ const handleCompositionUpdate = () => {
background: #fff; background: #fff;
overflow: hidden; overflow: hidden;
@include textarea-padding; @include textarea-padding;
&.focus {
border-color: rgb(var(--primary-6)) !important;
box-shadow: 0 0 0 0 var(--color-primary-light-2) !important;
}
} }
:deep(.arco-textarea-wrapper) { :deep(.ant-input-textarea) {
@include textarea-style; @include textarea-style;
.arco-textarea { textarea {
padding: 0; padding: 0;
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
z-index: 1; z-index: 1;
width: 100%; width: 100%;
background: transparent; background-color: transparent !important;
color: transparent; color: transparent;
caret-color: #211f24 !important; caret-color: #211f24 !important;
resize: none; resize: none;
@include textarea-padding; @include textarea-padding;
overflow-y: auto; overflow-y: auto;
} &.ant-input-disabled {
background: #f2f3f5 !important;
-webkit-text-fill-color: rgba(0, 0, 0, 0.25) !important;
}
.arco-textarea-word-limit {
z-index: 2;
} }
&.ant-input-textarea-show-count {
&.arco-textarea-disabled { &::after {
.arco-textarea { position: absolute;
background: #f2f3f5; z-index: 2;
font-size: 12px;
right: 10px;
bottom: 6px;
user-select: none;
} }
} }
} }
// 处于中文输入法合成态时,显示真实文本并隐藏高亮层 // 处于中文输入法合成态时,显示真实文本并隐藏高亮层
:deep(.textarea-input.composing .arco-textarea) { :deep(.ant-input-textarea.composing textarea) {
color: #211f24 !important; color: #211f24 !important;
-webkit-text-fill-color: #211f24 !important; -webkit-text-fill-color: #211f24 !important;
} }