View Manager Plugin
The View Manager Plugin adds advanced layout capabilities to your application. It allows you to organize documents into distinct Views (panes), enabling features like split-screen comparisons, tabbed groups, and multi-monitor style layouts.
While the DocumentManager handles the lifecycle of loading and closing files, the ViewManager handles where those files are displayed and which one is currently visible to the user.
Installation
The plugin is available as a separate NPM package.
npm install @embedpdf/plugin-view-manager @embedpdf/plugin-document-managerRegistration
Import ViewManagerPluginPackage and add it to your plugin configuration.
import { createPluginRegistration } from '@embedpdf/core';
import { DocumentManagerPluginPackage } from '@embedpdf/plugin-document-manager/vue';
import { ViewManagerPluginPackage } from '@embedpdf/plugin-view-manager/vue';
const plugins = [
// ... other plugins
createPluginRegistration(DocumentManagerPluginPackage),
// Register View Manager
createPluginRegistration(ViewManagerPluginPackage, {
defaultViewCount: 1, // Start with one main view
}),
];Core Concepts
To effectively use this plugin, it helps to understand the hierarchy:
- View Manager: The global controller that holds the list of all views.
- View: A specific layout container (e.g., a div in a CSS Grid). It holds a list of
documentIds. - Active Document: Each View has exactly one active document visible at a time.
- Focused View: The View currently receiving user input.
Usage
The View Manager is primarily used to build Split Layouts or Tabbed Interfaces. The plugin provides a ViewContext component that simplifies managing state for individual views.
1. The <ViewContext /> Component
This is a headless component that connects a specific viewId to the plugin state. It provides all necessary data (documents list, active document) to render that specific view.
<script setup lang="ts">
import { ViewContext } from '@embedpdf/plugin-view-manager/vue';
</script>
<template>
<ViewContext :view-id="viewId" v-slot="{ documentIds, activeDocumentId, setActiveDocument, isFocused, focus }">
<div
:class="['view-pane', { focused: isFocused }]"
@click="focus"
>
<!-- Render Tabs -->
<div class="tabs">
<button
v-for="docId in documentIds"
:key="docId"
@click="setActiveDocument(docId)"
:class="{ active: docId === activeDocumentId }"
>
{{ docId }}
</button>
</div>
<!-- Render Active Document Content -->
<MyDocumentRenderer v-if="activeDocumentId" :document-id="activeDocumentId" />
</div>
</ViewContext>
</template>2. Building a Split View Layout
To create a dynamic layout, use the useAllViews composable to iterate over available views and render them.
<script setup lang="ts">
import { computed } from 'vue';
import { useAllViews } from '@embedpdf/plugin-view-manager/vue';
const views = useAllViews();
// Simple grid based on number of views
const gridClass = computed(() => views.value.length > 1 ? 'grid-cols-2' : 'grid-cols-1');
</script>
<template>
<div :class="['grid', 'h-full', gridClass, 'gap-4']">
<MyViewPane v-for="view in views" :key="view.id" :view-id="view.id" />
</div>
</template>3. Opening Documents into Views
When you open a document using the DocumentManager, it exists in memory but isn’t visible yet. You must assign it to a View using the ViewManager.
<script setup lang="ts">
import { useDocumentManagerCapability } from '@embedpdf/plugin-document-manager/vue';
import { useViewManagerCapability } from '@embedpdf/plugin-view-manager/vue';
const { provides: docManager } = useDocumentManagerCapability();
const { provides: viewManager } = useViewManagerCapability();
const handleOpen = async () => {
if (!docManager.value || !viewManager.value) return;
// 1. Open the file in the engine
const task = docManager.value.openFileDialog();
const result = await task.toPromise();
// 2. Get the currently focused view (or the first one)
const targetViewId = viewManager.value.getFocusedViewId() || viewManager.value.getAllViews()[0].id;
// 3. Add the document to that view
viewManager.value.addDocumentToView(targetViewId, result.documentId);
// 4. Make it visible immediately
viewManager.value.setViewActiveDocument(targetViewId, result.documentId);
};
</script>
<template>
<button @click="handleOpen">Open File</button>
</template>Live Example
The following example demonstrates a split-view capable layout. It uses a grid system to render multiple ViewContext instances side-by-side.
API Reference
Configuration (ViewManagerPluginConfig)
| Option | Type | Description |
|---|---|---|
defaultViewCount | number | The number of views to create automatically when the plugin initializes. Default: 1 |
Composable: useViewManagerCapability()
Provides global control over the view system.
ViewManagerCapability Methods
| Method | Description |
|---|---|
createView(viewId?) | Creates a new view container. Returns the viewId. |
removeView(viewId) | Removes a view container. Documents inside are detached from the view (but remain open in DocumentManager). |
addDocumentToView(...) | Assigns a document ID to a specific view. addDocumentToView(viewId, docId, index?) |
removeDocumentFromView(...) | Removes a document from a specific view. |
setViewActiveDocument(...) | Sets which document is currently visible in a specific view. |
moveDocumentBetweenViews(...) | Moves a document tab from one view to another. |
setFocusedView(viewId) | Sets the global application focus to a specific view. |
getAllViews() | Returns an array of all View objects. |
Composable: useView(viewId)
Returns the state for a specific view.
Parameters
| Parameter | Type | Description |
|---|---|---|
viewId | () => string | A getter function that returns the view ID to track. |
Returns (Ref<View | null>)
| Property | Type | Description |
|---|---|---|
id | string | The unique ID of the view. |
documentIds | string[] | Array of document IDs assigned to this view. |
activeDocumentId | string | null | The ID of the currently visible document. |
Composable: useAllViews()
Returns a reactive ref containing all views.
Returns
| Property | Type | Description |
|---|---|---|
views | Ref<View[]> | A ref containing an array of all view objects. |
Component: <ViewContext />
A headless provider that exposes data and actions for a specific view via a scoped slot.
Props
| Prop | Type | Description |
|---|---|---|
viewId | string | (Required) The ID of the view to render. |
Scoped Slot Props
| Prop | Type | Description |
|---|---|---|
view | View | The view object. |
documentIds | string[] | List of documents in this view. |
activeDocumentId | string | The currently active document. |
isFocused | boolean | True if this view currently has focus. |
focus | () => void | Helper to set focus to this view. |
addDocument | (id) => void | Helper to add a doc to this view. |
removeDocument | (id) => void | Helper to remove a doc from this view. |
setActiveDocument | (id) => void | Helper to switch the active tab. |
Need Help?
Join our community for support, discussions, and to contribute to EmbedPDF's development.