Feature(custom): optimize hover ui

This commit is contained in:
Kuingsmile
2026-01-25 16:26:58 +08:00
parent 88a5a8087a
commit 25788252f9
8 changed files with 45 additions and 35 deletions

View File

@@ -1,7 +1,7 @@
<template> <template>
<button <button
:disabled="disabled" :disabled="disabled"
class="flex min-w-fit cursor-pointer items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-all duration-fast ease-apple not-disabled:hover:shadow-sm disabled:cursor-not-allowed disabled:opacity-50" class="group flex min-w-fit cursor-pointer items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-all duration-fast ease-apple not-disabled:hover:shadow-sm disabled:cursor-not-allowed disabled:opacity-50"
:class="classVar" :class="classVar"
:data-active="active" :data-active="active"
@click="emit('click')" @click="emit('click')"
@@ -49,9 +49,9 @@ const textClassVar = computed(() => {
case 'primary': case 'primary':
return 'text-white' return 'text-white'
case 'secondary': case 'secondary':
return 'text-main' return 'text-main group-not-disabled:group-hover:text-white!'
case 'tab': case 'tab':
return active ? 'text-white' : 'text-secondary' return active ? 'text-white' : 'text-secondary group-not-disabled:group-hover:text-white!'
default: default:
return textClass || '' return textClass || ''
} }
@@ -62,9 +62,9 @@ const classVar = computed(() => {
case 'primary': case 'primary':
return 'bg-accent text-white not-disabled:hover:bg-accent-hover! not-disabled:hover:-translate-y-px' return 'bg-accent text-white not-disabled:hover:bg-accent-hover! not-disabled:hover:-translate-y-px'
case 'secondary': case 'secondary':
return 'border border-border bg-bg-secondary text-main not-disabled:hover:bg-surface-elevated! not-disabled:hover:-translate-y-px' return 'border border-border bg-bg-secondary text-main not-disabled:hover:bg-accent/30! not-disabled:hover:text-white! not-disabled:hover:-translate-y-px'
case 'tab': case 'tab':
return 'flex-1 text-secondary not-disabled:data-[active=false]:hover:bg-accent/30 data-[active=true]:text-white data-[active=true]:bg-accent' return 'flex-1 text-secondary not-disabled:data-[active=false]:hover:bg-accent/30 data-[active=true]:text-white data-[active=true]:bg-accent not-disabled:hover:text-white!'
default: default:
return '' return ''
} }

View File

@@ -1,5 +1,8 @@
<template> <template>
<div class="flex items-center rounded-xl" :class="noHover ? '' : 'hover:bg-surface hover:shadow-sm'"> <div
class="flex items-center rounded-xl"
:class="noHover ? '' : 'hover:border-accenthover:shadow-sm hover:bg-surface'"
>
<label <label
class="flex cursor-pointer items-center gap-4 rounded-lg border border-border transition-all duration-200 ease-apple hover:border-accent" class="flex cursor-pointer items-center gap-4 rounded-lg border border-border transition-all duration-200 ease-apple hover:border-accent"
:class="{ :class="{

View File

@@ -70,7 +70,7 @@ onBeforeMount(() => {
<template> <template>
<div class="relative flex items-center"> <div class="relative flex items-center">
<button <button
class="flex cursor-pointer items-center gap-2 rounded-md border border-border-secondary bg-bg-secondary px-3 py-2 text-sm text-secondary transition-all duration-fast ease-standard hover:text-main max-md:justify-center max-md:gap-0 max-md:p-2 [.collapsed]:justify-center [.collapsed]:gap-0 [.collapsed]:p-2" class="flex cursor-pointer items-center gap-2 rounded-md border border-border-secondary bg-bg-secondary px-3 py-2 text-sm text-secondary transition-all duration-fast ease-standard hover:bg-accent/30 hover:text-white max-md:justify-center max-md:gap-0 max-md:p-2 [.collapsed]:justify-center [.collapsed]:gap-0 [.collapsed]:p-2"
:class="{ collapsed }" :class="{ collapsed }"
:title="t('settings.theme.toggle')" :title="t('settings.theme.toggle')"
@click="toggleTheme" @click="toggleTheme"

View File

@@ -39,7 +39,7 @@
<button <button
v-for="item in tabItems" v-for="item in tabItems"
:key="item.key" :key="item.key"
class="transition-al flex min-w-fit flex-none cursor-pointer items-center gap-2 rounded-md border border-border-secondary bg-bg-secondary px-4 py-2 text-sm font-semibold whitespace-nowrap text-secondary no-underline duration-200 ease-apple hover:border-border hover:bg-accent/10 hover:text-main [.active]:border-accent [.active]:bg-accent [.active]:text-white" class="transition-al flex min-w-fit flex-none cursor-pointer items-center gap-2 rounded-md border border-border-secondary bg-bg-secondary px-4 py-2 text-sm font-semibold whitespace-nowrap text-secondary no-underline duration-200 ease-apple hover:border-border hover:bg-accent/30 hover:text-white [.active]:border-accent [.active]:bg-accent [.active]:text-white"
:class="{ active: activePlatform === item.key }" :class="{ active: activePlatform === item.key }"
@click="handleTabChange(item.key)" @click="handleTabChange(item.key)"
> >

View File

@@ -21,7 +21,7 @@
</div> </div>
<button <button
:title="isCollapsed ? t('navigation.expand') : t('navigation.collapse')" :title="isCollapsed ? t('navigation.expand') : t('navigation.collapse')"
class="absolute top-1/2 right-[8px] flex -translate-y-1/2 cursor-pointer items-center justify-center rounded-sm border-none bg-transparent p-[4px] transition-all duration-200 ease-apple group-[.collapsed]:absolute group-[.collapsed]:top-[20px] group-[.collapsed]:right-[16px] group-[.collapsed]:transform-none hover:bg-surface-elevated hover:text-main" class="absolute top-1/2 right-[8px] flex -translate-y-1/2 cursor-pointer items-center justify-center rounded-sm border-none bg-transparent p-[4px] transition-all duration-200 ease-apple group-[.collapsed]:absolute group-[.collapsed]:top-[20px] group-[.collapsed]:right-[16px] group-[.collapsed]:transform-none hover:bg-accent/30 hover:text-white"
@click="isCollapsed = !isCollapsed" @click="isCollapsed = !isCollapsed"
> >
<component :is="isCollapsed ? ChevronRightIcon : ChevronLeftIcon" :size="16" /> <component :is="isCollapsed ? ChevronRightIcon : ChevronLeftIcon" :size="16" />
@@ -100,7 +100,7 @@
</div> </div>
<div class="border-t border-t-border p-3"> <div class="border-t border-t-border p-3">
<button <button
class="fixed bottom-[4px] left-[4px] cursor-pointer rounded-full border-none bg-transparent p-[8px] text-tertiary hover:bg-surface-elevated hover:text-main" class="fixed bottom-[4px] left-[4px] cursor-pointer rounded-full border-none bg-transparent p-[8px] text-tertiary hover:bg-accent/30 hover:text-white"
:title="t('navigation.moreOptions')" :title="t('navigation.moreOptions')"
@click="openMenu" @click="openMenu"
> >

View File

@@ -9,21 +9,22 @@
> >
<div class="flex max-w-[calc(100%-300px)] flex-1 flex-wrap items-center gap-2 max-md:order-1"> <div class="flex max-w-[calc(100%-300px)] flex-1 flex-wrap items-center gap-2 max-md:order-1">
<button <button
class="provider-button group/provider flex w-auto min-w-[150px] shrink-0 cursor-pointer items-center gap-3 rounded-lg bg-bg-secondary px-4 py-2 font-[inherit] shadow-sm duration-fast ease-standard hover:-translate-y-px hover:border-accent-hover/70 hover:bg-surface hover:shadow-sm focus-visible:focus-ring max-xs:w-full max-xs:min-w-[100px]" class="provider-button group/provider flex w-auto min-w-[150px] shrink-0 cursor-pointer items-center gap-3 rounded-lg bg-bg-secondary px-4 py-2 font-[inherit] shadow-sm duration-fast ease-standard hover:-translate-y-px hover:bg-accent/30 hover:text-white hover:shadow-sm focus-visible:focus-ring max-xs:w-full max-xs:min-w-[100px]"
:title="t('pages.upload.uploadViewHint')" :title="t('pages.upload.uploadViewHint')"
@click="handlePicBedNameClick(picBedName)" @click="handlePicBedNameClick(picBedName)"
> >
<div class="flex flex-1 flex-col items-start"> <div class="flex flex-1 flex-col items-start">
<span class="text-sm leading-[1.2] font-semibold text-main">{{ picBedName }}</span> <span class="text-sm leading-[1.2] font-semibold text-main group-hover/provider:text-white">{{
<span class="text-xs leading-[1.2] text-secondary">{{ defaultConfigNameG || 'Default' }}</span> picBedName
}}</span>
<span class="text-xs leading-[1.2] text-secondary group-hover/provider:text-white">{{
defaultConfigNameG || 'Default'
}}</span>
</div> </div>
<EditIcon <EditIcon :size="16" class="text-secondary duration-fast ease-standard group-hover/provider:text-white" />
:size="16"
class="text-secondary duration-fast ease-standard group-hover/provider:text-accent-hover"
/>
</button> </button>
<div <div
class="flex h-[22px] w-[22px] shrink-0 cursor-pointer items-center justify-center rounded-lg border border-border bg-surface font-[inherit] text-secondary duration-fast ease-standard hover:-translate-y-px hover:border-accent-hover hover:text-accent-hover data-[disabled=true]:pointer-events-none data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50" class="flex h-[22px] w-[22px] shrink-0 cursor-pointer items-center justify-center rounded-lg border border-border bg-surface font-[inherit] text-secondary duration-fast ease-standard hover:-translate-y-px hover:bg-accent/30 hover:text-white data-[disabled=true]:pointer-events-none data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50"
:title="t('pages.upload.addToFavorites')" :title="t('pages.upload.addToFavorites')"
:data-disabled="favoritePicbeds.length >= MAX_FAVORITE_PICBEDS || isCurrentPicBedInFavorites" :data-disabled="favoritePicbeds.length >= MAX_FAVORITE_PICBEDS || isCurrentPicBedInFavorites"
@click="addCurrentPicbedToFavorites" @click="addCurrentPicbedToFavorites"
@@ -47,7 +48,7 @@
<button <button
v-for="picbedType in favoritePicbeds" v-for="picbedType in favoritePicbeds"
:key="picbedType.id" :key="picbedType.id"
class="group/badge relative flex w-[85px] shrink-0 cursor-pointer items-center gap-2 overflow-hidden rounded-md bg-bg-secondary pt-1.5 pr-2 pb-1.5 pl-3 text-xs font-medium whitespace-nowrap text-secondary shadow-sm transition-all duration-fast ease-standard select-none hover:-translate-y-px hover:border-accent-hover hover:bg-bg-tertiary hover:text-accent-hover [.is-active]:border-[0.1rem] [.is-active]:border-accent-hover [.is-active]:font-semibold [.show-delete]:pr-2" class="group/badge relative flex w-[85px] shrink-0 cursor-pointer items-center gap-2 overflow-hidden rounded-md bg-bg-secondary pt-1.5 pr-2 pb-1.5 pl-3 text-xs font-medium whitespace-nowrap text-secondary shadow-sm transition-all duration-fast ease-standard select-none hover:-translate-y-px hover:border-accent-hover hover:bg-accent/30 hover:text-white [.is-active]:border-[0.1rem] [.is-active]:border-accent-hover [.is-active]:font-semibold [.show-delete]:pr-2"
:class="{ 'is-active': isCurrentPicbed(picbedType), 'show-delete': longPressedBadge === picbedType.id }" :class="{ 'is-active': isCurrentPicbed(picbedType), 'show-delete': longPressedBadge === picbedType.id }"
:title="t('pages.upload.longPressToRemoveFromFavorites') + getPicbedName(picbedType)" :title="t('pages.upload.longPressToRemoveFromFavorites') + getPicbedName(picbedType)"
@click="handleBadgeClick(picbedType)" @click="handleBadgeClick(picbedType)"
@@ -173,24 +174,30 @@
</h4> </h4>
</div> </div>
<div class="flex w-full flex-1 flex-row flex-wrap items-center justify-center gap-4 max-md:gap-3 max-md:px-5"> <div class="flex w-full flex-1 flex-row flex-wrap items-center justify-center gap-4 max-md:gap-3 max-md:px-5">
<button class="quick-action-button" @click="uploadClipboardFiles"> <button class="quick-action-button group" @click="uploadClipboardFiles">
<ClipboardIcon class="shrink-0 text-accent" :size="15" /> <ClipboardIcon class="shrink-0 text-accent group-hover:text-white" :size="15" />
<span class="text-sm font-medium text-secondary">{{ t('pages.upload.clipboardPicture') }}</span> <span class="text-sm font-medium text-secondary group-hover:text-white">{{
t('pages.upload.clipboardPicture')
}}</span>
</button> </button>
<button class="quick-action-button" @click="uploadURLFiles"> <button class="quick-action-button group" @click="uploadURLFiles">
<LinkIcon class="shrink-0 text-accent" :size="15" /> <LinkIcon class="shrink-0 text-accent group-hover:text-white" :size="15" />
<span class="text-sm font-medium text-secondary">{{ t('pages.upload.urlUpload') }}</span> <span class="text-sm font-medium text-secondary group-hover:text-white">{{
t('pages.upload.urlUpload')
}}</span>
</button> </button>
<button <button
class="quick-action-button" class="quick-action-button group"
:class="{ 'has-badge': taskQueueStatus.tasks.length > 0 }" :class="{ 'has-badge': taskQueueStatus.tasks.length > 0 }"
@click="openTaskDialog" @click="openTaskDialog"
> >
<ListTodoIcon class="shrink-0 text-accent" :size="15" /> <ListTodoIcon class="shrink-0 text-accent group-hover:text-white" :size="15" />
<span class="mt-1 text-sm font-medium text-secondary">{{ t('pages.upload.taskUpload') }}</span> <span class="mt-1 text-sm font-medium text-secondary group-hover:text-white">{{
t('pages.upload.taskUpload')
}}</span>
<span <span
v-if="taskQueueStatus.tasks.length > 0" v-if="taskQueueStatus.tasks.length > 0"
class="absolute top-1/2 right-3 flex min-w-6 -translate-y-1/2 animate-[badge-pulse_2s_ease-in-out_infinite] items-center justify-center rounded-full border border-border-secondary px-1.5 py-0 text-sm font-bold text-accent" class="absolute top-1/2 right-3 flex min-w-6 -translate-y-1/2 animate-[badge-pulse_2s_ease-in-out_infinite] items-center justify-center rounded-full border border-border-secondary px-1.5 py-0 text-sm font-bold text-accent group-hover:text-white"
> >
{{ taskQueueStatus.tasks.length }} {{ taskQueueStatus.tasks.length }}
</span> </span>
@@ -215,7 +222,7 @@
<button <button
v-for="(format, key) in pasteFormatList" v-for="(format, key) in pasteFormatList"
:key="key" :key="key"
class="flex-1 cursor-pointer rounded-md border border-border-secondary bg-bg-secondary px-1 py-1 font-['SF_Mono',Monaco,'Cascadia_Code','Roboto_Mono',Consolas,'Courier_New',monospace] text-[0.7rem] font-medium text-secondary duration-fast ease-standard hover:border-accent-hover hover:text-main focus-visible:focus-ring data-[active=true]:border-accent data-[active=true]:bg-accent data-[active=true]:text-white" class="flex-1 cursor-pointer rounded-md border border-border-secondary bg-bg-secondary px-1 py-1 font-['SF_Mono',Monaco,'Cascadia_Code','Roboto_Mono',Consolas,'Courier_New',monospace] text-[0.7rem] font-medium text-secondary duration-fast ease-standard hover:bg-accent/30 hover:text-white focus-visible:focus-ring data-[active=true]:border-accent data-[active=true]:bg-accent data-[active=true]:text-white"
:data-active="pasteStyle === key" :data-active="pasteStyle === key"
:title="format" :title="format"
@click="updatePasteStyle(key)" @click="updatePasteStyle(key)"
@@ -230,14 +237,14 @@
<label class="m-0 text-xs font-medium text-secondary">{{ t('pages.upload.urlType.title') }}</label> <label class="m-0 text-xs font-medium text-secondary">{{ t('pages.upload.urlType.title') }}</label>
<div class="flex w-full overflow-hidden rounded-md border border-border-secondary bg-bg-secondary"> <div class="flex w-full overflow-hidden rounded-md border border-border-secondary bg-bg-secondary">
<button <button
class="flex-1 cursor-pointer border-0 bg-transparent py-1 font-[inherit] text-xs font-medium text-secondary duration-fast ease-standard hover:text-main focus-visible:focus-ring data-[active=true]:bg-accent data-[active=true]:text-white" class="flex-1 cursor-pointer border-0 bg-transparent py-1 font-[inherit] text-xs font-medium text-secondary duration-fast ease-standard hover:bg-accent/30 hover:text-white focus-visible:focus-ring data-[active=true]:bg-accent data-[active=true]:text-white"
:data-active="!useShortUrl" :data-active="!useShortUrl"
@click="updateUrlType(false)" @click="updateUrlType(false)"
> >
<span>{{ t('pages.upload.urlType.normal') }}</span> <span>{{ t('pages.upload.urlType.normal') }}</span>
</button> </button>
<button <button
class="flex-1 cursor-pointer border-0 bg-transparent py-1 font-[inherit] text-xs font-medium text-secondary duration-fast ease-standard hover:text-main focus-visible:focus-ring data-[active=true]:bg-accent data-[active=true]:text-white" class="flex-1 cursor-pointer border-0 bg-transparent py-1 font-[inherit] text-xs font-medium text-secondary duration-fast ease-standard hover:bg-accent/30 hover:text-white focus-visible:focus-ring data-[active=true]:bg-accent data-[active=true]:text-white"
:data-active="useShortUrl" :data-active="useShortUrl"
@click="updateUrlType(true)" @click="updateUrlType(true)"
> >

View File

@@ -4,7 +4,7 @@
.nav-item { .nav-item {
@apply flex items-center justify-center py-3 px-4 text-sm font-medium no-underline text-secondary gap-3 cursor-pointer transition-all duration-200 ease-apple; @apply flex items-center justify-center py-3 px-4 text-sm font-medium no-underline text-secondary gap-3 cursor-pointer transition-all duration-200 ease-apple;
@apply hover:text-main hover:bg-surface; @apply hover:text-accent hover:bg-surface;
@apply group-[.collapsed]:justify-center group-[.collapsed]:py-3 group-[.collapsed]:px-2 group-[.collapsed]:gap-0 ; @apply group-[.collapsed]:justify-center group-[.collapsed]:py-3 group-[.collapsed]:px-2 group-[.collapsed]:gap-0 ;
@apply [.router-link-active]:border-accent [.router-link-active]:border-r-4 [.router-link-active]:text-accent [.router-link-active]:bg-surface; @apply [.router-link-active]:border-accent [.router-link-active]:border-r-4 [.router-link-active]:text-accent [.router-link-active]:bg-surface;
} }

View File

@@ -3,12 +3,12 @@
@import '../../assets/css/utilities.css' reference; @import '../../assets/css/utilities.css' reference;
.segmented-button { .segmented-button {
@apply flex cursor-pointer items-center gap-2 border-r border-none border-r-border-secondary px-4 py-2.5 font-[inherit] text-sm font-medium whitespace-nowrap text-secondary duration-fast ease-standard last:border-r-0 hover:bg-bg-tertiary hover:text-accent-hover; @apply flex cursor-pointer items-center gap-2 border-r border-none border-r-border-secondary px-4 py-2.5 font-[inherit] text-sm font-medium whitespace-nowrap text-secondary duration-fast ease-standard last:border-r-0 hover:bg-accent/30 hover:text-white;
} }
/* Quick Actions Card */ /* Quick Actions Card */
.quick-action-button { .quick-action-button {
@apply relative flex flex-1 cursor-pointer items-center gap-2 rounded-lg border border-border-secondary bg-bg-secondary px-4 py-3.5 text-left font-[inherit] duration-medium ease-standard hover:-translate-y-[2px] hover:border-accent-hover hover:shadow-md focus-visible:focus-ring max-xs:px-3.5 max-xs:py-3 ; @apply relative flex flex-1 cursor-pointer items-center gap-2 rounded-lg border border-border-secondary bg-bg-secondary px-4 py-3.5 text-left font-[inherit] duration-medium ease-standard hover:-translate-y-[2px] hover:bg-accent/30 hover:shadow-md focus-visible:focus-ring max-xs:px-3.5 max-xs:py-3 ;
} }
.filter-tab { .filter-tab {