mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 08:21:39 -06:00
fix: ebook reader UI - bookmark overlay, search panel, sidebar tabs
This commit is contained in:
@@ -315,6 +315,12 @@ function closeSearch() {
|
||||
</template>
|
||||
</ReaderHeader>
|
||||
|
||||
<Transition name="bookmark-fade">
|
||||
<div v-if="bookmarks.isCurrentCfiBookmarked.value" class="absolute left-8 z-30 pointer-events-none" aria-hidden="true">
|
||||
<div class="w-7 h-14 bg-primary" style="clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 80%, 0 100%)" />
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<div class="absolute inset-0">
|
||||
<div v-if="loading" class="absolute inset-0 flex items-center justify-center z-10 bg-background">
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
@@ -401,3 +407,14 @@ function closeSearch() {
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.bookmark-fade-enter-active,
|
||||
.bookmark-fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
.bookmark-fade-enter-from,
|
||||
.bookmark-fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { Loader2, Search, X } from 'lucide-vue-next'
|
||||
import { ChevronLeft, Loader2, Search, X } from 'lucide-vue-next'
|
||||
import type { SearchResult } from '../composables/useSearch'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
|
||||
@@ -40,8 +40,19 @@ function onClear() {
|
||||
<template>
|
||||
<div class="fixed inset-0 z-50 flex">
|
||||
<div class="search-panel w-80 h-full bg-card text-card-foreground flex flex-col shadow-2xl border-r border-border" @click.stop>
|
||||
<div class="flex items-center gap-2 px-4 py-3 border-b border-border shrink-0">
|
||||
<Search :size="16" class="text-muted-foreground shrink-0" />
|
||||
<div class="flex items-center gap-2 px-3 py-2.5 border-b border-border shrink-0">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<button
|
||||
class="flex items-center justify-center w-7 h-7 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0"
|
||||
@click="emit('close')"
|
||||
>
|
||||
<ChevronLeft :size="18" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Close</TooltipContent>
|
||||
</Tooltip>
|
||||
<Search :size="15" class="text-muted-foreground shrink-0" />
|
||||
<input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
@@ -56,17 +67,6 @@ function onClear() {
|
||||
>
|
||||
<X :size="14" />
|
||||
</button>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<button
|
||||
class="flex items-center justify-center w-7 h-7 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0"
|
||||
@click="emit('close')"
|
||||
>
|
||||
<X :size="16" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Close</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Bookmark, BookOpen, Highlighter, Trash2, X } from 'lucide-vue-next'
|
||||
import { Bookmark, BookOpen, Highlighter, Trash2 } from 'lucide-vue-next'
|
||||
import type { TocItem } from '../composables/useToc'
|
||||
import type { Bookmark as BookmarkType } from '../composables/useBookmarks'
|
||||
import type { Annotation } from '../composables/useAnnotations'
|
||||
@@ -31,28 +31,21 @@ const activeTab = ref<Tab>('chapters')
|
||||
<template>
|
||||
<div class="fixed inset-0 z-50 flex">
|
||||
<div class="sidebar-panel w-80 h-full bg-card text-card-foreground flex flex-col shadow-2xl border-r border-border" @click.stop>
|
||||
<div class="flex items-center justify-between px-4 py-3 border-b border-border shrink-0">
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
v-for="tab in [
|
||||
{ id: 'chapters', icon: BookOpen, label: 'Chapters' },
|
||||
{ id: 'bookmarks', icon: Bookmark, label: 'Bookmarks' },
|
||||
{ id: 'highlights', icon: Highlighter, label: 'Highlights' },
|
||||
] as const"
|
||||
:key="tab.id"
|
||||
class="flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium transition-colors"
|
||||
:class="activeTab === tab.id ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:text-foreground hover:bg-muted'"
|
||||
@click="activeTab = tab.id"
|
||||
>
|
||||
<component :is="tab.icon" :size="13" />
|
||||
{{ tab.label }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex items-stretch border-b border-border shrink-0">
|
||||
<button
|
||||
class="flex items-center justify-center w-7 h-7 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
|
||||
@click="emit('close')"
|
||||
v-for="tab in [
|
||||
{ id: 'chapters', icon: BookOpen, label: 'Chapters' },
|
||||
{ id: 'bookmarks', icon: Bookmark, label: 'Bookmarks' },
|
||||
{ id: 'highlights', icon: Highlighter, label: 'Highlights' },
|
||||
] as const"
|
||||
:key="tab.id"
|
||||
class="flex-1 flex items-center justify-center gap-1.5 py-3 text-[13.5px] relative transition-colors"
|
||||
:class="activeTab === tab.id ? 'text-primary' : 'text-muted-foreground hover:text-foreground'"
|
||||
@click="activeTab = tab.id"
|
||||
>
|
||||
<X :size="16" />
|
||||
<component :is="tab.icon" :size="16" />
|
||||
{{ tab.label }}
|
||||
<span v-if="activeTab === tab.id" class="absolute bottom-0 inset-x-0 h-0.5 bg-primary rounded-t-full" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -180,7 +173,7 @@ const TocList = defineComponent({
|
||||
emit('toggleExpand', item.href)
|
||||
},
|
||||
},
|
||||
[expanded ? h(ChevronDown as Component, { size: 14 }) : h(ChevronRight as Component, { size: 14 })],
|
||||
[expanded ? h(ChevronDown as Component, { size: 14 }) : h(ChevronRight as Component, { size: 12 })],
|
||||
)
|
||||
: h('span', { class: 'w-3.5 shrink-0' }),
|
||||
h('span', { class: 'truncate' }, item.label),
|
||||
|
||||
Reference in New Issue
Block a user