Commit a16a05a6 by pangchong

style(xml-editor): 优化搜索面板样式并添加中文翻译支持

- 将搜索面板布局改为 CSS Grid,调整搜索相关元素的定位
- 优化输入框和按钮的尺寸、间距及字体大小使界面更紧凑一致
- 为搜索和替换输入框添加 input 事件监听,实现即时触发搜索
- 引入中文短语映射,完善查找替换功能的本地化支持
- 调整插入片段弹窗的编辑器最大高度
- 移除查看 XML 弹窗内无用注释,提升代码简洁性
parent c7097fff
......@@ -205,39 +205,85 @@ const customTheme = EditorView.theme({
'.cm-panels-top': {
borderBottom: '1px solid var(--divider-color, #e8eaed) !important'
},
'.cm-panels-bottom': {
borderTop: '1px solid var(--divider-color, #e8eaed) !important'
},
'.cm-search': {
display: 'flex',
display: 'grid !important',
gridTemplateColumns: '140px repeat(8, auto)',
alignItems: 'center',
padding: '5px 12px !important',
gap: '6px',
flexWrap: 'wrap',
padding: '4px 28px 4px 8px !important',
gap: '4px',
position: 'relative'
},
'.cm-search input[name="search"]': {
gridRow: '1',
gridColumn: '1'
},
'.cm-search input[name="replace"]': {
gridRow: '2',
gridColumn: '1'
},
'.cm-search button[name="next"]': {
gridRow: '1',
gridColumn: '2'
},
'.cm-search button[name="prev"]': {
gridRow: '1',
gridColumn: '3'
},
'.cm-search button[name="select"]': {
gridRow: '1',
gridColumn: '4'
},
'.cm-search .cm-search-count': {
gridRow: '1',
gridColumn: '5',
justifyContent: 'flex-start',
fontSize: '11px !important',
padding: '0 2px !important'
},
'.cm-search label:nth-of-type(1)': {
gridRow: '1',
gridColumn: '6'
},
'.cm-search label:nth-of-type(2)': {
gridRow: '1',
gridColumn: '7'
},
'.cm-search label:nth-of-type(3)': {
gridRow: '1',
gridColumn: '8'
},
'.cm-search button[name="replace"]': {
gridRow: '2',
gridColumn: '2'
},
'.cm-search button[name="replaceAll"]': {
gridRow: '2',
gridColumn: '3'
},
'.cm-search label': {
display: 'inline-flex',
alignItems: 'center',
fontSize: '12px',
fontSize: '11px !important',
color: 'var(--textColor2, #555555)',
cursor: 'pointer',
gap: '2px',
margin: '0 2px !important'
gap: '1px',
margin: '0 !important'
},
'.cm-search input[type="checkbox"]': {
accentColor: 'var(--primary-color, #165DFF)',
marginRight: '2px',
cursor: 'pointer'
marginRight: '1px',
cursor: 'pointer',
transform: 'scale(0.85)'
},
'.cm-textfield': {
width: '140px !important',
backgroundColor: 'var(--card-color, #ffffff) !important',
color: 'var(--textColor1, #333333) !important',
border: '1px solid var(--border-color, #dee2e6) !important',
borderRadius: '4px !important',
padding: '3px 6px !important',
borderRadius: '3px !important',
padding: '2px 5px !important',
outline: 'none !important',
fontSize: '12px !important',
fontSize: '11px !important',
transition: 'border-color 0.15s ease, box-shadow 0.15s ease',
boxShadow: '0 1px 2px rgba(0, 0, 0, 0.02) !important'
},
......@@ -250,13 +296,13 @@ const customTheme = EditorView.theme({
color: 'var(--textColor1, #333333) !important',
backgroundImage: 'none !important',
border: 'none !important',
borderRadius: '4px !important',
padding: '3px 8px !important',
fontSize: '12px !important',
borderRadius: '3px !important',
padding: '2px 6px !important',
fontSize: '11px !important',
fontWeight: '500 !important',
cursor: 'pointer !important',
transition: 'all 0.15s ease',
margin: '0 1px !important'
margin: '0 !important'
},
'.cm-button:hover': {
backgroundColor: 'var(--primary-color, #165DFF) !important',
......@@ -270,19 +316,19 @@ const customTheme = EditorView.theme({
position: 'absolute',
top: '50% !important',
transform: 'translateY(-50%)',
right: '8px !important',
right: '6px !important',
color: 'var(--textColor3, #999999) !important',
backgroundColor: 'transparent !important',
border: 'none !important',
cursor: 'pointer !important',
width: '22px !important',
height: '22px !important',
width: '18px !important',
height: '18px !important',
display: 'inline-flex !important',
alignItems: 'center !important',
justifyContent: 'center !important',
borderRadius: '50% !important',
transition: 'all 0.15s ease',
fontSize: '14px !important',
fontSize: '12px !important',
padding: '0 !important',
margin: '0 !important'
},
......@@ -424,15 +470,44 @@ const xmlCompletionSource = (context: CompletionContext) => {
return null
}
const chinesePhrases = EditorState.phrases.of({
"Find": "查找",
"Replace": "替换",
"next": "下一个",
"previous": "上一个",
"all": "全部",
"match case": "区分大小写",
"regexp": "正则表达式",
"by word": "全字匹配",
"replace": "替换",
"replace all": "全部替换"
})
const updateSearchCount = (view: EditorView) => {
const searchPanel = view.dom.querySelector('.cm-search')
if (!searchPanel) return
// 绑定 input 监听器以实现即时检索
const searchInput = searchPanel.querySelector('input[name="search"]') as HTMLInputElement
if (searchInput && !searchInput.dataset.instantBound) {
searchInput.dataset.instantBound = 'true'
searchInput.addEventListener('input', () => {
searchInput.dispatchEvent(new Event('change', { bubbles: true }))
})
}
const replaceInput = searchPanel.querySelector('input[name="replace"]') as HTMLInputElement
if (replaceInput && !replaceInput.dataset.instantBound) {
replaceInput.dataset.instantBound = 'true'
replaceInput.addEventListener('input', () => {
replaceInput.dispatchEvent(new Event('change', { bubbles: true }))
})
}
let countEl = searchPanel.querySelector('.cm-search-count') as HTMLElement
if (!countEl) {
countEl = document.createElement('span')
countEl.className = 'cm-search-count'
const searchInput = searchPanel.querySelector('input[name="search"]')
if (searchInput && searchInput.nextSibling) {
searchPanel.insertBefore(countEl, searchInput.nextSibling)
} else if (searchInput) {
......@@ -515,6 +590,7 @@ const initCodeMirror = () => {
xml(),
syntaxHighlighting(customHighlightStyle),
customTheme,
chinesePhrases,
EditorState.readOnly.of(props.disabled),
EditorView.editable.of(!props.disabled),
...(!props.disabled ? [autocompletion({ override: [xmlCompletionSource] })] : []),
......
......@@ -15,7 +15,7 @@
</div>
<!-- 编辑器组件 -->
<CommonXmlEditor ref="xmlEditorRef" v-model="xmlContent" :max-height="hasClipboardContent ? '70vh' : undefined" />
<CommonXmlEditor ref="xmlEditorRef" v-model="xmlContent" :max-height="hasClipboardContent ? '65vh' : undefined" />
<!-- 底部快捷键或帮助提示 -->
<div class="text-[10px] text-color3 flex items-center justify-between">
......
<template>
<CommonModal :scrollable="false" v-model="viewXmlVisible" :title="viewXmlTitle" :width="900" :show-confirm="false" cancel-text="关闭">
<div class="flex flex-col space-y-4">
<!-- 使用全局 CommonXmlEditor 组件展示只读的 XML 内容 -->
<CommonXmlEditor :model-value="formattedXmlContent" disabled max-height="70vh" />
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment