feat(ui): add collapsible PDF strip and abbreviated labels on mobile
PDF viewer collapses to 70px on mobile in read mode, expandable to 50vh. Toggle button with chevron. Paragraph tap auto-expands strip. Mode toggle abbreviates to "Bearb." on small screens. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -54,12 +54,13 @@ function handleReadClick() {
|
|||||||
? 'bg-primary text-primary-fg'
|
? 'bg-primary text-primary-fg'
|
||||||
: 'text-ink-2 hover:text-ink'}"
|
: 'text-ink-2 hover:text-ink'}"
|
||||||
>
|
>
|
||||||
{m.mode_edit()}
|
<span class="md:hidden">{m.mode_edit_short()}</span>
|
||||||
|
<span class="hidden md:inline">{m.mode_edit()}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Status line -->
|
<!-- Status line (hidden on mobile to save space) -->
|
||||||
<p class="text-xs text-ink-2">
|
<p class="hidden text-xs text-ink-2 md:block">
|
||||||
{#if blockCount === 1}
|
{#if blockCount === 1}
|
||||||
{m.transcription_status_section()}
|
{m.transcription_status_section()}
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
import { m } from '$lib/paraglide/messages.js';
|
||||||
import DocumentTopBar from '$lib/components/DocumentTopBar.svelte';
|
import DocumentTopBar from '$lib/components/DocumentTopBar.svelte';
|
||||||
import DocumentViewer from '$lib/components/DocumentViewer.svelte';
|
import DocumentViewer from '$lib/components/DocumentViewer.svelte';
|
||||||
import TranscriptionEditView from '$lib/components/TranscriptionEditView.svelte';
|
import TranscriptionEditView from '$lib/components/TranscriptionEditView.svelte';
|
||||||
@@ -55,6 +56,7 @@ let panelMode = $state<'read' | 'edit'>('read');
|
|||||||
let activeAnnotationId = $state<string | null>(null);
|
let activeAnnotationId = $state<string | null>(null);
|
||||||
let highlightBlockId = $state<string | null>(null);
|
let highlightBlockId = $state<string | null>(null);
|
||||||
let flashAnnotationId = $state<string | null>(null);
|
let flashAnnotationId = $state<string | null>(null);
|
||||||
|
let pdfStripExpanded = $state(false);
|
||||||
|
|
||||||
const prefersReducedMotion = $derived(
|
const prefersReducedMotion = $derived(
|
||||||
typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||||
@@ -187,6 +189,7 @@ async function handleAnnotationClick(annotationId: string) {
|
|||||||
function handleParagraphClick(annotationId: string) {
|
function handleParagraphClick(annotationId: string) {
|
||||||
activeAnnotationId = annotationId;
|
activeAnnotationId = annotationId;
|
||||||
flashAnnotationId = annotationId;
|
flashAnnotationId = annotationId;
|
||||||
|
pdfStripExpanded = true;
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() => {
|
() => {
|
||||||
flashAnnotationId = null;
|
flashAnnotationId = null;
|
||||||
@@ -246,7 +249,9 @@ onMount(() => {
|
|||||||
|
|
||||||
<div class="relative flex-1 overflow-hidden {transcribeMode ? 'flex flex-col md:flex-row' : ''}">
|
<div class="relative flex-1 overflow-hidden {transcribeMode ? 'flex flex-col md:flex-row' : ''}">
|
||||||
<div
|
<div
|
||||||
class={transcribeMode ? 'relative min-h-[40vh] flex-1 overflow-hidden md:min-h-0' : 'absolute inset-0'}
|
class={transcribeMode
|
||||||
|
? `relative flex-1 overflow-hidden md:min-h-0 ${panelMode === 'read' ? (pdfStripExpanded ? 'max-h-[50vh] min-h-[50vh] md:max-h-none md:min-h-0' : 'max-h-[70px] min-h-[70px] md:max-h-none md:min-h-0') : 'min-h-[40vh]'} transition-[min-height,max-height] duration-300`
|
||||||
|
: 'absolute inset-0'}
|
||||||
>
|
>
|
||||||
<DocumentViewer
|
<DocumentViewer
|
||||||
doc={doc}
|
doc={doc}
|
||||||
@@ -264,9 +269,30 @@ onMount(() => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if transcribeMode && panelMode === 'read'}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => (pdfStripExpanded = !pdfStripExpanded)}
|
||||||
|
class="flex h-7 w-full shrink-0 items-center justify-center border-t border-line bg-muted text-xs font-semibold text-ink-2 md:hidden"
|
||||||
|
aria-label={pdfStripExpanded ? m.scan_collapse() : m.scan_expand()}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="mr-1 h-3 w-3 transition-transform duration-200 {pdfStripExpanded ? 'rotate-180' : ''}"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2.5"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
{pdfStripExpanded ? m.scan_collapse() : m.scan_expand()}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if transcribeMode}
|
{#if transcribeMode}
|
||||||
<div
|
<div
|
||||||
class="flex shrink-0 flex-col border-t border-line md:w-[400px] md:border-t-0 md:border-l lg:w-[480px]"
|
class="flex min-h-0 flex-1 shrink-0 flex-col border-t border-line md:w-[400px] md:flex-none md:border-t-0 md:border-l lg:w-[480px]"
|
||||||
>
|
>
|
||||||
<TranscriptionPanelHeader
|
<TranscriptionPanelHeader
|
||||||
mode={panelMode}
|
mode={panelMode}
|
||||||
|
|||||||
Reference in New Issue
Block a user