Skip to content

Commit 9521c0a

Browse files
committed
Refactor empty state UI and improve document handling
Extracted the empty state UI into reusable EmptyState components for both React and Svelte examples. Updated viewer pages to use these components, simplifying code and improving maintainability. Adjusted Svelte and React logic to handle document opening via callbacks. Updated Scroller and related components to use a consistent renderPage snippet prop. Minor improvements to FullscreenProvider prop/state usage and favicon asset.
1 parent afa1f7b commit 9521c0a

9 files changed

Lines changed: 212 additions & 169 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { useDocumentManagerCapability } from '@embedpdf/plugin-document-manager/react';
2+
3+
interface EmptyStateProps {
4+
onDocumentOpened?: (documentId: string) => void;
5+
}
6+
7+
export function EmptyState({ onDocumentOpened }: EmptyStateProps) {
8+
const { provides } = useDocumentManagerCapability();
9+
10+
const handleOpenFile = () => {
11+
const openTask = provides?.openFileDialog();
12+
openTask?.wait(
13+
(result) => {
14+
onDocumentOpened?.(result.documentId);
15+
},
16+
(error) => {
17+
console.error('Open file failed:', error);
18+
},
19+
);
20+
};
21+
22+
return (
23+
<div className="flex flex-1 items-center justify-center bg-gradient-to-br from-gray-50 to-gray-100">
24+
<div className="max-w-md text-center">
25+
<div className="mb-6 flex justify-center">
26+
<div className="rounded-full bg-indigo-100 p-6">
27+
<svg
28+
className="h-16 w-16 text-indigo-600"
29+
fill="none"
30+
stroke="currentColor"
31+
viewBox="0 0 24 24"
32+
>
33+
<path
34+
strokeLinecap="round"
35+
strokeLinejoin="round"
36+
strokeWidth={1.5}
37+
d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"
38+
/>
39+
<path
40+
strokeLinecap="round"
41+
strokeLinejoin="round"
42+
strokeWidth={1.5}
43+
d="M9 13h6m-6 4h6"
44+
/>
45+
</svg>
46+
</div>
47+
</div>
48+
<h2 className="mb-3 text-2xl font-bold text-gray-900">No Documents Open</h2>
49+
<p className="mb-8 text-gray-600">
50+
Get started by opening a PDF document. You can view multiple documents at once using tabs.
51+
</p>
52+
<button
53+
onClick={handleOpenFile}
54+
className="inline-flex items-center gap-2 rounded-lg bg-indigo-600 px-6 py-3 font-semibold text-white shadow-lg transition-all hover:bg-indigo-700 hover:shadow-xl"
55+
>
56+
<svg className="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
57+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
58+
</svg>
59+
Open PDF Document
60+
</button>
61+
<div className="mt-6 text-sm text-gray-500">Supported format: PDF</div>
62+
</div>
63+
</div>
64+
);
65+
}

examples/react-tailwind/src/pages/viewer-simple.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { ThumbnailsSidebar } from '../components/thumbnails-sidebar';
4040
import { PageControls } from '../components/page-controls';
4141
import { ConsoleLogger } from '@embedpdf/models';
4242
import { NavigationBar } from '../components/navigation-bar';
43+
import { EmptyState } from '../components/empty-state';
4344

4445
const logger = new ConsoleLogger();
4546

@@ -187,6 +188,8 @@ export function ViewerSimplePage() {
187188
/>
188189
)}
189190

191+
{!activeDocumentId && <EmptyState />}
192+
190193
{/* Document Content Area */}
191194
{activeDocumentId && (
192195
<div id="document-content" className="flex flex-1 overflow-hidden bg-white">

examples/react-tailwind/src/pages/viewer.tsx

Lines changed: 7 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import { ConsoleLogger } from '@embedpdf/models';
4242
import { SplitViewLayout } from '../components/split-view-layout';
4343
import { AnnotationSelectionMenu } from '../components/annotation-selection-menu';
4444
import { NavigationBar } from '../components/navigation-bar';
45+
import { EmptyState } from '../components/empty-state';
4546

4647
const logger = new ConsoleLogger();
4748

@@ -229,74 +230,12 @@ export function ViewerPage() {
229230

230231
{/* Empty State - No Documents */}
231232
{!documentId && (
232-
<div className="flex flex-1 items-center justify-center bg-gradient-to-br from-gray-50 to-gray-100">
233-
<div className="max-w-md text-center">
234-
<div className="mb-6 flex justify-center">
235-
<div className="rounded-full bg-indigo-100 p-6">
236-
<svg
237-
className="h-16 w-16 text-indigo-600"
238-
fill="none"
239-
stroke="currentColor"
240-
viewBox="0 0 24 24"
241-
>
242-
<path
243-
strokeLinecap="round"
244-
strokeLinejoin="round"
245-
strokeWidth={1.5}
246-
d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"
247-
/>
248-
<path
249-
strokeLinecap="round"
250-
strokeLinejoin="round"
251-
strokeWidth={1.5}
252-
d="M9 13h6m-6 4h6"
253-
/>
254-
</svg>
255-
</div>
256-
</div>
257-
<h2 className="mb-3 text-2xl font-bold text-gray-900">
258-
No Documents Open
259-
</h2>
260-
<p className="mb-8 text-gray-600">
261-
Get started by opening a PDF document. You can view multiple documents
262-
at once using tabs.
263-
</p>
264-
<button
265-
onClick={() => {
266-
const openTask = registry
267-
?.getPlugin<DocumentManagerPlugin>(DocumentManagerPlugin.id)
268-
?.provides()
269-
?.openFileDialog();
270-
openTask?.wait(
271-
(result) => {
272-
addDocument(result.documentId);
273-
setActiveDocument(result.documentId);
274-
},
275-
(error) => {
276-
console.error('Open file failed:', error);
277-
},
278-
);
279-
}}
280-
className="inline-flex items-center gap-2 rounded-lg bg-indigo-600 px-6 py-3 font-semibold text-white shadow-lg transition-all hover:bg-indigo-700 hover:shadow-xl"
281-
>
282-
<svg
283-
className="h-5 w-5"
284-
fill="none"
285-
stroke="currentColor"
286-
viewBox="0 0 24 24"
287-
>
288-
<path
289-
strokeLinecap="round"
290-
strokeLinejoin="round"
291-
strokeWidth={2}
292-
d="M12 4v16m8-8H4"
293-
/>
294-
</svg>
295-
Open PDF Document
296-
</button>
297-
<div className="mt-6 text-sm text-gray-500">Supported format: PDF</div>
298-
</div>
299-
</div>
233+
<EmptyState
234+
onDocumentOpened={(documentId) => {
235+
addDocument(documentId);
236+
setActiveDocument(documentId);
237+
}}
238+
/>
300239
)}
301240

302241
{/* Document Content Area */}
Lines changed: 15 additions & 1 deletion
Loading
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<script lang="ts">
2+
import { useDocumentManagerCapability } from '@embedpdf/plugin-document-manager/svelte';
3+
4+
interface EmptyStateProps {
5+
onDocumentOpened?: (documentId: string) => void;
6+
}
7+
8+
let { onDocumentOpened }: EmptyStateProps = $props();
9+
10+
const documentManagerCapability = useDocumentManagerCapability();
11+
12+
const handleOpenFile = () => {
13+
const provides = documentManagerCapability.provides;
14+
const openTask = provides?.openFileDialog();
15+
openTask?.wait(
16+
(result) => {
17+
onDocumentOpened?.(result.documentId);
18+
},
19+
(error) => {
20+
console.error('Open file failed:', error);
21+
},
22+
);
23+
};
24+
</script>
25+
26+
<div class="flex flex-1 items-center justify-center bg-gradient-to-br from-gray-50 to-gray-100">
27+
<div class="max-w-md text-center">
28+
<div class="mb-6 flex justify-center">
29+
<div class="rounded-full bg-indigo-100 p-6">
30+
<svg
31+
class="h-16 w-16 text-indigo-600"
32+
fill="none"
33+
stroke="currentColor"
34+
viewBox="0 0 24 24"
35+
>
36+
<path
37+
stroke-linecap="round"
38+
stroke-linejoin="round"
39+
stroke-width="1.5"
40+
d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"
41+
/>
42+
<path
43+
stroke-linecap="round"
44+
stroke-linejoin="round"
45+
stroke-width="1.5"
46+
d="M9 13h6m-6 4h6"
47+
/>
48+
</svg>
49+
</div>
50+
</div>
51+
<h2 class="mb-3 text-2xl font-bold text-gray-900">No Documents Open</h2>
52+
<p class="mb-8 text-gray-600">
53+
Get started by opening a PDF document. You can view multiple documents at once using tabs and
54+
split views.
55+
</p>
56+
<button
57+
onclick={handleOpenFile}
58+
class="inline-flex items-center gap-2 rounded-lg bg-indigo-600 px-6 py-3 font-semibold text-white shadow-lg transition-all hover:bg-indigo-700 hover:shadow-xl"
59+
>
60+
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
61+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
62+
</svg>
63+
Open PDF Document
64+
</button>
65+
<div class="mt-6 text-sm text-gray-500">Supported format: PDF</div>
66+
</div>
67+
</div>

examples/svelte-tailwind/src/routes/viewer-simple/+page.svelte

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import PageControls from '$lib/components/PageControls.svelte';
3939
import NavigationBar from '$lib/components/NavigationBar.svelte';
4040
import { ConsoleLogger } from '@embedpdf/models';
41+
import EmptyState from '$lib/components/EmptyState.svelte';
4142
4243
const logger = new ConsoleLogger();
4344
@@ -154,6 +155,10 @@
154155
/>
155156
{/if}
156157

158+
{#if !activeDocumentId}
159+
<EmptyState />
160+
{/if}
161+
157162
<!-- Document Content Area -->
158163
{#if activeDocumentId}
159164
<div id="document-content" class="flex flex-1 overflow-hidden bg-white">
@@ -180,7 +185,7 @@
180185
<GlobalPointerProvider documentId={activeDocumentId}>
181186
<Viewport class="bg-gray-100" documentId={activeDocumentId}>
182187
<Scroller documentId={activeDocumentId}>
183-
{#snippet children(page)}
188+
{#snippet renderPage(page)}
184189
<Rotate
185190
documentId={activeDocumentId}
186191
pageIndex={page.pageIndex}

0 commit comments

Comments
 (0)