mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-10 08:57:10 +08:00
revert: 还原深浅主题切换
This commit is contained in:
@@ -1,65 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-button size="mini" class="gi_hover_btn" @click="handleToggleTheme">
|
|
||||||
<template #icon>
|
|
||||||
<icon-moon-fill v-if="appStore.theme === 'light'" :size="18" />
|
|
||||||
<icon-sun-fill v-else :size="18" />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { useDark, useToggle } from '@vueuse/core'
|
|
||||||
|
|
||||||
import { useAppStore } from '@/stores'
|
|
||||||
|
|
||||||
defineOptions({
|
|
||||||
name: 'ToggleDark',
|
|
||||||
})
|
|
||||||
|
|
||||||
const appStore = useAppStore()
|
|
||||||
|
|
||||||
const isDark = useDark({
|
|
||||||
onChanged(dark: boolean) {
|
|
||||||
document.documentElement.setAttribute('class', dark ? 'dark' : 'light')
|
|
||||||
appStore.toggleTheme(dark)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const toggleTheme = useToggle(isDark)
|
|
||||||
|
|
||||||
const isAppearanceTransition = typeof document !== 'undefined'
|
|
||||||
&& 'startViewTransition' in document
|
|
||||||
&& !window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
||||||
|
|
||||||
const handleToggleTheme = (event?: MouseEvent) => {
|
|
||||||
if (!isAppearanceTransition || !event) {
|
|
||||||
return toggleTheme()
|
|
||||||
}
|
|
||||||
|
|
||||||
const { clientX: x, clientY: y } = event
|
|
||||||
const endRadius = Math.hypot(
|
|
||||||
Math.max(x, innerWidth - x),
|
|
||||||
Math.max(y, innerHeight - y),
|
|
||||||
)
|
|
||||||
const transition = (document as any).startViewTransition(toggleTheme)
|
|
||||||
|
|
||||||
transition.ready.then(() => {
|
|
||||||
const clipPath = [
|
|
||||||
`circle(0px at ${x}px ${y}px)`,
|
|
||||||
`circle(${endRadius}px at ${x}px ${y}px)`,
|
|
||||||
]
|
|
||||||
document.documentElement.animate(
|
|
||||||
{
|
|
||||||
clipPath: isDark.value ? [...clipPath].reverse() : clipPath,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
duration: 500,
|
|
||||||
easing: 'ease-in',
|
|
||||||
pseudoElement: isDark.value
|
|
||||||
? '::view-transition-old(root)'
|
|
||||||
: '::view-transition-new(root)',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
@@ -1,3 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<div class="search-trigger" @click="visible = true">
|
||||||
|
<icon-search :size="18" style="margin-right: 4px;" />
|
||||||
|
<span class="search-text">
|
||||||
|
搜索
|
||||||
|
</span>
|
||||||
|
<span class="shortcut-key">
|
||||||
|
Ctrl + K
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="search-modal">
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
:mask-closable="true"
|
||||||
|
:align-center="false"
|
||||||
|
:closable="false"
|
||||||
|
:render-to-body="false"
|
||||||
|
@cancel="visible = false"
|
||||||
|
@keydown="handleKeyDown"
|
||||||
|
>
|
||||||
|
<template #title>
|
||||||
|
<div class="search-input-wrapper">
|
||||||
|
<icon-search :size="24" />
|
||||||
|
<input ref="searchInput" v-model="searchKeyword" placeholder="搜索页面" class="search-input">
|
||||||
|
<div class="esc-tip">
|
||||||
|
ESC 退出
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="search-content">
|
||||||
|
<div v-if="searchResults.length">
|
||||||
|
<div class="result-count">
|
||||||
|
搜索到 {{ searchResults.length }} 个结果
|
||||||
|
</div>
|
||||||
|
<div class="result-list">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in searchResults" :key="item.path" class="result-item"
|
||||||
|
:class="{ selected: selectedIndex === index }" @click="handleResultClick(item)"
|
||||||
|
>
|
||||||
|
<icon-file :size="18" style="margin-right: 6px;" />
|
||||||
|
<div class="result-title">
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="searchHistory.length" class="history-section">
|
||||||
|
<div class="history-header">
|
||||||
|
<div class="history-title">
|
||||||
|
搜索历史
|
||||||
|
</div>
|
||||||
|
<a-button type="text" size="small" class="text-xs" @click="clearHistory">
|
||||||
|
清空历史
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="history-list">
|
||||||
|
<div v-for="item in searchHistory" :key="item.path" class="history-item" @click="handleHistoryClick(item)">
|
||||||
|
<icon-history :size="18" style="margin-right: 6px;" />
|
||||||
|
<div class="result-title">
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="shortcut">
|
||||||
|
<GiSvgIcon name="select" :size="12" class="shortcut-icon" />
|
||||||
|
<div>切换</div>
|
||||||
|
</div>
|
||||||
|
<div class="shortcut">
|
||||||
|
<GiSvgIcon name="shortcut-enter" :size="12" class="shortcut-icon" />
|
||||||
|
<div>选择</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useEventListener } from '@vueuse/core'
|
import { useEventListener } from '@vueuse/core'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
@@ -114,85 +193,6 @@ watch(searchKeyword, (newValue) => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="search-trigger" @click="visible = true">
|
|
||||||
<icon-search :size="18" style="margin-right: 4px;" />
|
|
||||||
<span class="search-text">
|
|
||||||
搜索
|
|
||||||
</span>
|
|
||||||
<span class="shortcut-key">
|
|
||||||
Ctrl + K
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="search-modal">
|
|
||||||
<a-modal
|
|
||||||
:visible="visible"
|
|
||||||
:mask-closable="true"
|
|
||||||
:align-center="false"
|
|
||||||
:closable="false"
|
|
||||||
:render-to-body="false"
|
|
||||||
@cancel="visible = false"
|
|
||||||
@keydown="handleKeyDown"
|
|
||||||
>
|
|
||||||
<template #title>
|
|
||||||
<div class="search-input-wrapper">
|
|
||||||
<icon-search :size="24" />
|
|
||||||
<input ref="searchInput" v-model="searchKeyword" placeholder="搜索页面" class="search-input">
|
|
||||||
<div class="esc-tip">
|
|
||||||
ESC 退出
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="search-content">
|
|
||||||
<div v-if="searchResults.length">
|
|
||||||
<div class="result-count">
|
|
||||||
搜索到 {{ searchResults.length }} 个结果
|
|
||||||
</div>
|
|
||||||
<div class="result-list">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in searchResults" :key="item.path" class="result-item"
|
|
||||||
:class="{ selected: selectedIndex === index }" @click="handleResultClick(item)"
|
|
||||||
>
|
|
||||||
<icon-file :size="18" style="margin-right: 6px;" />
|
|
||||||
<div class="result-title">
|
|
||||||
{{ item.title }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="searchHistory.length" class="history-section">
|
|
||||||
<div class="history-header">
|
|
||||||
<div class="history-title">
|
|
||||||
搜索历史
|
|
||||||
</div>
|
|
||||||
<a-button type="text" size="small" class="text-xs" @click="clearHistory">
|
|
||||||
清空历史
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
<div class="history-list">
|
|
||||||
<div v-for="item in searchHistory" :key="item.path" class="history-item" @click="handleHistoryClick(item)">
|
|
||||||
<icon-history :size="18" style="margin-right: 6px;" />
|
|
||||||
<div class="result-title">
|
|
||||||
{{ item.title }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<div class="shortcut">
|
|
||||||
<GiSvgIcon name="select" :size="12" class="shortcut-icon" />
|
|
||||||
<div>切换</div>
|
|
||||||
</div>
|
|
||||||
<div class="shortcut">
|
|
||||||
<GiSvgIcon name="shortcut-enter" :size="12" class="shortcut-icon" />
|
|
||||||
<div>选择</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</a-modal>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.search-trigger {
|
.search-trigger {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -201,11 +201,7 @@ watch(searchKeyword, (newValue) => {
|
|||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #f3f4f6;
|
background-color: var(--color-bg-4);
|
||||||
|
|
||||||
.dark & {
|
|
||||||
background-color: var(--color-bg-2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-text {
|
.search-text {
|
||||||
@@ -218,12 +214,8 @@ watch(searchKeyword, (newValue) => {
|
|||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: #e5e7eb;
|
background-color: var(--color-bg-3);
|
||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
|
|
||||||
.dark & {
|
|
||||||
background-color: var(--color-bg-4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-modal {
|
.search-modal {
|
||||||
@@ -263,12 +255,8 @@ watch(searchKeyword, (newValue) => {
|
|||||||
padding: 0.25rem 0.375rem;
|
padding: 0.25rem 0.375rem;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
border-radius: 0.375rem;
|
border-radius: 0.375rem;
|
||||||
background-color: #e5e7eb;
|
background-color: var(--color-fill-2);
|
||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
|
|
||||||
.dark & {
|
|
||||||
background-color: var(--color-bg-4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.result-count {
|
.result-count {
|
||||||
@@ -292,13 +280,8 @@ watch(searchKeyword, (newValue) => {
|
|||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #000;
|
background-color: var(--color-bg-4);
|
||||||
background-color: #f3f4f6;
|
color: var(--color-text-1);
|
||||||
|
|
||||||
.dark & {
|
|
||||||
color: #fff;
|
|
||||||
background-color: var(--color-bg-4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,24 +320,13 @@ watch(searchKeyword, (newValue) => {
|
|||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #000;
|
background-color: var(--color-bg-4);
|
||||||
background-color: #f3f4f6;
|
color: var(--color-text-1);
|
||||||
|
|
||||||
.dark & {
|
|
||||||
color: #fff;
|
|
||||||
background-color: var(--color-bg-4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.selected {
|
.selected {
|
||||||
color: #000;
|
background-color: var(--color-bg-4);
|
||||||
background-color: #f3f4f6;
|
|
||||||
|
|
||||||
.dark & {
|
|
||||||
color: #fff;
|
|
||||||
background-color: var(--color-bg-4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.arco-modal-footer){
|
:deep(.arco-modal-footer){
|
||||||
@@ -372,13 +344,9 @@ watch(searchKeyword, (newValue) => {
|
|||||||
|
|
||||||
&-icon{
|
&-icon{
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
background-color: #e5e7eb;
|
background-color:var(--color-fill-2);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: var(--color-text-1);
|
color: var(--color-text-1);
|
||||||
|
|
||||||
.dark & {
|
|
||||||
background-color: var(--color-bg-5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
<a-row justify="end" align="center">
|
<a-row justify="end" align="center">
|
||||||
<a-space size="medium">
|
<a-space size="medium">
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<Search />
|
<Search v-if="isDesktop" />
|
||||||
<!-- 项目配置 -->
|
<!-- 项目配置 -->
|
||||||
<a-tooltip content="项目配置" position="bl">
|
<a-tooltip content="项目配置" position="bl">
|
||||||
<a-button size="mini" class="gi_hover_btn" @click="SettingDrawerRef?.open">
|
<a-button size="mini" class="gi_hover_btn" @click="SettingDrawerRef?.open">
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
<!-- 暗黑模式切换 -->
|
<!-- 暗黑模式切换 -->
|
||||||
<a-tooltip content="主题切换" position="bottom">
|
<a-tooltip content="主题切换" position="bottom">
|
||||||
<ToggleDark />
|
<GiThemeBtn></GiThemeBtn>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
|
||||||
<!-- 管理员账户 -->
|
<!-- 管理员账户 -->
|
||||||
@@ -80,10 +80,11 @@ import Search from './Search.vue'
|
|||||||
import { getUnreadMessageCount } from '@/apis'
|
import { getUnreadMessageCount } from '@/apis'
|
||||||
import { useUserStore } from '@/stores'
|
import { useUserStore } from '@/stores'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import { useBreakpoint } from '@/hooks'
|
import { useBreakpoint, useDevice } from '@/hooks'
|
||||||
|
|
||||||
defineOptions({ name: 'HeaderRight' })
|
defineOptions({ name: 'HeaderRight' })
|
||||||
|
|
||||||
|
const { isDesktop } = useDevice()
|
||||||
const { breakpoint } = useBreakpoint()
|
const { breakpoint } = useBreakpoint()
|
||||||
let socket: WebSocket
|
let socket: WebSocket
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
@@ -529,20 +529,3 @@
|
|||||||
border-radius: 0 4px 4px 0;
|
border-radius: 0 4px 4px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 禁用 view-transition 动画
|
|
||||||
::view-transition-old(root),
|
|
||||||
::view-transition-new(root) {
|
|
||||||
animation: none;
|
|
||||||
mix-blend-mode: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
::view-transition-old(root),
|
|
||||||
.dark::view-transition-new(root) {
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
::view-transition-new(root),
|
|
||||||
.dark::view-transition-old(root) {
|
|
||||||
z-index: 9999;
|
|
||||||
}
|
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ToggleDark class="theme-btn" />
|
<GiThemeBtn class="theme-btn" />
|
||||||
<Background />
|
<Background />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ToggleDark class="theme-btn" />
|
<GiThemeBtn class="theme-btn" />
|
||||||
<Background />
|
<Background />
|
||||||
</div>
|
</div>
|
||||||
<div class="login h5">
|
<div class="login h5">
|
||||||
|
Reference in New Issue
Block a user