feat(reader): convert settings bottom sheet to full-screen overlay
Replaces the bottom drawer + backdrop with a fixed full-screen overlay matching the voice/chapter picker style in ListeningMode — chevron header, tab bar with brand-color active state, scrollable content. Escape closes it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -139,10 +139,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard nav for paginated mode
|
// Keyboard nav for paginated mode + Escape to close settings overlay
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!browser) return;
|
if (!browser) return;
|
||||||
function onKey(e: KeyboardEvent) {
|
function onKey(e: KeyboardEvent) {
|
||||||
|
if (e.key === 'Escape' && settingsPanelOpen) {
|
||||||
|
settingsPanelOpen = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (layout.readMode !== 'paginated') return;
|
if (layout.readMode !== 'paginated') return;
|
||||||
if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') {
|
if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -669,28 +673,37 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- ── Reader settings bottom sheet ─────────────────────────────────────── -->
|
<!-- ── Reader settings overlay ───────────────────────────────────────────── -->
|
||||||
{#if settingsCtx}
|
{#if settingsCtx}
|
||||||
{#if settingsPanelOpen}
|
{#if settingsPanelOpen}
|
||||||
<!-- Backdrop -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
|
<div
|
||||||
<div role="none" class="fixed inset-0 z-40 bg-black/40" onclick={() => (settingsPanelOpen = false)}></div>
|
class="fixed inset-0 z-50 flex flex-col"
|
||||||
|
style="background: var(--color-surface);"
|
||||||
<div class="fixed bottom-0 left-0 right-0 z-50 bg-(--color-surface-2) border-t border-(--color-border) rounded-t-2xl shadow-2xl flex flex-col max-h-[80dvh]">
|
>
|
||||||
|
<!-- Header -->
|
||||||
<!-- Drag handle -->
|
<div class="flex items-center gap-3 px-4 py-3 border-b border-(--color-border) shrink-0">
|
||||||
<div class="flex justify-center pt-3 pb-1 shrink-0">
|
<button
|
||||||
<div class="w-10 h-1 rounded-full bg-(--color-border)"></div>
|
type="button"
|
||||||
|
onclick={() => (settingsPanelOpen = false)}
|
||||||
|
class="p-2 rounded-full text-(--color-muted) hover:text-(--color-text) hover:bg-(--color-surface-2) transition-colors"
|
||||||
|
aria-label="Close settings"
|
||||||
|
>
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<span class="text-xs font-semibold text-(--color-muted) uppercase tracking-wider flex-1">Reader Settings</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tab bar -->
|
<!-- Tab bar -->
|
||||||
<div class="flex gap-1 mx-4 mb-3 p-1 rounded-xl bg-(--color-surface-3) shrink-0">
|
<div class="flex gap-1 mx-4 mt-3 mb-1 p-1 rounded-xl bg-(--color-surface-2) shrink-0 border border-(--color-border)">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => (settingsTab = 'reading')}
|
onclick={() => (settingsTab = 'reading')}
|
||||||
class="flex-1 py-1.5 rounded-lg text-xs font-semibold transition-colors
|
class="flex-1 py-1.5 rounded-lg text-xs font-semibold transition-colors
|
||||||
{settingsTab === 'reading'
|
{settingsTab === 'reading'
|
||||||
? 'bg-(--color-surface-2) text-(--color-text) shadow-sm'
|
? 'bg-(--color-brand) text-(--color-surface)'
|
||||||
: 'text-(--color-muted) hover:text-(--color-text)'}"
|
: 'text-(--color-muted) hover:text-(--color-text)'}"
|
||||||
>Reading</button>
|
>Reading</button>
|
||||||
<button
|
<button
|
||||||
@@ -698,13 +711,13 @@
|
|||||||
onclick={() => (settingsTab = 'listening')}
|
onclick={() => (settingsTab = 'listening')}
|
||||||
class="flex-1 py-1.5 rounded-lg text-xs font-semibold transition-colors
|
class="flex-1 py-1.5 rounded-lg text-xs font-semibold transition-colors
|
||||||
{settingsTab === 'listening'
|
{settingsTab === 'listening'
|
||||||
? 'bg-(--color-surface-2) text-(--color-text) shadow-sm'
|
? 'bg-(--color-brand) text-(--color-surface)'
|
||||||
: 'text-(--color-muted) hover:text-(--color-text)'}"
|
: 'text-(--color-muted) hover:text-(--color-text)'}"
|
||||||
>Listening</button>
|
>Listening</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Scrollable content -->
|
<!-- Scrollable content -->
|
||||||
<div class="overflow-y-auto px-4 pb-6 flex flex-col gap-0">
|
<div class="flex-1 overflow-y-auto px-4 pb-6 flex flex-col gap-0 mt-2">
|
||||||
|
|
||||||
{#if settingsTab === 'reading'}
|
{#if settingsTab === 'reading'}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user