WebViewer UI

repository·12.0·Indexed 19 days ago

https://github.com/aprysesdk/webviewer-ui

A React-based responsive user interface built on top of the WebViewer JavaScript PDF library. It enables developers to view, annotate, and manipulate PDFs within web projects, providing full source code access for advanced UI customization and workflow integration. The library includes a high-level UI API for controlling panels, tools, zoom, language, and view-only modes, as well as access to the underlying WebViewer Core engine.

Tokens
47.3K
Snippets
319
Records
369
Agent score
66%

What's inside webviewer-ui

  1. Understand the WebViewer UI project structure

    12.0

    The repository is organized into the following directories:

    • src/apis/: APIs exposed via myWebViewer.getInstance().
    • src/components/: React components.
    • src/constants/: JavaScript or CSS constants.
    • src/core/: APIs from the Core library.
    • src/event-listeners/: Listeners for Core events.
    • src/helpers/: Reusable utility functions.
    • src/redux/: Redux files for state management.
    • src/lib/: A folder created upon npm install, used for development testing only.
  2. Use the WebViewer UI API namespaces

    12.0

    Once initialized, the API is exposed through two main namespaces on the window object:

    window.Core

    Provides access to the underlying WebViewer Core engine. Key properties include:

    • Tools: Core tool definitions.
    • Annotations: Core annotation management.
    • Actions: Core document actions.
    • PDFNet: Access to the PDFNet engine.
    • documentViewer: The active document viewer instance.
    • annotationManager: The annotation manager associated with the document viewer.

    window.UI

    Provides high-level methods to manipulate the WebViewer interface. This includes controlling tools, panels, zoom, language, themes, and more.

  3. How WebViewer UI instantiation modes work

    12.0

    WebViewer UI supports two primary modes of operation which dictate how the entrypoint src/index.js behaves:

    WebComponent Multi-instance Mode

    • Trigger: The host application calls createUIInstance(shadowRoot) for every <apryse-webviewer> element.
    • Isolation: Each call creates a completely independent environment (Redux store, i18n instance, DocumentViewer, etc.). There are no shared module-level singletons.
    • Targeting: The ShadowRoot passed to the function is used to scope all DOM operations within that instance.

    Iframe Mode (Legacy)

    • Trigger: Automatically executes upon module evaluation (no arguments required).
    • Configuration: Reads settings from the URL hash parameters.
    • Mounting: Mounts directly into the document.
    • Compatibility: Uses a global singleton for i18n and other services to maintain backward compatibility.
  4. Use theme query parameters in SCSS imports

    12.0

    The WebViewer UI build system supports dynamic theme switching via Vite query parameters in SCSS imports. By appending ?theme-<name> to an SCSS file import, the themeSCSSPlugin will compile the file using a specific theme configuration.

    Available theme keys:

    • theme-light (uses light.scss)
    • theme-dark (uses dark.scss)
    • theme-light-modular (uses lightWCAG.scss)
    • theme-dark-modular (uses darkWCAG.scss)

    When a themed SCSS file is loaded, the plugin prepends the corresponding theme constants, compiles the SCSS, transforms :root selectors to :host for compatibility, and injects the resulting CSS into the document head with a data-theme attribute matching the theme name (e.g., data-theme="light").

    @import "./styles/my-component.scss?theme-dark";
  5. Configure Vite for WebViewer UI HMR

    12.0

    The vite.ui-hmr.config.js file is a specialized Vite configuration designed to enable Hot Module Replacement (HMR) and Fast Refresh for the WebViewer UI development environment. It includes several custom plugins to handle legacy code patterns and specific UI requirements:

    • Theme Support: themeSCSSPlugin handles themed SCSS via query parameters.
    • SVG Inlining: svgInlinePlugin automatically inlines .svg files as raw strings, stripping width and height attributes.
    • Legacy Compatibility:
      • cjsToEsmPlugin: Converts specific CommonJS patterns (like require('redux-logger')) to ESM.
      • stripReactHotLoaderPlugin: Removes react-hot-loader wrappers to allow Vite's native Fast Refresh to work.
    • Icon Handling: iconGlobPlugin transforms dynamic require() calls for icons into Vite import.meta.glob calls for eager loading.
    • Node Polyfills: Provides process, buffer, util, and stream globals.
    • Emotion Integration: Configures React to use @emotion/react as the JSX runtime.
  6. Initialize the WebViewer UI API

    12.0

    The WebViewer UI API is initialized via a default export function that takes a Redux store, an instanceDocViewerKey, an instanceI18n object, and an instanceRootNode. This function populates the window object with two primary namespaces: Core and UI.

    • Core: Contains access to WebViewer Core functionalities like Tools, Annotations, Actions, and the documentViewer.
    • UI: Contains the high-level API for controlling the user interface, panels, tools, and settings.

    Note that the documentViewer is retrieved using the provided instanceDocViewerKey or a default key from the store state.

    // The API is initialized by calling the default export
    // with the required WebViewer UI dependencies.
    import initializeUI from './src/apis/index.js';
    
    initializeUI(store, instanceDocViewerKey, instanceI18n, instanceRootNode);
    
    // After initialization, you can access the APIs via the window object:
    // window.Core -> Core functionalities
    // window.UI -> UI control functionalities
  7. Troubleshoot NPM dependency tree errors

    12.0

    If you are using NPM version 7 or higher, you may encounter errors regarding the dependency tree. You can resolve this using one of two methods:

    1. Use the legacy flag: Run npm install --legacy-peer-deps.
    2. Downgrade Node: Use Node v14, which uses NPM version 6.
    npm install --legacy-peer-deps
  8. Configure GroupedItems properties

    12.0

    When instantiating GroupedItems, you can provide the following properties in the configuration object:

    PropertyTypeDescription
    dataElementstringA unique identifier for the grouped item.
    placement'top' | 'bottom' | 'left' | 'right'Determines the placement of the header.
    justifyContent'start' | 'end' | 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly'Determines the flex justify content value of the container.
    grownumberThe flex grow value of the container.
    gapnumberThe gap (in pixels) between items.
    position'start' | 'center' | 'end'Determines the position of the container.
    alwaysVisiblebooleanWhether the group should always be visible. Defaults to false.
    styleObjectCSS style object for the container.
    itemsArray<Object>An array of modular components to be grouped.
  9. Create and configure a Flyout component

    12.0

    The Flyout component is used to create flyout menus in the WebViewer UI. You can instantiate it with a unique dataElement and an array of items. Items can be simple objects with labels and click handlers, or they can be nested to create sub-menus.

    FlyoutItem Configuration

    Each item in the items array can be one of the following:

    • An object defining the item properties (see flyoutItemBase).
    • A string, which acts as a divider.
    • A React element.
    • An object with a type that matches a valid FLYOUT_ITEM_TYPES value.

    flyoutItemBase properties:

    • label (string, optional): The text displayed for the item.
    • onClick (function, optional): The callback triggered when the item is clicked.
    • icon (string, optional): A path to an image, base64 data, or a filename of an .svg from the WebViewer icons folder (e.g., icon-save to use icon-save.svg).
    • render (string or function, optional): A preset component name (e.g., 'stylePanel') or a custom render function.
    • children (Array, optional): An array of FlyoutItem objects to create a nested sub-menu.
    • dataElement (string, optional): A unique identifier for the item.
    const flyout = new UI.Components.Flyout({
      dataElement: 'exampleFlyout',
      label: 'Flyout',
    });
    
    flyout.setItems([
      {
        label: 'Item 1',
        onClick: () => {
          console.log('Item 1 clicked');
        },
      },
      {
        label: 'Sub-menu',
        children: [
          {
            label: 'Nested Item',
            onClick: () => console.log('Nested clicked'),
          }
        ]
      },
      'divider-string' // Acts as a divider
    ]);