Skip to content
This plugin is new and currently in beta. For the stable version, please use the previous version of the plugin.

BaseApi

Core interface providing fundamental API functionality for all extension components in the Stripo Email Editor Extensions SDK.

typescript
interface BaseApi

Description

The BaseApi interface defines the fundamental API methods available to all extension components, including blocks, controls, renderers, and context actions. It provides access to editor configuration, internationalization, state management, and UI features such as popovers.

Import

typescript
import { BaseApi } from '@stripoinc/ui-editor-extensions';

Properties

None (all functionality is provided through methods)

Methods

getDocumentRootHtmlNode()

Retrieves the root immutable HTML node of the document template.

typescript
getDocumentRootHtmlNode(): ImmutableHtmlNode

Returns

ImmutableHtmlNode - The root HTML node of the email document

Usage Notes

  • Provides read-only access to the entire document structure
  • Use for querying elements across the document
  • Combine with selectors to find specific nodes
  • Immutable nodes ensure document consistency

Example

typescript
const rootNode = this.api.getDocumentRootHtmlNode();
const allImages = rootNode.querySelectorAll('img');
const stripeCount = rootNode.querySelectorAll('.esd-stripe').length;

getDocumentRootCssNode()

Retrieves the root immutable CSS node of the document's stylesheet.

typescript
getDocumentRootCssNode(): ImmutableCssNode

Returns

ImmutableCssNode - The root CSS node containing all styles

Usage Notes

  • Provides access to document-level CSS rules
  • Allows querying for specific CSS rules or media queries
  • Enables reading CSS properties and values
  • Essential for style-related controls

Example

typescript
const desktopH1CssNode = this.api.getDocumentRootCssNode().querySelector('h1');
const mobileH1CssNode = this.api.getDocumentRootCssNode().querySelector('@{media only screen and (max-width: 600px)} h1');

getEditorConfig()

Retrieves the current configuration settings of the editor instance.

typescript
getEditorConfig(): Record<string, unknown>

Returns

Record<string, unknown> - A record object containing editor configuration key-value pairs

Usage Notes

  • Contains editor features, metadata, and settings
  • Configuration is set during editor initialization
  • May include custom metadata for your application
  • Read-only—configuration cannot be modified through this method

Example

typescript
const config = this.api.getEditorConfig();

// Access standard configuration
const locale = config.locale;
const name = config.name;
const emailId = config.metadata.emailId;

// Access custom data
const enabled = config.customBlock?.enabled;

translate()

Translates a given key into the currently configured language, optionally interpolating parameters.

typescript
translate(key: string, params?: Record<string, unknown>): string

Parameters

ParameterTypeDescription
keystringThe localization key to translate
paramsRecord<string, unknown>Optional parameters for interpolation into the translated string

Returns

string - The translated string

Usage Notes

  • Respects the current editor language setting
  • Supports parameter interpolation using placeholders
  • Returns the key itself if translation is not found
  • Essential for creating multilingual extensions

Example

typescript
// Simple translation
const title = this.api.translate('block.product.title');

// Translation with parameters
const message = this.api.translate('block.product.count', {
    count: 5,
    total: 10
});
// If translation is "Showing {count} of {total} products"
// Result: "Showing 5 of 10 products"

// Using in block names
public getName(): string {
    return this.api.translate('blocks.myBlock.name');
}

addCustomFont()

Adds a new font family to the editor configuration.

typescript
addCustomFont(font: CustomFontFamily): void

Parameters

ParameterTypeDescription
fontCustomFontFamilyFont family configuration object

Usage Notes

  • Makes font available in all font selection dropdowns
  • Font CSS is automatically loaded if URL is provided
  • Useful for brand-specific or custom fonts
  • Fonts are available for the entire editor session

Example

typescript
// Add a custom brand font
this.api.addCustomFont({
    name: 'Brand Font',
    fontFamily: 'BrandFont, Arial, sans-serif',
    url: 'https://fonts.example.com/brand-font.css'
});

ignoreClickOutside()

Controls whether clicking outside the current element triggers deselection.

typescript
ignoreClickOutside(ignore: boolean): void

Parameters

ParameterTypeDescription
ignorebooleanIf true, disables deselection on outside clicks; if false, enables it

Usage Notes

  • Useful when showing custom UI that users need to interact with
  • Prevents loss of context when using external controls
  • Remember to reset (set to false) when interaction is complete
  • Only affects the current selection context

Example

typescript
public onSelect(node: ImmutableHtmlNode): void {
    // Prevent deselection while configuration dialog is open
    this.api.ignoreClickOutside(true);

    this.showConfigurationDialog({
        onClose: () => {
            // Re-enable normal deselection behavior
            this.api.ignoreClickOutside(false);
        }
    });
}

// Another example with external panel
private openExternalPanel(): void {
    this.api.ignoreClickOutside(true);

    const panel = document.getElementById('external-panel');
    panel.style.display = 'block';

    panel.addEventListener('close', () => {
        this.api.ignoreClickOutside(false);
    }, { once: true });
}

getEditorState()

Returns information about the active state of the editor.

typescript
getEditorState(): {
    previewDeviceMode: PreviewDeviceMode;
    panelPosition: PanelPosition;
}

Returns

Object containing:

PropertyTypeDescription
previewDeviceModePreviewDeviceModeCurrent preview mode
panelPositionPanelPositionPosition of the settings panel

Usage Notes

  • Use to adapt behavior based on preview mode
  • State reflects current user interface configuration
  • Useful for responsive behavior in extensions

Example

typescript
const state = this.api.getEditorState();

// Adapt to preview mode
if (state.previewDeviceMode === PreviewDeviceMode.MOBILE) {
    // Simplified behavior for mobile preview
    this.useMobileSettings();
} else {
    // Full desktop functionality
    this.useDesktopSettings();
}

// Check panel position
if (state.panelPosition === PanelPosition.BLOCKS_SETTINGS) {
    // Adjust UI accordingly
}

onEditorStatePropUpdated()

Subscribes to changes in specific editor state properties.

typescript
onEditorStatePropUpdated(
    prop: EditorStatePropertyType,
    callback: (newValue: unknown, oldValue: unknown) => void
): void

Parameters

ParameterTypeDescription
propEditorStatePropertyTypeThe property to monitor for changes
callbackFunctionFunction called when the property value changes

EditorStatePropertyType

See EditorStatePropertyType for available property types.

Usage Notes

  • Callback is triggered whenever the specified property changes
  • Useful for reactive UI updates
  • Multiple subscriptions to the same property are supported
  • No automatic cleanup - subscriptions persist for component lifetime

Example

typescript
public onDocumentInit(): void {
    // Monitor preview mode changes
    this.api.onEditorStatePropUpdated(
        EditorStatePropertyType.previewDeviceMode,
        (newMode, oldMode) => {
            console.log(`Preview changed from ${oldMode} to ${newMode}`);
            this.updateBlockDisplay(newMode);
        }
    );
}

private updateBlockDisplay(mode: PreviewDeviceMode): void {
    if (mode === PreviewDeviceMode.MOBILE) {
        // Update for mobile preview
    }
}

openAIPopover()

Opens an AI assistant popover anchored to a target element.

typescript
openAIPopover(options: AIPopoverOptions): void

Parameters

ParameterTypeDescription
optionsAIPopoverOptionsConfiguration for the AI popover

Usage Notes

  • Requires AI features to be enabled in editor configuration
  • Provides context-aware content generation
  • Popover placement auto-adjusts to stay visible
  • User must have appropriate permissions for AI features

Example

typescript
import {ExtensionPopoverType, PopoverSide, UIElement} from '@stripoinc/ui-editor-extensions';

export class AIPopoverUIElement extends UIElement {
    getId() {
        return 'ai-popover-element';
    }

    getTemplate() {
        return `
            <div>
                <button class="ai-button">Improve with AI</button>
            </div>`
    }

    onRender(container) {
        this.aiButton = container.querySelector('.ai-button');
        this.aiButton.addEventListener('click', this.showAiPopover.bind(this));
    }

    showAiPopover() {
        this.api.openAIPopover({
            targetElement: this.aiButton,
            value: 'Hello world',
            preferredSides: [PopoverSide.LEFT],
            type: ExtensionPopoverType.AI_TEXT,
            onResult: (result) => {console.log(result)}
        })
    }

    onDestroy() {
        this.aiButton.removeEventListener('click', this.showAiPopover.bind(this));
    }
}

openEmojiPopover()

Opens an emoji picker popover anchored to a target element.

typescript
openEmojiPopover(options: EmojiPopoverOptions): void

Parameters

ParameterTypeDescription
optionsEmojiPopoverOptionsConfiguration for the emoji picker

Usage Notes

  • Shows native emoji picker interface
  • Supports search and categories
  • Auto-positions to stay within viewport
  • Returns the selected emoji character

Example

typescript
import {ExtensionPopoverType, PopoverSide, UIElement} from '@stripoinc/ui-editor-extensions';

export class EmojiPopoverUIElement extends UIElement {
    getId() {
        return 'emoji-popover-element';
    }

    getTemplate() {
        return `
            <div>
                <button class="emoji-button">Pick Emoji</button>
            </div>`
    }

    onRender(container) {
        this.emojiButton = container.querySelector('.emoji-button');
        this.emojiButton.addEventListener('click', this.showEmojiPopover.bind(this));
    }

    showEmojiPopover() {
        this.api.openEmojiPopover({
            targetElement: this.emojiButton,
            preferredSides: [PopoverSide.LEFT],
            onResult: (result) => {console.log(result)}
        })
    }

    onDestroy() {
        this.emojiButton.removeEventListener('click', this.showEmojiPopover.bind(this));
    }
}

Implementation Context

The BaseApi is available in various extension components through their respective API properties:

  • Block: Access via this.api in block methods
  • Control: Access via this.api in control methods
  • BlockRenderer: Access via this.api in renderer methods
  • ContextAction: Access via this.api in action methods

Best Practices

  1. Always use translations for user-facing text to support internationalization
  2. Check configuration before using optional features
  3. Reset interaction states (like ignoreClickOutside) when done
  4. Subscribe to state changes early in component lifecycle
  5. Validate configuration values before using them