# # AnnotComponentConfig Dynamic Configuration Guide

## # Overview

`AnnotComponentConfig` is the core configuration API in Foxit PDF SDK for Web, used to control the operational features of annotation components. By dynamically updating the configuration, developers can flexibly manage users' permissions for annotation functionalities at runtime, such as moving, rotating, resizing, and other operations.

## # Core Components

### # 1. AnnotComponentConfig API

`AnnotComponentConfig` API defines all available configuration properties for annotation components, as detailed below:

    export interface AnnotComponentConfig {
        moveable: boolean; // Whether moving is allowed
        rotatable: boolean; // Whether rotation is allowed
        resizable: boolean; // Whether resizing is allowed
        enableDiagonally: boolean; // Whether diagonal resizing is allowed
        moveDirection: string; // Restriction on movement direction
    }

### # 2. CustomOptionsUpdater Class

`CustomOptionsUpdater` is a core class used for dynamically updating configurations, providing the ability to modify annotation operations at runtime.

## # Configuration Properties Detailed Explanation

### # moveable

- Type: `boolean`
- Default Value:
  - Area Highlight Annotation: `false`
  - Other Annotation Types: `true`
- Supported Annotation Types: stamp，circle，ink，link，square，screen，redact，Area highlight，widget
- Functionality: Control whether the annotation can be moved by the user

### # rotatable

- Type: `boolean`
- Default Value: `true`
- Supported Annotation Types: stamp
- Functionality: Control whether the annotation can be rotated by the user

### # resizable

- Type: `boolean`
- Default Value: `true`
- Supported Annotation Types: stamp, circle, ink, link, square, screen, redact, Area highlight, widget
- Functionality: Control whether the annotation can be resized by the user

### # enableDiagonally

- Type: `boolean`
- Default Value: `true`
- Supported Annotation Types: ink, link, square, screen, redact, Area highlight, widget
- Functionality: When `resizable` is set to `true`, it controls whether diagonal resizing is allowed

### # enableFrame

- Type: `boolean`
- Default Value: `false`
- Supported Annotation Types: stamp
- Functionality: Control whether the annotation can be resized from the top, bottom, left, and right directions

### # moveDirection

- Type: `string`
- Default Value: `'All'`
- Supported Annotation Types: stamp, circle, ink, link, square, screen, redact, Area highlight, widget
- Optional Values:
  - `'horizontal'` - Allow movement only in the horizontal direction
  - `'vertical'` - Allow movement only in the vertical direction
  - `'all'` - Allow movement in all directions
- Note: If `moveDirection` is not set to `'all'`, the annotation cannot move across pages

## # Usage

### # 1. Configuration During Initialization

When creating a PDFViewer instance, you can set the initial configuration using the `customs.getAnnotComponentConfig` callback function:

    const pdfViewer = new PDFViewer({
        customs: {
            getAnnotComponentConfig: function (annotComponent, props) {
                const annot = annotComponent.getModel();
                const annotType = annot.getType();

                // Return different configurations based on the annotation type
                switch (annotType) {
                    case "square":
                        return { moveable: false, resizable: true };
                    case "highlight":
                        if (annot.isArea()) {
                            return { moveable: false };
                        }
                        break;
                    case "freetext":
                        return { moveable: false, resizable: false };
                    case "strikeout":
                        return { adjustable: false }; // Textmark annotations only support the adjustable configuration
                    case "line":
                        return { moveable: false, resizable: false }; // Line, arrow, polyline, polygon, and cloud support these two configurations
                    case "text":
                    case "fileattachment":
                        return { moveable: false }; // Text and file attachment annotations only support the moveable configuration
                }
                return {}; // Returning an empty object indicates using the default configuration
            },
        },
    });

### # 2. Dynamically Update Configuration

Use `CustomOptionsUpdater` to dynamically update the configuration at runtime:

    // Get the configuration updater
    const updater = pdfViewer.getCustomOptionsUpdater();

    // Dynamically update the configuration
    updater.updateGetAnnotComponentConfig(function (annotComponent, props) {
        const annot = annotComponent.getModel();
        const annotType = annot.getType();

        // Dynamically return configurations based on business logic
        if (annotType === "square") {
            return {
                moveable: false,
                resizable: true,
                enableDiagonally: false,
            };
        } else if (annotType === "highlight" && annot.isArea()) {
            return {
                moveable: false,
                moveDirection: "horizontal", // Only allow horizontal movement
            };
        }

        return {};
    });

## # Supported Annotation Types Overview

Annotation Type | moveable | rotatable | resizable | enableDiagonally | enableFrame | moveDirection
--- | --- | --- | --- | --- | --- | ---
stamp | ✅ | ✅ | ✅ | ❌ | ✅ | ✅
circle | ✅ | ❌ | ✅ | ✅ | ❌ | ✅
ink | ✅ | ❌ | ✅ | ✅ | ❌ | ✅
link | ✅ | ❌ | ✅ | ✅ | ❌ | ✅
square | ✅ | ❌ | ✅ | ✅ | ❌ | ✅
screen | ✅ | ❌ | ✅ | ✅ | ❌ | ✅
redact | ✅ | ❌ | ✅ | ✅ | ❌ | ✅
Area highlight | ✅ | ❌ | ✅ | ✅ | ❌ | ✅
widget | ✅ | ❌ | ✅ | ✅ | ❌ | ✅
freetext(textbox,callout) | ✅ | ❌ | ✅ | ✅ | ❌ | ❌
freetext(typewriter) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌
text | ✅ | ❌ | ❌ | ❌ | ❌ | ❌
fileattachment | ✅ | ❌ | ❌ | ❌ | ❌ | ❌
textmarks | ❌ | ❌ | ❌ | ❌ | ❌ | ❌

TextMarks (including underline, text highlight, strikeout, squiggly, excluding caret) only support the `adjustable` configuration.

## # Practical Application Scenarios

> Note: In the following code examples, `getCurrentUserRole` and `getUserPermissions` are placeholder functions. Please replace them with your own implementations based on your actual business logic.

### # 1. Document Review Mode

    // In review mode, disable the user's ability to modify annotations
    updater.updateGetAnnotComponentConfig(function (annotComponent, props) {
        const annot = annotComponent.getModel();
        const userRole = getCurrentUserRole(); // Get the current user role

        if (userRole === "reviewer") {
            return {
                moveable: false,
                resizable: false,
                rotatable: false,
            };
        }

        return {};
    });

### # 2. Functionality Control for Specific Annotation Types

    // Control operation functionalities for specific annotation types
    updater.updateGetAnnotComponentConfig(function (annotComponent, props) {
        const annot = annotComponent.getModel();
        const annotType = annot.getType();

        // Disable movement for all "link" annotations
        if (annotType === "link") {
            return { moveable: false };
        }

        // Restrict "stamp" annotations to horizontal movement only
        if (annotType === "stamp") {
            return { moveDirection: "horizontal" };
        }

        return {};
    });

### # 3. Control Based on User Permissions

    // Dynamically control annotation operation functionalities based on user permissions
    updater.updateGetAnnotComponentConfig(function (annotComponent, props) {
        const annot = annotComponent.getModel();
        const userPermissions = getUserPermissions();

        if (!userPermissions.canEditAnnotations) {
            return {
                moveable: false,
                resizable: false,
                rotatable: false,
            };
        }

        if (!userPermissions.canMoveAnnotations) {
            return { moveable: false };
        }

        return {};
    });

## # Notes

1. Configuration Priority: Dynamically updated configurations will override the initial configurations set during initialization.
2. Cross-Page Movement: When `moveDirection` is not `'all'`, annotations cannot be moved across pages.
3. Performance Considerations: Frequent updates to configurations may impact performance. It is recommended to update only when necessary.
4. Type Compatibility: Different annotation types support different configuration options. Ensure that the configuration returned is compatible with the specific type.
5. Feature Nature: These configurations are functional toggles designed to enable/disable UI interaction features, rather than access control based on permissions.

## # Version Information

- Initial Release: 9.1.0
- moveDirection Feature Added: 11.0.0
- Compatibility: Support Foxit PDF SDK for Web 9.1.0 and later