web_ppt / frontend /src /views /Editor /SearchPanel.vue
CatPtain's picture
Upload 339 files
89ce340 verified
raw
history blame
3.54 kB
<template>
<MoveablePanel
class="search-panel"
:width="330"
:height="0"
:left="-270"
:top="90"
>
<div class="close-btn" @click="close()" @mousedown.stop><IconClose /></div>
<Tabs
:tabs="tabs"
v-model:value="type"
/>
<div class="content" :class="type" @mousedown.stop>
<Input class="input" v-model:value="searchWord" placeholder="输入查找内容" @enter="searchNext()" ref="searchInpRef">
<template #suffix>
<span class="count">{{searchIndex + 1}}/{{searchResults.length}}</span>
<Divider type="vertical" />
<span class="ignore-case"
:class="{ 'active': modifiers === 'g' }"
v-tooltip="'忽略大小写'"
@click="toggleModifiers()"
>Aa</span>
<Divider type="vertical" />
<IconLeft class="next-btn left" @click="searchPrev()" v-tooltip="'上一个'" />
<IconRight class="next-btn right" @click="searchNext()" v-tooltip="'下一个'" />
</template>
</Input>
<Input class="input" v-model:value="replaceWord" placeholder="输入替换内容" @enter="replace()" v-if="type === 'replace'"></Input>
<div class="footer" v-if="type === 'replace'">
<Button :disabled="!searchWord" style="margin-left: 5px;" @click="replace()">替换</Button>
<Button :disabled="!searchWord" type="primary" style="margin-left: 5px;" @click="replaceAll()">全部替换</Button>
</div>
</div>
</MoveablePanel>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, watch } from 'vue'
import { useMainStore } from '@/store'
import useSearch from '@/hooks/useSearch'
import MoveablePanel from '@/components/MoveablePanel.vue'
import Tabs from '@/components/Tabs.vue'
import Divider from '@/components/Divider.vue'
import Input from '@/components/Input.vue'
import Button from '@/components/Button.vue'
type TypeKey = 'search' | 'replace'
interface TabItem {
key: TypeKey
label: string
}
const mainStore = useMainStore()
const {
searchWord,
replaceWord,
searchResults,
searchIndex,
modifiers,
searchNext,
searchPrev,
replace,
replaceAll,
toggleModifiers,
} = useSearch()
const type = ref<TypeKey>('search')
const tabs: TabItem[] = [
{ key: 'search', label: '查找' },
{ key: 'replace', label: '替换' },
]
const close = () => {
mainStore.setSearchPanelState(false)
}
const searchInpRef = ref<InstanceType<typeof Input>>()
onMounted(() => {
searchInpRef.value!.focus()
})
watch(type, () => {
nextTick(() => {
searchInpRef.value!.focus()
})
})
</script>
<style lang="scss" scoped>
.search-panel {
font-size: 13px;
}
.content {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.input {
margin-top: 10px;
}
.count {
font-size: 12px;
margin-right: 8px;
user-select: none;
}
.ignore-case {
font-size: 12px;
user-select: none;
cursor: pointer;
&.active {
color: $themeColor;
}
}
.next-btn {
width: 22px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
margin: 0 !important;
user-select: none;
cursor: pointer;
&:hover {
color: $themeColor;
}
}
.footer {
display: flex;
justify-content: flex-end;
align-items: center;
margin-top: 10px;
}
.close-btn {
width: 32px;
height: 32px;
position: absolute;
top: 8px;
right: 3px;
display: flex;
justify-content: center;
align-items: center;
color: #666;
font-size: 13px;
cursor: pointer;
}
</style>